1/*****************************************************************************\
2 Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3 This file is licensed under the Snes9x License.
4 For further information, consult the LICENSE file in the root directory.
5\*****************************************************************************/
6
7#include "snes9x.h"
8#include "memmap.h"
9#include "seta.h"
10
11static int line; // line counter
12
13
14uint8 S9xGetST018 (uint32 Address)
15{
16 uint8 t = 0;
17 uint16 address = (uint16) Address & 0xFFFF;
18
19 line++;
20
21 // these roles may be flipped
22 // op output
23 if (address == 0x3804)
24 {
25 if (ST018.out_count)
26 {
27 t = (uint8) ST018.output[ST018.out_index];
28 ST018.out_index++;
29 if (ST018.out_count == ST018.out_index)
30 ST018.out_count = 0;
31 }
32 else
33 t = 0x81;
34 }
35 // status register
36 else
37 if (address == 0x3800)
38 t = ST018.status;
39
40#ifdef DEBUGGER
41 printf("ST018 R: %06X %02X\n", Address, t);
42#endif
43
44 return (t);
45}
46
47void S9xSetST018 (uint8 Byte, uint32 Address)
48{
49 static bool reset = false;
50 uint16 address = (uint16) Address & 0xFFFF;
51
52#ifdef DEBUGGER
53 printf("ST018 W: %06X %02X\n", Address, Byte);
54#endif
55
56 line++;
57
58 if (!reset)
59 {
60 // bootup values
61 ST018.waiting4command = true;
62 ST018.part_command = 0;
63 reset = true;
64 }
65
66 Memory.SRAM[address] = Byte;
67
68 // default status for now
69 ST018.status = 0x00;
70
71 // op data goes through this address
72 if (address == 0x3804)
73 {
74 // check for new commands: 3 bytes length
75 if (ST018.waiting4command && ST018.part_command == 2)
76 {
77 ST018.waiting4command = false;
78 ST018.in_index = 0;
79 ST018.out_index = 0;
80 ST018.part_command = 0; // 3-byte commands
81 ST018.pass = 0; // data streams into the chip
82 ST018.command <<= 8;
83 ST018.command |= Byte;
84
85 switch (ST018.command & 0xFFFFFF)
86 {
87 case 0x0100: ST018.in_count = 0; break;
88 case 0xFF00: ST018.in_count = 0; break;
89 default: ST018.waiting4command = true; break;
90 }
91 }
92 else
93 if (ST018.waiting4command)
94 {
95 // 3-byte commands
96 ST018.part_command++;
97 ST018.command <<= 8;
98 ST018.command |= Byte;
99 }
100 }
101 // extra parameters
102 else
103 if (address == 0x3802)
104 {
105 ST018.parameters[ST018.in_index] = Byte;
106 ST018.in_index++;
107 }
108
109 if (ST018.in_count == ST018.in_index)
110 {
111 // qctually execute the command
112 ST018.waiting4command = true;
113 ST018.in_index = 0;
114 ST018.out_index = 0;
115
116 switch (ST018.command)
117 {
118 // hardware check?
119 case 0x0100:
120 ST018.waiting4command = false;
121 ST018.pass++;
122
123 if (ST018.pass == 1)
124 {
125 ST018.in_count = 1;
126 ST018.out_count = 2;
127
128 // Overload's research
129 ST018.output[0x00] = 0x81;
130 ST018.output[0x01] = 0x81;
131 }
132 else
133 {
134 //ST018.in_count = 1;
135 ST018.out_count = 3;
136
137 // no reason to change this
138 //ST018.output[0x00] = 0x81;
139 //ST018.output[0x01] = 0x81;
140 ST018.output[0x02] = 0x81;
141
142 // done processing requests
143 if (ST018.pass == 3)
144 ST018.waiting4command = true;
145 }
146
147 break;
148
149 // unknown: feels like a security detection
150 // format identical to 0x0100
151 case 0xFF00:
152 ST018.waiting4command = false;
153 ST018.pass++;
154
155 if (ST018.pass == 1)
156 {
157 ST018.in_count = 1;
158 ST018.out_count = 2;
159
160 // Overload's research
161 ST018.output[0x00] = 0x81;
162 ST018.output[0x01] = 0x81;
163 }
164 else
165 {
166 //ST018.in_count = 1;
167 ST018.out_count = 3;
168
169 // no reason to change this
170 //ST018.output[0x00] = 0x81;
171 //ST018.output[0x01] = 0x81;
172 ST018.output[0x02] = 0x81;
173
174 // done processing requests
175 if (ST018.pass == 3)
176 ST018.waiting4command = true;
177 }
178
179 break;
180 }
181 }
182}
183