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