Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/chip/hitachidsp/opcodes.cpp
2 views
1
#ifdef HITACHIDSP_CPP
2
3
void HitachiDSP::push() {
4
stack[7] = stack[6];
5
stack[6] = stack[5];
6
stack[5] = stack[4];
7
stack[4] = stack[3];
8
stack[3] = stack[2];
9
stack[2] = stack[1];
10
stack[1] = stack[0];
11
stack[0] = regs.pc;
12
}
13
14
void HitachiDSP::pull() {
15
regs.pc = stack[0];
16
stack[0] = stack[1];
17
stack[1] = stack[2];
18
stack[2] = stack[3];
19
stack[3] = stack[4];
20
stack[4] = stack[5];
21
stack[5] = stack[6];
22
stack[6] = stack[7];
23
stack[7] = 0x0000;
24
}
25
26
//Shift-A: math opcodes can shift A register prior to ALU operation
27
unsigned HitachiDSP::sa() {
28
switch(opcode & 0x0300) { default:
29
case 0x0000: return regs.a << 0;
30
case 0x0100: return regs.a << 1;
31
case 0x0200: return regs.a << 8;
32
case 0x0300: return regs.a << 16;
33
}
34
}
35
36
//Register-or-Immediate: most opcodes can load from a register or immediate
37
unsigned HitachiDSP::ri() {
38
if(opcode & 0x0400) return opcode & 0xff;
39
return reg_read(opcode & 0xff);
40
}
41
42
//New-PC: determine jump target address; opcode.d9 = long jump flag (1 = yes)
43
unsigned HitachiDSP::np() {
44
if(opcode & 0x0200) return (regs.p << 8) | (opcode & 0xff);
45
return (regs.pc & 0xffff00) | (opcode & 0xff);
46
}
47
48
void HitachiDSP::exec() {
49
if((opcode & 0xffff) == 0x0000) {
50
//0000 0000 0000 0000
51
//nop
52
}
53
54
else if((opcode & 0xdd00) == 0x0800) {
55
//00.0 10.0 .... ....
56
//jump i
57
if(opcode & 0x2000) push();
58
regs.pc = np();
59
}
60
61
else if((opcode & 0xdd00) == 0x0c00) {
62
//00.0 11.0 .... ....
63
//jumpeq i
64
if(regs.z) {
65
if(opcode & 0x2000) push();
66
regs.pc = np();
67
}
68
}
69
70
else if((opcode & 0xdd00) == 0x1000) {
71
//00.1 00.0 .... ....
72
//jumpge i
73
if(regs.c) {
74
if(opcode & 0x2000) push();
75
regs.pc = np();
76
}
77
}
78
79
else if((opcode & 0xdd00) == 0x1400) {
80
//00.1 01.0 .... ....
81
//jumpmi i
82
if(regs.n) {
83
if(opcode & 0x2000) push();
84
regs.pc = np();
85
}
86
}
87
88
else if((opcode & 0xffff) == 0x1c00) {
89
//0001 1100 0000 0000
90
//loop?
91
}
92
93
else if((opcode & 0xfffe) == 0x2500) {
94
//0010 0101 0000 000.
95
//skiplt/skipge
96
if(regs.c == (opcode & 1)) regs.pc++;
97
}
98
99
else if((opcode & 0xfffe) == 0x2600) {
100
//0010 0110 0000 000.
101
//skipne/skipeq
102
if(regs.z == (opcode & 1)) regs.pc++;
103
}
104
105
else if((opcode & 0xfffe) == 0x2700) {
106
//0010 0111 0000 000.
107
//skipmi/skippl
108
if(regs.n == (opcode & 1)) regs.pc++;
109
}
110
111
else if((opcode & 0xffff) == 0x3c00) {
112
//0011 1100 0000 0000
113
//ret
114
pull();
115
}
116
117
else if((opcode & 0xffff) == 0x4000) {
118
//0100 0000 0000 0000
119
//rdbus
120
regs.busdata = bus_read(regs.busaddr++);
121
}
122
123
else if((opcode & 0xf800) == 0x4800) {
124
//0100 1... .... ....
125
//cmpr a<<n,ri
126
int result = ri() - sa();
127
regs.n = result & 0x800000;
128
regs.z = (uint24)result == 0;
129
regs.c = result >= 0;
130
}
131
132
else if((opcode & 0xf800) == 0x5000) {
133
//0101 0... .... ....
134
//cmp a<<n,ri
135
int result = sa() - ri();
136
regs.n = result & 0x800000;
137
regs.z = (uint24)result == 0;
138
regs.c = result >= 0;
139
}
140
141
else if((opcode & 0xfb00) == 0x5900) {
142
//0101 1.01 .... ....
143
//sxb
144
regs.a = (int8)ri();
145
}
146
147
else if((opcode & 0xfb00) == 0x5a00) {
148
//0101 1.10 .... ....
149
//sxw
150
regs.a = (int16)ri();
151
}
152
153
else if((opcode & 0xfb00) == 0x6000) {
154
//0110 0.00 .... ....
155
//ld a,ri
156
regs.a = ri();
157
}
158
159
else if((opcode & 0xfb00) == 0x6100) {
160
//0110 0.01 .... ....
161
//ld ?,ri
162
}
163
164
else if((opcode & 0xfb00) == 0x6300) {
165
//0110 0.11 .... ....
166
//ld p,ri
167
regs.p = ri();
168
}
169
170
else if((opcode & 0xfb00) == 0x6800) {
171
//0110 1.00 .... ....
172
//rdraml
173
uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);
174
if(target < 0xc00) regs.ramdata = (regs.ramdata & 0xffff00) | (dataRAM[target] << 0);
175
}
176
177
else if((opcode & 0xfb00) == 0x6900) {
178
//0110 1.01 .... ....
179
//rdramh
180
uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);
181
if(target < 0xc00) regs.ramdata = (regs.ramdata & 0xff00ff) | (dataRAM[target] << 8);
182
}
183
184
else if((opcode & 0xfb00) == 0x6a00) {
185
//0110 1.10 .... ....
186
//rdramb
187
uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);
188
if(target < 0xc00) regs.ramdata = (regs.ramdata & 0x00ffff) | (dataRAM[target] << 16);
189
}
190
191
else if((opcode & 0xffff) == 0x7000) {
192
//0111 0000 0000 0000
193
//rdrom
194
regs.romdata = dataROM[regs.a & 0x3ff];
195
}
196
197
else if((opcode & 0xff00) == 0x7c00) {
198
//0111 1100 .... ....
199
//ld pl,i
200
regs.p = (regs.p & 0xff00) | ((opcode & 0xff) << 0);
201
}
202
203
else if((opcode & 0xff00) == 0x7d00) {
204
//0111 1101 .... ....
205
//ld ph,i
206
regs.p = (regs.p & 0x00ff) | ((opcode & 0xff) << 8);
207
}
208
209
else if((opcode & 0xf800) == 0x8000) {
210
//1000 0... .... ....
211
//add a<<n,ri
212
int result = sa() + ri();
213
regs.a = result;
214
regs.n = regs.a & 0x800000;
215
regs.z = regs.a == 0;
216
regs.c = result > 0xffffff;
217
}
218
219
else if((opcode & 0xf800) == 0x8800) {
220
//1000 1... .... ....
221
//subr a<<n,ri
222
int result = ri() - sa();
223
regs.a = result;
224
regs.n = regs.a & 0x800000;
225
regs.z = regs.a == 0;
226
regs.c = result >= 0;
227
}
228
229
else if((opcode & 0xf800) == 0x9000) {
230
//1001 0... .... ....
231
//sub a<<n,ri
232
int result = sa() - ri();
233
regs.a = result;
234
regs.n = regs.a & 0x800000;
235
regs.z = regs.a == 0;
236
regs.c = result >= 0;
237
}
238
239
else if((opcode & 0xfb00) == 0x9800) {
240
//1001 1.00 .... ....
241
//mul a,ri
242
int64 x = (int24)regs.a;
243
int64 y = (int24)ri();
244
x *= y;
245
regs.accl = x >> 0ull;
246
regs.acch = x >> 24ull;
247
regs.n = regs.acch & 0x800000;
248
regs.z = x == 0;
249
}
250
251
else if((opcode & 0xf800) == 0xa800) {
252
//1010 1... .... ....
253
//xor a<<n,ri
254
regs.a = sa() ^ ri();
255
regs.n = regs.a & 0x800000;
256
regs.z = regs.a == 0;
257
}
258
259
else if((opcode & 0xf800) == 0xb000) {
260
//1011 0... .... ....
261
//and a<<n,ri
262
regs.a = sa() & ri();
263
regs.n = regs.a & 0x800000;
264
regs.z = regs.a == 0;
265
}
266
267
else if((opcode & 0xf800) == 0xb800) {
268
//1011 1... .... ....
269
//or a<<n,ri
270
regs.a = sa() | ri();
271
regs.n = regs.a & 0x800000;
272
regs.z = regs.a == 0;
273
}
274
275
else if((opcode & 0xfb00) == 0xc000) {
276
//1100 0.00 .... ....
277
//shr a,ri
278
regs.a = regs.a >> ri();
279
regs.n = regs.a & 0x800000;
280
regs.z = regs.a == 0;
281
}
282
283
else if((opcode & 0xfb00) == 0xc800) {
284
//1100 1.00 .... ....
285
//asr a,ri
286
regs.a = (int24)regs.a >> ri();
287
regs.n = regs.a & 0x800000;
288
regs.z = regs.a == 0;
289
}
290
291
else if((opcode & 0xfb00) == 0xd000) {
292
//1101 0.00 .... ....
293
//ror a,ri
294
uint24 length = ri();
295
regs.a = (regs.a >> length) | (regs.a << (24 - length));
296
regs.n = regs.a & 0x800000;
297
regs.z = regs.a == 0;
298
}
299
300
else if((opcode & 0xfb00) == 0xd800) {
301
//1101 1.00 .... ....
302
//shl a,ri
303
regs.a = regs.a << ri();
304
regs.n = regs.a & 0x800000;
305
regs.z = regs.a == 0;
306
}
307
308
else if((opcode & 0xff00) == 0xe000) {
309
//1110 0000 .... ....
310
//st r,a
311
reg_write(opcode & 0xff, regs.a);
312
}
313
314
else if((opcode & 0xfb00) == 0xe800) {
315
//1110 1.00 .... ....
316
//wrraml
317
uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);
318
if(target < 0xc00) dataRAM[target] = regs.ramdata >> 0;
319
}
320
321
else if((opcode & 0xfb00) == 0xe900) {
322
//1110 1.01 .... ....
323
//wrramh
324
uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);
325
if(target < 0xc00) dataRAM[target] = regs.ramdata >> 8;
326
}
327
328
else if((opcode & 0xfb00) == 0xea00) {
329
//1110 1.10 .... ....
330
//wrramb
331
uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);
332
if(target < 0xc00) dataRAM[target] = regs.ramdata >> 16;
333
}
334
335
else if((opcode & 0xff00) == 0xf000) {
336
//1111 0000 .... ....
337
//swap a,r
338
uint24 source = reg_read(opcode & 0xff);
339
uint24 target = regs.a;
340
regs.a = source;
341
reg_write(opcode & 0xff, target);
342
}
343
344
else if((opcode & 0xffff) == 0xfc00) {
345
//1111 1100 0000 0000
346
//halt
347
state = State::Idle;
348
}
349
350
else {
351
print("Hitachi DSP: invalid opcode @ ", hex<4>(regs.pc - 1), " = ", hex<4>(opcode), "\n");
352
state = State::Idle;
353
}
354
}
355
356
#endif
357
358