1 /*******************************************************************************
2 Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
4 (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
5 Jerremy Koot (jkoot@snes9x.com)
7 (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
9 (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
10 funkyass (funkyass@spam.shaw.ca),
11 Joel Yliluoma (http://iki.fi/bisqwit/)
12 Kris Bleakley (codeviolation@hotmail.com),
14 Nach (n-a-c-h@users.sourceforge.net),
15 Peter Bortas (peter@bortas.org) and
16 zones (kasumitokoduck@yahoo.com)
18 C4 x86 assembler and some C emulation code
19 (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
20 _Demo_ (_demo_@zsnes.com), and Nach
23 (c) Copyright 2003 Brad Jorsch
26 (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
27 John Weidman, neviksti (neviksti@hotmail.com),
28 Kris Bleakley, Andreas Naive
31 (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
32 Lord Nightmare (lord_nightmare@users.sourceforge.net
35 (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
37 Ported from x86 assembler to C by sanmaiwashi
39 SPC7110 and RTC C++ emulator code
40 (c) Copyright 2002 Matthew Kendora with research by
41 zsKnight, John Weidman, and Dark Force
44 (c) Copyright 2003 Brad Jorsch with research by
45 Andreas Naive and John Weidman
48 (c) Copyright 2001 John Weidman
50 ST010 C++ emulator code
51 (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
53 Super FX x86 assembler emulator code
54 (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
56 Super FX C emulator code
57 (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
60 SH assembler code partly based on x86 assembler code
61 (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
64 Specific ports contains the works of other authors. See headers in
67 Snes9x homepage: http://www.snes9x.com
69 Permission to use, copy, modify and distribute Snes9x in both binary and
70 source form, for non-commercial purposes, is hereby granted without fee,
71 providing that this license information and copyright notice appear with
72 all copies and any derived work.
74 This software is provided 'as-is', without any express or implied
75 warranty. In no event shall the authors be held liable for any damages
76 arising from the use of this software.
78 Snes9x is freeware for PERSONAL USE only. Commercial users should
79 seek permission of the copyright holders first. Commercial use includes
80 charging money for Snes9x or software derived from Snes9x.
82 The copyright holders request that bug fixes and improvements to the code
83 should be forwarded to them so everyone can benefit from the modifications
86 Super NES and Super Nintendo Entertainment System are trademarks of
87 Nintendo Co., Limited and its subsidiary companies.
88 *******************************************************************************/
93 // Mode 7 scaling constants for all raster lines
94 const int16 ST010_M7Scale[176] = {
95 0x0380, 0x0325, 0x02da, 0x029c, 0x0268, 0x023b, 0x0215, 0x01f3,
96 0x01d5, 0x01bb, 0x01a3, 0x018e, 0x017b, 0x016a, 0x015a, 0x014b,
97 0x013e, 0x0132, 0x0126, 0x011c, 0x0112, 0x0109, 0x0100, 0x00f8,
98 0x00f0, 0x00e9, 0x00e3, 0x00dc, 0x00d6, 0x00d1, 0x00cb, 0x00c6,
99 0x00c1, 0x00bd, 0x00b8, 0x00b4, 0x00b0, 0x00ac, 0x00a8, 0x00a5,
100 0x00a2, 0x009e, 0x009b, 0x0098, 0x0095, 0x0093, 0x0090, 0x008d,
101 0x008b, 0x0088, 0x0086, 0x0084, 0x0082, 0x0080, 0x007e, 0x007c,
102 0x007a, 0x0078, 0x0076, 0x0074, 0x0073, 0x0071, 0x006f, 0x006e,
103 0x006c, 0x006b, 0x0069, 0x0068, 0x0067, 0x0065, 0x0064, 0x0063,
104 0x0062, 0x0060, 0x005f, 0x005e, 0x005d, 0x005c, 0x005b, 0x005a,
105 0x0059, 0x0058, 0x0057, 0x0056, 0x0055, 0x0054, 0x0053, 0x0052,
106 0x0051, 0x0051, 0x0050, 0x004f, 0x004e, 0x004d, 0x004d, 0x004c,
107 0x004b, 0x004b, 0x004a, 0x0049, 0x0048, 0x0048, 0x0047, 0x0047,
108 0x0046, 0x0045, 0x0045, 0x0044, 0x0044, 0x0043, 0x0042, 0x0042,
109 0x0041, 0x0041, 0x0040, 0x0040, 0x003f, 0x003f, 0x003e, 0x003e,
110 0x003d, 0x003d, 0x003c, 0x003c, 0x003b, 0x003b, 0x003a, 0x003a,
111 0x003a, 0x0039, 0x0039, 0x0038, 0x0038, 0x0038, 0x0037, 0x0037,
112 0x0036, 0x0036, 0x0036, 0x0035, 0x0035, 0x0035, 0x0034, 0x0034,
113 0x0034, 0x0033, 0x0033, 0x0033, 0x0032, 0x0032, 0x0032, 0x0031,
114 0x0031, 0x0031, 0x0030, 0x0030, 0x0030, 0x0030, 0x002f, 0x002f,
115 0x002f, 0x002e, 0x002e, 0x002e, 0x002e, 0x002d, 0x002d, 0x002d,
116 0x002d, 0x002c, 0x002c, 0x002c, 0x002c, 0x002b, 0x002b, 0x002b
122 //temporary Op04 requirement
126 #define PI 3.1415926535897932384626433832795
131 uint8 S9xGetST010(uint32 Address)
133 if(!(Address&0x80000))
136 if((Address&0xFFF)==0x20)
138 if ((Address&0xFFF)==0x21)
139 return ST010.execute;
140 return Memory.SRAM[Address&CPU.Memory_SRAMMask];
143 const int16 ST010_SinTable[256] = {
144 0x0000, 0x0324, 0x0648, 0x096a, 0x0c8c, 0x0fab, 0x12c8, 0x15e2,
145 0x18f9, 0x1c0b, 0x1f1a, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11,
146 0x30fb, 0x33df, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a,
147 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842,
148 0x5a82, 0x5cb3, 0x5ed7, 0x60eb, 0x62f1, 0x64e8, 0x66cf, 0x68a6,
149 0x6a6d, 0x6c23, 0x6dc9, 0x6f5e, 0x70e2, 0x7254, 0x73b5, 0x7504,
150 0x7641, 0x776b, 0x7884, 0x7989, 0x7a7c, 0x7b5c, 0x7c29, 0x7ce3,
151 0x7d89, 0x7e1d, 0x7e9c, 0x7f09, 0x7f61, 0x7fa6, 0x7fd8, 0x7ff5,
152 0x7fff, 0x7ff5, 0x7fd8, 0x7fa6, 0x7f61, 0x7f09, 0x7e9c, 0x7e1d,
153 0x7d89, 0x7ce3, 0x7c29, 0x7b5c, 0x7a7c, 0x7989, 0x7884, 0x776b,
154 0x7641, 0x7504, 0x73b5, 0x7254, 0x70e2, 0x6f5e, 0x6dc9, 0x6c23,
155 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f1, 0x60eb, 0x5ed7, 0x5cb3,
156 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4,
157 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33df,
158 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f1a, 0x1c0b,
159 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8c, 0x096a, 0x0648, 0x0324,
160 0x0000, -0x0324, -0x0648, -0x096b, -0x0c8c, -0x0fab, -0x12c8, -0x15e2,
161 -0x18f9, -0x1c0b, -0x1f1a, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11,
162 -0x30fb, -0x33df, -0x36ba, -0x398d, -0x3c56, -0x3f17, -0x41ce, -0x447a,
163 -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842,
164 -0x5a82, -0x5cb3, -0x5ed7, -0x60ec, -0x62f1, -0x64e8, -0x66cf, -0x68a6,
165 -0x6a6d, -0x6c23, -0x6dc9, -0x6f5e, -0x70e2, -0x7254, -0x73b5, -0x7504,
166 -0x7641, -0x776b, -0x7884, -0x7989, -0x7a7c, -0x7b5c, -0x7c29, -0x7ce3,
167 -0x7d89, -0x7e1d, -0x7e9c, -0x7f09, -0x7f61, -0x7fa6, -0x7fd8, -0x7ff5,
168 -0x7fff, -0x7ff5, -0x7fd8, -0x7fa6, -0x7f61, -0x7f09, -0x7e9c, -0x7e1d,
169 -0x7d89, -0x7ce3, -0x7c29, -0x7b5c, -0x7a7c, -0x7989, -0x7883, -0x776b,
170 -0x7641, -0x7504, -0x73b5, -0x7254, -0x70e2, -0x6f5e, -0x6dc9, -0x6c23,
171 -0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f1, -0x60eb, -0x5ed7, -0x5cb3,
172 -0x5a82, -0x5842, -0x55f5, -0x539a, -0x5133, -0x4ebf, -0x4c3f, -0x49b3,
173 -0x471c, -0x447a, -0x41cd, -0x3f17, -0x3c56, -0x398c, -0x36b9, -0x33de,
174 -0x30fb, -0x2e10, -0x2b1f, -0x2826, -0x2527, -0x2223, -0x1f19, -0x1c0b,
175 -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324};
177 const unsigned char ST010_ArcTan[32][32] = {
178 { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
179 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
180 { 0x80, 0xa0, 0xad, 0xb3, 0xb6, 0xb8, 0xb9, 0xba, 0xbb, 0xbb, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd,
181 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf},
182 { 0x80, 0x93, 0xa0, 0xa8, 0xad, 0xb0, 0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb,
183 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd},
184 { 0x80, 0x8d, 0x98, 0xa0, 0xa6, 0xaa, 0xad, 0xb0, 0xb1, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb7, 0xb8,
185 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc},
186 { 0x80, 0x8a, 0x93, 0x9a, 0xa0, 0xa5, 0xa8, 0xab, 0xad, 0xaf, 0xb0, 0xb2, 0xb3, 0xb4, 0xb5, 0xb5,
187 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb},
188 { 0x80, 0x88, 0x90, 0x96, 0x9b, 0xa0, 0xa4, 0xa7, 0xa9, 0xab, 0xad, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
189 0xb4, 0xb4, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9},
190 { 0x80, 0x87, 0x8d, 0x93, 0x98, 0x9c, 0xa0, 0xa3, 0xa6, 0xa8, 0xaa, 0xac, 0xad, 0xae, 0xb0, 0xb0,
191 0xb1, 0xb2, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8},
192 { 0x80, 0x86, 0x8b, 0x90, 0x95, 0x99, 0x9d, 0xa0, 0xa3, 0xa5, 0xa7, 0xa9, 0xaa, 0xac, 0xad, 0xae,
193 0xaf, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7},
194 { 0x80, 0x85, 0x8a, 0x8f, 0x93, 0x97, 0x9a, 0x9d, 0xa0, 0xa2, 0xa5, 0xa6, 0xa8, 0xaa, 0xab, 0xac,
195 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, 0xb5},
196 { 0x80, 0x85, 0x89, 0x8d, 0x91, 0x95, 0x98, 0x9b, 0x9e, 0xa0, 0xa0, 0xa4, 0xa6, 0xa7, 0xa9, 0xaa,
197 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4},
198 { 0x80, 0x84, 0x88, 0x8c, 0x90, 0x93, 0x96, 0x99, 0x9b, 0x9e, 0xa0, 0xa2, 0xa4, 0xa5, 0xa7, 0xa8,
199 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3},
200 { 0x80, 0x84, 0x87, 0x8b, 0x8e, 0x91, 0x94, 0x97, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5, 0xa6,
201 0xa7, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2},
202 { 0x80, 0x83, 0x87, 0x8a, 0x8d, 0x90, 0x93, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5,
203 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1},
204 { 0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x94, 0x96, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa2, 0xa3,
205 0xa4, 0xa5, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xb0},
206 { 0x80, 0x83, 0x86, 0x89, 0x8b, 0x8e, 0x90, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa1,
207 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf},
208 { 0x80, 0x83, 0x85, 0x88, 0x8b, 0x8d, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9b, 0x9d, 0x9f, 0xa0,
209 0xa1, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae},
210 { 0x80, 0x83, 0x85, 0x88, 0x8a, 0x8c, 0x8f, 0x91, 0x93, 0x95, 0x97, 0x99, 0x9a, 0x9c, 0x9d, 0x9f,
211 0xa0, 0xa1, 0xa2, 0xa3, 0xa5, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xab, 0xac, 0xad},
212 { 0x80, 0x82, 0x85, 0x87, 0x89, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x97, 0x99, 0x9b, 0x9c, 0x9d,
213 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac},
214 { 0x80, 0x82, 0x85, 0x87, 0x89, 0x8b, 0x8d, 0x8f, 0x91, 0x93, 0x95, 0x96, 0x98, 0x99, 0x9b, 0x9c,
215 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab},
216 { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x9a, 0x9b,
217 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa},
218 { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x99, 0x9a,
219 0x9b, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9},
220 { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8f, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x99,
221 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8},
222 { 0x80, 0x82, 0x84, 0x86, 0x87, 0x89, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x98,
223 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7},
224 { 0x80, 0x82, 0x84, 0x85, 0x87, 0x89, 0x8a, 0x8c, 0x8e, 0x8f, 0x91, 0x92, 0x94, 0x95, 0x96, 0x98,
225 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6},
226 { 0x80, 0x82, 0x83, 0x85, 0x87, 0x88, 0x8a, 0x8c, 0x8d, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x96, 0x97,
227 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5},
228 { 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x94, 0x95, 0x96,
229 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4},
230 { 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x89, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x95,
231 0x96, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4},
232 { 0x80, 0x82, 0x83, 0x85, 0x86, 0x87, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, 0x95,
233 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2, 0xa3},
234 { 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8d, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94,
235 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2},
236 { 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x88, 0x8a, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93,
237 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1, 0xa1},
238 { 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8b, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93,
239 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1},
240 { 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92,
241 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0}};
243 short ST010_Sin(short Theta)
245 return ST010_SinTable[(Theta >> 8) & 0xff];
248 short ST010_Cos(short Theta)
250 return ST010_SinTable[((Theta + 0x4000) >> 8) & 0xff];
253 void ST010_OP01(short x0, short y0, short &x1, short &y1, short &Quadrant, short &Theta)
255 if ((x0 < 0) && (y0 < 0))
280 while ((x1 > 0x1f) || (y1 > 0x1f))
282 if (x1 > 1) x1 >>= 1;
283 if (y1 > 1) y1 >>= 1;
286 if (y1 == 0) Quadrant += 0x4000;
288 Theta = (ST010_ArcTan[y1][x1] << 8) ^ Quadrant;
291 void ST010_Scale(short Multiplier, short X0, short Y0, int &X1, int &Y1)
293 X1 = X0 * Multiplier << 1;
294 Y1 = Y0 * Multiplier << 1;
297 void ST010_Multiply(short Multiplicand, short Multiplier, int &Product)
299 Product = Multiplicand * Multiplier << 1;
302 void ST010_Rotate(short Theta, short X0, short Y0, short &X1, short &Y1)
304 X1 = (Y0 * ST010_Sin(Theta) >> 15) + (X0 * ST010_Cos(Theta) >> 15);
305 Y1 = (Y0 * ST010_Cos(Theta) >> 15) - (X0 * ST010_Sin(Theta) >> 15);
308 void SETA_Distance(short Y0, short X0, short &Distance)
310 if (X0 < 0) X0 = -X0;
311 if (Y0 < 0) Y0 = -Y0;
312 Distance = ((X0 * 0x7af0) + 0x4000) >> 15;
315 void ST010_SortDrivers(uint16 Positions, uint16 Places[32], uint16 Drivers[32])
323 for (int i = 0; i < Positions - 1; i++)
324 if (Places[i] < Places[i + 1])
326 Temp = Places[i + 1];
327 Places[i + 1] = Places[i];
330 Temp = Drivers[i + 1];
331 Drivers[i + 1] = Drivers[i];
340 #define ST010_WORD(offset) (Memory.SRAM[offset + 1] << 8) | Memory.SRAM[offset]
342 void S9xSetST010(uint32 Address, uint8 Byte)
344 if(!(Address&0x80000))
346 ST010.control_enable=TRUE;
349 //printf("Write %06X:%02X\n", Address, Byte);
351 if((Address &0xFFF) ==0x20 && ST010.control_enable)
353 if((Address &0xFFF) ==0x21 && ST010.control_enable)
355 else Memory.SRAM[Address&CPU.Memory_SRAMMask]=Byte;
357 if(ST010.execute&0x80)
361 // Sorts Driver Placements
364 // 0x0024-0x0025 : Positions
365 // 0x0040-0x007f : Places
366 // 0x0080-0x00ff : Drivers
368 // 0x0040-0x007f : Places
369 // 0x0080-0x00ff : Drivers
373 #ifdef FAST_LSB_WORD_ACCESS
374 ST010_SortDrivers(*(short*)&SRAM[0x0024], (uint16*) (SRAM + 0x0040), (uint16*) (SRAM + 0x0080));
377 uint16 Positions = ST010_WORD(0x0024);
382 for (Pos = 0; Pos < Positions; Pos++)
384 Places[Pos] = ST010_WORD(0x0040 + Offset);
388 ST010_SortDrivers(Positions, Places, (uint16*) (SRAM + 0x0080));
392 for (Pos = 0; Pos < Positions; Pos++)
394 SRAM[0x0040 + Offset]=(uint8)(Places[Pos]);
395 SRAM[0x0041 + Offset]=(uint8)(Places[Pos] >> 8);
403 // Two Dimensional Coordinate Scale
406 // 0x0000-0x0001 : X0 (signed)
407 // 0x0002-0x0003 : Y0 (signed)
408 // 0x0004-0x0005 : Multiplier (signed)
410 // 0x0010-0x0013 : X1 (signed)
411 // 0x0014-0x0017 : Y1 (signed)
415 #ifdef FAST_LSB_WORD_ACCESS
416 ST010_Scale(*(short*)&Memory.SRAM[0x0004], *(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002],
417 (int&) Memory.SRAM[0x0010], (int&) Memory.SRAM[0x0014]);
421 ST010_Scale(ST010_WORD(0x0004), ST010_WORD(0x0000), ST010_WORD(0x0002), x1, y1);
423 Memory.SRAM[0x0010]=(uint8)(x1);
424 Memory.SRAM[0x0011]=(uint8)(x1 >> 8);
425 Memory.SRAM[0x0012]=(uint8)(x1 >> 16);
426 Memory.SRAM[0x0013]=(uint8)(x1 >> 24);
427 Memory.SRAM[0x0014]=(uint8)(y1);
428 Memory.SRAM[0x0015]=(uint8)(y1 >> 8);
429 Memory.SRAM[0x0016]=(uint8)(y1 >> 16);
430 Memory.SRAM[0x0017]=(uint8)(y1 >> 24);
435 // 16-bit Multiplication
438 // 0x0000-0x0001 : Multiplcand (signed)
439 // 0x0002-0x0003 : Multiplier (signed)
441 // 0x0010-0x0013 : Product (signed)
445 #ifdef FAST_LSB_WORD_ACCESS
446 ST010_Multiply(*(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002], (int&) Memory.SRAM[0x0010]);
450 ST010_Multiply(ST010_WORD(0x0000), ST010_WORD(0x0002), Product);
452 Memory.SRAM[0x0010]=(uint8)(Product);
453 Memory.SRAM[0x0011]=(uint8)(Product >> 8);
454 Memory.SRAM[0x0012]=(uint8)(Product >> 16);
455 Memory.SRAM[0x0013]=(uint8)(Product >> 24);
460 // Mode 7 Raster Data Calculation
463 // 0x0000-0x0001 : Angle (signed)
465 // 0x00f0-0x024f : Mode 7 Matrix A
466 // 0x0250-0x03af : Mode 7 Matrix B
467 // 0x03b0-0x050f : Mode 7 Matrix C
468 // 0x0510-0x066f : Mode 7 Matrix D
474 int16 Theta = ST010_WORD(0x0000);
476 for (int32 line = 0; line < 176; line++)
478 // Calculate Mode 7 Matrix A/D data
479 data = ST010_M7Scale[line] * ST010_Cos(Theta) >> 15;
481 Memory.SRAM[0x00f0 + offset]=(uint8)(data);
482 Memory.SRAM[0x00f1 + offset]=(uint8)(data >> 8);
483 Memory.SRAM[0x0510 + offset]=(uint8)(data);
484 Memory.SRAM[0x0511 + offset]=(uint8)(data >> 8);
486 // Calculate Mode 7 Matrix B/C data
487 data = ST010_M7Scale[line] * ST010_Sin(Theta) >> 15;
489 Memory.SRAM[0x0250 + offset]=(uint8)(data);
490 Memory.SRAM[0x0251 + offset]=(uint8)(data >> 8);
492 if (data) data = ~data;
494 Memory.SRAM[0x03b0 + offset]=(uint8)(data);
495 Memory.SRAM[0x03b1 + offset]=(uint8)(data >> 8);
500 // Shift Angle for use with Lookup table
501 Memory.SRAM[0x00] = Memory.SRAM[0x01];
502 Memory.SRAM[0x01] = 0x00;
507 // Two dimensional Coordinate Rotation
510 // 0x0000-0x0001 : X0 (signed)
511 // 0x0002-0x0003 : Y0 (signed)
512 // 0x0004-0x0005 : Angle (signed)
514 // 0x0010-0x0011 : X1 (signed)
515 // 0x0012-0x0013 : Y1 (signed)
519 #ifdef FAST_LSB_WORD_ACCESS
520 ST010_Rotate(*(short*)&Memory.SRAM[0x0004], *(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002],
521 (short&) Memory.SRAM[0x0010], (short&) Memory.SRAM[0x0012]);
525 ST010_Rotate(ST010_WORD(0x0004), ST010_WORD(0x0000), ST010_WORD(0x0002), x1, y1);
527 Memory.SRAM[0x0010]=(uint8)(x1);
528 Memory.SRAM[0x0011]=(uint8)(x1 >> 8);
529 Memory.SRAM[0x0012]=(uint8)(y1);
530 Memory.SRAM[0x0013]=(uint8)(y1 >> 8);
536 // 0x0000-0x0001 : DX (signed)
537 // 0x0002-0x0003 : DY (signed)
539 // 0x0010-0x0011 : Angle (signed)
543 Memory.SRAM[0x0006] = Memory.SRAM[0x0002];
544 Memory.SRAM[0x0007] = Memory.SRAM[0x0003];
546 #ifdef FAST_LSB_WORD_ACCESS
547 ST010_OP01(*(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002],
548 (short&) Memory.SRAM[0x0000], (short&) Memory.SRAM[0x0002],
549 (short&) Memory.SRAM[0x0004], (short&) Memory.SRAM[0x0010]);
551 short x1, y1, Quadrant, Theta;
553 ST010_OP01(ST010_WORD(0x0000), ST010_WORD(0x0002), x1, y1, Quadrant, Theta);
555 Memory.SRAM[0x0000]=(uint8)(x1);
556 Memory.SRAM[0x0001]=(uint8)(x1 >> 8);
557 Memory.SRAM[0x0002]=(uint8)(y1);
558 Memory.SRAM[0x0003]=(uint8)(y1 >> 8);
559 Memory.SRAM[0x0004]=(uint8)(Quadrant);
560 Memory.SRAM[0x0005]=(uint8)(Quadrant >> 8);
561 Memory.SRAM[0x0010]=(uint8)(Theta);
562 Memory.SRAM[0x0011]=(uint8)(Theta >> 8);
567 // calculate the vector length of (x,y)
571 #ifdef FAST_LSB_WORD_ACCESS
572 x=*((int16*)Memory.SRAM);
573 y=*((int16*)&Memory.SRAM[2]);
575 x=Memory.SRAM[0]|(Memory.SRAM[1]<<8);
576 y=Memory.SRAM[2]|(Memory.SRAM[3]<<8);
578 square=(int16)sqrt((double)(y*y+x*x));
579 //SETA_Distance( x,y,square );
581 #ifdef FAST_LSB_WORD_ACCESS
582 *((int16*)&Memory.SRAM[0x10])=square;
584 Memory.SRAM[0x10]=(uint8)(square);
585 Memory.SRAM[0x11]=(uint8)(square>>8);
590 // calculate AI orientation based on specific guidelines
599 // target (x,y) coordinates
600 int16 ypos_max = ST010_WORD(0x00C0);
601 int16 xpos_max = ST010_WORD(0x00C2);
603 // current coordinates and direction
604 int32 ypos = SRAM[0xC4]|(SRAM[0xC5]<<8)|(SRAM[0xC6]<<16)|(SRAM[0xC7]<<24);
605 int32 xpos = SRAM[0xC8]|(SRAM[0xC9]<<8)|(SRAM[0xCA]<<16)|(SRAM[0xCB]<<24);
606 uint16 rot = SRAM[0xCC]|(SRAM[0xCD]<<8);
609 uint16 speed = ST010_WORD(0x00D4);
610 uint16 accel = ST010_WORD(0x00D6);
611 uint16 speed_max = ST010_WORD(0x00D8);
613 // special condition acknowledgment
614 int16 system = ST010_WORD(0x00DA);
615 int16 flags = ST010_WORD(0x00DC);
617 // new target coordinates
618 int16 ypos_new = ST010_WORD(0x00DE);
619 int16 xpos_new = ST010_WORD(0x00E0);
624 // get the current distance
625 dx = xpos_max-(xpos>>16);
626 dy = ypos_max-(ypos>>16);
628 // quirk: clear and move in9
634 // grab the target angle
635 ST010_OP01(dy,dx,a1,b1,c1,(int16 &)o1);
637 // check for wrapping
638 //if((o1<0x6000 && rot>0xA000) ||
639 // (rot<0x6000 && o1>0xA000))
641 if(abs(o1-rot)>0x8000)
655 if(abs(o1-rot)==0x8000)
659 // slow down for sharp curves
660 else if(abs(o1-rot)>=0x1000)
662 uint32 slow = abs(o1-rot);
663 slow >>= 4; // scaling
666 // otherwise accelerate
670 if(speed > speed_max)
677 // prevent negative/positive overflow
678 if(abs(old_speed-speed)>0x8000) {
679 if(old_speed<speed) speed=0;
683 // adjust direction by so many degrees
684 // be careful of negative adjustments
685 if( (o1>rot && (o1-rot)>0x80) ||
686 (o1<rot && (rot-o1)>=0x80) )
688 if(o1<rot) rot-=0x280;
689 else if(o1>rot) rot+=0x280;
693 if(wrap) rot-=0x8000;
695 // now check the distances (store for later)
696 dx = (xpos_max<<16)-xpos;
697 dy = (ypos_max<<16)-ypos;
701 // if we're in so many units of the target, signal it
702 if( ( system && (dy<=6 && dy>=-8) && (dx<=126 && dx>=-128)) ||
703 (!system && (dx<=6 && dx>=-8) && (dy<=126 && dy>=-128)) )
705 // announce our new destination and flag it
706 xpos_max = xpos_new&0x7FFF;
712 xpos -= (ST010_Cos(rot) * 0x400 >> 15) * (speed >> 8) << 1;
713 ypos -= (ST010_Sin(rot) * 0x400 >> 15) * (speed >> 8) << 1;
715 // quirk: mask upper byte
719 SRAM[0x00C0]=(uint8)(ypos_max);
720 SRAM[0x00C1]=(uint8)(ypos_max >> 8);
721 SRAM[0x00C2]=(uint8)(xpos_max);
722 SRAM[0x00C3]=(uint8)(xpos_max >> 8);
723 SRAM[0x00C4]=(uint8)(ypos);
724 SRAM[0x00C5]=(uint8)(ypos >> 8);
725 SRAM[0x00C6]=(uint8)(ypos >> 16);
726 SRAM[0x00C7]=(uint8)(ypos >> 24);
727 SRAM[0x00C8]=(uint8)(xpos);
728 SRAM[0x00C9]=(uint8)(xpos >> 8);
729 SRAM[0x00CA]=(uint8)(xpos >> 16);
730 SRAM[0x00CB]=(uint8)(xpos >> 24);
731 SRAM[0x00CC]=(uint8)(rot);
732 SRAM[0x00CD]=(uint8)(rot >> 8);
733 SRAM[0x00D4]=(uint8)(speed);
734 SRAM[0x00D5]=(uint8)(speed >> 8);
735 SRAM[0x00DC]=(uint8)(flags);
736 SRAM[0x00DD]=(uint8)(flags >> 8);
742 printf("Unknown Op\n");
746 // lower signal: op processed