~ubuntu-branches/ubuntu/lucid/sdlmame/lucid

« back to all changes in this revision

Viewing changes to src/mame/machine/snesst10.c

  • Committer: Bazaar Package Importer
  • Author(s): Cesare Falco
  • Date: 2009-11-03 17:10:15 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20091103171015-6hop4ory5lxnumpn
Tags: 0.135-0ubuntu1
* New upstream release - Closes (LP: #403212)
* debian/watch: unstable releases are no longer detected
* mame.ini: added the cheat subdirectories to cheatpath so zipped
  cheatfiles will be searched too
* renamed crsshair subdirectory to crosshair to reflect upstream change
* mame.ini: renamed references to crosshair subdirectory (see above)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 
 
3
    snesst10.c
 
4
 
 
5
    File to handle emulation of the SNES "Seta ST-010" add-on chip.
 
6
 
 
7
    Code based on original work by The Dumper, Matthew Kendora,
 
8
    Overload and Feather.
 
9
    This implementation is based on byuu's BSNES C++ version
 
10
 
 
11
    Byuu's code is released under GNU General Public License
 
12
    version 2 as published by the Free Software Foundation.
 
13
    The implementation below is released under the MAME license
 
14
    for use in MAME, MESS and derivatives by permission of the author.
 
15
 
 
16
***************************************************************************/
 
17
 
 
18
typedef struct
 
19
{
 
20
        INT16 x1, y1, quadrant, theta, o1;
 
21
        UINT8 *ram;
 
22
} _snes_st010_t;
 
23
 
 
24
static _snes_st010_t snes_st010;
 
25
 
 
26
static const INT16 st010_sin_table[256] = {
 
27
   0x0000,  0x0324,  0x0648,  0x096a,  0x0c8c,  0x0fab,  0x12c8,  0x15e2,
 
28
   0x18f9,  0x1c0b,  0x1f1a,  0x2223,  0x2528,  0x2826,  0x2b1f,  0x2e11,
 
29
   0x30fb,  0x33df,  0x36ba,  0x398c,  0x3c56,  0x3f17,  0x41ce,  0x447a,
 
30
   0x471c,  0x49b4,  0x4c3f,  0x4ebf,  0x5133,  0x539b,  0x55f5,  0x5842,
 
31
   0x5a82,  0x5cb3,  0x5ed7,  0x60eb,  0x62f1,  0x64e8,  0x66cf,  0x68a6,
 
32
   0x6a6d,  0x6c23,  0x6dc9,  0x6f5e,  0x70e2,  0x7254,  0x73b5,  0x7504,
 
33
   0x7641,  0x776b,  0x7884,  0x7989,  0x7a7c,  0x7b5c,  0x7c29,  0x7ce3,
 
34
   0x7d89,  0x7e1d,  0x7e9c,  0x7f09,  0x7f61,  0x7fa6,  0x7fd8,  0x7ff5,
 
35
   0x7fff,  0x7ff5,  0x7fd8,  0x7fa6,  0x7f61,  0x7f09,  0x7e9c,  0x7e1d,
 
36
   0x7d89,  0x7ce3,  0x7c29,  0x7b5c,  0x7a7c,  0x7989,  0x7884,  0x776b,
 
37
   0x7641,  0x7504,  0x73b5,  0x7254,  0x70e2,  0x6f5e,  0x6dc9,  0x6c23,
 
38
   0x6a6d,  0x68a6,  0x66cf,  0x64e8,  0x62f1,  0x60eb,  0x5ed7,  0x5cb3,
 
39
   0x5a82,  0x5842,  0x55f5,  0x539b,  0x5133,  0x4ebf,  0x4c3f,  0x49b4,
 
40
   0x471c,  0x447a,  0x41ce,  0x3f17,  0x3c56,  0x398c,  0x36ba,  0x33df,
 
41
   0x30fb,  0x2e11,  0x2b1f,  0x2826,  0x2528,  0x2223,  0x1f1a,  0x1c0b,
 
42
   0x18f8,  0x15e2,  0x12c8,  0x0fab,  0x0c8c,  0x096a,  0x0648,  0x0324,
 
43
   0x0000, -0x0324, -0x0648, -0x096b, -0x0c8c, -0x0fab, -0x12c8, -0x15e2,
 
44
  -0x18f9, -0x1c0b, -0x1f1a, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11,
 
45
  -0x30fb, -0x33df, -0x36ba, -0x398d, -0x3c56, -0x3f17, -0x41ce, -0x447a,
 
46
  -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842,
 
47
  -0x5a82, -0x5cb3, -0x5ed7, -0x60ec, -0x62f1, -0x64e8, -0x66cf, -0x68a6,
 
48
  -0x6a6d, -0x6c23, -0x6dc9, -0x6f5e, -0x70e2, -0x7254, -0x73b5, -0x7504,
 
49
  -0x7641, -0x776b, -0x7884, -0x7989, -0x7a7c, -0x7b5c, -0x7c29, -0x7ce3,
 
50
  -0x7d89, -0x7e1d, -0x7e9c, -0x7f09, -0x7f61, -0x7fa6, -0x7fd8, -0x7ff5,
 
51
  -0x7fff, -0x7ff5, -0x7fd8, -0x7fa6, -0x7f61, -0x7f09, -0x7e9c, -0x7e1d,
 
52
  -0x7d89, -0x7ce3, -0x7c29, -0x7b5c, -0x7a7c, -0x7989, -0x7883, -0x776b,
 
53
  -0x7641, -0x7504, -0x73b5, -0x7254, -0x70e2, -0x6f5e, -0x6dc9, -0x6c23,
 
54
  -0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f1, -0x60eb, -0x5ed7, -0x5cb3,
 
55
  -0x5a82, -0x5842, -0x55f5, -0x539a, -0x5133, -0x4ebf, -0x4c3f, -0x49b3,
 
56
  -0x471c, -0x447a, -0x41cd, -0x3f17, -0x3c56, -0x398c, -0x36b9, -0x33de,
 
57
  -0x30fb, -0x2e10, -0x2b1f, -0x2826, -0x2527, -0x2223, -0x1f19, -0x1c0b,
 
58
  -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324
 
59
};
 
60
 
 
61
static const INT16 st010_mode7_scale[176] = {
 
62
  0x0380,  0x0325,  0x02da,  0x029c,  0x0268,  0x023b,  0x0215,  0x01f3,
 
63
  0x01d5,  0x01bb,  0x01a3,  0x018e,  0x017b,  0x016a,  0x015a,  0x014b,
 
64
  0x013e,  0x0132,  0x0126,  0x011c,  0x0112,  0x0109,  0x0100,  0x00f8,
 
65
  0x00f0,  0x00e9,  0x00e3,  0x00dc,  0x00d6,  0x00d1,  0x00cb,  0x00c6,
 
66
  0x00c1,  0x00bd,  0x00b8,  0x00b4,  0x00b0,  0x00ac,  0x00a8,  0x00a5,
 
67
  0x00a2,  0x009e,  0x009b,  0x0098,  0x0095,  0x0093,  0x0090,  0x008d,
 
68
  0x008b,  0x0088,  0x0086,  0x0084,  0x0082,  0x0080,  0x007e,  0x007c,
 
69
  0x007a,  0x0078,  0x0076,  0x0074,  0x0073,  0x0071,  0x006f,  0x006e,
 
70
  0x006c,  0x006b,  0x0069,  0x0068,  0x0067,  0x0065,  0x0064,  0x0063,
 
71
  0x0062,  0x0060,  0x005f,  0x005e,  0x005d,  0x005c,  0x005b,  0x005a,
 
72
  0x0059,  0x0058,  0x0057,  0x0056,  0x0055,  0x0054,  0x0053,  0x0052,
 
73
  0x0051,  0x0051,  0x0050,  0x004f,  0x004e,  0x004d,  0x004d,  0x004c,
 
74
  0x004b,  0x004b,  0x004a,  0x0049,  0x0048,  0x0048,  0x0047,  0x0047,
 
75
  0x0046,  0x0045,  0x0045,  0x0044,  0x0044,  0x0043,  0x0042,  0x0042,
 
76
  0x0041,  0x0041,  0x0040,  0x0040,  0x003f,  0x003f,  0x003e,  0x003e,
 
77
  0x003d,  0x003d,  0x003c,  0x003c,  0x003b,  0x003b,  0x003a,  0x003a,
 
78
  0x003a,  0x0039,  0x0039,  0x0038,  0x0038,  0x0038,  0x0037,  0x0037,
 
79
  0x0036,  0x0036,  0x0036,  0x0035,  0x0035,  0x0035,  0x0034,  0x0034,
 
80
  0x0034,  0x0033,  0x0033,  0x0033,  0x0032,  0x0032,  0x0032,  0x0031,
 
81
  0x0031,  0x0031,  0x0030,  0x0030,  0x0030,  0x0030,  0x002f,  0x002f,
 
82
  0x002f,  0x002e,  0x002e,  0x002e,  0x002e,  0x002d,  0x002d,  0x002d,
 
83
  0x002d,  0x002c,  0x002c,  0x002c,  0x002c,  0x002b,  0x002b,  0x002b
 
84
};
 
85
 
 
86
static const UINT8 st010_arctan[32][32] = {
 
87
  { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
 
88
    0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 },
 
89
  { 0x80, 0xa0, 0xad, 0xb3, 0xb6, 0xb8, 0xb9, 0xba, 0xbb, 0xbb, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd,
 
90
    0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf },
 
91
  { 0x80, 0x93, 0xa0, 0xa8, 0xad, 0xb0, 0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb,
 
92
    0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd },
 
93
  { 0x80, 0x8d, 0x98, 0xa0, 0xa6, 0xaa, 0xad, 0xb0, 0xb1, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb7, 0xb8,
 
94
    0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc },
 
95
  { 0x80, 0x8a, 0x93, 0x9a, 0xa0, 0xa5, 0xa8, 0xab, 0xad, 0xaf, 0xb0, 0xb2, 0xb3, 0xb4, 0xb5, 0xb5,
 
96
    0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb },
 
97
  { 0x80, 0x88, 0x90, 0x96, 0x9b, 0xa0, 0xa4, 0xa7, 0xa9, 0xab, 0xad, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
 
98
    0xb4, 0xb4, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9 },
 
99
  { 0x80, 0x87, 0x8d, 0x93, 0x98, 0x9c, 0xa0, 0xa3, 0xa6, 0xa8, 0xaa, 0xac, 0xad, 0xae, 0xb0, 0xb0,
 
100
    0xb1, 0xb2, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8 },
 
101
  { 0x80, 0x86, 0x8b, 0x90, 0x95, 0x99, 0x9d, 0xa0, 0xa3, 0xa5, 0xa7, 0xa9, 0xaa, 0xac, 0xad, 0xae,
 
102
    0xaf, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7 },
 
103
  { 0x80, 0x85, 0x8a, 0x8f, 0x93, 0x97, 0x9a, 0x9d, 0xa0, 0xa2, 0xa5, 0xa6, 0xa8, 0xaa, 0xab, 0xac,
 
104
    0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, 0xb5 },
 
105
  { 0x80, 0x85, 0x89, 0x8d, 0x91, 0x95, 0x98, 0x9b, 0x9e, 0xa0, 0xa0, 0xa4, 0xa6, 0xa7, 0xa9, 0xaa,
 
106
    0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4 },
 
107
  { 0x80, 0x84, 0x88, 0x8c, 0x90, 0x93, 0x96, 0x99, 0x9b, 0x9e, 0xa0, 0xa2, 0xa4, 0xa5, 0xa7, 0xa8,
 
108
    0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3 },
 
109
  { 0x80, 0x84, 0x87, 0x8b, 0x8e, 0x91, 0x94, 0x97, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5, 0xa6,
 
110
    0xa7, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2 },
 
111
  { 0x80, 0x83, 0x87, 0x8a, 0x8d, 0x90, 0x93, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5,
 
112
    0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1 },
 
113
  { 0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x94, 0x96, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa2, 0xa3,
 
114
    0xa4, 0xa5, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xb0 },
 
115
  { 0x80, 0x83, 0x86, 0x89, 0x8b, 0x8e, 0x90, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa1,
 
116
    0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf },
 
117
  { 0x80, 0x83, 0x85, 0x88, 0x8b, 0x8d, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9b, 0x9d, 0x9f, 0xa0,
 
118
    0xa1, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae },
 
119
  { 0x80, 0x83, 0x85, 0x88, 0x8a, 0x8c, 0x8f, 0x91, 0x93, 0x95, 0x97, 0x99, 0x9a, 0x9c, 0x9d, 0x9f,
 
120
    0xa0, 0xa1, 0xa2, 0xa3, 0xa5, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xab, 0xac, 0xad },
 
121
  { 0x80, 0x82, 0x85, 0x87, 0x89, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x97, 0x99, 0x9b, 0x9c, 0x9d,
 
122
    0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac },
 
123
  { 0x80, 0x82, 0x85, 0x87, 0x89, 0x8b, 0x8d, 0x8f, 0x91, 0x93, 0x95, 0x96, 0x98, 0x99, 0x9b, 0x9c,
 
124
    0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab },
 
125
  { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x9a, 0x9b,
 
126
    0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa },
 
127
  { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x99, 0x9a,
 
128
    0x9b, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9 },
 
129
  { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8f, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x99,
 
130
    0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8 },
 
131
  { 0x80, 0x82, 0x84, 0x86, 0x87, 0x89, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x98,
 
132
    0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7 },
 
133
  { 0x80, 0x82, 0x84, 0x85, 0x87, 0x89, 0x8a, 0x8c, 0x8e, 0x8f, 0x91, 0x92, 0x94, 0x95, 0x96, 0x98,
 
134
    0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6 },
 
135
  { 0x80, 0x82, 0x83, 0x85, 0x87, 0x88, 0x8a, 0x8c, 0x8d, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x96, 0x97,
 
136
    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5 },
 
137
  { 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x94, 0x95, 0x96,
 
138
    0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4 },
 
139
  { 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x89, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x95,
 
140
    0x96, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4 },
 
141
  { 0x80, 0x82, 0x83, 0x85, 0x86, 0x87, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, 0x95,
 
142
    0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2, 0xa3 },
 
143
  { 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8d, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94,
 
144
    0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2 },
 
145
  { 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x88, 0x8a, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93,
 
146
    0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1, 0xa1 },
 
147
  { 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8b, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93,
 
148
    0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1 },
 
149
  { 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92,
 
150
    0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0 }
 
151
};
 
152
 
 
153
 
 
154
static INT16 st010_sin( INT16 theta )
 
155
{
 
156
        return st010_sin_table[(theta >> 8) & 0xff];
 
157
}
 
158
 
 
159
static INT16 st010_cos( INT16 theta )
 
160
{
 
161
        return st010_sin_table[((theta + 0x4000) >> 8) & 0xff];
 
162
}
 
163
 
 
164
static UINT8 st010_readb( UINT16 address )
 
165
{
 
166
        return snes_st010.ram[address & 0xfff];
 
167
}
 
168
 
 
169
static UINT16 st010_readw( UINT16 address )
 
170
{
 
171
        return (st010_readb(address + 0) <<  0) |
 
172
                        (st010_readb(address + 1) <<  8);
 
173
}
 
174
 
 
175
static UINT32 st010_readd( UINT16 address )
 
176
{
 
177
        return (st010_readb(address + 0) <<  0) |
 
178
                        (st010_readb(address + 1) <<  8) |
 
179
                        (st010_readb(address + 2) << 16) |
 
180
                        (st010_readb(address + 3) << 24);
 
181
}
 
182
 
 
183
static void st010_writeb( UINT16 address, UINT8 data )
 
184
{
 
185
        snes_st010.ram[address & 0xfff] = data;
 
186
}
 
187
 
 
188
static void st010_writew( UINT16 address, UINT16 data )
 
189
{
 
190
        st010_writeb(address + 0, data >> 0);
 
191
        st010_writeb(address + 1, data >> 8);
 
192
}
 
193
 
 
194
static void st010_writed( UINT16 address, UINT32 data )
 
195
{
 
196
        st010_writeb(address + 0, data >>  0);
 
197
        st010_writeb(address + 1, data >>  8);
 
198
        st010_writeb(address + 2, data >> 16);
 
199
        st010_writeb(address + 3, data >> 24);
 
200
}
 
201
 
 
202
//
 
203
 
 
204
static void st010_op_01_do_work(INT16 x0, INT16 y0) {
 
205
  if((x0 < 0) && (y0 < 0)) {
 
206
    snes_st010.x1 = -x0;
 
207
    snes_st010.y1 = -y0;
 
208
    snes_st010.quadrant = -0x8000;
 
209
  } else if(x0 < 0) {
 
210
    snes_st010.x1 = y0;
 
211
    snes_st010.y1 = -x0;
 
212
    snes_st010.quadrant = -0x4000;
 
213
  } else if(y0 < 0) {
 
214
    snes_st010.x1 = -y0;
 
215
    snes_st010.y1 = x0;
 
216
    snes_st010.quadrant = 0x4000;
 
217
  } else {
 
218
    snes_st010.x1 = x0;
 
219
    snes_st010.y1 = y0;
 
220
    snes_st010.quadrant = 0x0000;
 
221
  }
 
222
 
 
223
  while((snes_st010.x1 > 0x1f) || (snes_st010.y1 > 0x1f)) {
 
224
    if(snes_st010.x1 > 1) { snes_st010.x1 >>= 1; }
 
225
    if(snes_st010.y1 > 1) { snes_st010.y1 >>= 1; }
 
226
  }
 
227
 
 
228
  if(snes_st010.y1 == 0) { snes_st010.quadrant += 0x4000; }
 
229
 
 
230
  snes_st010.theta = (st010_arctan[snes_st010.y1][snes_st010.x1] << 8) ^ snes_st010.quadrant;
 
231
}
 
232
 
 
233
//
 
234
 
 
235
static void st010_op_01( void ) {
 
236
  INT16 x0 = st010_readw(0x0000);
 
237
  INT16 y0 = st010_readw(0x0002);
 
238
 
 
239
  st010_op_01_do_work(x0, y0);
 
240
 
 
241
  st010_writew(0x0000, snes_st010.x1);
 
242
  st010_writew(0x0002, snes_st010.y1);
 
243
  st010_writew(0x0004, snes_st010.quadrant);
 
244
//st010_writew(0x0006, y0);  //Overload's docs note this write occurs, SNES9x disagrees
 
245
  st010_writew(0x0010, snes_st010.theta);
 
246
}
 
247
 
 
248
static void st010_op_02( void ) {
 
249
  INT16 positions = st010_readw(0x0024);
 
250
  UINT16 *places  = (UINT16*)(snes_st010.ram + 0x0040);
 
251
  UINT16 *drivers = (UINT16*)(snes_st010.ram + 0x0080);
 
252
 
 
253
  UINT8 sorted;
 
254
  UINT16 temp;
 
255
  int i;
 
256
  if(positions > 1) {
 
257
    do {
 
258
      sorted = 1;
 
259
      for(i = 0; i < positions - 1; i++) {
 
260
        if(places[i] < places[i + 1]) {
 
261
          temp = places[i + 1];
 
262
          places[i + 1] = places[i];
 
263
          places[i] = temp;
 
264
 
 
265
          temp = drivers[i + 1];
 
266
          drivers[i + 1] = drivers[i];
 
267
          drivers[i] = temp;
 
268
 
 
269
          sorted = 0;
 
270
        }
 
271
      }
 
272
      positions--;
 
273
    } while(!sorted);
 
274
  }
 
275
}
 
276
 
 
277
static void st010_op_03( void ) {
 
278
  INT16 x0 = st010_readw(0x0000);
 
279
  INT16 y0 = st010_readw(0x0002);
 
280
  INT16 multiplier = st010_readw(0x0004);
 
281
  INT32 x1, y1;
 
282
 
 
283
  x1 = x0 * multiplier << 1;
 
284
  y1 = y0 * multiplier << 1;
 
285
 
 
286
  st010_writed(0x0010, x1);
 
287
  st010_writed(0x0014, y1);
 
288
}
 
289
 
 
290
static void st010_op_04( void ) {
 
291
  INT16 x = st010_readw(0x0000);
 
292
  INT16 y = st010_readw(0x0002);
 
293
  INT16 square;
 
294
  //calculate the vector length of (x,y)
 
295
  square = sqrt((double)(y * y + x * x));
 
296
 
 
297
  st010_writew(0x0010, square);
 
298
}
 
299
 
 
300
// same as op_01_do_work, but we are only interested in the angle!
 
301
static void st010_op_05_do_work(INT16 x0, INT16 y0) {
 
302
  INT16 x1, y1, quadrant;
 
303
  if((x0 < 0) && (y0 < 0)) {
 
304
    x1 = -x0;
 
305
    y1 = -y0;
 
306
    quadrant = -0x8000;
 
307
  } else if(x0 < 0) {
 
308
    x1 = y0;
 
309
    y1 = -x0;
 
310
    quadrant = -0x4000;
 
311
  } else if(y0 < 0) {
 
312
    x1 = -y0;
 
313
    y1 = x0;
 
314
    quadrant = 0x4000;
 
315
  } else {
 
316
    x1 = x0;
 
317
    y1 = y0;
 
318
    quadrant = 0x0000;
 
319
  }
 
320
 
 
321
  while((x1 > 0x1f) || (y1 > 0x1f)) {
 
322
    if(x1 > 1) { x1 >>= 1; }
 
323
    if(y1 > 1) { y1 >>= 1; }
 
324
  }
 
325
 
 
326
  if(y1 == 0) { quadrant += 0x4000; }
 
327
 
 
328
  snes_st010.o1 = (st010_arctan[y1][x1] << 8) ^ quadrant;
 
329
}
 
330
 
 
331
static void st010_op_05( void ) {
 
332
  INT32 dx, dy;
 
333
  UINT16 o1 = 0;
 
334
  UINT8 wrap = 0;
 
335
 
 
336
  //target (x,y) coordinates
 
337
  INT16 ypos_max = st010_readw(0x00c0);
 
338
  INT16 xpos_max = st010_readw(0x00c2);
 
339
 
 
340
  //current coordinates and direction
 
341
  INT32 ypos = st010_readd(0x00c4);
 
342
  INT32 xpos = st010_readd(0x00c8);
 
343
  UINT16 rot = st010_readw(0x00cc);
 
344
 
 
345
  //physics
 
346
  UINT16 speed = st010_readw(0x00d4);
 
347
  UINT16 accel = st010_readw(0x00d6);
 
348
  UINT16 speed_max = st010_readw(0x00d8);
 
349
  UINT16 old_speed;
 
350
 
 
351
  //special condition acknowledgement
 
352
  INT16 system = st010_readw(0x00da);
 
353
  INT16 flags = st010_readw(0x00dc);
 
354
 
 
355
  //new target coordinates
 
356
  INT16 ypos_new = st010_readw(0x00de);
 
357
  INT16 xpos_new = st010_readw(0x00e0);
 
358
 
 
359
  //mask upper bit
 
360
  xpos_new &= 0x7fff;
 
361
 
 
362
  //get the current distance
 
363
  dx = xpos_max - (xpos >> 16);
 
364
  dy = ypos_max - (ypos >> 16);
 
365
 
 
366
  //quirk: clear and move in9
 
367
  st010_writew(0x00d2, 0xffff);
 
368
  st010_writew(0x00da, 0x0000);
 
369
 
 
370
  //grab the target angle
 
371
  st010_op_05_do_work(dy, dx);
 
372
  o1 = (UINT16)snes_st010.o1;
 
373
 
 
374
  //check for wrapping
 
375
  if(abs(o1 - rot) > 0x8000) {
 
376
    o1 += 0x8000;
 
377
    rot += 0x8000;
 
378
    wrap = 1;
 
379
  }
 
380
 
 
381
  old_speed = speed;
 
382
 
 
383
  //special case
 
384
  if(abs(o1 - rot) == 0x8000) {
 
385
    speed = 0x100;
 
386
  }
 
387
 
 
388
  //slow down for sharp curves
 
389
  else if(abs(o1 - rot) >= 0x1000) {
 
390
  UINT32 slow = abs(o1 - rot);
 
391
    slow >>= 4;  //scaling
 
392
    speed -= slow;
 
393
  }
 
394
 
 
395
  //otherwise accelerate
 
396
  else {
 
397
    speed += accel;
 
398
    if(speed > speed_max) {
 
399
      speed = speed_max;  //clip speed
 
400
    }
 
401
  }
 
402
 
 
403
  //prevent negative/positive overflow
 
404
  if(abs(old_speed - speed) > 0x8000) {
 
405
    if(old_speed < speed) { speed = 0; }
 
406
    else speed = 0xff00;
 
407
  }
 
408
 
 
409
  //adjust direction by so many degrees
 
410
  //be careful of negative adjustments
 
411
  if((o1 > rot && (o1 - rot) > 0x80) || (o1 < rot && (rot - o1) >= 0x80)) {
 
412
    if(o1 < rot) { rot -= 0x280; }
 
413
    else if(o1 > rot) { rot += 0x280; }
 
414
  }
 
415
 
 
416
  //turn off wrapping
 
417
  if(wrap) { rot -= 0x8000; }
 
418
 
 
419
  //now check the distances (store for later)
 
420
  dx = (xpos_max << 16) - xpos;
 
421
  dy = (ypos_max << 16) - ypos;
 
422
  dx >>= 16;
 
423
  dy >>= 16;
 
424
 
 
425
  //if we're in so many units of the target, signal it
 
426
  if((system && (dy <= 6 && dy >= -8) && (dx <= 126 && dx >= -128)) || (!system && (dx <= 6 && dx >= -8) && (dy <= 126 && dy >= -128))) {
 
427
    //announce our new destination and flag it
 
428
    xpos_max = xpos_new & 0x7fff;
 
429
    ypos_max = ypos_new;
 
430
    flags |= 0x08;
 
431
  }
 
432
 
 
433
  //update position
 
434
  xpos -= (st010_cos(rot) * 0x400 >> 15) * (speed >> 8) << 1;
 
435
  ypos -= (st010_sin(rot) * 0x400 >> 15) * (speed >> 8) << 1;
 
436
 
 
437
  //quirk: mask upper byte
 
438
  xpos &= 0x1fffffff;
 
439
  ypos &= 0x1fffffff;
 
440
 
 
441
  st010_writew(0x00c0, ypos_max);
 
442
  st010_writew(0x00c2, xpos_max);
 
443
  st010_writed(0x00c4, ypos);
 
444
  st010_writed(0x00c8, xpos);
 
445
  st010_writew(0x00cc, rot);
 
446
  st010_writew(0x00d4, speed);
 
447
  st010_writew(0x00dc, flags);
 
448
}
 
449
 
 
450
static void st010_op_06( void ) {
 
451
  INT16 multiplicand = st010_readw(0x0000);
 
452
  INT16 multiplier = st010_readw(0x0002);
 
453
  INT32 product;
 
454
 
 
455
  product = multiplicand * multiplier << 1;
 
456
 
 
457
  st010_writed(0x0010, product);
 
458
}
 
459
 
 
460
static void st010_op_07( void ) {
 
461
  INT16 theta = st010_readw(0x0000);
 
462
 
 
463
  INT16 data;
 
464
  int i, offset;
 
465
  for(i = 0, offset = 0; i < 176; i++) {
 
466
    data = st010_mode7_scale[i] * st010_cos(theta) >> 15;
 
467
    st010_writew(0x00f0 + offset, data);
 
468
    st010_writew(0x0510 + offset, data);
 
469
 
 
470
    data = st010_mode7_scale[i] * st010_sin(theta) >> 15;
 
471
    st010_writew(0x0250 + offset, data);
 
472
    if(data) { data = ~data; }
 
473
    st010_writew(0x03b0 + offset, data);
 
474
 
 
475
    offset += 2;
 
476
  }
 
477
}
 
478
 
 
479
static void st010_op_08( void ) {
 
480
  INT16 x0 = st010_readw(0x0000);
 
481
  INT16 y0 = st010_readw(0x0002);
 
482
  INT16 theta = st010_readw(0x0004);
 
483
  INT16 x1, y1;
 
484
 
 
485
  x1 = (y0 * st010_sin(theta) >> 15) + (x0 * st010_cos(theta) >> 15);
 
486
  y1 = (y0 * st010_cos(theta) >> 15) - (x0 * st010_sin(theta) >> 15);
 
487
 
 
488
  st010_writew(0x0010, x1);
 
489
  st010_writew(0x0012, y1);
 
490
}
 
491
 
 
492
// init, reset & handlers
 
493
 
 
494
static UINT8 st010_read( UINT16 address )
 
495
{
 
496
        return st010_readb(address);
 
497
}
 
498
 
 
499
static void st010_write( UINT16 address, UINT8 data )
 
500
{
 
501
        st010_writeb(address, data);
 
502
 
 
503
        if ((address & 0xfff) == 0x0021 && (data & 0x80))
 
504
        {
 
505
                switch (snes_st010.ram[0x0020])
 
506
                {
 
507
                        case 0x01: st010_op_01(); break;
 
508
                        case 0x02: st010_op_02(); break;
 
509
                        case 0x03: st010_op_03(); break;
 
510
                        case 0x04: st010_op_04(); break;
 
511
                        case 0x05: st010_op_05(); break;
 
512
                        case 0x06: st010_op_06(); break;
 
513
                        case 0x07: st010_op_07(); break;
 
514
                        case 0x08: st010_op_08(); break;
 
515
                }
 
516
 
 
517
                snes_st010.ram[0x0021] &= ~0x80;
 
518
        }
 
519
}
 
520
 
 
521
 
 
522
static void st010_init( running_machine* machine )
 
523
{
 
524
        snes_st010.ram = (UINT8*)auto_alloc_array(machine, UINT8, 0x1000);
 
525
}
 
526
 
 
527
static void st010_reset( void )
 
528
{
 
529
        snes_st010.x1 = 0;
 
530
        snes_st010.y1 = 0;
 
531
        snes_st010.quadrant = 0;
 
532
        snes_st010.theta = 0;
 
533
        memset(snes_st010.ram, 0, 0x1000);
 
534
}