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 | |
11 | static int line; // line counter |
12 | |
13 | |
14 | uint8 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 | |
47 | void 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 |