1 // license:BSD-3-Clause
2 // copyright-holders:Pierpaolo Prazzoli
3 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_chk()4 void hyperstone_device::hyperstone_chk()
5 {
6 check_delay_PC();
7
8 const uint32_t fp = GET_FP;
9 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
10 const uint32_t dreg = DST_GLOBAL ? m_core->global_regs[DST_CODE] : m_core->local_regs[(DST_CODE + fp) & 0x3f];
11
12 if (SRC_GLOBAL && (src_code == SR_REGISTER))
13 {
14 if (dreg == 0)
15 execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
16 }
17 else
18 {
19 const uint32_t sreg = (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code];
20 if ((SRC_GLOBAL && (src_code == PC_REGISTER)) ? (dreg >= sreg) : (dreg > sreg))
21 execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
22 }
23
24 m_core->icount -= m_core->clock_cycles_1;
25 }
26
27 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_movd()28 void hyperstone_device::hyperstone_movd()
29 {
30 check_delay_PC();
31
32 const uint32_t fp = GET_FP;
33 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
34 const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
35 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
36 const uint32_t dstf_code = DST_GLOBAL ? (dst_code + 1) : ((dst_code + 1) & 0x3f);
37
38 const uint32_t sreg = (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code];
39 const uint32_t sregf = (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[srcf_code];
40
41 if (DST_GLOBAL && (dst_code == PC_REGISTER))
42 {
43 // RET instruction
44 if (SRC_GLOBAL && src_code < 2)
45 {
46 LOG("Denoted PC or SR in RET instruction. PC = %08X\n", PC);
47 m_core->icount -= m_core->clock_cycles_1;
48 return;
49 }
50
51 const uint32_t old_s = SR & S_MASK;
52 const uint32_t old_l = SR & L_MASK;
53 PC = sreg & ~1;
54 SR = (sregf & 0xffe3ffff) | ((sreg & 0x01) << 18);
55 if (m_core->intblock < 1)
56 m_core->intblock = 1;
57
58 const uint32_t new_s = SR & S_MASK;
59 const uint32_t new_l = SR & L_MASK;
60 if( (!old_s && new_s) || (!new_s && !old_l && new_l))
61 execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR));
62
63 int8_t difference = GET_FP - ((SP & 0x1fc) >> 2);
64
65 /* convert to 8 bits */
66 if(difference > 63)
67 difference = (int8_t)(difference|0x80);
68 else if( difference < -64 )
69 difference = difference & 0x7f;
70
71 for (; difference < 0; difference++)
72 {
73 SP -= 4;
74 m_core->local_regs[(SP & 0xfc) >> 2] = READ_W(SP);
75 }
76
77 //TODO: not 2!
78 m_core->icount -= m_core->clock_cycles_2;
79 }
80 else if (SRC_GLOBAL && (src_code == SR_REGISTER)) // Rd doesn't denote PC and Rs denotes SR
81 {
82 SR |= Z_MASK;
83 SR &= ~N_MASK;
84 if (DST_GLOBAL)
85 {
86 set_global_register(dst_code, 0);
87 set_global_register(dstf_code, 0);
88 }
89 else
90 {
91 m_core->local_regs[dst_code] = 0;
92 m_core->local_regs[dstf_code] = 0;
93 }
94
95 m_core->icount -= m_core->clock_cycles_2;
96 }
97 else // Rd doesn't denote PC and Rs doesn't denote SR
98 {
99 SR &= ~(Z_MASK | N_MASK);
100 if (concat_64(sreg, sregf) == 0)
101 SR |= Z_MASK;
102 SR |= SIGN_TO_N(sreg);
103
104 if (DST_GLOBAL)
105 {
106 set_global_register(dst_code, sreg);
107 set_global_register(dstf_code, sregf);
108 }
109 else
110 {
111 m_core->local_regs[dst_code] = sreg;
112 m_core->local_regs[dstf_code] = sregf;
113 }
114
115 m_core->icount -= m_core->clock_cycles_2;
116 }
117 }
118
119 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL, hyperstone_device::sign_mode SIGNED>
hyperstone_divsu()120 void hyperstone_device::hyperstone_divsu()
121 {
122 check_delay_PC();
123
124 const uint32_t fp = GET_FP;
125 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
126 const uint32_t dstf_code = DST_GLOBAL ? (dst_code + 1) : ((dst_code + 1) & 0x3f);
127 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
128
129 if ((SRC_GLOBAL == DST_GLOBAL && (src_code == dst_code || src_code == dstf_code)) || (SRC_GLOBAL && src_code < 2))
130 {
131 LOG("Denoted the same register code or PC/SR as source in hyperstone_divu instruction. PC = %08X\n", PC);
132 m_core->icount -= 36 << m_core->clck_scale;
133 return;
134 }
135
136 const uint32_t sreg = (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code];
137 const uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
138 const uint32_t dregf = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dstf_code];
139 const uint64_t dividend = concat_64(dreg, dregf);
140
141 if (sreg == 0 || (SIGNED && (dividend & 0x8000000000000000U)))
142 {
143 //Rd//Rdf -> undefined
144 //Z -> undefined
145 //N -> undefined
146 SR |= V_MASK;
147 execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
148 }
149 else
150 {
151 /* TODO: add quotient overflow */
152 const uint32_t quotient = SIGNED ? (uint32_t)((int64_t)dividend / (int32_t)sreg) : (dividend / sreg);
153 SR &= ~(V_MASK | Z_MASK | N_MASK);
154 if (quotient == 0)
155 SR |= Z_MASK;
156 SR |= SIGN_TO_N(quotient);
157 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] = SIGNED ? (uint32_t)((int64_t)dividend % (int32_t)sreg) : (dividend % sreg);
158 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dstf_code] = (uint32_t)quotient;
159 }
160
161 m_core->icount -= m_core->clock_cycles_36;
162 }
163
164 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_xm()165 void hyperstone_device::hyperstone_xm()
166 {
167 const uint32_t next = m_pr16(PC);
168 PC += 2;
169
170 const uint8_t sub_type = (next & 0x7000) >> 12;
171
172 uint32_t extra_u = next & 0xfff;
173 if (next & 0x8000)
174 {
175 extra_u = ((extra_u & 0xfff) << 16) | m_pr16(PC);
176 PC += 2;
177 m_instruction_length = (3<<19);
178 }
179 else
180 {
181 m_instruction_length = (2<<19);
182 }
183
184 check_delay_PC();
185
186 const uint32_t fp = GET_FP;
187 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
188 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
189
190 if ((SRC_GLOBAL && (src_code == SR_REGISTER)) || (DST_GLOBAL && (dst_code < 2)))
191 {
192 LOG("Denoted PC or SR in hyperstone_xm. PC = %08X\n", PC);
193 m_core->icount -= m_core->clock_cycles_1;
194 return;
195 }
196
197 uint32_t sreg = (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code];
198
199 if (sub_type < 4)
200 {
201 if ((SRC_GLOBAL && (src_code == PC_REGISTER)) ? (sreg >= extra_u) : (sreg > extra_u))
202 execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
203 else
204 sreg <<= sub_type;
205 }
206 else
207 {
208 sreg <<= (sub_type - 4);
209 }
210
211 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] = sreg;
212
213 m_core->icount -= m_core->clock_cycles_1;
214 }
215
216 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_mask()217 void hyperstone_device::hyperstone_mask()
218 {
219 const uint32_t extra_u = decode_const();
220 check_delay_PC();
221 const uint32_t dreg = (SRC_GLOBAL ? m_core->global_regs[SRC_CODE] : m_core->local_regs[(SRC_CODE + GET_FP) & 0x3f]) & extra_u;
222
223 if (dreg == 0)
224 SR |= Z_MASK;
225 else
226 SR &= ~Z_MASK;
227
228 if (DST_GLOBAL)
229 set_global_register(DST_CODE, dreg);
230 else
231 m_core->local_regs[(DST_CODE + GET_FP) & 0x3f] = dreg;
232
233 m_core->icount -= m_core->clock_cycles_1;
234 }
235
236 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_sum()237 void hyperstone_device::hyperstone_sum()
238 {
239 const uint32_t extra_u = decode_const();
240 check_delay_PC();
241 const uint32_t fp = GET_FP;
242 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
243 const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_core->global_regs[src_code]) : m_core->local_regs[src_code];
244
245 const uint64_t tmp = uint64_t(sreg) + uint64_t(extra_u);
246
247 SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK);
248 SR |= (tmp & 0x100000000) >> 32;
249 SR |= ((sreg ^ tmp) & (extra_u ^ tmp) & 0x80000000) >> 28;
250
251 const uint32_t dreg = sreg + extra_u;
252
253 if (dreg == 0)
254 SR |= Z_MASK;
255 SR |= SIGN_TO_N(dreg);
256
257 if (DST_GLOBAL)
258 set_global_register(DST_CODE, dreg);
259 else
260 m_core->local_regs[(DST_CODE + fp) & 0x3f] = dreg;
261
262
263 m_core->icount -= m_core->clock_cycles_1;
264 }
265
266 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_sums()267 void hyperstone_device::hyperstone_sums()
268 {
269 const int32_t extra_s = decode_const();
270
271 check_delay_PC();
272
273 const uint32_t fp = GET_FP;
274 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
275 const int32_t sreg = int32_t(SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_core->global_regs[src_code]) : m_core->local_regs[src_code]);
276
277 const int64_t tmp = int64_t(sreg) + int64_t(extra_s);
278
279 SR &= ~(Z_MASK | N_MASK | V_MASK);
280 SR |= ((sreg ^ tmp) & (extra_s ^ tmp) & 0x80000000) >> 28;
281
282 //#if SETCARRYS
283 // SR |= (tmp & 0x100000000) >> 32;
284 //#endif
285
286 const int32_t res = sreg + extra_s;
287
288 if (res == 0)
289 SR |= Z_MASK;
290 SR |= SIGN_TO_N(res);
291
292 if (DST_GLOBAL)
293 set_global_register(DST_CODE, res);
294 else
295 m_core->local_regs[(DST_CODE + fp) & 0x3f] = res;
296
297 m_core->icount -= m_core->clock_cycles_1;
298
299 if ((SR & V_MASK) && src_code != SR_REGISTER)
300 execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
301 }
302
303
304 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_cmp()305 void hyperstone_device::hyperstone_cmp()
306 {
307 check_delay_PC();
308
309 const uint32_t fp = GET_FP;
310 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
311 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
312
313 const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_core->global_regs[src_code]) : m_core->local_regs[src_code];
314 uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
315
316 const uint64_t tmp = uint64_t(dreg) - uint64_t(sreg);
317
318 SR &= ~(Z_MASK | N_MASK | V_MASK | C_MASK);
319 SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28;
320
321 if (dreg < sreg)
322 SR |= C_MASK;
323 else if (dreg == sreg)
324 SR |= Z_MASK;
325
326 if (int32_t(dreg) < int32_t(sreg))
327 SR |= N_MASK;
328
329 m_core->icount -= m_core->clock_cycles_1;
330 }
331
332 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_mov()333 void hyperstone_device::hyperstone_mov()
334 {
335 m_core->icount -= m_core->clock_cycles_1;
336
337 check_delay_PC();
338
339 const bool h = (SR & H_MASK) != 0;
340 SR &= ~H_MASK;
341 if (DST_GLOBAL && h && !(SR & S_MASK))
342 {
343 execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR));
344 }
345 else
346 {
347 const uint32_t fp = GET_FP;
348 const uint32_t src_code = SRC_GLOBAL ? (SRC_CODE + (h ? 16 : 0)) : ((SRC_CODE + fp) & 0x3f);
349 const uint32_t sreg = SRC_GLOBAL ? ((WRITE_ONLY_REGMASK & (1 << src_code)) ? 0 : get_global_register(src_code)) : m_core->local_regs[src_code];
350
351 SR &= ~(Z_MASK | N_MASK);
352 if (sreg == 0)
353 SR |= Z_MASK;
354 SR |= SIGN_TO_N(sreg);
355
356 if (DST_GLOBAL)
357 {
358 const uint32_t dst_code = DST_CODE + (h ? 16 : 0);
359 set_global_register(dst_code, sreg);
360
361 if (dst_code == PC_REGISTER)
362 SR &= ~M_MASK;
363 }
364 else
365 {
366 m_core->local_regs[(DST_CODE + fp) & 0x3f] = sreg;
367 }
368 }
369 }
370
371 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_add()372 void hyperstone_device::hyperstone_add()
373 {
374 check_delay_PC();
375
376 const uint32_t fp = GET_FP;
377 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
378 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
379
380 const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_core->global_regs[src_code]) : m_core->local_regs[src_code];
381 uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
382
383 const uint64_t tmp = uint64_t(sreg) + uint64_t(dreg);
384
385 SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK);
386
387 SR |= (tmp & 0x100000000) >> 32;
388 SR |= ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28;
389
390 dreg += sreg;
391
392 if (dreg == 0)
393 SR |= Z_MASK;
394 SR |= SIGN_TO_N(dreg);
395
396 if (DST_GLOBAL)
397 {
398 set_global_register(dst_code, dreg);
399
400 if (dst_code == 0)
401 SR &= ~M_MASK;
402 }
403 else
404 {
405 m_core->local_regs[dst_code] = dreg;
406 }
407
408 m_core->icount -= m_core->clock_cycles_1;
409 }
410
411 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_adds()412 void hyperstone_device::hyperstone_adds()
413 {
414 check_delay_PC();
415
416 const uint32_t fp = GET_FP;
417 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
418 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
419
420 const int32_t sreg = int32_t(SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_core->global_regs[src_code]) : m_core->local_regs[src_code]);
421 int32_t dreg = int32_t((DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code]);
422 const int64_t tmp = int64_t(sreg) + int64_t(dreg);
423
424 SR &= ~(V_MASK | Z_MASK | N_MASK);
425 SR |= ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28;
426
427 //#if SETCARRYS
428 // SR |= (tmp & 0x100000000) >> 32;
429 //#endif
430
431 const int32_t res = sreg + dreg;
432
433 if (res == 0)
434 SR |= Z_MASK;
435 SR |= SIGN_TO_N(res);
436
437 if (DST_GLOBAL)
438 set_global_register(dst_code, res);
439 else
440 m_core->local_regs[dst_code] = res;
441
442 m_core->icount -= m_core->clock_cycles_1;
443
444 if (SR & V_MASK)
445 execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
446 }
447
448
449
450 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_cmpb()451 void hyperstone_device::hyperstone_cmpb()
452 {
453 check_delay_PC();
454
455 const uint32_t fp = GET_FP;
456 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
457 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
458
459 const uint32_t sreg = (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code];
460 const uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
461
462 if (dreg & sreg)
463 SR &= ~Z_MASK;
464 else
465 SR |= Z_MASK;
466
467 m_core->icount -= m_core->clock_cycles_1;
468 }
469
470 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_andn()471 void hyperstone_device::hyperstone_andn()
472 {
473 check_delay_PC();
474
475 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
476 const uint32_t sreg = SRC_GLOBAL ? m_core->global_regs[SRC_CODE] : m_core->local_regs[(SRC_CODE + GET_FP) & 0x3f];
477 const uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] & ~sreg;
478
479 if (dreg == 0)
480 SR |= Z_MASK;
481 else
482 SR &= ~Z_MASK;
483
484 if (DST_GLOBAL)
485 set_global_register(dst_code, dreg);
486 else
487 m_core->local_regs[dst_code] = dreg;
488
489 m_core->icount -= m_core->clock_cycles_1;
490 }
491
492 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_or()493 void hyperstone_device::hyperstone_or()
494 {
495 check_delay_PC();
496
497 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
498 const uint32_t sreg = SRC_GLOBAL ? m_core->global_regs[SRC_CODE] : m_core->local_regs[(SRC_CODE + GET_FP) & 0x3f];
499 const uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] | sreg;
500
501 if (dreg == 0)
502 SR |= Z_MASK;
503 else
504 SR &= ~Z_MASK;
505
506 if (DST_GLOBAL)
507 set_global_register(dst_code, dreg);
508 else
509 m_core->local_regs[dst_code] = dreg;
510
511 m_core->icount -= m_core->clock_cycles_1;
512 }
513
514 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_xor()515 void hyperstone_device::hyperstone_xor()
516 {
517 check_delay_PC();
518
519 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
520 const uint32_t sreg = SRC_GLOBAL ? m_core->global_regs[SRC_CODE] : m_core->local_regs[(SRC_CODE + GET_FP) & 0x3f];
521 const uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] ^ sreg;
522
523 if (dreg == 0)
524 SR |= Z_MASK;
525 else
526 SR &= ~Z_MASK;
527
528 if (DST_GLOBAL)
529 set_global_register(dst_code, dreg);
530 else
531 m_core->local_regs[dst_code] = dreg;
532
533 m_core->icount -= m_core->clock_cycles_1;
534 }
535
536
537
538 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_subc()539 void hyperstone_device::hyperstone_subc()
540 {
541 check_delay_PC();
542
543 const uint32_t fp = GET_FP;
544 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
545 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
546
547 const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? 0 : m_core->global_regs[src_code]) : m_core->local_regs[src_code];
548 uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
549 const uint32_t c = GET_C;
550
551 const uint64_t tmp = uint64_t(dreg) - (uint64_t(sreg) + uint64_t(c));
552
553 uint32_t old_z = SR & Z_MASK;
554 SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK);
555
556 const uint32_t sreg_c = sreg + c;
557 SR |= ((tmp ^ dreg) & (dreg ^ sreg_c) & 0x80000000) >> 28;
558 SR |= (tmp & 0x100000000) >> 32;
559 dreg -= sreg + c;
560
561 if (old_z && dreg == 0)
562 SR |= Z_MASK;
563 SR |= SIGN_TO_N(dreg);
564
565 if (DST_GLOBAL)
566 set_global_register(DST_CODE, dreg);
567 else
568 m_core->local_regs[dst_code] = dreg;
569
570 m_core->icount -= m_core->clock_cycles_1;
571 }
572
573 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_not()574 void hyperstone_device::hyperstone_not()
575 {
576 check_delay_PC();
577
578 const uint32_t dreg = ~(SRC_GLOBAL ? m_core->global_regs[SRC_CODE] : m_core->local_regs[(SRC_CODE + GET_FP) & 0x3f]);
579
580 if (dreg == 0)
581 SR |= Z_MASK;
582 else
583 SR &= ~Z_MASK;
584
585 if (DST_GLOBAL)
586 set_global_register(DST_CODE, dreg);
587 else
588 m_core->local_regs[(DST_CODE + GET_FP) & 0x3f] = dreg;
589
590 m_core->icount -= m_core->clock_cycles_1;
591 }
592
593 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_sub()594 void hyperstone_device::hyperstone_sub()
595 {
596 check_delay_PC();
597
598 const uint32_t fp = GET_FP;
599 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
600 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
601
602 const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_core->global_regs[src_code]) : m_core->local_regs[src_code];
603 uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
604
605 const uint64_t tmp = uint64_t(dreg) - uint64_t(sreg);
606
607 SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK);
608 SR |= (tmp & 0x100000000) >> 32;
609 SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28;
610
611 dreg -= sreg;
612
613 if (dreg == 0)
614 SR |= Z_MASK;
615 SR |= SIGN_TO_N(dreg);
616
617 if (DST_GLOBAL)
618 {
619 set_global_register(dst_code, dreg);
620
621 if (dst_code == PC_REGISTER)
622 SR &= ~M_MASK;
623 }
624 else
625 {
626 m_core->local_regs[dst_code] = dreg;
627 }
628
629 m_core->icount -= m_core->clock_cycles_1;
630 }
631
632 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_subs()633 void hyperstone_device::hyperstone_subs()
634 {
635 check_delay_PC();
636
637 const uint32_t fp = GET_FP;
638 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
639 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
640
641 const int32_t sreg = int32_t(SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_core->global_regs[src_code]) : m_core->local_regs[src_code]);
642 int32_t dreg = int32_t((DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code]);
643 const int64_t tmp = int64_t(dreg) - int64_t(sreg);
644
645 SR &= ~(V_MASK | Z_MASK | N_MASK);
646
647 SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28;
648
649 dreg -= sreg;
650
651 if (dreg == 0)
652 SR |= Z_MASK;
653 SR |= SIGN_TO_N(dreg);
654
655 if (DST_GLOBAL)
656 set_global_register(dst_code, dreg);
657 else
658 m_core->local_regs[dst_code] = dreg;
659
660 m_core->icount -= m_core->clock_cycles_1;
661
662 if (SR & V_MASK)
663 execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
664 }
665
666
667
668 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_addc()669 void hyperstone_device::hyperstone_addc()
670 {
671 check_delay_PC();
672
673 const uint32_t fp = GET_FP;
674 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
675 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
676
677 const uint32_t sreg = (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code];
678 uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
679
680 const bool old_z = (SR & Z_MASK) != 0;
681 const uint32_t c = GET_C;
682
683 SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK);
684
685 uint64_t tmp;
686 if (SRC_GLOBAL && (src_code == SR_REGISTER))
687 {
688 tmp = uint64_t(dreg) + uint64_t(c);
689 SR |= ((dreg ^ tmp) & tmp & 0x80000000) >> 28;
690 dreg += c;
691 }
692 else
693 {
694 tmp = uint64_t(sreg) + uint64_t(dreg) + uint64_t(c);
695 SR |= ((sreg ^ tmp) & (dreg ^ tmp) & tmp & 0x80000000) >> 28;
696 dreg += sreg + c;
697 }
698
699 SR |= (tmp & 0x100000000) >> 32;
700
701 if (dreg == 0 && old_z)
702 SR |= Z_MASK;
703 SR |= SIGN_TO_N(dreg);
704
705 if (DST_GLOBAL)
706 set_global_register(dst_code, dreg);
707 else
708 m_core->local_regs[dst_code] = dreg;
709
710 m_core->icount -= m_core->clock_cycles_1;
711 }
712
713 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_and()714 void hyperstone_device::hyperstone_and()
715 {
716 check_delay_PC();
717
718 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
719 const uint32_t sreg = SRC_GLOBAL ? m_core->global_regs[SRC_CODE] : m_core->local_regs[(SRC_CODE + GET_FP) & 0x3f];
720 const uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] & sreg;
721
722 if (dreg == 0)
723 SR |= Z_MASK;
724 else
725 SR &= ~Z_MASK;
726
727 if (DST_GLOBAL)
728 set_global_register(dst_code, dreg);
729 else
730 m_core->local_regs[dst_code] = dreg;
731
732 m_core->icount -= m_core->clock_cycles_1;
733 }
734
735 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_neg()736 void hyperstone_device::hyperstone_neg()
737 {
738 check_delay_PC();
739
740 const uint32_t fp = GET_FP;
741 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
742
743 const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_core->global_regs[src_code]) : m_core->local_regs[src_code];
744 const uint64_t tmp = -uint64_t(sreg);
745
746 SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK);
747 SR |= (tmp & 0x100000000) >> 32;
748 SR |= (tmp & sreg & 0x80000000) >> 28;
749
750 const uint32_t dreg = -sreg;
751
752 if (dreg == 0)
753 SR |= Z_MASK;
754 SR |= SIGN_TO_N(dreg);
755
756 if (DST_GLOBAL)
757 set_global_register(DST_CODE, dreg);
758 else
759 m_core->local_regs[(DST_CODE + fp) & 0x3f] = dreg;
760
761 m_core->icount -= m_core->clock_cycles_1;
762 }
763
764 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_negs()765 void hyperstone_device::hyperstone_negs()
766 {
767 check_delay_PC();
768
769 const uint32_t fp = GET_FP;
770 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
771
772 const int32_t sreg = int32_t(SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_core->global_regs[src_code]) : m_core->local_regs[src_code]);
773 const int64_t tmp = -int64_t(sreg);
774
775 SR &= ~(V_MASK | Z_MASK | N_MASK);
776
777 if (tmp & sreg & 0x80000000)
778 SR |= V_MASK;
779
780 //#if SETCARRYS
781 // SR |= (tmp & 0x100000000) >> 32;
782 //#endif
783
784 const int32_t res = -sreg;
785
786 if (res == 0)
787 SR |= Z_MASK;
788 SR |= SIGN_TO_N(res);
789
790 if (DST_GLOBAL)
791 set_global_register(DST_CODE, res);
792 else
793 m_core->local_regs[(DST_CODE + fp) & 0x3f] = res;
794
795 m_core->icount -= m_core->clock_cycles_1;
796
797 if (GET_V)
798 execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
799 }
800
801
802
803 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG>
hyperstone_cmpi()804 void hyperstone_device::hyperstone_cmpi()
805 {
806 uint32_t imm;
807 if (IMM_LONG)
808 imm = decode_immediate_s();
809
810 check_delay_PC();
811
812 if (!IMM_LONG)
813 imm = m_op & 0x0f;
814 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
815 const uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
816
817 SR &= ~(V_MASK | Z_MASK | N_MASK | C_MASK);
818
819 uint64_t tmp = (uint64_t)dreg - (uint64_t)imm;
820 SR |= ((tmp ^ dreg) & (dreg ^ imm) & 0x80000000) >> 28;
821
822 if (dreg < imm)
823 SR |= C_MASK;
824 else if (dreg == imm)
825 SR |= Z_MASK;
826
827 if ((int32_t)dreg < (int32_t)imm)
828 SR |= N_MASK;
829
830 m_core->icount -= m_core->clock_cycles_1;
831 }
832
833 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG>
hyperstone_movi()834 void hyperstone_device::hyperstone_movi()
835 {
836 m_core->icount -= m_core->clock_cycles_1;
837
838 uint32_t imm;
839 if (IMM_LONG)
840 imm = decode_immediate_s();
841 check_delay_PC();
842
843 if (!IMM_LONG)
844 imm = m_op & 0x0f;
845
846 const bool h = (SR & H_MASK) != 0;
847 SR &= ~H_MASK;
848 if (DST_GLOBAL && h && !(SR & S_MASK))
849 {
850 execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR));
851 }
852 else
853 {
854 SR &= ~(Z_MASK | N_MASK);
855 if (imm == 0)
856 SR |= Z_MASK;
857 SR |= SIGN_TO_N(imm);
858
859 #if MISSIONCRAFT_FLAGS
860 SR &= ~V_MASK; // or V undefined ?
861 #endif
862
863 if (DST_GLOBAL)
864 {
865 const uint32_t dst_code = DST_CODE + (h ? 16 : 0);
866 set_global_register(dst_code, imm);
867
868 if (dst_code == PC_REGISTER)
869 SR &= ~M_MASK;
870 }
871 else
872 {
873 m_core->local_regs[(DST_CODE + GET_FP) & 0x3f] = imm;
874 }
875 }
876 }
877
878 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG>
hyperstone_addi()879 void hyperstone_device::hyperstone_addi()
880 {
881 uint32_t imm;
882 if (IMM_LONG)
883 imm = decode_immediate_s();
884 check_delay_PC();
885
886 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
887 uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
888
889 if (!N_OP_MASK)
890 imm = GET_C & (((SR & Z_MASK) ? 0 : 1) | (dreg & 0x01));
891 else if (!IMM_LONG)
892 imm = m_op & 0x0f;
893
894 SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK);
895
896 const uint64_t tmp = (uint64_t)imm + (uint64_t)dreg;
897
898 SR |= (tmp & 0x100000000) >> 32;
899 SR |= ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28;
900
901 dreg += imm;
902
903 if (dreg == 0)
904 SR |= Z_MASK;
905 SR |= SIGN_TO_N(dreg);
906
907 if (DST_GLOBAL)
908 {
909 set_global_register(dst_code, dreg);
910
911 if (dst_code == 0)
912 SR &= ~M_MASK;
913 }
914 else
915 {
916 m_core->local_regs[dst_code] = dreg;
917 }
918
919 m_core->icount -= m_core->clock_cycles_1;
920 }
921
922 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG>
hyperstone_addsi()923 void hyperstone_device::hyperstone_addsi()
924 {
925 if (!IMM_LONG)
926 check_delay_PC();
927
928 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
929 const int32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
930
931 int32_t imm;
932 if (N_OP_MASK)
933 {
934 if (IMM_LONG)
935 {
936 imm = decode_immediate_s();
937 check_delay_PC();
938 }
939 else
940 {
941 imm = m_op & 0x0f;
942 }
943 }
944 else
945 {
946 if (IMM_LONG)
947 {
948 ignore_immediate_s();
949 check_delay_PC();
950 }
951 imm = SR & (((SR & Z_MASK) ? 0 : 1) | (dreg & 0x01));
952 }
953
954 SR &= ~(V_MASK | Z_MASK | N_MASK);
955
956 const int64_t tmp = (int64_t)imm + (int64_t)(int32_t)dreg;
957 SR |= ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28;
958
959 //#if SETCARRYS
960 // SR |= (tmp & 0x100000000) >> 32;
961 //#endif
962
963 const int32_t res = imm + (int32_t)dreg;
964
965 if (res == 0)
966 SR |= Z_MASK;
967 SR |= SIGN_TO_N(res);
968
969 if (DST_GLOBAL)
970 set_global_register(dst_code, res);
971 else
972 m_core->local_regs[dst_code] = res;
973
974 m_core->icount -= m_core->clock_cycles_1;
975
976 if (SR & V_MASK)
977 execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
978 }
979
980
981
982 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG>
hyperstone_cmpbi()983 void hyperstone_device::hyperstone_cmpbi()
984 {
985 if (!IMM_LONG)
986 check_delay_PC();
987
988 const uint32_t dreg = DST_GLOBAL ? m_core->global_regs[DST_CODE] : m_core->local_regs[(DST_CODE + GET_FP) & 0x3f];
989
990 const uint32_t n = N_VALUE;
991 if (n)
992 {
993 uint32_t imm;
994 if (n == 31)
995 {
996 if (IMM_LONG)
997 {
998 ignore_immediate_s();
999 check_delay_PC();
1000 }
1001 imm = 0x7fffffff; // bit 31 = 0, others = 1
1002 }
1003 else
1004 {
1005 if (IMM_LONG)
1006 {
1007 imm = decode_immediate_s();
1008 check_delay_PC();
1009 }
1010 else
1011 {
1012 imm = m_op & 0x0f;
1013 }
1014 }
1015
1016 if (dreg & imm)
1017 SR &= ~Z_MASK;
1018 else
1019 SR |= Z_MASK;
1020 }
1021 else
1022 {
1023 if (IMM_LONG)
1024 {
1025 ignore_immediate_s();
1026 check_delay_PC();
1027 }
1028 if ((dreg & 0xff000000) == 0 || (dreg & 0x00ff0000) == 0 || (dreg & 0x0000ff00) == 0 || (dreg & 0x000000ff) == 0)
1029 SR |= Z_MASK;
1030 else
1031 SR &= ~Z_MASK;
1032 }
1033
1034 m_core->icount -= m_core->clock_cycles_1;
1035 }
1036
1037 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG>
hyperstone_andni()1038 void hyperstone_device::hyperstone_andni()
1039 {
1040 uint32_t imm;
1041 if (IMM_LONG)
1042 imm = decode_immediate_s();
1043
1044 check_delay_PC();
1045
1046 if (N_OP_MASK == 0x10f)
1047 imm = 0x7fffffff; // bit 31 = 0, others = 1
1048 else if (!IMM_LONG)
1049 imm = m_op & 0x0f;
1050
1051 uint32_t dreg;
1052 if (DST_GLOBAL)
1053 {
1054 const uint32_t dst_code = DST_CODE;
1055 dreg = m_core->global_regs[dst_code] & ~imm;
1056
1057 if (dreg == 0)
1058 SR |= Z_MASK;
1059 else
1060 SR &= ~Z_MASK;
1061
1062 set_global_register(dst_code, dreg);
1063 }
1064 else
1065 {
1066 const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f;
1067 dreg = m_core->local_regs[dst_code] & ~imm;
1068 m_core->local_regs[dst_code] = dreg;
1069
1070 if (dreg == 0)
1071 SR |= Z_MASK;
1072 else
1073 SR &= ~Z_MASK;
1074 }
1075
1076 m_core->icount -= m_core->clock_cycles_1;
1077 }
1078
1079 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG>
hyperstone_ori()1080 void hyperstone_device::hyperstone_ori()
1081 {
1082 uint32_t imm;
1083 if (IMM_LONG)
1084 imm = decode_immediate_s();
1085
1086 check_delay_PC();
1087
1088 if (!IMM_LONG)
1089 imm = m_op & 0x0f;
1090
1091 if (DST_GLOBAL)
1092 {
1093 const uint32_t dst_code = DST_CODE;
1094 const uint32_t dreg = m_core->global_regs[dst_code] | imm;
1095
1096 if (dreg)
1097 SR &= ~Z_MASK;
1098 else
1099 SR |= Z_MASK;
1100
1101 set_global_register(dst_code, dreg);
1102 }
1103 else
1104 {
1105 const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f;
1106 const uint32_t dreg = m_core->local_regs[dst_code] |= imm;
1107
1108 if (dreg)
1109 SR &= ~Z_MASK;
1110 else
1111 SR |= Z_MASK;
1112 }
1113
1114 m_core->icount -= m_core->clock_cycles_1;
1115 }
1116
1117 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG>
hyperstone_xori()1118 void hyperstone_device::hyperstone_xori()
1119 {
1120 uint32_t imm;
1121 if (IMM_LONG)
1122 imm = decode_immediate_s();
1123
1124 check_delay_PC();
1125
1126 if (!IMM_LONG)
1127 imm = m_op & 0x0f;
1128 uint32_t dreg;
1129 if (DST_GLOBAL)
1130 {
1131 const uint32_t dst_code = DST_CODE;
1132 dreg = m_core->global_regs[dst_code] ^ imm;
1133
1134 if (dreg)
1135 SR &= ~Z_MASK;
1136 else
1137 SR |= Z_MASK;
1138
1139 set_global_register(dst_code, dreg);
1140 }
1141 else
1142 {
1143 const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f;
1144 dreg = m_core->local_regs[dst_code] ^= imm;
1145
1146 if (dreg)
1147 SR &= ~Z_MASK;
1148 else
1149 SR |= Z_MASK;
1150 }
1151
1152 m_core->icount -= m_core->clock_cycles_1;
1153 }
1154
1155
1156 template <hyperstone_device::shift_type HI_N>
hyperstone_shrdi()1157 void hyperstone_device::hyperstone_shrdi()
1158 {
1159 check_delay_PC();
1160
1161 const uint32_t fp = GET_FP;
1162 const uint32_t code = DST_CODE;
1163 const uint32_t dst_code = (code + fp) & 0x3f;
1164 const uint32_t dstf_code = (code + 1 + fp) & 0x3f;
1165 uint32_t high_order = m_core->local_regs[dst_code];
1166 const uint32_t low_order = m_core->local_regs[dstf_code];
1167
1168 uint64_t val = concat_64(high_order, low_order);
1169
1170 SR &= ~(C_MASK | Z_MASK | N_MASK);
1171
1172 const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE;
1173 if (HI_N || n)
1174 {
1175 SR |= (val >> (n - 1)) & 1;
1176
1177 val >>= n;
1178 }
1179
1180 high_order = extract_64hi(val);
1181
1182 if (val == 0)
1183 SR |= Z_MASK;
1184 SR |= SIGN_TO_N(high_order);
1185
1186 m_core->local_regs[dst_code] = high_order;
1187 m_core->local_regs[dstf_code] = extract_64lo(val);
1188
1189 m_core->icount -= m_core->clock_cycles_2;
1190 }
1191
1192
hyperstone_shrd()1193 void hyperstone_device::hyperstone_shrd()
1194 {
1195 check_delay_PC();
1196
1197 const uint32_t fp = GET_FP;
1198 const uint32_t src_code = (SRC_CODE + fp) & 0x3f;
1199 const uint32_t d_code = DST_CODE;
1200 const uint32_t dst_code = (d_code + fp) & 0x3f;
1201 const uint32_t dstf_code = (d_code + 1 + fp) & 0x3f;
1202
1203 if (src_code == dst_code || src_code == dstf_code)
1204 {
1205 m_core->icount -= m_core->clock_cycles_2;
1206 return;
1207 }
1208
1209 uint64_t val = concat_64(m_core->local_regs[dst_code], m_core->local_regs[dstf_code]);
1210
1211 SR &= ~(C_MASK | Z_MASK | N_MASK);
1212
1213 const uint32_t n = m_core->local_regs[src_code] & 0x1f;
1214
1215 if (n)
1216 {
1217 SR |= (val >> (n - 1)) & 1;
1218 val >>= n;
1219 }
1220
1221 if (val == 0)
1222 SR |= Z_MASK;
1223 SR |= SIGN64_TO_N(val);
1224
1225 m_core->local_regs[dst_code] = (uint32_t)(val >> 32);
1226 m_core->local_regs[dstf_code] = (uint32_t)val;
1227
1228 m_core->icount -= m_core->clock_cycles_2;
1229 }
1230
hyperstone_shr()1231 void hyperstone_device::hyperstone_shr()
1232 {
1233 check_delay_PC();
1234
1235 const uint32_t fp = GET_FP;
1236 const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
1237 const uint32_t n = m_core->local_regs[(SRC_CODE + fp) & 0x3f] & 0x1f;
1238 uint32_t dreg = m_core->local_regs[dst_code];
1239
1240 SR &= ~(C_MASK | Z_MASK | N_MASK);
1241
1242 if (n && (dreg & (1 << (n - 1))))
1243 SR |= C_MASK;
1244
1245 dreg >>= n;
1246
1247 if (dreg == 0)
1248 SR |= Z_MASK;
1249 SR |= SIGN_TO_N(dreg);
1250
1251 m_core->local_regs[dst_code] = dreg;
1252
1253 m_core->icount -= m_core->clock_cycles_1;
1254 }
1255
1256 template <hyperstone_device::shift_type HI_N>
hyperstone_sardi()1257 void hyperstone_device::hyperstone_sardi()
1258 {
1259 check_delay_PC();
1260
1261 const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f;
1262 const uint32_t dstf_code = (dst_code + 1) & 0x3f;
1263
1264 uint64_t val = concat_64(m_core->local_regs[dst_code], m_core->local_regs[dstf_code]);
1265
1266 SR &= ~(C_MASK | Z_MASK | N_MASK);
1267
1268 const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE;
1269 if (HI_N || n)
1270 {
1271 SR |= (val >> (n - 1)) & 1;
1272
1273 const uint64_t sign_bit = val >> 63;
1274 val >>= n;
1275
1276 if (sign_bit)
1277 val |= 0xffffffff00000000U << (32 - n);
1278 }
1279
1280 if (val == 0)
1281 SR |= Z_MASK;
1282 SR |= SIGN_TO_N(m_core->local_regs[dst_code]);
1283
1284 m_core->local_regs[dst_code] = (uint32_t)(val >> 32);
1285 m_core->local_regs[dstf_code] = (uint32_t)val;
1286
1287 m_core->icount -= m_core->clock_cycles_2;
1288 }
1289
hyperstone_sard()1290 void hyperstone_device::hyperstone_sard()
1291 {
1292 check_delay_PC();
1293
1294 const uint32_t fp = GET_FP;
1295 const uint32_t src_code = (SRC_CODE + fp) & 0x3f;
1296 const uint32_t d_code = DST_CODE;
1297 const uint32_t dst_code = (d_code + fp) & 0x3f;
1298 const uint32_t dstf_code = (d_code + 1 + fp) & 0x3f;
1299
1300 if (src_code == dst_code || src_code == dstf_code)
1301 {
1302 m_core->icount -= m_core->clock_cycles_2;
1303 return;
1304 }
1305
1306 uint64_t val = concat_64(m_core->local_regs[dst_code], m_core->local_regs[dstf_code]);
1307
1308 SR &= ~(C_MASK | Z_MASK | N_MASK);
1309
1310 const uint32_t n = m_core->local_regs[src_code] & 0x1f;
1311
1312 if (n)
1313 {
1314 SR |= (val >> (n - 1)) & 1;
1315
1316 uint32_t sign_bit = val >> 63;
1317
1318 val >>= n;
1319
1320 if (sign_bit)
1321 {
1322 val |= 0xffffffff00000000L << (32 - n);
1323 }
1324 }
1325
1326 if (val == 0)
1327 SR |= Z_MASK;
1328 SR |= SIGN64_TO_N(val);
1329
1330 m_core->local_regs[dst_code] = (uint32_t)(val >> 32);
1331 m_core->local_regs[dstf_code] = (uint32_t)val;
1332
1333 m_core->icount -= m_core->clock_cycles_2;
1334 }
1335
hyperstone_sar()1336 void hyperstone_device::hyperstone_sar()
1337 {
1338 check_delay_PC();
1339
1340 const uint32_t fp = GET_FP;
1341 const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
1342
1343 const uint32_t n = m_core->local_regs[(SRC_CODE + fp) & 0x3f] & 0x1f;
1344 uint32_t ret = m_core->local_regs[dst_code];
1345
1346 SR &= ~(C_MASK | Z_MASK | N_MASK);
1347
1348 if (n)
1349 {
1350 const uint32_t sign_bit = ret & 0x80000000;
1351
1352 SR |= (ret >> (n - 1)) & 1;
1353
1354 ret >>= n;
1355
1356 if (sign_bit)
1357 ret |= 0xffffffff << (32 - n);
1358 }
1359
1360 if (ret == 0)
1361 SR |= Z_MASK;
1362 SR |= SIGN_TO_N(ret);
1363
1364 m_core->local_regs[dst_code] = ret;
1365
1366 m_core->icount -= m_core->clock_cycles_1;
1367 }
1368
1369 template <hyperstone_device::shift_type HI_N>
hyperstone_shldi()1370 void hyperstone_device::hyperstone_shldi()
1371 {
1372 check_delay_PC();
1373
1374 const uint32_t fp = GET_FP;
1375 const uint32_t code = DST_CODE;
1376 const uint32_t dst_code = (code + fp) & 0x3f;
1377 const uint32_t dstf_code = (code + 1 + fp) & 0x3f;
1378 uint32_t high_order = m_core->local_regs[dst_code];
1379 uint32_t low_order = m_core->local_regs[dstf_code];
1380
1381 uint64_t val = concat_64(high_order, low_order);
1382
1383 SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK);
1384
1385 const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE;
1386 SR |= (n)?(((val<<(n-1))&0x8000000000000000ULL)?1:0):0;
1387
1388 const uint32_t tmp = high_order << n;
1389 uint32_t mask = (uint32_t)(0xffffffff00000000ULL >> n);
1390
1391 if (((high_order & mask) && (!(tmp & 0x80000000))) || (((high_order & mask) ^ mask) && (tmp & 0x80000000)))
1392 SR |= V_MASK;
1393
1394 val <<= n;
1395
1396 if (val == 0)
1397 SR |= Z_MASK;
1398 SR |= SIGN64_TO_N(val);
1399
1400 m_core->local_regs[dst_code] = extract_64hi(val);
1401 m_core->local_regs[dstf_code] = extract_64lo(val);
1402
1403 m_core->icount -= m_core->clock_cycles_2;
1404 }
1405
hyperstone_shld()1406 void hyperstone_device::hyperstone_shld()
1407 {
1408 check_delay_PC();
1409
1410 const uint32_t fp = GET_FP;
1411 const uint32_t d_code = DST_CODE;
1412 uint32_t src_code = (SRC_CODE + fp) & 0x3f;
1413 uint32_t dst_code = (d_code + fp) & 0x3f;
1414 uint32_t dstf_code = (d_code + fp + 1) & 0x3f;
1415
1416 // result undefined if Ls denotes the same register as Ld or Ldf
1417 if (src_code == dst_code || src_code == dstf_code)
1418 {
1419 LOG("Denoted same registers in hyperstone_shld. PC = %08X\n", PC);
1420 m_core->icount -= m_core->clock_cycles_2;
1421 return;
1422 }
1423
1424 uint32_t high_order = m_core->local_regs[dst_code];
1425 uint32_t low_order = m_core->local_regs[dstf_code];
1426
1427 uint64_t val = concat_64(high_order, low_order);
1428
1429 SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK);
1430
1431 const uint32_t n = m_core->local_regs[src_code] & 0x1f;
1432 SR |= (n)?(((val<<(n-1))&0x8000000000000000ULL)?1:0):0;
1433
1434 const uint32_t tmp = high_order << n;
1435 const uint32_t mask = (uint32_t)(0xffffffff00000000ULL >> n);
1436
1437 if (((high_order & mask) && (!(tmp & 0x80000000))) || (((high_order & mask) ^ mask) && (tmp & 0x80000000)))
1438 SR |= V_MASK;
1439
1440 val <<= n;
1441
1442 if (val == 0)
1443 SR |= Z_MASK;
1444 SR |= SIGN64_TO_N(val);
1445
1446 m_core->local_regs[dst_code] = extract_64hi(val);
1447 m_core->local_regs[dstf_code] = extract_64lo(val);
1448
1449 m_core->icount -= m_core->clock_cycles_2;
1450 }
1451
hyperstone_shl()1452 void hyperstone_device::hyperstone_shl()
1453 {
1454 check_delay_PC();
1455
1456 const uint32_t fp = GET_FP;
1457 uint32_t src_code = SRC_CODE + fp;
1458 uint32_t dst_code = DST_CODE + fp;
1459
1460 uint32_t n = m_core->local_regs[src_code & 0x3f] & 0x1f;
1461 uint32_t base = m_core->local_regs[dst_code & 0x3f]; /* registers offset by frame pointer */
1462 uint64_t mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff;
1463
1464 SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK);
1465
1466 SR |= (n)?(((base<<(n-1))&0x80000000)?1:0):0;
1467 uint32_t ret = base << n;
1468
1469 if (((base & mask) && (!(ret & 0x80000000))) || (((base & mask) ^ mask) && (ret & 0x80000000)))
1470 SR |= V_MASK;
1471
1472 if (ret == 0)
1473 SR |= Z_MASK;
1474 SR |= SIGN_TO_N(ret);
1475
1476 m_core->local_regs[dst_code & 0x3f] = ret;
1477
1478 m_core->icount -= m_core->clock_cycles_1;
1479 }
1480
hyperstone_testlz()1481 void hyperstone_device::hyperstone_testlz()
1482 {
1483 check_delay_PC();
1484
1485 const uint32_t fp = GET_FP;
1486 const uint32_t sreg = m_core->local_regs[(SRC_CODE + fp) & 0x3f];
1487 uint32_t zeros = 0;
1488 for (uint32_t mask = 0x80000000; mask != 0; mask >>= 1 )
1489 {
1490 if (sreg & mask)
1491 break;
1492 else
1493 zeros++;
1494 }
1495
1496 m_core->local_regs[(DST_CODE + fp) & 0x3f] = zeros;
1497
1498 m_core->icount -= m_core->clock_cycles_2;
1499 }
1500
hyperstone_rol()1501 void hyperstone_device::hyperstone_rol()
1502 {
1503 check_delay_PC();
1504
1505 const uint32_t fp = GET_FP;
1506 const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
1507
1508 uint32_t n = m_core->local_regs[(SRC_CODE + fp) & 0x3f] & 0x1f;
1509 uint32_t val = m_core->local_regs[dst_code];
1510
1511 #ifdef MISSIONCRAFT_FLAGS
1512 const uint32_t base = val;
1513 const uint32_t mask = (uint32_t)(0xffffffff00000000ULL >> n);
1514 #endif
1515
1516 if (n)
1517 val = (val << n) | (val >> (32 - n));
1518
1519 #ifdef MISSIONCRAFT_FLAGS
1520 SR &= ~(V_MASK | Z_MASK | C_MASK | N_MASK);
1521 if (((base & mask) && (!(val & 0x80000000))) || (((base & mask) ^ mask) && (val & 0x80000000)))
1522 SR |= V_MASK;
1523 #else
1524 SR &= ~(Z_MASK | C_MASK | N_MASK);
1525 #endif
1526
1527 if (val == 0)
1528 SR |= Z_MASK;
1529 SR |= SIGN_TO_N(val);
1530
1531 m_core->local_regs[dst_code] = val;
1532
1533 m_core->icount -= m_core->clock_cycles_1;
1534 }
1535
1536 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_ldxx1()1537 void hyperstone_device::hyperstone_ldxx1()
1538 {
1539 uint16_t next_1 = m_pr16(PC);
1540 PC += 2;
1541
1542 const uint16_t sub_type = (next_1 & 0x3000) >> 12;
1543
1544 uint32_t extra_s;
1545 if (next_1 & 0x8000)
1546 {
1547 const uint16_t next_2 = m_pr16(PC);
1548 PC += 2;
1549 m_instruction_length = (3<<19);
1550
1551 extra_s = next_2;
1552 extra_s |= ((next_1 & 0xfff) << 16);
1553
1554 if (next_1 & 0x4000)
1555 extra_s |= 0xf0000000;
1556 }
1557 else
1558 {
1559 m_instruction_length = (2<<19);
1560 extra_s = next_1 & 0xfff;
1561
1562 if (next_1 & 0x4000)
1563 extra_s |= 0xfffff000;
1564 }
1565
1566 check_delay_PC();
1567
1568 const uint32_t fp = GET_FP;
1569 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
1570 const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
1571 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
1572 const uint32_t dreg = ((DST_GLOBAL && dst_code == SR_REGISTER) ? 0 : (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code]);
1573
1574 switch (sub_type)
1575 {
1576 case 0: // LDBS.D
1577 if (SRC_GLOBAL)
1578 set_global_register(src_code, (int32_t)(int8_t)READ_B(dreg + extra_s));
1579 else
1580 m_core->local_regs[src_code] = (int32_t)(int8_t)READ_B(dreg + extra_s);
1581 break;
1582
1583 case 1: // LDBU.D
1584 if (SRC_GLOBAL)
1585 set_global_register(src_code, READ_B(dreg + extra_s));
1586 else
1587 m_core->local_regs[src_code] = READ_B(dreg + extra_s);
1588 break;
1589
1590 case 2:
1591 if (SRC_GLOBAL)
1592 {
1593 if (extra_s & 1)
1594 set_global_register(src_code, (int32_t)(int16_t)READ_HW(dreg + (extra_s & ~1)));
1595 else
1596 set_global_register(src_code, READ_HW(dreg + (extra_s & ~1)));
1597 }
1598 else
1599 {
1600 if (extra_s & 1)
1601 m_core->local_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg + (extra_s & ~1));
1602 else
1603 m_core->local_regs[src_code] = READ_HW(dreg + (extra_s & ~1));
1604 }
1605 break;
1606
1607 case 3:
1608 switch (extra_s & 3)
1609 {
1610 case 0: // LDW.D
1611 if (SRC_GLOBAL)
1612 set_global_register(src_code, READ_W(dreg + extra_s));
1613 else
1614 m_core->local_regs[src_code] = READ_W(dreg + extra_s);
1615 break;
1616 case 1: // LDD.D
1617 if (SRC_GLOBAL)
1618 {
1619 set_global_register(src_code, READ_W(dreg + (extra_s & ~1)));
1620 set_global_register(srcf_code, READ_W(dreg + (extra_s & ~1) + 4));
1621 }
1622 else
1623 {
1624 m_core->local_regs[src_code] = READ_W(dreg + (extra_s & ~1));
1625 m_core->local_regs[srcf_code] = READ_W(dreg + (extra_s & ~1) + 4);
1626 }
1627 m_core->icount -= m_core->clock_cycles_1; // extra cycle
1628 break;
1629 case 2: // LDW.IOD
1630 if (SRC_GLOBAL)
1631 set_global_register(src_code, IO_READ_W(dreg + (extra_s & ~3)));
1632 else
1633 m_core->local_regs[src_code] = IO_READ_W(dreg + (extra_s & ~3));
1634 break;
1635 case 3: // LDD.IOD
1636 if (SRC_GLOBAL)
1637 {
1638 set_global_register(src_code, IO_READ_W(dreg + (extra_s & ~3)));
1639 set_global_register(srcf_code, IO_READ_W(dreg + (extra_s & ~3) + 4));
1640 }
1641 else
1642 {
1643 m_core->local_regs[src_code] = IO_READ_W(dreg + (extra_s & ~3));
1644 m_core->local_regs[srcf_code] = IO_READ_W(dreg + (extra_s & ~3) + 4);
1645 }
1646 m_core->icount -= m_core->clock_cycles_1; // extra cycle
1647 break;
1648 }
1649 break;
1650 }
1651
1652 m_core->icount -= m_core->clock_cycles_1;
1653 }
1654
1655 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_ldxx2()1656 void hyperstone_device::hyperstone_ldxx2()
1657 {
1658 uint16_t next_1 = m_pr16(PC);
1659 PC += 2;
1660
1661 const uint16_t sub_type = (next_1 & 0x3000) >> 12;
1662
1663 uint32_t extra_s;
1664 if (next_1 & 0x8000)
1665 {
1666 const uint16_t next_2 = m_pr16(PC);
1667 PC += 2;
1668 m_instruction_length = (3<<19);
1669
1670 extra_s = next_2;
1671 extra_s |= ((next_1 & 0xfff) << 16);
1672
1673 if (next_1 & 0x4000)
1674 extra_s |= 0xf0000000;
1675 }
1676 else
1677 {
1678 m_instruction_length = (2<<19);
1679 extra_s = next_1 & 0xfff;
1680
1681 if (next_1 & 0x4000)
1682 extra_s |= 0xfffff000;
1683 }
1684
1685 check_delay_PC();
1686
1687 const uint32_t fp = GET_FP;
1688 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : (DST_CODE + fp) & 0x3f;
1689
1690 if (DST_GLOBAL && dst_code < 2)
1691 {
1692 m_core->icount -= m_core->clock_cycles_1;
1693 LOG("Denoted PC or SR in hyperstone_ldxx2. PC = %08X\n", PC);
1694 return;
1695 }
1696
1697 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : (SRC_CODE + fp) & 0x3f;
1698 const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
1699 const uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
1700
1701 switch (sub_type)
1702 {
1703 case 0: // LDBS.N
1704 if (SRC_GLOBAL)
1705 set_global_register(src_code, (int32_t)(int8_t)READ_B(dreg));
1706 else
1707 m_core->local_regs[src_code] = (int32_t)(int8_t)READ_B(dreg);
1708 if (DST_GLOBAL != SRC_GLOBAL || src_code != dst_code)
1709 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s;
1710 break;
1711
1712 case 1: // LDBU.N
1713 if (SRC_GLOBAL)
1714 set_global_register(src_code, READ_B(dreg));
1715 else
1716 m_core->local_regs[src_code] = READ_B(dreg);
1717 if(DST_GLOBAL != SRC_GLOBAL || src_code != dst_code)
1718 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s;
1719 break;
1720
1721 case 2:
1722 if (SRC_GLOBAL)
1723 {
1724 if (extra_s & 1) // LDHS.N
1725 set_global_register(src_code, (int32_t)(int16_t)READ_HW(dreg));
1726 else // LDHU.N
1727 set_global_register(src_code, READ_HW(dreg));
1728 }
1729 else
1730 {
1731 if (extra_s & 1) // LDHS.N
1732 m_core->local_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg);
1733 else // LDHU.N
1734 m_core->local_regs[src_code] = READ_HW(dreg);
1735 }
1736
1737 if(DST_GLOBAL != SRC_GLOBAL || src_code != dst_code)
1738 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] += (extra_s & ~1);
1739 break;
1740
1741 case 3:
1742 switch (extra_s & 3)
1743 {
1744 case 0: // LDW.N
1745 if (SRC_GLOBAL)
1746 set_global_register(src_code, READ_W(dreg));
1747 else
1748 m_core->local_regs[src_code] = READ_W(dreg);
1749 if(DST_GLOBAL != SRC_GLOBAL || src_code != dst_code)
1750 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s;
1751 break;
1752 case 1: // LDD.N
1753 if (SRC_GLOBAL)
1754 {
1755 set_global_register(src_code, READ_W(dreg));
1756 set_global_register(srcf_code, READ_W(dreg + 4));
1757 }
1758 else
1759 {
1760 m_core->local_regs[src_code] = READ_W(dreg);
1761 m_core->local_regs[srcf_code] = READ_W(dreg + 4);
1762 }
1763
1764 if (DST_GLOBAL != SRC_GLOBAL || (src_code != dst_code && srcf_code != dst_code))
1765 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s & ~1;
1766
1767 m_core->icount -= m_core->clock_cycles_1; // extra cycle
1768 break;
1769 case 2: // Reserved
1770 LOG("Executed Reserved instruction in hyperstone_ldxx2. PC = %08X\n", PC);
1771 break;
1772 case 3: // LDW.S
1773 if (SRC_GLOBAL)
1774 {
1775 if (dreg < SP)
1776 set_global_register(src_code, READ_W(dreg));
1777 else
1778 set_global_register(src_code, m_core->local_regs[(dreg & 0xfc) >> 2]);
1779 }
1780 else
1781 {
1782 if (dreg < SP)
1783 m_core->local_regs[src_code] = READ_W(dreg);
1784 else
1785 m_core->local_regs[src_code] = m_core->local_regs[(dreg & 0xfc) >> 2];
1786 }
1787
1788 if (DST_GLOBAL != SRC_GLOBAL || src_code != dst_code)
1789 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s & ~3;
1790
1791 m_core->icount -= m_core->clock_cycles_2; // extra cycles
1792 break;
1793 }
1794 break;
1795 }
1796
1797 m_core->icount -= m_core->clock_cycles_1;
1798 }
1799
1800 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_stxx1()1801 void hyperstone_device::hyperstone_stxx1()
1802 {
1803 uint16_t next_1 = m_pr16(PC);
1804 PC += 2;
1805
1806 const uint16_t sub_type = (next_1 & 0x3000) >> 12;
1807
1808 uint32_t extra_s;
1809 if (next_1 & 0x8000)
1810 {
1811 const uint16_t next_2 = m_pr16(PC);
1812 PC += 2;
1813 m_instruction_length = (3<<19);
1814
1815 extra_s = next_2;
1816 extra_s |= ((next_1 & 0xfff) << 16);
1817
1818 if (next_1 & 0x4000)
1819 extra_s |= 0xf0000000;
1820 }
1821 else
1822 {
1823 m_instruction_length = (2<<19);
1824 extra_s = next_1 & 0xfff;
1825
1826 if (next_1 & 0x4000)
1827 extra_s |= 0xfffff000;
1828 }
1829
1830 check_delay_PC();
1831
1832 const uint32_t fp = GET_FP;
1833 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
1834 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
1835 const uint32_t dreg = ((DST_GLOBAL && dst_code == SR_REGISTER) ? 0 : (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code]);
1836 const uint32_t sreg = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code]);
1837
1838 switch (sub_type)
1839 {
1840 case 0: // STBS.D
1841 // TODO: missing trap on range error
1842 WRITE_B(dreg + extra_s, (uint8_t)sreg);
1843 break;
1844
1845 case 1: // STBU.D
1846 WRITE_B(dreg + extra_s, (uint8_t)sreg);
1847 break;
1848
1849 case 2: // STHS.D, STHU.D
1850 WRITE_HW(dreg + (extra_s & ~1), (uint16_t)sreg);
1851 // TODO: missing trap on range error with STHS.D
1852 break;
1853
1854 case 3:
1855 switch (extra_s & 3)
1856 {
1857 case 0: // STW.D
1858 WRITE_W(dreg + (extra_s & ~1), sreg);
1859 break;
1860 case 1: // STD.D
1861 {
1862 const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
1863 const uint32_t sregf = ((SRC_GLOBAL && srcf_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[srcf_code]);
1864 extra_s &= ~1;
1865 WRITE_W(dreg + extra_s, sreg);
1866 WRITE_W(dreg + extra_s + 4, sregf);
1867 m_core->icount -= m_core->clock_cycles_1; // extra cycle
1868 break;
1869 }
1870 case 2: // STW.IOD
1871 IO_WRITE_W(dreg + (extra_s & ~3), sreg);
1872 break;
1873 case 3: // STD.IOD
1874 {
1875 const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
1876 const uint32_t sregf = ((SRC_GLOBAL && srcf_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[srcf_code]);
1877 extra_s &= ~3;
1878 IO_WRITE_W(dreg + extra_s, sreg);
1879 IO_WRITE_W(dreg + extra_s + 4, sregf);
1880 m_core->icount -= m_core->clock_cycles_1; // extra cycle
1881 break;
1882 }
1883 }
1884 break;
1885 }
1886
1887 m_core->icount -= m_core->clock_cycles_1;
1888 }
1889
1890 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_stxx2()1891 void hyperstone_device::hyperstone_stxx2()
1892 {
1893 uint16_t next_1 = m_pr16(PC);
1894 PC += 2;
1895
1896 const uint16_t sub_type = (next_1 & 0x3000) >> 12;
1897
1898 uint32_t extra_s;
1899 if (next_1 & 0x8000)
1900 {
1901 const uint16_t next_2 = m_pr16(PC);
1902 PC += 2;
1903 m_instruction_length = (3<<19);
1904
1905 extra_s = next_2;
1906 extra_s |= ((next_1 & 0xfff) << 16);
1907
1908 if (next_1 & 0x4000)
1909 extra_s |= 0xf0000000;
1910 }
1911 else
1912 {
1913 m_instruction_length = (2<<19);
1914 extra_s = next_1 & 0xfff;
1915
1916 if (next_1 & 0x4000)
1917 extra_s |= 0xfffff000;
1918 }
1919
1920 check_delay_PC();
1921
1922 const uint32_t fp = GET_FP;
1923 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
1924 const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code];
1925 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
1926 const uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
1927
1928 if (DST_GLOBAL && dst_code < 2)
1929 {
1930 m_core->icount -= m_core->clock_cycles_1;
1931 return;
1932 }
1933
1934 switch (sub_type)
1935 {
1936 case 0: // STBS.N
1937 // TODO: missing trap on range error
1938 WRITE_B(dreg, (uint8_t)sreg);
1939 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s;
1940 break;
1941
1942 case 1: // STBU.N
1943 WRITE_B(dreg, (uint8_t)sreg);
1944 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s;
1945 break;
1946
1947 case 2: // STHS.N, STHU.N
1948 WRITE_HW(dreg, (uint16_t)sreg);
1949 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s & ~1;
1950 // TODO: missing trap on range error with STHS.N
1951 break;
1952
1953 case 3:
1954 switch (extra_s & 3)
1955 {
1956 case 0: // STW.N
1957 WRITE_W(dreg, sreg);
1958 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s;
1959 break;
1960 case 1: // STD.N
1961 {
1962 WRITE_W(dreg, sreg);
1963 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] += extra_s & ~1;
1964
1965 const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
1966 const uint32_t sregf = (SRC_GLOBAL && srcf_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[srcf_code];
1967 WRITE_W(dreg + 4, sregf);
1968
1969 m_core->icount -= m_core->clock_cycles_1; // extra cycle
1970 break;
1971 }
1972 case 2: // Reserved
1973 LOG("Executed Reserved instruction in hyperstone_stxx2. PC = %08X\n", PC);
1974 break;
1975 case 3: // STW.S
1976 if(dreg < SP)
1977 WRITE_W(dreg, sreg);
1978 else
1979 m_core->local_regs[(dreg & 0xfc) >> 2] = sreg;
1980
1981 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] += (extra_s & ~3);
1982
1983 m_core->icount -= m_core->clock_cycles_2; // extra cycles
1984 break;
1985 }
1986 break;
1987 }
1988
1989 m_core->icount -= m_core->clock_cycles_1;
1990 }
1991
1992 template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL>
hyperstone_shri()1993 void hyperstone_device::hyperstone_shri()
1994 {
1995 check_delay_PC();
1996
1997 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
1998 uint32_t val = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
1999
2000 SR &= ~(C_MASK | Z_MASK | N_MASK);
2001
2002 const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE;
2003 if (HI_N || n)
2004 SR |= (val >> (n - 1)) & 1;
2005
2006 val >>= n;
2007
2008 if (val == 0)
2009 SR |= Z_MASK;
2010 SR |= SIGN_TO_N(val);
2011
2012 if (DST_GLOBAL)
2013 set_global_register(dst_code, val);
2014 else
2015 m_core->local_regs[dst_code] = val;
2016
2017 m_core->icount -= m_core->clock_cycles_1;
2018 }
2019
2020 template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL>
hyperstone_sari()2021 void hyperstone_device::hyperstone_sari()
2022 {
2023 check_delay_PC();
2024
2025 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
2026
2027 const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE;
2028 uint32_t val = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
2029
2030 SR &= ~(C_MASK | Z_MASK | N_MASK);
2031
2032 if (HI_N || n)
2033 {
2034 const uint32_t sign_bit = val & 0x80000000;
2035
2036 SR |= (val >> (n - 1)) & 1;
2037
2038 val >>= n;
2039
2040 if (sign_bit)
2041 val |= 0xffffffff << (32 - n);
2042 }
2043
2044 if (val == 0)
2045 SR |= Z_MASK;
2046 SR |= SIGN_TO_N(val);
2047
2048 if (DST_GLOBAL)
2049 set_global_register(dst_code, val);
2050 else
2051 m_core->local_regs[dst_code] = val;
2052
2053 m_core->icount -= m_core->clock_cycles_1;
2054 }
2055
2056 template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL>
hyperstone_shli()2057 void hyperstone_device::hyperstone_shli()
2058 {
2059 check_delay_PC();
2060
2061 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
2062 uint32_t val = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
2063
2064 const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE;
2065 SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK);
2066
2067 if (HI_N || n)
2068 {
2069 SR |= (val & (0x80000000 >> (n - 1))) ? 1 : 0;
2070 }
2071
2072 uint64_t mask = ((1U << (32 - n)) - 1) ^ 0xffffffff;
2073 uint32_t val2 = val << n;
2074
2075 if (((val & mask) && (!(val2 & 0x80000000))) || (((val & mask) ^ mask) && (val2 & 0x80000000)))
2076 SR |= V_MASK;
2077
2078 if (val2 == 0)
2079 SR |= Z_MASK;
2080 SR |= SIGN_TO_N(val2);
2081
2082 if (DST_GLOBAL)
2083 set_global_register(dst_code, val2);
2084 else
2085 m_core->local_regs[dst_code] = val2;
2086
2087 m_core->icount -= m_core->clock_cycles_1;
2088 }
2089
2090 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL, hyperstone_device::sign_mode SIGNED>
hyperstone_mulsu()2091 void hyperstone_device::hyperstone_mulsu()
2092 {
2093 check_delay_PC();
2094
2095 const uint32_t fp = GET_FP;
2096 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
2097 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
2098 const uint32_t dstf_code = DST_GLOBAL ? (dst_code + 1) : ((dst_code + 1) & 0x3f);
2099
2100 if ((SRC_GLOBAL && src_code < 2) || (DST_GLOBAL && dst_code < 2))
2101 {
2102 LOG("Denoted PC or SR in hyperstone_muls/u instruction. PC = %08X\n", PC);
2103 return;
2104 }
2105
2106 const uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
2107 const uint32_t sreg = (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code];
2108 const uint64_t double_word = SIGNED ? (uint64_t)((int64_t)(int32_t)sreg * (int64_t)(int32_t)dreg) : ((uint64_t)sreg *(uint64_t)dreg);
2109
2110 const uint32_t high_order = (uint32_t)(double_word >> 32);
2111
2112 SR &= ~(Z_MASK | N_MASK);
2113 if (double_word == 0)
2114 SR |= Z_MASK;
2115 SR |= SIGN_TO_N(high_order);
2116
2117 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] = high_order;
2118 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dstf_code] = (uint32_t)double_word;
2119
2120 m_core->icount -= m_core->clock_cycles_6;
2121 if(SIGNED == IS_SIGNED && ((int32_t) sreg >= -0x8000 && (int32_t) sreg <= 0x7fff) && ((int32_t) dreg >= -0x8000 && (int32_t) dreg <= 0x7fff))
2122 m_core->icount += m_core->clock_cycles_2;
2123 else if(SIGNED == IS_UNSIGNED && sreg <= 0xffff && dreg <= 0xffff)
2124 m_core->icount += m_core->clock_cycles_2;
2125 }
2126
2127 template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL>
hyperstone_set()2128 void hyperstone_device::hyperstone_set()
2129 {
2130 check_delay_PC();
2131
2132 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
2133 const uint32_t n = LO_N_VALUE;
2134
2135 if (DST_GLOBAL && dst_code < 2)
2136 {
2137 m_core->icount -= m_core->clock_cycles_1;
2138 return;
2139 }
2140
2141 if (HI_N)
2142 {
2143 if (n >= 4 || n == 2)
2144 {
2145 static const uint32_t set_result[16] = { 0, 0, 0, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0 };
2146 static const uint32_t unset_result[16] = { 0, 0, 0xffffffff, 0, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff };
2147 static const uint32_t mask[16] = { 0, 0, 0, 0, (N_MASK | Z_MASK), (N_MASK | Z_MASK), N_MASK, N_MASK,
2148 (C_MASK | Z_MASK), (C_MASK | Z_MASK), C_MASK, C_MASK, Z_MASK, Z_MASK, V_MASK, V_MASK };
2149
2150 if (SR & mask[n])
2151 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] = set_result[n];
2152 else
2153 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] = unset_result[n];
2154 }
2155 else
2156 {
2157 LOG("Used reserved N value (%d) in hyperstone_set. PC = %08X\n", n, PC);
2158 }
2159 }
2160 else
2161 {
2162 if (n == 0)
2163 {
2164 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] = (SP & 0xfffffe00) | (GET_FP << 2) | (((SP & 0x100) && (SIGN_BIT(SR) == 0)) ? 1 : 0);
2165 }
2166 else if (n >= 2)
2167 {
2168 static const uint32_t set_result[16] = { 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 };
2169 static const uint32_t unset_result[16] = { 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
2170 static const uint32_t mask[16] = { 0, 0, 0, 0, (N_MASK | Z_MASK), (N_MASK | Z_MASK), N_MASK, N_MASK,
2171 (C_MASK | Z_MASK), (C_MASK | Z_MASK), C_MASK, C_MASK, Z_MASK, Z_MASK, V_MASK, V_MASK };
2172
2173 if (SR & mask[n])
2174 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] = set_result[n];
2175 else
2176 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] = unset_result[n];
2177 }
2178 else
2179 {
2180 LOG("Used reserved N value (%d) in hyperstone_set. PC = %08X\n", n, PC);
2181 }
2182 }
2183
2184 m_core->icount -= m_core->clock_cycles_1;
2185 }
2186
2187 template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_mul()2188 void hyperstone_device::hyperstone_mul()
2189 {
2190 check_delay_PC();
2191
2192 const uint32_t fp = GET_FP;
2193 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
2194 const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
2195
2196 if ((SRC_GLOBAL && src_code < 2) || (DST_GLOBAL && dst_code < 2))
2197 {
2198 LOG("Denoted PC or SR in hyperstone_mul instruction. PC = %08X\n", PC);
2199 return;
2200 }
2201
2202 const uint32_t dreg = (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code];
2203 const uint32_t sreg = (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code];
2204 const uint32_t result = sreg * dreg;
2205
2206 SR &= ~(Z_MASK | N_MASK);
2207 if (result == 0)
2208 SR |= Z_MASK;
2209 SR |= SIGN_TO_N(result);
2210
2211 (DST_GLOBAL ? m_core->global_regs : m_core->local_regs)[dst_code] = result;
2212
2213 if ((int32_t)sreg < -0x8000 || (int32_t) sreg > 0x7fff || (int32_t) dreg < -0x8000 || (int32_t) dreg > 0x7fff)
2214 m_core->icount -= 5 << m_core->clck_scale;
2215 else
2216 m_core->icount -= 3 << m_core->clck_scale;
2217 }
2218
hyperstone_extend()2219 void hyperstone_device::hyperstone_extend()
2220 {
2221 m_instruction_length = (2<<19);
2222 const uint32_t func = m_pr16(PC);
2223 PC += 2;
2224 check_delay_PC();
2225
2226 //TODO: add locks, overflow error and other things
2227 const uint32_t fp = GET_FP;
2228 const uint32_t vals = m_core->local_regs[(SRC_CODE + fp) & 0x3f];
2229 const uint32_t vald = m_core->local_regs[(DST_CODE + fp) & 0x3f];
2230
2231 switch (func) // extended opcode
2232 {
2233 // signed or unsigned multiplication, single word product
2234 case EMUL:
2235 case EMUL_N: // used in "N" type cpu
2236 m_core->global_regs[15] = (uint32_t)(vals * vald);
2237 break;
2238
2239 // unsigned multiplication, double word product
2240 case EMULU:
2241 {
2242 const uint64_t result = (uint64_t)vals * (uint64_t)vald;
2243 m_core->global_regs[14] = (uint32_t)(result >> 32);
2244 m_core->global_regs[15] = (uint32_t)result;
2245 break;
2246 }
2247
2248 // signed multiplication, double word product
2249 case EMULS:
2250 {
2251 const int64_t result = (int64_t)(int32_t)vals * (int64_t)(int32_t)vald;
2252 m_core->global_regs[14] = (uint32_t)(result >> 32);
2253 m_core->global_regs[15] = (uint32_t)result;
2254 break;
2255 }
2256
2257 // signed multiply/add, single word product sum
2258 case EMAC:
2259 m_core->global_regs[15] += (int32_t)vals * (int32_t)vald;
2260 break;
2261
2262 // signed multiply/add, double word product sum
2263 case EMACD:
2264 {
2265 int64_t result = (int64_t)concat_64(m_core->global_regs[14], m_core->global_regs[15]) + (int64_t)((int64_t)(int32_t)vals * (int64_t)(int32_t)vald);
2266 m_core->global_regs[14] = (uint32_t)(result >> 32);
2267 m_core->global_regs[15] = (uint32_t)result;
2268 break;
2269 }
2270
2271 // signed multiply/substract, single word product difference
2272 case EMSUB:
2273 m_core->global_regs[15] = (int32_t)m_core->global_regs[15] - ((int32_t)vals * (int32_t)vald);
2274 break;
2275
2276 // signed multiply/substract, double word product difference
2277 case EMSUBD:
2278 {
2279 int64_t result = (int64_t)concat_64(m_core->global_regs[14], m_core->global_regs[15]) - (int64_t)((int64_t)(int32_t)vals * (int64_t)(int32_t)vald);
2280 m_core->global_regs[14] = (uint32_t)(result >> 32);
2281 m_core->global_regs[15] = (uint32_t)result;
2282 break;
2283 }
2284
2285 // signed half-word multiply/add, single word product sum
2286 case EHMAC:
2287 m_core->global_regs[15] = (int32_t)m_core->global_regs[15] + ((int32_t)(vald >> 16) * (int32_t)(vals >> 16)) + ((int32_t)(vald & 0xffff) * (int32_t)(vals & 0xffff));
2288 break;
2289
2290 // signed half-word multiply/add, double word product sum
2291 case EHMACD:
2292 {
2293 int64_t result = (int64_t)concat_64(m_core->global_regs[14], m_core->global_regs[15]) + (int64_t)((int64_t)(int32_t)(vald >> 16) * (int64_t)(int32_t)(vals >> 16)) + ((int64_t)(int32_t)(vald & 0xffff) * (int64_t)(int32_t)(vals & 0xffff));
2294 m_core->global_regs[14] = (uint32_t)(result >> 32);
2295 m_core->global_regs[15] = (uint32_t)result;
2296 break;
2297 }
2298
2299 // half-word complex multiply
2300 case EHCMULD:
2301 m_core->global_regs[14] = ((vald >> 16) * (vals >> 16 )) - ((vald & 0xffff) * (vals & 0xffff));
2302 m_core->global_regs[15] = ((vald >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * (vals >> 16 ));
2303 break;
2304
2305 // half-word complex multiply/add
2306 case EHCMACD:
2307 m_core->global_regs[14] += ((vald >> 16) * (vals >> 16 )) - ((vald & 0xffff) * (vals & 0xffff));
2308 m_core->global_regs[15] += ((vald >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * (vals >> 16 ));
2309 break;
2310
2311 // half-word (complex) add/substract
2312 // Ls is not used and should denote the same register as Ld
2313 case EHCSUMD:
2314 {
2315 const uint32_t r14 = m_core->global_regs[14];
2316 const uint32_t r15 = m_core->global_regs[15];
2317 m_core->global_regs[14] = (((vals >> 16) + r14) << 16) | (((vals & 0xffff) + r15) & 0xffff);
2318 m_core->global_regs[15] = (((vals >> 16) - r14) << 16) | (((vals & 0xffff) - r15) & 0xffff);
2319 break;
2320 }
2321
2322 // half-word (complex) add/substract with fixed point adjustment
2323 // Ls is not used and should denote the same register as Ld
2324 case EHCFFTD:
2325 {
2326 const uint32_t r14 = m_core->global_regs[14];
2327 const uint32_t r15 = m_core->global_regs[15];
2328 m_core->global_regs[14] = (((((vals & 0xffff0000) >> 16) + (r14 >> 15)) << 16) & 0xffff0000) | (((vals & 0xffff) + (r15 >> 15)) & 0xffff);
2329 m_core->global_regs[15] = (((((vals & 0xffff0000) >> 16) - (r14 >> 15)) << 16) & 0xffff0000) | (((vals & 0xffff) - (r15 >> 15)) & 0xffff);
2330 break;
2331 }
2332
2333 // half-word (complex) add/substract with fixed point adjustment and shift
2334 // Ls is not used and should denote the same register as Ld
2335 case EHCFFTSD:
2336 {
2337 const uint32_t r14 = m_core->global_regs[14];
2338 const uint32_t r15 = m_core->global_regs[15];
2339 m_core->global_regs[14] = ((((((vals & 0xffff0000) >> 16) + (r14 >> 15)) >> 1) << 16) & 0xffff0000) | (((((vals & 0xffff) + (r15 >> 15)) >> 1) & 0xffff));
2340 m_core->global_regs[15] = ((((((vals & 0xffff0000) >> 16) - (r14 >> 15)) >> 1) << 16) & 0xffff0000) | (((((vals & 0xffff) - (r15 >> 15)) >> 1) & 0xffff));
2341 break;
2342 }
2343
2344 default:
2345 LOG("Executed Illegal extended opcode (%X). PC = %08X\n", func, PC);
2346 break;
2347 }
2348
2349 m_core->icount -= m_core->clock_cycles_1; // TODO: with the latency it can change
2350 }
2351
2352
2353 template <hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_ldwr()2354 void hyperstone_device::hyperstone_ldwr()
2355 {
2356 check_delay_PC();
2357 const uint32_t fp = GET_FP;
2358 if (SRC_GLOBAL)
2359 set_global_register(SRC_CODE, READ_W(m_core->local_regs[(DST_CODE + fp) & 0x3f]));
2360 else
2361 m_core->local_regs[(SRC_CODE + fp) & 0x3f] = READ_W(m_core->local_regs[(DST_CODE + fp) & 0x3f]);
2362 m_core->icount -= m_core->clock_cycles_1;
2363 }
2364
2365 template <hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_lddr()2366 void hyperstone_device::hyperstone_lddr()
2367 {
2368 check_delay_PC();
2369
2370 const uint32_t fp = GET_FP;
2371 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
2372 const uint32_t dreg = m_core->local_regs[(DST_CODE + fp) & 0x3f];
2373
2374 if (SRC_GLOBAL)
2375 {
2376 set_global_register(src_code, READ_W(dreg));
2377 set_global_register(src_code + 1, READ_W(dreg + 4));
2378 }
2379 else
2380 {
2381 m_core->local_regs[src_code] = READ_W(dreg);
2382 m_core->local_regs[(src_code + 1) & 0x3f] = READ_W(dreg + 4);
2383 }
2384
2385 m_core->icount -= m_core->clock_cycles_2;
2386 }
2387
2388 template <hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_ldwp()2389 void hyperstone_device::hyperstone_ldwp()
2390 {
2391 check_delay_PC();
2392
2393 const uint32_t fp = GET_FP;
2394 const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
2395
2396 if (SRC_GLOBAL)
2397 {
2398 set_global_register(SRC_CODE, READ_W(m_core->local_regs[dst_code]));
2399 m_core->local_regs[dst_code] += 4;
2400 }
2401 else
2402 {
2403 const uint32_t src_code = (SRC_CODE + fp) & 0x3f;
2404 m_core->local_regs[src_code] = READ_W(m_core->local_regs[dst_code]);
2405 // post increment the destination register if it's different from the source one
2406 // (needed by Hidden Catch)
2407 if (src_code != dst_code)
2408 m_core->local_regs[dst_code] += 4;
2409 }
2410
2411 m_core->icount -= m_core->clock_cycles_1;
2412 }
2413
2414 template <hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_lddp()2415 void hyperstone_device::hyperstone_lddp()
2416 {
2417 check_delay_PC();
2418
2419 const uint32_t fp = GET_FP;
2420 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
2421 const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
2422 const uint32_t dreg = m_core->local_regs[dst_code];
2423
2424 if (SRC_GLOBAL)
2425 {
2426 set_global_register(src_code, READ_W(dreg));
2427 set_global_register(src_code + 1, READ_W(dreg + 4));
2428 m_core->local_regs[dst_code] += 8;
2429 }
2430 else
2431 {
2432 const uint32_t srcf_code = (src_code + 1) & 0x3f;
2433 m_core->local_regs[src_code] = READ_W(dreg);
2434 m_core->local_regs[srcf_code] = READ_W(dreg + 4);
2435
2436 // post increment the destination register if it's different from the source one
2437 // and from the "next source" one
2438 if (src_code != dst_code && srcf_code != dst_code)
2439 m_core->local_regs[dst_code] += 8;
2440 }
2441
2442 m_core->icount -= m_core->clock_cycles_2;
2443 }
2444
2445 template <hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_stwr()2446 void hyperstone_device::hyperstone_stwr()
2447 {
2448 check_delay_PC();
2449
2450 const uint32_t fp = GET_FP;
2451 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
2452 const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code];
2453 WRITE_W(m_core->local_regs[(DST_CODE + fp) & 0x3f], sreg);
2454
2455 m_core->icount -= m_core->clock_cycles_1;
2456 }
2457
2458 template <hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_stdr()2459 void hyperstone_device::hyperstone_stdr()
2460 {
2461 check_delay_PC();
2462
2463 const uint32_t fp = GET_FP;
2464 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
2465 const uint32_t srcf_code = SRC_GLOBAL ? (SRC_CODE + 1) : ((src_code + 1) & 0x3f);
2466 const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code];
2467 const uint32_t sregf = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[srcf_code];
2468
2469 const uint32_t dreg = m_core->local_regs[(DST_CODE + GET_FP) & 0x3f];
2470
2471 WRITE_W(dreg, sreg);
2472 WRITE_W(dreg + 4, sregf);
2473
2474 m_core->icount -= m_core->clock_cycles_2;
2475 }
2476
2477 template <hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_stwp()2478 void hyperstone_device::hyperstone_stwp()
2479 {
2480 check_delay_PC();
2481
2482 const uint32_t fp = GET_FP;
2483 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
2484 const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code];
2485
2486 const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
2487 const uint32_t dreg = m_core->local_regs[dst_code];
2488
2489 WRITE_W(dreg, sreg);
2490 m_core->local_regs[dst_code] += 4;
2491
2492 m_core->icount -= m_core->clock_cycles_1;
2493 }
2494
2495 template <hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_stdp()2496 void hyperstone_device::hyperstone_stdp()
2497 {
2498 check_delay_PC();
2499
2500 const uint32_t fp = GET_FP;
2501 const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
2502 const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
2503 const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code];
2504
2505 const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
2506 const uint32_t dreg = m_core->local_regs[dst_code];
2507
2508 WRITE_W(dreg, sreg);
2509
2510 m_core->local_regs[dst_code] += 8;
2511
2512 const uint32_t sregf = (SRC_GLOBAL && srcf_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[srcf_code];
2513
2514 WRITE_W(dreg + 4, sregf);
2515
2516 m_core->icount -= m_core->clock_cycles_2;
2517 }
2518
2519 template <hyperstone_device::branch_condition CONDITION, hyperstone_device::condition_set COND_SET>
hyperstone_db()2520 void hyperstone_device::hyperstone_db()
2521 {
2522 static const uint32_t condition_masks[6] = { V_MASK, Z_MASK, C_MASK, C_MASK | Z_MASK, N_MASK, N_MASK | Z_MASK };
2523 if (COND_SET)
2524 {
2525 if (SR & condition_masks[CONDITION])
2526 {
2527 const int32_t offset = decode_pcrel();
2528 check_delay_PC();
2529 m_core->delay_slot = 1;
2530 m_core->delay_pc = PC + offset;
2531 m_core->intblock = 3;
2532 m_core->icount -= m_core->clock_cycles_2;
2533 }
2534 else
2535 {
2536 ignore_pcrel();
2537 check_delay_PC();
2538 m_core->icount -= m_core->clock_cycles_1;
2539 }
2540 }
2541 else
2542 {
2543 if (SR & condition_masks[CONDITION])
2544 {
2545 ignore_pcrel();
2546 check_delay_PC();
2547 m_core->icount -= m_core->clock_cycles_1;
2548 }
2549 else
2550 {
2551 const int32_t offset = decode_pcrel();
2552 check_delay_PC();
2553 m_core->delay_slot = 1;
2554 m_core->delay_pc = PC + offset;
2555 m_core->intblock = 3;
2556 m_core->icount -= m_core->clock_cycles_2;
2557 }
2558 }
2559 }
2560
hyperstone_dbr()2561 void hyperstone_device::hyperstone_dbr()
2562 {
2563 const int32_t offset = decode_pcrel();
2564 check_delay_PC();
2565
2566 m_core->delay_slot = 1;
2567 m_core->delay_pc = PC + offset;
2568 m_core->intblock = 3;
2569
2570 m_core->icount -= m_core->clock_cycles_2;
2571 }
2572
hyperstone_frame()2573 void hyperstone_device::hyperstone_frame()
2574 {
2575 check_delay_PC();
2576
2577 uint8_t realfp = GET_FP - SRC_CODE;
2578 uint8_t dst_code = DST_CODE;
2579
2580 SET_FP(realfp);
2581 SET_FL(dst_code);
2582 SR &= ~M_MASK;
2583
2584 int8_t difference = ((SP & 0x1fc) >> 2) + (64 - 10) - (realfp + GET_FL); // really it's 7 bits
2585
2586 /* convert to 8 bits */
2587 if(difference > 63)
2588 difference = (int8_t)(difference|0x80);
2589 else if( difference < -64 )
2590 difference = difference & 0x7f;
2591
2592 if (difference < 0) // else it's finished
2593 {
2594 bool tmp_flag = SP >= UB;
2595
2596 for (; difference < 0; difference++)
2597 {
2598 WRITE_W(SP, m_core->local_regs[(SP & 0xfc) >> 2]);
2599 SP += 4;
2600 }
2601
2602 if (tmp_flag)
2603 {
2604 execute_exception(get_trap_addr(TRAPNO_FRAME_ERROR));
2605 }
2606 }
2607
2608 // TODO: More than 1 cycle!
2609 m_core->icount -= m_core->clock_cycles_1;
2610 }
2611
2612 template <hyperstone_device::reg_bank SRC_GLOBAL>
hyperstone_call()2613 void hyperstone_device::hyperstone_call()
2614 {
2615 uint16_t imm_1 = m_pr16(PC);
2616 PC += 2;
2617
2618 int32_t extra_s = 0;
2619
2620 if (imm_1 & 0x8000)
2621 {
2622 uint16_t imm_2 = m_pr16(PC);
2623
2624 PC += 2;
2625 SET_ILC(3<<19);
2626 m_instruction_length = (3<<19);
2627
2628 extra_s = imm_2;
2629 extra_s |= ((imm_1 & 0x3fff) << 16);
2630
2631 if (imm_1 & 0x4000)
2632 extra_s |= 0xc0000000;
2633 }
2634 else
2635 {
2636 extra_s = imm_1 & 0x3fff;
2637
2638 SET_ILC(2<<19);
2639 m_instruction_length = (2<<19);
2640
2641 if (imm_1 & 0x4000)
2642 extra_s |= 0xffffc000;
2643 }
2644
2645 check_delay_PC();
2646
2647 uint32_t fp = GET_FP;
2648 uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
2649 uint32_t dst_code = DST_CODE;
2650
2651 uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_core->global_regs : m_core->local_regs)[src_code];
2652
2653 if (!DST_CODE)
2654 dst_code = 16;
2655
2656 uint32_t dreg_index = dst_code + fp;
2657 m_core->local_regs[dreg_index & 0x3f] = (PC & ~1) | GET_S;
2658 m_core->local_regs[(dreg_index + 1) & 0x3f] = SR;
2659
2660 SET_FP(fp + dst_code);
2661 SET_FL(6); //default value for call
2662 SR &= ~M_MASK;
2663
2664 PC = (extra_s & ~1) + sreg;
2665
2666 m_core->intblock = 2;
2667
2668 //TODO: add interrupt locks, errors, ....
2669
2670 // TODO: More than 1 cycle!
2671 m_core->icount -= m_core->clock_cycles_1;
2672 }
2673
2674 template <hyperstone_device::branch_condition CONDITION, hyperstone_device::condition_set COND_SET>
hyperstone_b()2675 void hyperstone_device::hyperstone_b()
2676 {
2677 static const uint32_t condition_masks[6] = { V_MASK, Z_MASK, C_MASK, C_MASK | Z_MASK, N_MASK, N_MASK | Z_MASK };
2678 if (COND_SET)
2679 {
2680 if (SR & condition_masks[CONDITION])
2681 {
2682 hyperstone_br();
2683 }
2684 else
2685 {
2686 ignore_pcrel();
2687 check_delay_PC();
2688 m_core->icount -= m_core->clock_cycles_1;
2689 }
2690 }
2691 else
2692 {
2693 if (SR & condition_masks[CONDITION])
2694 {
2695 ignore_pcrel();
2696 check_delay_PC();
2697 m_core->icount -= m_core->clock_cycles_1;
2698 }
2699 else
2700 {
2701 hyperstone_br();
2702 }
2703 }
2704 }
2705