1 // license:BSD-3-Clause
2 // copyright-holders:Olivier Galibert
3 /***************************************************************************
4
5 h8.h
6
7 H8-300 base cpu emulation
8
9
10 ***************************************************************************/
11
12 #include "emu.h"
13 #include "debugger.h"
14 #include "h8.h"
15 #include "h8_dma.h"
16 #include "h8_dtc.h"
17 #include "h8d.h"
18
h8_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock,address_map_constructor map_delegate)19 h8_device::h8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor map_delegate) :
20 cpu_device(mconfig, type, tag, owner, clock),
21 program_config("program", ENDIANNESS_BIG, 16, 16, 0, map_delegate),
22 io_config("io", ENDIANNESS_BIG, 16, 16, -1), PPC(0), NPC(0), PC(0), PIR(0), EXR(0), CCR(0), MAC(0), MACF(0),
23 TMP1(0), TMP2(0), TMPR(0), inst_state(0), inst_substate(0), icount(0), bcount(0), irq_vector(0), taken_irq_vector(0), irq_level(0), taken_irq_level(0), irq_required(false), irq_nmi(false)
24 {
25 supports_advanced = false;
26 mode_advanced = false;
27 mode_a20 = false;
28 has_exr = false;
29 mac_saturating = false;
30 has_trace = false;
31 }
32
device_config_complete()33 void h8_device::device_config_complete()
34 {
35 uint8_t addrbits = mode_advanced ? (mode_a20 ? 20 : 24) : 16;
36 program_config.m_addr_width = program_config.m_logaddr_width = addrbits;
37 }
38
device_start()39 void h8_device::device_start()
40 {
41 space(AS_PROGRAM).cache(cache);
42 space(AS_PROGRAM).specific(program);
43 space(AS_IO).specific(io);
44
45 uint32_t pcmask = mode_advanced ? 0xffffff : 0xffff;
46 state_add<uint32_t>(H8_PC, "PC",
47 [this]() { return NPC; },
48 [this](uint32_t pc) { PC = PPC = NPC = pc; prefetch_noirq_notrace(); }
49 ).mask(pcmask);
50 state_add<uint32_t>(STATE_GENPC, "GENPC",
51 [this]() { return NPC; },
52 [this](uint32_t pc) { PC = PPC = NPC = pc; prefetch_noirq_notrace(); }
53 ).mask(pcmask).noshow();
54 state_add(STATE_GENPCBASE, "CURPC", PPC).mask(pcmask).noshow();
55 state_add(H8_CCR, "CCR", CCR);
56 if(has_exr)
57 state_add(STATE_GENFLAGS, "GENFLAGS", CCR).formatstr("%11s").noshow();
58 else
59 state_add(STATE_GENFLAGS, "GENFLAGS", CCR).formatstr("%8s").noshow();
60
61 if(has_exr)
62 state_add(H8_EXR, "EXR", EXR);
63 if(!supports_advanced) {
64 state_add(H8_R0, "R0", R[0]);
65 state_add(H8_R1, "R1", R[1]);
66 state_add(H8_R2, "R2", R[2]);
67 state_add(H8_R3, "R3", R[3]);
68 state_add(H8_R4, "R4", R[4]);
69 state_add(H8_R5, "R5", R[5]);
70 state_add(H8_R6, "R6", R[6]);
71 state_add(H8_R7, "R7", R[7]);
72 } else {
73 state_add(H8_R0, "R0", R[0]).noshow();
74 state_add(H8_R1, "R1", R[1]).noshow();
75 state_add(H8_R2, "R2", R[2]).noshow();
76 state_add(H8_R3, "R3", R[3]).noshow();
77 state_add(H8_R4, "R4", R[4]).noshow();
78 state_add(H8_R5, "R5", R[5]).noshow();
79 state_add(H8_R6, "R6", R[6]).noshow();
80 state_add(H8_R7, "R7", R[7]).noshow();
81 state_add(H8_E0, "E0", R[8]).noshow();
82 state_add(H8_E1, "E1", R[9]).noshow();
83 state_add(H8_E2, "E2", R[10]).noshow();
84 state_add(H8_E3, "E3", R[11]).noshow();
85 state_add(H8_E4, "E4", R[12]).noshow();
86 state_add(H8_E5, "E5", R[13]).noshow();
87 state_add(H8_E6, "E6", R[14]).noshow();
88 state_add(H8_E7, "E7", R[15]).noshow();
89 state_add(H8_R0, "ER0", TMPR).callimport().callexport().formatstr("%9s");
90 state_add(H8_R1, "ER1", TMPR).callimport().callexport().formatstr("%9s");
91 state_add(H8_R2, "ER2", TMPR).callimport().callexport().formatstr("%9s");
92 state_add(H8_R3, "ER3", TMPR).callimport().callexport().formatstr("%9s");
93 state_add(H8_R4, "ER4", TMPR).callimport().callexport().formatstr("%9s");
94 state_add(H8_R5, "ER5", TMPR).callimport().callexport().formatstr("%9s");
95 state_add(H8_R6, "ER6", TMPR).callimport().callexport().formatstr("%9s");
96 state_add(H8_R7, "ER7", TMPR).callimport().callexport().formatstr("%9s");
97 }
98
99 save_item(NAME(PPC));
100 save_item(NAME(NPC));
101 save_item(NAME(PC));
102 save_item(NAME(PIR));
103 save_item(NAME(IR));
104 save_item(NAME(R));
105 save_item(NAME(EXR));
106 save_item(NAME(CCR));
107 save_item(NAME(TMP1));
108 save_item(NAME(TMP2));
109 save_item(NAME(inst_state));
110 save_item(NAME(inst_substate));
111 save_item(NAME(irq_vector));
112 save_item(NAME(taken_irq_vector));
113 save_item(NAME(irq_level));
114 save_item(NAME(taken_irq_level));
115 save_item(NAME(irq_nmi));
116
117 set_icountptr(icount);
118
119 PC = 0;
120 PPC = 0;
121 NPC = 0;
122 memset(IR, 0, sizeof(IR));
123 memset(R, 0, sizeof(R));
124 EXR = 0;
125 CCR = 0;
126 MAC = 0;
127 MACF = 0;
128 inst_state = STATE_RESET;
129 inst_substate = 0;
130 count_before_instruction_step = 0;
131 requested_state = -1;
132 dma_device = nullptr;
133 dtc_device = nullptr;
134 }
135
device_reset()136 void h8_device::device_reset()
137 {
138 inst_state = STATE_RESET;
139 inst_substate = 0;
140 count_before_instruction_step = 0;
141 requested_state = -1;
142
143 irq_vector = 0;
144 irq_level = -1;
145 irq_nmi = false;
146 taken_irq_vector = 0;
147 taken_irq_level = -1;
148 current_dma = nullptr;
149 current_dtc = nullptr;
150 }
151
trigger_dma(int vector)152 bool h8_device::trigger_dma(int vector)
153 {
154 return (dma_device && dma_device->trigger_dma(vector)) || (dtc_device && dtc_device->trigger_dtc(vector));
155 }
156
set_current_dma(h8_dma_state * state)157 void h8_device::set_current_dma(h8_dma_state *state)
158 {
159 current_dma = state;
160 if(!state)
161 logerror("DMA done\n");
162 else
163 logerror("New current dma s=%x d=%x is=%d id=%d count=%x m=%d autoreq=%d\n",
164 state->source, state->dest, state->incs, state->incd,
165 state->count, state->mode_16 ? 16 : 8, state->autoreq);
166
167 }
168
set_current_dtc(h8_dtc_state * state)169 void h8_device::set_current_dtc(h8_dtc_state *state)
170 {
171 current_dtc = state;
172 }
173
request_state(int state)174 void h8_device::request_state(int state)
175 {
176 requested_state = state;
177 }
178
execute_min_cycles() const179 uint32_t h8_device::execute_min_cycles() const noexcept
180 {
181 return 1;
182 }
183
execute_max_cycles() const184 uint32_t h8_device::execute_max_cycles() const noexcept
185 {
186 return 1;
187 }
188
execute_input_lines() const189 uint32_t h8_device::execute_input_lines() const noexcept
190 {
191 return 0;
192 }
193
execute_input_edge_triggered(int inputnum) const194 bool h8_device::execute_input_edge_triggered(int inputnum) const noexcept
195 {
196 return inputnum == INPUT_LINE_NMI;
197 }
198
recompute_bcount(uint64_t event_time)199 void h8_device::recompute_bcount(uint64_t event_time)
200 {
201 if(!event_time || event_time >= total_cycles() + icount) {
202 bcount = 0;
203 return;
204 }
205 bcount = total_cycles() + icount - event_time;
206 }
207
execute_run()208 void h8_device::execute_run()
209 {
210 internal_update(total_cycles());
211
212 icount -= count_before_instruction_step;
213 if(icount < 0) {
214 count_before_instruction_step = -icount;
215 icount = 0;
216 } else
217 count_before_instruction_step = 0;
218
219 while(bcount && icount <= bcount)
220 internal_update(total_cycles() + icount - bcount);
221
222 if(icount > 0 && inst_substate)
223 do_exec_partial();
224
225 while(icount > 0) {
226 while(icount > bcount) {
227 if(inst_state < 0x10000) {
228 PPC = NPC;
229 if(machine().debug_flags & DEBUG_FLAG_ENABLED)
230 debugger_instruction_hook(NPC);
231 }
232 do_exec_full();
233 }
234 if(icount > 0)
235 while(bcount && icount <= bcount)
236 internal_update(total_cycles() + icount - bcount);
237 if(icount > 0 && inst_substate)
238 do_exec_partial();
239 }
240 if(icount < 0) {
241 count_before_instruction_step = -icount;
242 icount = 0;
243 }
244 }
245
add_event(uint64_t & event_time,uint64_t new_event)246 void h8_device::add_event(uint64_t &event_time, uint64_t new_event)
247 {
248 if(!new_event)
249 return;
250 if(!event_time || event_time > new_event)
251 event_time = new_event;
252 }
253
internal_update()254 void h8_device::internal_update()
255 {
256 internal_update(total_cycles());
257 }
258
memory_space_config() const259 device_memory_interface::space_config_vector h8_device::memory_space_config() const
260 {
261 return space_config_vector {
262 std::make_pair(AS_PROGRAM, &program_config),
263 std::make_pair(AS_IO, &io_config)
264 };
265 }
266
267
state_import(const device_state_entry & entry)268 void h8_device::state_import(const device_state_entry &entry)
269 {
270 switch(entry.index()) {
271 case H8_R0:
272 case H8_R1:
273 case H8_R2:
274 case H8_R3:
275 case H8_R4:
276 case H8_R5:
277 case H8_R6:
278 case H8_R7: {
279 int r = entry.index() - H8_R0;
280 R[r + 8] = TMPR >> 16;
281 R[r] = TMPR;
282 break;
283 }
284 }
285 }
286
state_export(const device_state_entry & entry)287 void h8_device::state_export(const device_state_entry &entry)
288 {
289 switch(entry.index()) {
290 case H8_R0:
291 case H8_R1:
292 case H8_R2:
293 case H8_R3:
294 case H8_R4:
295 case H8_R5:
296 case H8_R6:
297 case H8_R7: {
298 int r = entry.index() - H8_R0;
299 TMPR = (R[r + 8] << 16) | R[r];
300 break;
301 }
302 }
303 }
304
state_string_export(const device_state_entry & entry,std::string & str) const305 void h8_device::state_string_export(const device_state_entry &entry, std::string &str) const
306 {
307 switch(entry.index()) {
308 case STATE_GENFLAGS:
309 if(has_exr)
310 str = string_format("%c%c %c%c%c%c%c%c%c%c",
311 (EXR & EXR_T) ? 'T' : '-',
312 '0' + (EXR & EXR_I),
313 (CCR & F_I) ? 'I' : '-',
314 (CCR & F_UI) ? 'u' : '-',
315 (CCR & F_H) ? 'H' : '-',
316 (CCR & F_U) ? 'U' : '-',
317 (CCR & F_N) ? 'N' : '-',
318 (CCR & F_Z) ? 'Z' : '-',
319 (CCR & F_V) ? 'V' : '-',
320 (CCR & F_C) ? 'C' : '-');
321 else
322 str = string_format("%c%c%c%c%c%c%c%c",
323 (CCR & F_I) ? 'I' : '-',
324 (CCR & F_UI) ? 'u' : '-',
325 (CCR & F_H) ? 'H' : '-',
326 (CCR & F_U) ? 'U' : '-',
327 (CCR & F_N) ? 'N' : '-',
328 (CCR & F_Z) ? 'Z' : '-',
329 (CCR & F_V) ? 'V' : '-',
330 (CCR & F_C) ? 'C' : '-');
331 break;
332 case H8_R0:
333 case H8_R1:
334 case H8_R2:
335 case H8_R3:
336 case H8_R4:
337 case H8_R5:
338 case H8_R6:
339 case H8_R7: {
340 int r = entry.index() - H8_R0;
341 str = string_format("%04X %04X", R[r + 8], R[r]);
342 break;
343 }
344 }
345 }
346
read16i(uint32_t adr)347 uint16_t h8_device::read16i(uint32_t adr)
348 {
349 icount--;
350 return cache.read_word(adr & ~1);
351 }
352
fetch()353 uint16_t h8_device::fetch()
354 {
355 uint16_t res = read16i(PC);
356 PC += 2;
357 return res;
358 }
359
read8(uint32_t adr)360 uint8_t h8_device::read8(uint32_t adr)
361 {
362 icount--;
363 return program.read_byte(adr);
364 }
365
write8(uint32_t adr,uint8_t data)366 void h8_device::write8(uint32_t adr, uint8_t data)
367 {
368 icount--;
369 program.write_byte(adr, data);
370 }
371
read16(uint32_t adr)372 uint16_t h8_device::read16(uint32_t adr)
373 {
374 icount--;
375 return program.read_word(adr & ~1);
376 }
377
write16(uint32_t adr,uint16_t data)378 void h8_device::write16(uint32_t adr, uint16_t data)
379 {
380 icount--;
381 program.write_word(adr & ~1, data);
382 }
383
exr_in_stack() const384 bool h8_device::exr_in_stack() const
385 {
386 return false;
387 }
388
prefetch_done()389 void h8_device::prefetch_done()
390 {
391 if(requested_state != -1) {
392 inst_state = requested_state;
393 requested_state = -1;
394 } else if(current_dma && !current_dma->suspended)
395 inst_state = STATE_DMA;
396 else if(current_dtc)
397 inst_state = STATE_DTC;
398 else if(irq_vector) {
399 inst_state = STATE_IRQ;
400 taken_irq_vector = irq_vector;
401 taken_irq_level = irq_level;
402 } else if(has_trace && (EXR & EXR_T) && exr_in_stack())
403 inst_state = STATE_TRACE;
404 else
405 inst_state = IR[0] = PIR;
406 }
407
prefetch_done_noirq()408 void h8_device::prefetch_done_noirq()
409 {
410 if(has_trace && (EXR & EXR_T) && exr_in_stack())
411 inst_state = STATE_TRACE;
412 else
413 inst_state = IR[0] = PIR;
414 }
415
prefetch_done_noirq_notrace()416 void h8_device::prefetch_done_noirq_notrace()
417 {
418 inst_state = IR[0] = PIR;
419 }
420
set_irq(int _irq_vector,int _irq_level,bool _irq_nmi)421 void h8_device::set_irq(int _irq_vector, int _irq_level, bool _irq_nmi)
422 {
423 irq_vector = _irq_vector;
424 irq_level = _irq_level;
425 irq_nmi = _irq_nmi;
426 }
427
internal(int cycles)428 void h8_device::internal(int cycles)
429 {
430 icount -= cycles;
431 }
432
illegal()433 void h8_device::illegal()
434 {
435 logerror("Illegal instruction at address %x\n", PPC);
436 icount = -10000000;
437 }
438
trace_setup()439 int h8_device::trace_setup()
440 {
441 throw emu_fatalerror("%s: Trace setup called but unimplemented.\n", tag());
442 }
443
trapa_setup()444 int h8_device::trapa_setup()
445 {
446 throw emu_fatalerror("%s: Trapa setup called but unimplemented.\n", tag());
447 }
448
do_addx8(uint8_t v1,uint8_t v2)449 uint8_t h8_device::do_addx8(uint8_t v1, uint8_t v2)
450 {
451 uint16_t res = v1 + v2 + (CCR & F_C ? 1 : 0);
452 CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
453 if(((v1 & 0xf) + (v2 & 0xf) + (CCR & F_C ? 1 : 0)) & 0x10)
454 CCR |= F_H;
455 if(!uint8_t(res))
456 CCR |= F_Z;
457 else if(int8_t(res) < 0)
458 CCR |= F_N;
459 if(~(v1^v2) & (v1^res) & 0x80)
460 CCR |= F_V;
461 if(res & 0x100)
462 CCR |= F_C;
463 return res;
464
465 }
466
do_subx8(uint8_t v1,uint8_t v2)467 uint8_t h8_device::do_subx8(uint8_t v1, uint8_t v2)
468 {
469 uint16_t res = v1 - v2 - (CCR & F_C ? 1 : 0);
470 CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
471 if(((v1 & 0xf) - (v2 & 0xf) - (CCR & F_C ? 1 : 0)) & 0x10)
472 CCR |= F_H;
473 if(!uint8_t(res))
474 CCR |= F_Z;
475 else if(int8_t(res) < 0)
476 CCR |= F_N;
477 if((v1^v2) & (v1^res) & 0x80)
478 CCR |= F_V;
479 if(res & 0x100)
480 CCR |= F_C;
481 return res;
482
483 }
484
do_inc8(uint8_t v1,uint8_t v2)485 uint8_t h8_device::do_inc8(uint8_t v1, uint8_t v2)
486 {
487 uint8_t res = v1 + v2;
488 CCR &= ~(F_N|F_V|F_Z);
489 if(!res)
490 CCR |= F_Z;
491 else if(int8_t(res) < 0)
492 CCR |= F_N;
493 if((v1^v2) & (v1^res) & 0x80)
494 CCR |= F_V;
495 return res;
496 }
497
do_inc16(uint16_t v1,uint16_t v2)498 uint16_t h8_device::do_inc16(uint16_t v1, uint16_t v2)
499 {
500 uint16_t res = v1 + v2;
501 CCR &= ~(F_N|F_V|F_Z);
502 if(!res)
503 CCR |= F_Z;
504 else if(int16_t(res) < 0)
505 CCR |= F_N;
506 if((v1^v2) & (v1^res) & 0x8000)
507 CCR |= F_V;
508 return res;
509 }
510
do_inc32(uint32_t v1,uint32_t v2)511 uint32_t h8_device::do_inc32(uint32_t v1, uint32_t v2)
512 {
513 uint32_t res = v1 + v2;
514 CCR &= ~(F_N|F_V|F_Z);
515 if(!res)
516 CCR |= F_Z;
517 else if(int32_t(res) < 0)
518 CCR |= F_N;
519 if((v1^v2) & (v1^res) & 0x80000000)
520 CCR |= F_V;
521 return res;
522 }
523
do_add8(uint8_t v1,uint8_t v2)524 uint8_t h8_device::do_add8(uint8_t v1, uint8_t v2)
525 {
526 uint16_t res = v1 + v2;
527 CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
528 if(((v1 & 0xf) + (v2 & 0xf)) & 0x10)
529 CCR |= F_H;
530 if(!uint8_t(res))
531 CCR |= F_Z;
532 else if(int8_t(res) < 0)
533 CCR |= F_N;
534 if(~(v1^v2) & (v1^res) & 0x80)
535 CCR |= F_V;
536 if(res & 0x100)
537 CCR |= F_C;
538 return res;
539
540 }
541
do_add16(uint16_t v1,uint16_t v2)542 uint16_t h8_device::do_add16(uint16_t v1, uint16_t v2)
543 {
544 uint32_t res = v1 + v2;
545 CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
546 if(((v1 & 0xfff) + (v2 & 0xffff)) & 0x1000)
547 CCR |= F_H;
548 if(!uint16_t(res))
549 CCR |= F_Z;
550 else if(int16_t(res) < 0)
551 CCR |= F_N;
552 if(~(v1^v2) & (v1^res) & 0x8000)
553 CCR |= F_V;
554 if(res & 0x10000)
555 CCR |= F_C;
556 return res;
557
558 }
559
do_add32(uint32_t v1,uint32_t v2)560 uint32_t h8_device::do_add32(uint32_t v1, uint32_t v2)
561 {
562 uint64_t res = uint64_t(v1) + uint64_t(v2);
563 CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
564 if(((v1 & 0xfffffff) + (v2 & 0xfffffff)) & 0x10000000)
565 CCR |= F_H;
566 if(!uint32_t(res))
567 CCR |= F_Z;
568 else if(int32_t(res) < 0)
569 CCR |= F_N;
570 if(~(v1^v2) & (v1^res) & 0x80000000)
571 CCR |= F_V;
572 if(res & 0x100000000U)
573 CCR |= F_C;
574 return res;
575 }
576
do_dec8(uint8_t v1,uint8_t v2)577 uint8_t h8_device::do_dec8(uint8_t v1, uint8_t v2)
578 {
579 uint8_t res = v1 - v2;
580 CCR &= ~(F_N|F_V|F_Z);
581 if(!res)
582 CCR |= F_Z;
583 else if(int8_t(res) < 0)
584 CCR |= F_N;
585 if((v1^v2) & (v1^res) & 0x80)
586 CCR |= F_V;
587 return res;
588 }
589
do_dec16(uint16_t v1,uint16_t v2)590 uint16_t h8_device::do_dec16(uint16_t v1, uint16_t v2)
591 {
592 uint16_t res = v1 - v2;
593 CCR &= ~(F_N|F_V|F_Z);
594 if(!res)
595 CCR |= F_Z;
596 else if(int16_t(res) < 0)
597 CCR |= F_N;
598 if((v1^v2) & (v1^res) & 0x8000)
599 CCR |= F_V;
600 return res;
601 }
602
do_dec32(uint32_t v1,uint32_t v2)603 uint32_t h8_device::do_dec32(uint32_t v1, uint32_t v2)
604 {
605 uint32_t res = v1 - v2;
606 CCR &= ~(F_N|F_V|F_Z);
607 if(!res)
608 CCR |= F_Z;
609 else if(int32_t(res) < 0)
610 CCR |= F_N;
611 if((v1^v2) & (v1^res) & 0x80000000)
612 CCR |= F_V;
613 return res;
614 }
615
do_sub8(uint8_t v1,uint8_t v2)616 uint8_t h8_device::do_sub8(uint8_t v1, uint8_t v2)
617 {
618 uint16_t res = v1 - v2;
619 CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
620 if(((v1 & 0xf) - (v2 & 0xf)) & 0x10)
621 CCR |= F_H;
622 if(!uint8_t(res))
623 CCR |= F_Z;
624 else if(int8_t(res) < 0)
625 CCR |= F_N;
626 if((v1^v2) & (v1^res) & 0x80)
627 CCR |= F_V;
628 if(res & 0x100)
629 CCR |= F_C;
630 return res;
631
632 }
633
do_sub16(uint16_t v1,uint16_t v2)634 uint16_t h8_device::do_sub16(uint16_t v1, uint16_t v2)
635 {
636 uint32_t res = v1 - v2;
637 CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
638 if(((v1 & 0xfff) - (v2 & 0xffff)) & 0x1000)
639 CCR |= F_H;
640 if(!uint16_t(res))
641 CCR |= F_Z;
642 else if(int16_t(res) < 0)
643 CCR |= F_N;
644 if((v1^v2) & (v1^res) & 0x8000)
645 CCR |= F_V;
646 if(res & 0x10000)
647 CCR |= F_C;
648 return res;
649
650 }
651
do_sub32(uint32_t v1,uint32_t v2)652 uint32_t h8_device::do_sub32(uint32_t v1, uint32_t v2)
653 {
654 uint64_t res = uint64_t(v1) - uint64_t(v2);
655 CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
656 if(((v1 & 0xfffffff) - (v2 & 0xfffffff)) & 0x10000000)
657 CCR |= F_H;
658 if(!uint32_t(res))
659 CCR |= F_Z;
660 else if(int32_t(res) < 0)
661 CCR |= F_N;
662 if((v1^v2) & (v1^res) & 0x80000000)
663 CCR |= F_V;
664 if(res & 0x100000000U)
665 CCR |= F_C;
666 return res;
667 }
668
do_shal8(uint8_t v)669 uint8_t h8_device::do_shal8(uint8_t v)
670 {
671 CCR &= ~(F_N|F_V|F_Z|F_C);
672 if(v & 0x80)
673 CCR |= F_C;
674 if((v & 0xc0) == 0x40 || (v & 0xc0) == 0x80)
675 CCR |= F_V;
676 v <<= 1;
677 if(!v)
678 CCR |= F_Z;
679 else if(int8_t(v) < 0)
680 CCR |= F_N;
681 return v;
682 }
683
do_shal16(uint16_t v)684 uint16_t h8_device::do_shal16(uint16_t v)
685 {
686 CCR &= ~(F_N|F_V|F_Z|F_C);
687 if(v & 0x8000)
688 CCR |= F_C;
689 if((v & 0xc000) == 0x4000 || (v & 0xc000) == 0x8000)
690 CCR |= F_V;
691 v <<= 1;
692 if(!v)
693 CCR |= F_Z;
694 else if(int16_t(v) < 0)
695 CCR |= F_N;
696 return v;
697 }
698
do_shal32(uint32_t v)699 uint32_t h8_device::do_shal32(uint32_t v)
700 {
701 CCR &= ~(F_N|F_V|F_Z|F_C);
702 if(v & 0x80000000)
703 CCR |= F_C;
704 if((v & 0xc0000000) == 0x40000000 || (v & 0xc0000000) == 0x80000000)
705 CCR |= F_V;
706 v <<= 1;
707 if(!v)
708 CCR |= F_Z;
709 else if(int32_t(v) < 0)
710 CCR |= F_N;
711 return v;
712 }
713
do_shar8(uint8_t v)714 uint8_t h8_device::do_shar8(uint8_t v)
715 {
716 CCR &= ~(F_N|F_V|F_Z|F_C);
717 if(v & 1)
718 CCR |= F_C;
719 v >>= 1;
720 if(!v)
721 CCR |= F_Z;
722 else if (v & 0x40) {
723 v |= 0x80;
724 CCR |= F_N;
725 }
726 return v;
727 }
728
do_shar16(uint16_t v)729 uint16_t h8_device::do_shar16(uint16_t v)
730 {
731 CCR &= ~(F_N|F_V|F_Z|F_C);
732 if(v & 1)
733 CCR |= F_C;
734 v >>= 1;
735 if(!v)
736 CCR |= F_Z;
737 else if (v & 0x4000) {
738 v |= 0x8000;
739 CCR |= F_N;
740 }
741 return v;
742 }
743
do_shar32(uint32_t v)744 uint32_t h8_device::do_shar32(uint32_t v)
745 {
746 CCR &= ~(F_N|F_V|F_Z|F_C);
747 if(v & 1)
748 CCR |= F_C;
749 v >>= 1;
750 if(!v)
751 CCR |= F_Z;
752 else if (v & 0x40000000) {
753 v |= 0x80000000;
754 CCR |= F_N;
755 }
756 return v;
757 }
758
do_shll8(uint8_t v)759 uint8_t h8_device::do_shll8(uint8_t v)
760 {
761 CCR &= ~(F_N|F_V|F_Z|F_C);
762 if(v & 0x80)
763 CCR |= F_C;
764 v <<= 1;
765 if(!v)
766 CCR |= F_Z;
767 else if(int8_t(v) < 0)
768 CCR |= F_N;
769 return v;
770 }
771
do_shll16(uint16_t v)772 uint16_t h8_device::do_shll16(uint16_t v)
773 {
774 CCR &= ~(F_N|F_V|F_Z|F_C);
775 if(v & 0x8000)
776 CCR |= F_C;
777 v <<= 1;
778 if(!v)
779 CCR |= F_Z;
780 else if(int16_t(v) < 0)
781 CCR |= F_N;
782 return v;
783 }
784
do_shll32(uint32_t v)785 uint32_t h8_device::do_shll32(uint32_t v)
786 {
787 CCR &= ~(F_N|F_V|F_Z|F_C);
788 if(v & 0x80000000)
789 CCR |= F_C;
790 v <<= 1;
791 if(!v)
792 CCR |= F_Z;
793 else if(int32_t(v) < 0)
794 CCR |= F_N;
795 return v;
796 }
797
do_shlr8(uint8_t v)798 uint8_t h8_device::do_shlr8(uint8_t v)
799 {
800 CCR &= ~(F_N|F_V|F_Z|F_C);
801 if(v & 1)
802 CCR |= F_C;
803 v >>= 1;
804 if(!v)
805 CCR |= F_Z;
806 return v;
807 }
808
do_shlr16(uint16_t v)809 uint16_t h8_device::do_shlr16(uint16_t v)
810 {
811 CCR &= ~(F_N|F_V|F_Z|F_C);
812 if(v & 1)
813 CCR |= F_C;
814 v >>= 1;
815 if(!v)
816 CCR |= F_Z;
817 return v;
818 }
819
do_shlr32(uint32_t v)820 uint32_t h8_device::do_shlr32(uint32_t v)
821 {
822 CCR &= ~(F_N|F_V|F_Z|F_C);
823 if(v & 1)
824 CCR |= F_C;
825 v >>= 1;
826 if(!v)
827 CCR |= F_Z;
828 return v;
829 }
830
do_shal2_8(uint8_t v)831 uint8_t h8_device::do_shal2_8(uint8_t v)
832 {
833 CCR &= ~(F_N|F_V|F_Z|F_C);
834 if(v & 0x40)
835 CCR |= F_C;
836 if((v & 0xc0) == 0x40 || (v & 0xc0) == 0x80 ||
837 (v & 0x60) == 0x20 || (v & 0x60) == 0x40)
838 CCR |= F_V;
839 v <<= 2;
840 if(!v)
841 CCR |= F_Z;
842 else if(int8_t(v) < 0)
843 CCR |= F_N;
844 return v;
845 }
846
do_shal2_16(uint16_t v)847 uint16_t h8_device::do_shal2_16(uint16_t v)
848 {
849 CCR &= ~(F_N|F_V|F_Z|F_C);
850 if(v & 0x4000)
851 CCR |= F_C;
852 if((v & 0xc000) == 0x4000 || (v & 0xc000) == 0x8000 ||
853 (v & 0x6000) == 0x2000 || (v & 0x6000) == 0x4000)
854 CCR |= F_V;
855 v <<= 2;
856 if(!v)
857 CCR |= F_Z;
858 else if(int16_t(v) < 0)
859 CCR |= F_N;
860 return v;
861 }
862
do_shal2_32(uint32_t v)863 uint32_t h8_device::do_shal2_32(uint32_t v)
864 {
865 CCR &= ~(F_N|F_V|F_Z|F_C);
866 if(v & 0x40000000)
867 CCR |= F_C;
868 if((v & 0xc0000000) == 0x40000000 || (v & 0xc0000000) == 0x80000000 ||
869 (v & 0x60000000) == 0x20000000 || (v & 0x60000000) == 0x40000000)
870 CCR |= F_V;
871 v <<= 2;
872 if(!v)
873 CCR |= F_Z;
874 else if(int32_t(v) < 0)
875 CCR |= F_N;
876 return v;
877 }
878
do_shar2_8(uint8_t v)879 uint8_t h8_device::do_shar2_8(uint8_t v)
880 {
881 CCR &= ~(F_N|F_V|F_Z|F_C);
882 if(v & 2)
883 CCR |= F_C;
884 v >>= 2;
885 if(!v)
886 CCR |= F_Z;
887 else if (v & 0x20) {
888 v |= 0xc0;
889 CCR |= F_N;
890 }
891 return v;
892 }
893
do_shar2_16(uint16_t v)894 uint16_t h8_device::do_shar2_16(uint16_t v)
895 {
896 CCR &= ~(F_N|F_V|F_Z|F_C);
897 if(v & 2)
898 CCR |= F_C;
899 v >>= 2;
900 if(!v)
901 CCR |= F_Z;
902 else if (v & 0x2000) {
903 v |= 0xc000;
904 CCR |= F_N;
905 }
906 return v;
907 }
908
do_shar2_32(uint32_t v)909 uint32_t h8_device::do_shar2_32(uint32_t v)
910 {
911 CCR &= ~(F_N|F_V|F_Z|F_C);
912 if(v & 2)
913 CCR |= F_C;
914 v >>= 2;
915 if(!v)
916 CCR |= F_Z;
917 else if (v & 0x20000000) {
918 v |= 0xc0000000;
919 CCR |= F_N;
920 }
921 return v;
922 }
923
do_shll2_8(uint8_t v)924 uint8_t h8_device::do_shll2_8(uint8_t v)
925 {
926 CCR &= ~(F_N|F_V|F_Z|F_C);
927 if(v & 0x40)
928 CCR |= F_C;
929 v <<= 2;
930 if(!v)
931 CCR |= F_Z;
932 else if(int8_t(v) < 0)
933 CCR |= F_N;
934 return v;
935 }
936
do_shll2_16(uint16_t v)937 uint16_t h8_device::do_shll2_16(uint16_t v)
938 {
939 CCR &= ~(F_N|F_V|F_Z|F_C);
940 if(v & 0x4000)
941 CCR |= F_C;
942 v <<= 2;
943 if(!v)
944 CCR |= F_Z;
945 else if(int16_t(v) < 0)
946 CCR |= F_N;
947 return v;
948 }
949
do_shll2_32(uint32_t v)950 uint32_t h8_device::do_shll2_32(uint32_t v)
951 {
952 CCR &= ~(F_N|F_V|F_Z|F_C);
953 if(v & 0x40000000)
954 CCR |= F_C;
955 v <<= 2;
956 if(!v)
957 CCR |= F_Z;
958 else if(int32_t(v) < 0)
959 CCR |= F_N;
960 return v;
961 }
962
do_shlr2_8(uint8_t v)963 uint8_t h8_device::do_shlr2_8(uint8_t v)
964 {
965 CCR &= ~(F_N|F_V|F_Z|F_C);
966 if(v & 2)
967 CCR |= F_C;
968 v >>= 2;
969 if(!v)
970 CCR |= F_Z;
971 return v;
972 }
973
do_shlr2_16(uint16_t v)974 uint16_t h8_device::do_shlr2_16(uint16_t v)
975 {
976 CCR &= ~(F_N|F_V|F_Z|F_C);
977 if(v & 2)
978 CCR |= F_C;
979 v >>= 2;
980 if(!v)
981 CCR |= F_Z;
982 return v;
983 }
984
do_shlr2_32(uint32_t v)985 uint32_t h8_device::do_shlr2_32(uint32_t v)
986 {
987 CCR &= ~(F_N|F_V|F_Z|F_C);
988 if(v & 2)
989 CCR |= F_C;
990 v >>= 2;
991 if(!v)
992 CCR |= F_Z;
993 return v;
994 }
995
do_rotl8(uint8_t v)996 uint8_t h8_device::do_rotl8(uint8_t v)
997 {
998 CCR &= ~(F_N|F_V|F_Z|F_C);
999 if(v & 0x80)
1000 CCR |= F_C;
1001 v = (v << 1) | (v >> 7);
1002 if(!v)
1003 CCR |= F_Z;
1004 else if(int8_t(v) < 0)
1005 CCR |= F_N;
1006 return v;
1007 }
1008
do_rotl16(uint16_t v)1009 uint16_t h8_device::do_rotl16(uint16_t v)
1010 {
1011 CCR &= ~(F_N|F_V|F_Z|F_C);
1012 if(v & 0x8000)
1013 CCR |= F_C;
1014 v = (v << 1) | (v >> 15);
1015 if(!v)
1016 CCR |= F_Z;
1017 else if(int16_t(v) < 0)
1018 CCR |= F_N;
1019 return v;
1020 }
1021
do_rotl32(uint32_t v)1022 uint32_t h8_device::do_rotl32(uint32_t v)
1023 {
1024 CCR &= ~(F_N|F_V|F_Z|F_C);
1025 if(v & 0x80000000)
1026 CCR |= F_C;
1027 v = (v << 1) | (v >> 31);
1028 if(!v)
1029 CCR |= F_Z;
1030 else if(int32_t(v) < 0)
1031 CCR |= F_N;
1032 return v;
1033 }
1034
do_rotr8(uint8_t v)1035 uint8_t h8_device::do_rotr8(uint8_t v)
1036 {
1037 CCR &= ~(F_N|F_V|F_Z|F_C);
1038 if(v & 0x01)
1039 CCR |= F_C;
1040 v = (v << 7) | (v >> 1);
1041 if(!v)
1042 CCR |= F_Z;
1043 else if(int8_t(v) < 0)
1044 CCR |= F_N;
1045 return v;
1046 }
1047
do_rotr16(uint16_t v)1048 uint16_t h8_device::do_rotr16(uint16_t v)
1049 {
1050 CCR &= ~(F_N|F_V|F_Z|F_C);
1051 if(v & 0x0001)
1052 CCR |= F_C;
1053 v = (v << 15) | (v >> 1);
1054 if(!v)
1055 CCR |= F_Z;
1056 else if(int16_t(v) < 0)
1057 CCR |= F_N;
1058 return v;
1059 }
1060
do_rotr32(uint32_t v)1061 uint32_t h8_device::do_rotr32(uint32_t v)
1062 {
1063 CCR &= ~(F_N|F_V|F_Z|F_C);
1064 if(v & 0x00000001)
1065 CCR |= F_C;
1066 v = (v << 31) | (v >> 1);
1067 if(!v)
1068 CCR |= F_Z;
1069 else if(int32_t(v) < 0)
1070 CCR |= F_N;
1071 return v;
1072 }
1073
do_rotxl8(uint8_t v)1074 uint8_t h8_device::do_rotxl8(uint8_t v)
1075 {
1076 uint8_t c = CCR & F_C ? 1 : 0;
1077 CCR &= ~(F_N|F_V|F_Z|F_C);
1078 if(v & 0x80)
1079 CCR |= F_C;
1080 v = (v << 1) | c;
1081 if(!v)
1082 CCR |= F_Z;
1083 else if(int8_t(v) < 0)
1084 CCR |= F_N;
1085 return v;
1086 }
1087
do_rotxl16(uint16_t v)1088 uint16_t h8_device::do_rotxl16(uint16_t v)
1089 {
1090 uint16_t c = CCR & F_C ? 1 : 0;
1091 CCR &= ~(F_N|F_V|F_Z|F_C);
1092 if(v & 0x8000)
1093 CCR |= F_C;
1094 v = (v << 1) | c;
1095 if(!v)
1096 CCR |= F_Z;
1097 else if(int16_t(v) < 0)
1098 CCR |= F_N;
1099 return v;
1100 }
1101
do_rotxl32(uint32_t v)1102 uint32_t h8_device::do_rotxl32(uint32_t v)
1103 {
1104 uint32_t c = CCR & F_C ? 1 : 0;
1105 CCR &= ~(F_N|F_V|F_Z|F_C);
1106 if(v & 0x80000000)
1107 CCR |= F_C;
1108 v = (v << 1) | c;
1109 if(!v)
1110 CCR |= F_Z;
1111 else if(int32_t(v) < 0)
1112 CCR |= F_N;
1113 return v;
1114 }
1115
do_rotxr8(uint8_t v)1116 uint8_t h8_device::do_rotxr8(uint8_t v)
1117 {
1118 uint8_t c = CCR & F_C ? 1 : 0;
1119 CCR &= ~(F_N|F_V|F_Z|F_C);
1120 if(v & 0x01)
1121 CCR |= F_C;
1122 v = (v >> 1) | (c << 7);
1123 if(!v)
1124 CCR |= F_Z;
1125 else if(int8_t(v) < 0)
1126 CCR |= F_N;
1127 return v;
1128 }
1129
do_rotxr16(uint16_t v)1130 uint16_t h8_device::do_rotxr16(uint16_t v)
1131 {
1132 uint8_t c = CCR & F_C ? 1 : 0;
1133 CCR &= ~(F_N|F_V|F_Z|F_C);
1134 if(v & 0x0001)
1135 CCR |= F_C;
1136 v = (v >> 1) | (c << 15);
1137 if(!v)
1138 CCR |= F_Z;
1139 else if(int16_t(v) < 0)
1140 CCR |= F_N;
1141 return v;
1142 }
1143
do_rotxr32(uint32_t v)1144 uint32_t h8_device::do_rotxr32(uint32_t v)
1145 {
1146 uint8_t c = CCR & F_C ? 1 : 0;
1147 CCR &= ~(F_N|F_V|F_Z|F_C);
1148 if(v & 0x00000001)
1149 CCR |= F_C;
1150 v = (v >> 1) | (c << 31);
1151 if(!v)
1152 CCR |= F_Z;
1153 else if(int32_t(v) < 0)
1154 CCR |= F_N;
1155 return v;
1156 }
1157
do_rotl2_8(uint8_t v)1158 uint8_t h8_device::do_rotl2_8(uint8_t v)
1159 {
1160 CCR &= ~(F_N|F_V|F_Z|F_C);
1161 if(v & 0x40)
1162 CCR |= F_C;
1163 v = (v << 2) | (v >> 6);
1164 if(!v)
1165 CCR |= F_Z;
1166 else if(int8_t(v) < 0)
1167 CCR |= F_N;
1168 return v;
1169 }
1170
do_rotl2_16(uint16_t v)1171 uint16_t h8_device::do_rotl2_16(uint16_t v)
1172 {
1173 CCR &= ~(F_N|F_V|F_Z|F_C);
1174 if(v & 0x4000)
1175 CCR |= F_C;
1176 v = (v << 2) | (v >> 14);
1177 if(!v)
1178 CCR |= F_Z;
1179 else if(int16_t(v) < 0)
1180 CCR |= F_N;
1181 return v;
1182 }
1183
do_rotl2_32(uint32_t v)1184 uint32_t h8_device::do_rotl2_32(uint32_t v)
1185 {
1186 CCR &= ~(F_N|F_V|F_Z|F_C);
1187 if(v & 0x40000000)
1188 CCR |= F_C;
1189 v = (v << 2) | (v >> 30);
1190 if(!v)
1191 CCR |= F_Z;
1192 else if(int32_t(v) < 0)
1193 CCR |= F_N;
1194 return v;
1195 }
1196
do_rotr2_8(uint8_t v)1197 uint8_t h8_device::do_rotr2_8(uint8_t v)
1198 {
1199 CCR &= ~(F_N|F_V|F_Z|F_C);
1200 if(v & 0x02)
1201 CCR |= F_C;
1202 v = (v << 6) | (v >> 2);
1203 if(!v)
1204 CCR |= F_Z;
1205 else if(int8_t(v) < 0)
1206 CCR |= F_N;
1207 return v;
1208 }
1209
do_rotr2_16(uint16_t v)1210 uint16_t h8_device::do_rotr2_16(uint16_t v)
1211 {
1212 CCR &= ~(F_N|F_V|F_Z|F_C);
1213 if(v & 0x0002)
1214 CCR |= F_C;
1215 v = (v << 14) | (v >> 2);
1216 if(!v)
1217 CCR |= F_Z;
1218 else if(int16_t(v) < 0)
1219 CCR |= F_N;
1220 return v;
1221 }
1222
do_rotr2_32(uint32_t v)1223 uint32_t h8_device::do_rotr2_32(uint32_t v)
1224 {
1225 CCR &= ~(F_N|F_V|F_Z|F_C);
1226 if(v & 0x00000002)
1227 CCR |= F_C;
1228 v = (v << 30) | (v >> 2);
1229 if(!v)
1230 CCR |= F_Z;
1231 else if(int32_t(v) < 0)
1232 CCR |= F_N;
1233 return v;
1234 }
1235
do_rotxl2_8(uint8_t v)1236 uint8_t h8_device::do_rotxl2_8(uint8_t v)
1237 {
1238 uint8_t c = CCR & F_C ? 1 : 0;
1239 CCR &= ~(F_N|F_V|F_Z|F_C);
1240 if(v & 0x40)
1241 CCR |= F_C;
1242 v = (v << 2) | (c << 1) | ((v >> 6) & 0x01);
1243 if(!v)
1244 CCR |= F_Z;
1245 else if(int8_t(v) < 0)
1246 CCR |= F_N;
1247 return v;
1248 }
1249
do_rotxl2_16(uint16_t v)1250 uint16_t h8_device::do_rotxl2_16(uint16_t v)
1251 {
1252 uint16_t c = CCR & F_C ? 1 : 0;
1253 CCR &= ~(F_N|F_V|F_Z|F_C);
1254 if(v & 0x4000)
1255 CCR |= F_C;
1256 v = (v << 2) | (c << 1) | ((v >> 14) & 0x0001);
1257 if(!v)
1258 CCR |= F_Z;
1259 else if(int16_t(v) < 0)
1260 CCR |= F_N;
1261 return v;
1262 }
1263
do_rotxl2_32(uint32_t v)1264 uint32_t h8_device::do_rotxl2_32(uint32_t v)
1265 {
1266 uint32_t c = CCR & F_C ? 1 : 0;
1267 CCR &= ~(F_N|F_V|F_Z|F_C);
1268 if(v & 0x40000000)
1269 CCR |= F_C;
1270 v = (v << 2) | (c << 1) | ((v >> 30) & 0x00000001);
1271 if(!v)
1272 CCR |= F_Z;
1273 else if(int32_t(v) < 0)
1274 CCR |= F_N;
1275 return v;
1276 }
1277
do_rotxr2_8(uint8_t v)1278 uint8_t h8_device::do_rotxr2_8(uint8_t v)
1279 {
1280 uint8_t c = CCR & F_C ? 1 : 0;
1281 CCR &= ~(F_N|F_V|F_Z|F_C);
1282 if(v & 0x02)
1283 CCR |= F_C;
1284 v = (v >> 2) | (c << 6) | (v << 7);
1285 if(!v)
1286 CCR |= F_Z;
1287 else if(int8_t(v) < 0)
1288 CCR |= F_N;
1289 return v;
1290 }
1291
do_rotxr2_16(uint16_t v)1292 uint16_t h8_device::do_rotxr2_16(uint16_t v)
1293 {
1294 uint16_t c = CCR & F_C ? 1 : 0;
1295 CCR &= ~(F_N|F_V|F_Z|F_C);
1296 if(v & 0x0002)
1297 CCR |= F_C;
1298 v = (v >> 2) | (c << 14) | (v << 15);
1299 if(!v)
1300 CCR |= F_Z;
1301 else if(int16_t(v) < 0)
1302 CCR |= F_N;
1303 return v;
1304 }
1305
do_rotxr2_32(uint32_t v)1306 uint32_t h8_device::do_rotxr2_32(uint32_t v)
1307 {
1308 uint32_t c = CCR & F_C ? 1 : 0;
1309 CCR &= ~(F_N|F_V|F_Z|F_C);
1310 if(v & 0x00000002)
1311 CCR |= F_C;
1312 v = (v >> 2) | (c << 30) | (v << 31);
1313 if(!v)
1314 CCR |= F_Z;
1315 else if(int32_t(v) < 0)
1316 CCR |= F_N;
1317 return v;
1318 }
1319
set_nzv8(uint8_t v)1320 void h8_device::set_nzv8(uint8_t v)
1321 {
1322 CCR &= ~(F_N|F_V|F_Z);
1323 if(!v)
1324 CCR |= F_Z;
1325 else if(int8_t(v) < 0)
1326 CCR |= F_N;
1327 }
1328
set_nzv16(uint16_t v)1329 void h8_device::set_nzv16(uint16_t v)
1330 {
1331 CCR &= ~(F_N|F_V|F_Z);
1332 if(!v)
1333 CCR |= F_Z;
1334 else if(int16_t(v) < 0)
1335 CCR |= F_N;
1336 }
1337
set_nzv32(uint32_t v)1338 void h8_device::set_nzv32(uint32_t v)
1339 {
1340 CCR &= ~(F_N|F_V|F_Z);
1341 if(!v)
1342 CCR |= F_Z;
1343 else if(int32_t(v) < 0)
1344 CCR |= F_N;
1345 }
1346
set_nz16(uint16_t v)1347 void h8_device::set_nz16(uint16_t v)
1348 {
1349 CCR &= ~(F_N|F_Z);
1350 if(!v)
1351 CCR |= F_Z;
1352 else if(int16_t(v) < 0)
1353 CCR |= F_N;
1354 }
1355
set_nz32(uint32_t v)1356 void h8_device::set_nz32(uint32_t v)
1357 {
1358 CCR &= ~(F_N|F_Z);
1359 if(!v)
1360 CCR |= F_Z;
1361 else if(int32_t(v) < 0)
1362 CCR |= F_N;
1363 }
1364
create_disassembler()1365 std::unique_ptr<util::disasm_interface> h8_device::create_disassembler()
1366 {
1367 return std::make_unique<h8_disassembler>();
1368 }
1369
1370 #include "cpu/h8/h8.hxx"
1371