1 // license:BSD-3-Clause
2 // copyright-holders:Juergen Buchmueller
3 /*****************************************************************************
4 *
5 * Portable F8 emulator (Fairchild 3850)
6 *
7 * This work is based on Frank Palazzolo's F8 emulation in a standalone
8 * Fairchild Channel F emulator and the 'Fairchild F3850 CPU' data sheets.
9 *
10 * TODO:
11 * - ROMC signals are supposed to be handled externally
12 *
13 *****************************************************************************
14 *
15 * The 3850 CPU itself does not include the address bus, pointer registers
16 * or an interrupt controller. Those functions are provided by at least one
17 * of the following devices:
18 *
19 * - 3851 Program Storage Unit (PSU)
20 * - 3852 Dynamic Memory Interface (DMI)
21 * - 3853 Static Memory Interface (SMI)
22 * - 3854 Direct Memory Access Controller (DMAC)
23 * - 3856 Program Storage Unit (PSU)
24 * - 38T56 Program Storage Unit (PSU)
25 * - 3861 Peripheral Input/Output (PIO)
26 * - 3871 Peripheral Input/Output (PIO)
27 *
28 * Of these support devices, the 3851 PSU includes 1024 bytes of mask ROM,
29 * and the 3856 PSU includes 2048 bytes of mask ROM; addressing for the PSU
30 * is also determined by mask option. The 3853 SMI may be used with external
31 * program ROMs.
32 *
33 * The PSU does not have DC0 and DC1, only DC0; as a result, it does not
34 * respond to the main CPU's DC0/DC1 swap instruction. This may lead to two
35 * devices responding to the same DC0 address and attempting to place their
36 * bytes on the data bus simultaneously!
37 *
38 * Combined packages:
39 * - 3859 = 3850 + 3851
40 * - 3870 = 3850 + 38T56
41 * - 3872 = 3870 + extra 2KB ROM
42 * - 3873 = 3870 + extra 64 bytes executable RAM
43 *
44 *****************************************************************************/
45
46 #include "emu.h"
47 #include "f8.h"
48 #include "f8dasm.h"
49 #include "debugger.h"
50
51
52 /* status flags */
53 static constexpr u8 S = 0x01; // sign
54 static constexpr u8 C = 0x02; // carry
55 static constexpr u8 Z = 0x04; // zero
56 static constexpr u8 O = 0x08; // overflow
57 static constexpr u8 I = 0x10; // interrupt control bit (ICB)
58
59 /* cycle (short/long) */
60 static constexpr int cS = 4;
61 static constexpr int cL = 6;
62
63
64 DEFINE_DEVICE_TYPE(F8, f8_cpu_device, "f8", "Fairchild F8")
65
66
f8_cpu_device(const machine_config & mconfig,const char * tag,device_t * owner,u32 clock)67 f8_cpu_device::f8_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
68 cpu_device(mconfig, F8, tag, owner, clock),
69 m_program_config("program", ENDIANNESS_BIG, 8, 16, 0),
70 m_regs_config("register", ENDIANNESS_BIG, 8, 6, 0, address_map_constructor(FUNC(f8_cpu_device::regs_map), this)),
71 m_io_config("io", ENDIANNESS_BIG, 8, 8, 0)
72 { }
73
regs_map(address_map & map)74 void f8_cpu_device::regs_map(address_map &map)
75 {
76 // 64-byte internal scratchpad RAM
77 map(0x00, 0x3f).ram().share("regs");
78 }
79
memory_space_config() const80 device_memory_interface::space_config_vector f8_cpu_device::memory_space_config() const
81 {
82 return space_config_vector {
83 std::make_pair(AS_PROGRAM, &m_program_config),
84 std::make_pair(AS_DATA, &m_regs_config),
85 std::make_pair(AS_IO, &m_io_config)
86 };
87 }
88
create_disassembler()89 std::unique_ptr<util::disasm_interface> f8_cpu_device::create_disassembler()
90 {
91 return std::make_unique<f8_disassembler>();
92 }
93
state_string_export(const device_state_entry & entry,std::string & str) const94 void f8_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const
95 {
96 switch (entry.index())
97 {
98 case STATE_GENFLAGS:
99 str = string_format("%c%c%c%c%c",
100 m_w & 0x10 ? 'I':'.',
101 m_w & 0x08 ? 'O':'.',
102 m_w & 0x04 ? 'Z':'.',
103 m_w & 0x02 ? 'C':'.',
104 m_w & 0x01 ? 'S':'.');
105 break;
106 }
107 }
108
device_start()109 void f8_cpu_device::device_start()
110 {
111 space(AS_PROGRAM).cache(m_program);
112 space(AS_DATA).cache(m_r);
113 space(AS_IO).specific(m_ios);
114
115 // zerofill
116 m_debug_pc = 0;
117 m_pc0 = 0;
118 m_pc1 = 0;
119 m_dc0 = 0;
120 m_dc1 = 0;
121 m_a = 0;
122 m_w = 0;
123 m_is = 0;
124 m_dbus = 0;
125 m_io = 0;
126 m_irq_vector = 0;
127 m_irq_request = 0;
128
129 // register for savestates
130 save_item(NAME(m_debug_pc));
131 save_item(NAME(m_pc0));
132 save_item(NAME(m_pc1));
133 save_item(NAME(m_dc0));
134 save_item(NAME(m_dc1));
135 save_item(NAME(m_a));
136 save_item(NAME(m_w));
137 save_item(NAME(m_is));
138 save_item(NAME(m_dbus));
139 save_item(NAME(m_io));
140 save_item(NAME(m_irq_vector));
141 save_item(NAME(m_irq_request));
142
143 // register for debugger
144 state_add(F8_PC0, "PC0", m_pc0);
145 state_add(F8_PC1, "PC1", m_pc1);
146 state_add(F8_DC0, "DC0", m_dc0);
147 state_add(F8_DC1, "DC1", m_dc1);
148 state_add(F8_W, "W", m_w).mask(0x1f);
149 state_add(F8_A, "A", m_a);
150 state_add(F8_IS, "IS", m_is).mask(0x3f);
151
152 u8 *regs = static_cast<u8 *>(memshare("regs")->ptr());
153 for (int r = 0; r < 9; r++)
154 state_add(F8_R0 + r, string_format("R%d", r).c_str(), regs[r]);
155 state_add(F8_J, "J", regs[9]);
156 state_add<u16>(F8_H, "H",
157 [regs]() { return u16(regs[10]) << 8 | regs[11]; },
158 [regs](u16 data) { regs[10] = data >> 8; regs[11] = data & 0xff; });
159 state_add<u16>(F8_K, "K",
160 [regs]() { return u16(regs[12]) << 8 | regs[13]; },
161 [regs](u16 data) { regs[12] = data >> 8; regs[13] = data & 0xff; });
162 state_add<u16>(F8_Q, "Q",
163 [regs]() { return u16(regs[14]) << 8 | regs[15]; },
164 [regs](u16 data) { regs[14] = data >> 8; regs[15] = data & 0xff; });
165 state_add(F8_HU, "HU", regs[10]).noshow();
166 state_add(F8_HL, "HL", regs[11]).noshow();
167 state_add(F8_KU, "KU", regs[12]).noshow();
168 state_add(F8_KL, "KL", regs[13]).noshow();
169 state_add(F8_QU, "QU", regs[14]).noshow();
170 state_add(F8_QL, "QL", regs[15]).noshow();
171
172 state_add(STATE_GENPC, "GENPC", m_debug_pc).formatstr("%04X").noshow();
173 state_add(STATE_GENPCBASE, "CURPC", m_debug_pc).formatstr("%04X").noshow();
174 state_add(STATE_GENFLAGS, "GENFLAGS", m_w).formatstr("%5s").noshow();
175
176 set_icountptr(m_icount);
177 }
178
device_reset()179 void f8_cpu_device::device_reset()
180 {
181 // save PC0 to PC1 and reset PC0, and clear ICB
182 ROMC_08();
183 m_w &= ~I;
184
185 // fetch the first opcode
186 ROMC_00(cS);
187 }
188
189
execute_set_input(int inptnum,int state)190 void f8_cpu_device::execute_set_input( int inptnum, int state )
191 {
192 assert (inptnum == F8_INPUT_LINE_INT_REQ);
193 m_irq_request = state;
194 }
195
196 /*****************************************************************************/
197
198 /* clear all flags */
CLR_OZCS()199 inline void f8_cpu_device::CLR_OZCS()
200 {
201 m_w &= ~(O|Z|C|S);
202 }
203
204 /* set sign and zero flags (note: the S flag is complementary) */
SET_SZ(u8 n)205 inline void f8_cpu_device::SET_SZ(u8 n)
206 {
207 if (n == 0)
208 m_w |= Z;
209 if (~n & 0x80)
210 m_w |= S;
211 }
212
213 /* set overflow and carry flags */
do_add(u8 n,u8 m,u8 c)214 inline u8 f8_cpu_device::do_add(u8 n, u8 m, u8 c)
215 {
216 u16 r = n + m + c;
217 if (r & 0x100)
218 m_w |= C;
219 if ((n^r) & (m^r) & 0x80)
220 m_w |= O;
221
222 return r & 0xff;
223 }
224
225 /* decimal add helper */
do_add_decimal(u8 augend,u8 addend)226 inline u8 f8_cpu_device::do_add_decimal(u8 augend, u8 addend)
227 {
228 /* From F8 Guide To programming description of AMD
229 * binary add the addend to the binary sum of the augend and $66
230 * *NOTE* the binary addition of the augend to $66 is done before AMD is called
231 * record the status of the carry and intermediate carry
232 * add a factor to the sum based on the carry and intermediate carry:
233 * - no carry, no intermediate carry, add $AA
234 * - no carry, intermediate carry, add $A0
235 * - carry, no intermediate carry, add $0A
236 * - carry, intermediate carry, add $00
237 * any carry from the low-order digit is suppressed
238 * *NOTE* status flags are updated prior to the factor being added
239 */
240 u8 tmp = augend + addend;
241
242 u8 c = 0; // high order carry
243 u8 ic = 0; // low order carry
244
245 if (((augend + addend) & 0xff0) > 0xf0)
246 c = 1;
247 if ((augend & 0x0f) + (addend & 0x0f) > 0x0F)
248 ic = 1;
249
250 CLR_OZCS();
251 do_add(augend,addend);
252 SET_SZ(tmp);
253
254 if (c == 0 && ic == 0)
255 tmp = ((tmp + 0xa0) & 0xf0) + ((tmp + 0x0a) & 0x0f);
256 if (c == 0 && ic == 1)
257 tmp = ((tmp + 0xa0) & 0xf0) + (tmp & 0x0f);
258 if (c == 1 && ic == 0)
259 tmp = (tmp & 0xf0) + ((tmp + 0x0a) & 0x0f);
260
261 return tmp;
262 }
263
264
265 /******************************************************************************
266 * ROMC (ROM cycles)
267 * This is what the Fairchild F8 CPUs use instead of an address bus
268 * There are 5 control lines and each combination of those lines has
269 * a special meaning. The devices attached to those control lines all
270 * have their own program counters (PC0 and PC1) and at least one
271 * data counter (DC0).
272 * Currently the emulation does not handle distinct PCs and DCs, but
273 * only one instance inside the CPU context.
274 ******************************************************************************/
ROMC_00(int insttim)275 void f8_cpu_device::ROMC_00(int insttim)
276 {
277 /*
278 * Instruction Fetch. The device whose address space includes the
279 * contents of the PC0 register must place on the data bus the op
280 * code addressed by PC0; then all devices increment the contents
281 * of PC0.
282 */
283
284 m_dbus = m_program.read_byte(m_pc0);
285 m_pc0 += 1;
286 m_icount -= insttim; /* ROMC00 is usually short, not short+long, but DS is long */
287 }
288
ROMC_01()289 void f8_cpu_device::ROMC_01()
290 {
291 /*
292 * The device whose address space includes the contents of the PC0
293 * register must place on the data bus the contents of the memory
294 * location addressed by PC0; then all devices add the 8-bit value
295 * on the data bus as signed binary number to PC0.
296 */
297 m_dbus = m_program.read_byte(m_pc0);
298 m_pc0 += (s8)m_dbus;
299 m_icount -= cL;
300 }
301
ROMC_02()302 void f8_cpu_device::ROMC_02()
303 {
304 /*
305 * The device whose DC0 addresses a memory word within the address
306 * space of that device must place on the data bus the contents of
307 * the memory location addressed by DC0; then all devices increment
308 * DC0.
309 */
310 m_dbus = m_program.read_byte(m_dc0);
311 m_dc0 += 1;
312 m_icount -= cL;
313 }
314
ROMC_03(int insttim)315 void f8_cpu_device::ROMC_03(int insttim)
316 {
317 /*
318 * Similiar to 0x00, except that it is used for immediate operands
319 * fetches (using PC0) instead of instruction fetches.
320 */
321 m_dbus = m_io = m_program.read_byte(m_pc0);
322 m_pc0 += 1;
323 m_icount -= insttim;
324 }
325
ROMC_04()326 void f8_cpu_device::ROMC_04()
327 {
328 /*
329 * Copy the contents of PC1 into PC0
330 */
331 m_pc0 = m_pc1;
332 m_icount -= cS;
333 }
334
ROMC_05()335 void f8_cpu_device::ROMC_05()
336 {
337 /*
338 * Store the data bus contents into the memory location pointed
339 * to by DC0; increment DC0.
340 */
341 m_program.write_byte(m_dc0, m_dbus);
342 m_dc0 += 1;
343 m_icount -= cL;
344 }
345
ROMC_06()346 void f8_cpu_device::ROMC_06()
347 {
348 /*
349 * Place the high order byte of DC0 on the data bus.
350 */
351 m_dbus = m_dc0 >> 8;
352 m_icount -= cL;
353 }
354
ROMC_07()355 void f8_cpu_device::ROMC_07()
356 {
357 /*
358 * Place the high order byte of PC1 on the data bus.
359 */
360 m_dbus = m_pc1 >> 8;
361 m_icount -= cL;
362 }
363
ROMC_08()364 void f8_cpu_device::ROMC_08()
365 {
366 /*
367 * All devices copy the contents of PC0 into PC1. The CPU outputs
368 * zero on the data bus in this ROMC state. Load the data bus into
369 * both halves of PC0, thus clearing the register.
370 */
371 m_pc1 = m_pc0;
372 m_dbus = 0;
373 m_pc0 = 0;
374 m_icount -= cL;
375 }
376
ROMC_09()377 void f8_cpu_device::ROMC_09()
378 {
379 /*
380 * The device whose address space includes the contents of the DC0
381 * register must place the low order byte of DC0 onto the data bus.
382 */
383 m_dbus = m_dc0 & 0xff;
384 m_icount -= cL;
385 }
386
ROMC_0A()387 void f8_cpu_device::ROMC_0A()
388 {
389 /*
390 * All devices add the 8-bit value on the data bus, treated as
391 * signed binary number, to the data counter.
392 */
393 m_dc0 += (s8)m_dbus;
394 m_icount -= cL;
395 }
396
ROMC_0B()397 void f8_cpu_device::ROMC_0B()
398 {
399 /*
400 * The device whose address space includes the value in PC1
401 * must place the low order byte of PC1 onto the data bus.
402 */
403 m_dbus = m_pc1 & 0xff;
404 m_icount -= cL;
405 }
406
ROMC_0C()407 void f8_cpu_device::ROMC_0C()
408 {
409 /*
410 * The device whose address space includes the contents of the PC0
411 * register must place the contents of the memory word addressed
412 * by PC0 into the data bus; then all devices move the value that
413 * has just been placed on the data bus into the low order byte of PC0.
414 */
415 m_dbus = m_program.read_byte(m_pc0);
416 m_pc0 = (m_pc0 & 0xff00) | m_dbus;
417 m_icount -= cL;
418 }
419
ROMC_0D()420 void f8_cpu_device::ROMC_0D()
421 {
422 /*
423 * All devices store in PC1 the current contents of PC0, incremented
424 * by 1; PC0 is unaltered.
425 */
426 m_pc1 = m_pc0 + 1;
427 m_icount -= cS;
428 }
429
ROMC_0E()430 void f8_cpu_device::ROMC_0E()
431 {
432 /*
433 * The device whose address space includes the contents of the PC0
434 * register must place the word addressed by PC0 into the data bus.
435 * The value on the data bus is then moved to the low order byte
436 * of DC0 by all devices.
437 */
438 m_dbus = m_program.read_byte(m_pc0);
439 m_dc0 = (m_dc0 & 0xff00) | m_dbus;
440 m_icount -= cL;
441 }
442
ROMC_0F()443 void f8_cpu_device::ROMC_0F()
444 {
445 /*
446 * The interrupting device with highest priority must place the
447 * low order byte of the interrupt vector on the data bus.
448 * All devices must copy the contents of PC0 into PC1. All devices
449 * must move the contents of the data bus into the low order
450 * byte of PC0.
451 */
452 m_irq_vector = standard_irq_callback(F8_INPUT_LINE_INT_REQ);
453 m_dbus = m_irq_vector & 0x00ff;
454 m_pc1 = m_pc0;
455 m_pc0 = (m_pc0 & 0xff00) | m_dbus;
456 m_icount -= cL;
457 }
458
ROMC_10()459 void f8_cpu_device::ROMC_10()
460 {
461 /*
462 * Inhibit any modification to the interrupt priority logic.
463 */
464 // TODO
465 m_icount -= cL;
466 }
467
ROMC_11()468 void f8_cpu_device::ROMC_11()
469 {
470 /*
471 * The device whose address space includes the contents of PC0
472 * must place the contents of the addressed memory word on the
473 * data bus. All devices must then move the contents of the
474 * data bus to the upper byte of DC0.
475 */
476 m_dbus = m_program.read_byte(m_pc0);
477 m_dc0 = (m_dc0 & 0x00ff) | (m_dbus << 8);
478 m_icount -= cL;
479 }
480
ROMC_12()481 void f8_cpu_device::ROMC_12()
482 {
483 /*
484 * All devices copy the contents of PC0 into PC1. All devices then
485 * move the contents of the data bus into the low order byte of PC0.
486 */
487 m_pc1 = m_pc0;
488 m_pc0 = (m_pc0 & 0xff00) | m_dbus;
489 m_icount -= cL;
490 }
491
ROMC_13()492 void f8_cpu_device::ROMC_13()
493 {
494 /*
495 * The interrupting device with highest priority must move the high
496 * order half of the interrupt vector onto the data bus. All devices
497 * must then move the contents of the data bus into the high order
498 * byte of PC0. The interrupting device resets its interrupt circuitry
499 * (so that it is no longer requesting CPU servicing and can respond
500 * to another interrupt).
501 */
502 m_dbus = m_irq_vector >> 8;
503 m_pc0 = (m_pc0 & 0x00ff) | (m_dbus << 8);
504 m_w&=~I;
505 m_icount -= cL;
506 }
507
ROMC_14()508 void f8_cpu_device::ROMC_14()
509 {
510 /*
511 * All devices move the contents of the data bus into the high
512 * order byte of PC0.
513 */
514 m_pc0 = (m_pc0 & 0x00ff) | (m_dbus << 8);
515 m_icount -= cL;
516 }
517
ROMC_15()518 void f8_cpu_device::ROMC_15()
519 {
520 /*
521 * All devices move the contents of the data bus into the high
522 * order byte of PC1.
523 */
524 m_pc1 = (m_pc1 & 0x00ff) | (m_dbus << 8);
525 m_icount -= cL;
526 }
527
ROMC_16()528 void f8_cpu_device::ROMC_16()
529 {
530 /*
531 * All devices move the contents of the data bus into the high
532 * order byte of DC0.
533 */
534 m_dc0 = (m_dc0 & 0x00ff) | (m_dbus << 8);
535 m_icount -= cL;
536 }
537
ROMC_17()538 void f8_cpu_device::ROMC_17()
539 {
540 /*
541 * All devices move the contents of the data bus into the low
542 * order byte of PC0.
543 */
544 m_pc0 = (m_pc0 & 0xff00) | m_dbus;
545 m_icount -= cL;
546 }
547
ROMC_18()548 void f8_cpu_device::ROMC_18()
549 {
550 /*
551 * All devices move the contents of the data bus into the low
552 * order byte of PC1.
553 */
554 m_pc1 = (m_pc1 & 0xff00) | m_dbus;
555 m_icount -= cL;
556 }
557
ROMC_19()558 void f8_cpu_device::ROMC_19()
559 {
560 /*
561 * All devices move the contents of the data bus into the low
562 * order byte of DC0.
563 */
564 m_dc0 = (m_dc0 & 0xff00) | m_dbus;
565 m_icount -= cL;
566 }
567
ROMC_1A()568 void f8_cpu_device::ROMC_1A()
569 {
570 /*
571 * During the prior cycle, an I/O port timer or interrupt control
572 * register was addressed; the device containing the addressed port
573 * must place the contents of the data bus into the address port.
574 */
575 m_ios.write_byte(m_io, m_dbus);
576 m_icount -= cL;
577 }
578
ROMC_1B()579 void f8_cpu_device::ROMC_1B()
580 {
581 /*
582 * During the prior cycle, the data bus specified the address of an
583 * I/O port. The device containing the addressed I/O port must place
584 * the contents of the I/O port on the data bus. (Note that the
585 * contents of timer and interrupt control registers cannot be read
586 * back onto the data bus).
587 */
588 m_dbus = m_ios.read_byte(m_io);
589 m_icount -= cL;
590 }
591
ROMC_1C(int insttim)592 void f8_cpu_device::ROMC_1C(int insttim)
593 {
594 /*
595 * None.
596 */
597 m_icount -= insttim;
598 }
599
ROMC_1D()600 void f8_cpu_device::ROMC_1D()
601 {
602 /*
603 * Devices with DC0 and DC1 registers must switch registers.
604 * Devices without a DC1 register perform no operation.
605 */
606 u16 tmp = m_dc0;
607 m_dc0 = m_dc1;
608 m_dc1 = tmp;
609 m_icount -= cS;
610 }
611
ROMC_1E()612 void f8_cpu_device::ROMC_1E()
613 {
614 /*
615 * The devices whose address space includes the contents of PC0
616 * must place the low order byte of PC0 onto the data bus.
617 */
618 m_dbus = m_pc0 & 0xff;
619 m_icount -= cL;
620 }
621
ROMC_1F()622 void f8_cpu_device::ROMC_1F()
623 {
624 /*
625 * The devices whose address space includes the contents of PC0
626 * must place the high order byte of PC0 onto the data bus.
627 */
628 m_dbus = (m_pc0 >> 8) & 0xff;
629 m_icount -= cL;
630 }
631
632 /***********************************
633 * illegal opcodes
634 ***********************************/
illegal()635 void f8_cpu_device::illegal()
636 {
637 logerror("f8 illegal opcode at 0x%04x: %02x\n", m_pc0, m_dbus);
638 }
639
640 /***************************************************
641 * O Z C S 0000 0000
642 * - - - - LR A,KU
643 ***************************************************/
f8_lr_a_ku()644 void f8_cpu_device::f8_lr_a_ku()
645 {
646 m_a = m_r.read_byte(12);
647 }
648
649 /***************************************************
650 * O Z C S 0000 0001
651 * - - - - LR A,KL
652 ***************************************************/
f8_lr_a_kl()653 void f8_cpu_device::f8_lr_a_kl()
654 {
655 m_a = m_r.read_byte(13);
656 }
657
658 /***************************************************
659 * O Z C S 0000 0010
660 * - - - - LR A,QU
661 ***************************************************/
f8_lr_a_qu()662 void f8_cpu_device::f8_lr_a_qu()
663 {
664 m_a = m_r.read_byte(14);
665 }
666
667 /***************************************************
668 * O Z C S 0000 0011
669 * - - - - LR A,QL
670 ***************************************************/
f8_lr_a_ql()671 void f8_cpu_device::f8_lr_a_ql()
672 {
673 m_a = m_r.read_byte(15);
674 }
675
676 /***************************************************
677 * O Z C S 0000 0100
678 * - - - - LR KU,A
679 ***************************************************/
f8_lr_ku_a()680 void f8_cpu_device::f8_lr_ku_a()
681 {
682 m_r.write_byte(12, m_a);
683 }
684
685 /***************************************************
686 * O Z C S 0000 0101
687 * - - - - LR KL,A
688 ***************************************************/
f8_lr_kl_a()689 void f8_cpu_device::f8_lr_kl_a()
690 {
691 m_r.write_byte(13, m_a);
692 }
693
694 /***************************************************
695 * O Z C S 0000 0110
696 * - - - - LR QU,A
697 ***************************************************/
f8_lr_qu_a()698 void f8_cpu_device::f8_lr_qu_a()
699 {
700 m_r.write_byte(14, m_a);
701 }
702
703 /***************************************************
704 * O Z C S 0000 0111
705 * - - - - LR QL,A
706 ***************************************************/
f8_lr_ql_a()707 void f8_cpu_device::f8_lr_ql_a()
708 {
709 m_r.write_byte(15, m_a);
710 }
711
712 /***************************************************
713 * O Z C S 0000 1000
714 * - - - - LR K,P
715 ***************************************************/
f8_lr_k_p()716 void f8_cpu_device::f8_lr_k_p()
717 {
718 ROMC_07();
719 m_r.write_byte(12, m_dbus);
720 ROMC_0B();
721 m_r.write_byte(13, m_dbus);
722 }
723
724 /***************************************************
725 * O Z C S 0000 1001
726 * - - - - LR P,K
727 ***************************************************/
f8_lr_p_k()728 void f8_cpu_device::f8_lr_p_k()
729 {
730 m_dbus = m_r.read_byte(12);
731 ROMC_15();
732 m_dbus = m_r.read_byte(13);
733 ROMC_18();
734 }
735
736 /***************************************************
737 * O Z C S 0000 1010
738 * - - - - LR A,IS
739 ***************************************************/
f8_lr_a_is()740 void f8_cpu_device::f8_lr_a_is()
741 {
742 m_a = m_is;
743 }
744
745 /***************************************************
746 * O Z C S 0000 1011
747 * - - - - LR IS,A
748 ***************************************************/
f8_lr_is_a()749 void f8_cpu_device::f8_lr_is_a()
750 {
751 m_is = m_a & 0x3f;
752 }
753
754 /***************************************************
755 * O Z C S 0000 1100
756 * - - - - PK
757 ***************************************************/
f8_pk()758 void f8_cpu_device::f8_pk()
759 {
760 m_dbus = m_r.read_byte(13);
761 ROMC_12();
762 m_dbus = m_r.read_byte(12);
763 ROMC_14();
764 }
765
766 /***************************************************
767 * O Z C S 0000 1101
768 * - - - - LR P0,Q
769 ***************************************************/
f8_lr_p0_q()770 void f8_cpu_device::f8_lr_p0_q()
771 {
772 m_dbus = m_r.read_byte(15);
773 ROMC_17();
774 m_dbus = m_r.read_byte(14);
775 ROMC_14();
776 }
777
778 /***************************************************
779 * O Z C S 0000 1110
780 * - - - - LR Q,DC
781 ***************************************************/
f8_lr_q_dc()782 void f8_cpu_device::f8_lr_q_dc()
783 {
784 ROMC_06();
785 m_r.write_byte(14, m_dbus);
786 ROMC_09();
787 m_r.write_byte(15, m_dbus);
788 }
789
790 /***************************************************
791 * O Z C S 0000 1111
792 * - - - - LR DC,Q
793 ***************************************************/
f8_lr_dc_q()794 void f8_cpu_device::f8_lr_dc_q()
795 {
796 m_dbus = m_r.read_byte(14);
797 ROMC_16();
798 m_dbus = m_r.read_byte(15);
799 ROMC_19();
800 }
801
802 /***************************************************
803 * O Z C S 0001 0000
804 * - - - - LR DC,H
805 ***************************************************/
f8_lr_dc_h()806 void f8_cpu_device::f8_lr_dc_h()
807 {
808 m_dbus = m_r.read_byte(10);
809 ROMC_16();
810 m_dbus = m_r.read_byte(11);
811 ROMC_19();
812 }
813
814 /***************************************************
815 * O Z C S 0001 0001
816 * - - - - LR H,DC
817 ***************************************************/
f8_lr_h_dc()818 void f8_cpu_device::f8_lr_h_dc()
819 {
820 ROMC_06();
821 m_r.write_byte(10, m_dbus);
822 ROMC_09();
823 m_r.write_byte(11, m_dbus);
824 }
825
826 /***************************************************
827 * O Z C S 0001 0010
828 * 0 x 0 1 SR 1
829 ***************************************************/
f8_sr_1()830 void f8_cpu_device::f8_sr_1()
831 {
832 m_a >>= 1;
833 CLR_OZCS();
834 SET_SZ(m_a);
835 }
836
837 /***************************************************
838 * O Z C S 0001 0011
839 * 0 x 0 x SL 1
840 ***************************************************/
f8_sl_1()841 void f8_cpu_device::f8_sl_1()
842 {
843 m_a <<= 1;
844 CLR_OZCS();
845 SET_SZ(m_a);
846 }
847
848 /***************************************************
849 * O Z C S 0001 0100
850 * 0 x 0 1 SR 4
851 ***************************************************/
f8_sr_4()852 void f8_cpu_device::f8_sr_4()
853 {
854 m_a >>= 4;
855 CLR_OZCS();
856 SET_SZ(m_a);
857 }
858
859 /***************************************************
860 * O Z C S 0001 0101
861 * 0 x 0 x SL 4
862 ***************************************************/
f8_sl_4()863 void f8_cpu_device::f8_sl_4()
864 {
865 m_a <<= 4;
866 CLR_OZCS();
867 SET_SZ(m_a);
868 }
869
870 /***************************************************
871 * O Z C S 0001 0110
872 * - - - - LM
873 ***************************************************/
f8_lm()874 void f8_cpu_device::f8_lm()
875 {
876 ROMC_02();
877 m_a = m_dbus;
878 }
879
880 /***************************************************
881 * O Z C S 0001 0111
882 * - - - - ST
883 ***************************************************/
f8_st()884 void f8_cpu_device::f8_st()
885 {
886 m_dbus = m_a;
887 ROMC_05();
888 }
889
890 /***************************************************
891 * O Z C S 0001 1000
892 * 0 x 0 x COM
893 ***************************************************/
f8_com()894 void f8_cpu_device::f8_com()
895 {
896 m_a = ~m_a;
897 CLR_OZCS();
898 SET_SZ(m_a);
899 }
900
901 /***************************************************
902 * O Z C S 0001 1001
903 * x x x x LNK
904 ***************************************************/
f8_lnk()905 void f8_cpu_device::f8_lnk()
906 {
907 bool c = (m_w & C) != 0;
908 CLR_OZCS();
909 if (c)
910 m_a = do_add(m_a,1);
911 SET_SZ(m_a);
912 }
913
914 /***************************************************
915 * O Z C S 0001 1010
916 * DI
917 ***************************************************/
f8_di()918 void f8_cpu_device::f8_di()
919 {
920 ROMC_1C(cS);
921 m_w &= ~I;
922 }
923
924 /***************************************************
925 * O Z C S 0001 1011
926 * EI
927 ***************************************************/
f8_ei()928 void f8_cpu_device::f8_ei()
929 {
930 ROMC_1C(cS);
931 m_w |= I;
932 }
933
934 /***************************************************
935 * O Z C S 0001 1100
936 * POP
937 ***************************************************/
f8_pop()938 void f8_cpu_device::f8_pop()
939 {
940 ROMC_04();
941 }
942
943 /***************************************************
944 * O Z C S 0001 1101
945 * x x x x LR W,J
946 ***************************************************/
f8_lr_w_j()947 void f8_cpu_device::f8_lr_w_j()
948 {
949 ROMC_1C(cS);
950 m_w = m_r.read_byte(9) & 0x1f;
951 }
952
953 /***************************************************
954 * O Z C S 0001 1110
955 * - - - - LR J,W
956 ***************************************************/
f8_lr_j_w()957 void f8_cpu_device::f8_lr_j_w()
958 {
959 m_r.write_byte(9, m_w);
960 }
961
962 /***************************************************
963 * O Z C S 0001 1111
964 * x x x x INC
965 ***************************************************/
f8_inc()966 void f8_cpu_device::f8_inc()
967 {
968 CLR_OZCS();
969 m_a = do_add(m_a,1);
970 SET_SZ(m_a);
971 }
972
973 /***************************************************
974 * O Z C S 0010 0000 aaaa aaaa
975 * - - - - LI aa
976 ***************************************************/
f8_li()977 void f8_cpu_device::f8_li()
978 {
979 ROMC_03(cL);
980 m_a = m_dbus;
981 }
982
983 /***************************************************
984 * O Z C S 0010 0001 aaaa aaaa
985 * 0 x 0 x NI aa
986 ***************************************************/
f8_ni()987 void f8_cpu_device::f8_ni()
988 {
989 ROMC_03(cL);
990 CLR_OZCS();
991 m_a &= m_dbus;
992 SET_SZ(m_a);
993 }
994
995 /***************************************************
996 * O Z C S 0010 0010 aaaa aaaa
997 * 0 x 0 x OI aa
998 ***************************************************/
f8_oi()999 void f8_cpu_device::f8_oi()
1000 {
1001 ROMC_03(cL);
1002 CLR_OZCS();
1003 m_a |= m_dbus;
1004 SET_SZ(m_a);
1005 }
1006
1007 /***************************************************
1008 * O Z C S 0010 0011 aaaa aaaa
1009 * 0 x 0 x XI aa
1010 ***************************************************/
f8_xi()1011 void f8_cpu_device::f8_xi()
1012 {
1013 ROMC_03(cL);
1014 CLR_OZCS();
1015 m_a ^= m_dbus;
1016 SET_SZ(m_a);
1017 }
1018
1019 /***************************************************
1020 * O Z C S 0010 0100 aaaa aaaa
1021 * x x x x AI aa
1022 ***************************************************/
f8_ai()1023 void f8_cpu_device::f8_ai()
1024 {
1025 ROMC_03(cL);
1026 CLR_OZCS();
1027 m_a = do_add(m_a,m_dbus);
1028 SET_SZ(m_a);
1029 }
1030
1031 /***************************************************
1032 * O Z C S 0010 0101 aaaa aaaa
1033 * x x x x CI aa
1034 ***************************************************/
f8_ci()1035 void f8_cpu_device::f8_ci()
1036 {
1037 ROMC_03(cL);
1038 CLR_OZCS();
1039 SET_SZ(do_add(~m_a,m_dbus,1));
1040 }
1041
1042 /***************************************************
1043 * O Z C S 0010 0110 aaaa aaaa
1044 * 0 x 0 x IN aa
1045 ***************************************************/
f8_in()1046 void f8_cpu_device::f8_in()
1047 {
1048 ROMC_03(cL);
1049 CLR_OZCS();
1050 ROMC_1B();
1051 m_a = m_dbus;
1052 SET_SZ(m_a);
1053 }
1054
1055 /***************************************************
1056 * O Z C S 0010 0111 aaaa aaaa
1057 * - - - - OUT aa
1058 ***************************************************/
f8_out()1059 void f8_cpu_device::f8_out()
1060 {
1061 ROMC_03(cL);
1062 m_dbus = m_a;
1063 ROMC_1A();
1064 }
1065
1066 /***************************************************
1067 * O Z C S 0010 1000 iiii iiii jjjj jjjj
1068 * - - - - PI iijj
1069 ***************************************************/
f8_pi()1070 void f8_cpu_device::f8_pi()
1071 {
1072 ROMC_03(cL);
1073 m_a = m_dbus;
1074 ROMC_0D();
1075 ROMC_0C();
1076 m_dbus = m_a;
1077 ROMC_14();
1078 }
1079
1080 /***************************************************
1081 * O Z C S 0010 1001 iiii iiii jjjj jjjj
1082 * - - - - JMP iijj
1083 ***************************************************/
f8_jmp()1084 void f8_cpu_device::f8_jmp()
1085 {
1086 ROMC_03(cL);
1087 m_a = m_dbus;
1088 ROMC_0C();
1089 m_dbus = m_a;
1090 ROMC_14();
1091 }
1092
1093 /***************************************************
1094 * O Z C S 0010 1010 iiii iiii jjjj jjjj
1095 * - - - - DCI iijj
1096 ***************************************************/
f8_dci()1097 void f8_cpu_device::f8_dci()
1098 {
1099 ROMC_11();
1100 ROMC_03(cS);
1101 ROMC_0E();
1102 ROMC_03(cS);
1103 }
1104
1105 /***************************************************
1106 * O Z C S 0010 1011
1107 * - - - - NOP
1108 ***************************************************/
f8_nop()1109 void f8_cpu_device::f8_nop()
1110 {
1111 }
1112
1113 /***************************************************
1114 * O Z C S 0010 1100
1115 * - - - - XDC
1116 ***************************************************/
f8_xdc()1117 void f8_cpu_device::f8_xdc()
1118 {
1119 ROMC_1D();
1120 }
1121
1122 /***************************************************
1123 * O Z C S 0011 rrrr
1124 * x x x x DS r
1125 ***************************************************/
f8_ds_r(int r)1126 void f8_cpu_device::f8_ds_r(int r)
1127 {
1128 CLR_OZCS();
1129 int d = do_add(m_r.read_byte(r), 0xff);
1130 m_r.write_byte(r, d);
1131 SET_SZ(d);
1132 }
1133
1134 /***************************************************
1135 * O Z C S 0011 1100
1136 * x x x x DS ISAR
1137 ***************************************************/
f8_ds_isar()1138 void f8_cpu_device::f8_ds_isar()
1139 {
1140 CLR_OZCS();
1141 int d = do_add(m_r.read_byte(m_is), 0xff);
1142 m_r.write_byte(m_is, d);
1143 SET_SZ(d);
1144 }
1145
1146 /***************************************************
1147 * O Z C S 0011 1101
1148 * x x x x DS ISAR++
1149 ***************************************************/
f8_ds_isar_i()1150 void f8_cpu_device::f8_ds_isar_i()
1151 {
1152 CLR_OZCS();
1153 int d = do_add(m_r.read_byte(m_is), 0xff);
1154 m_r.write_byte(m_is, d);
1155 SET_SZ(d);
1156 m_is = (m_is & 0x38) | ((m_is + 1) & 0x07);
1157 }
1158
1159 /***************************************************
1160 * O Z C S 0011 1110
1161 * x x x x DS ISAR--
1162 ***************************************************/
f8_ds_isar_d()1163 void f8_cpu_device::f8_ds_isar_d()
1164 {
1165 CLR_OZCS();
1166 int d = do_add(m_r.read_byte(m_is), 0xff);
1167 m_r.write_byte(m_is, d);
1168 SET_SZ(d);
1169 m_is = (m_is & 0x38) | ((m_is - 1) & 0x07);
1170 }
1171
1172 /***************************************************
1173 * O Z C S 0100 rrrr
1174 * - - - - LR A,r
1175 ***************************************************/
f8_lr_a_r(int r)1176 void f8_cpu_device::f8_lr_a_r(int r)
1177 {
1178 m_a = m_r.read_byte(r);
1179 }
1180
1181 /***************************************************
1182 * O Z C S 0100 1100
1183 * - - - - LR A,ISAR
1184 ***************************************************/
f8_lr_a_isar()1185 void f8_cpu_device::f8_lr_a_isar()
1186 {
1187 m_a = m_r.read_byte(m_is);
1188 }
1189
1190 /***************************************************
1191 * O Z C S 0100 1101
1192 * - - - - LR A,ISAR++
1193 ***************************************************/
f8_lr_a_isar_i()1194 void f8_cpu_device::f8_lr_a_isar_i()
1195 {
1196 m_a = m_r.read_byte(m_is);
1197 m_is = (m_is & 0x38) | ((m_is + 1) & 0x07);
1198 }
1199
1200 /***************************************************
1201 * O Z C S 0100 1110
1202 * - - - - LR A,ISAR--
1203 ***************************************************/
f8_lr_a_isar_d()1204 void f8_cpu_device::f8_lr_a_isar_d()
1205 {
1206 m_a = m_r.read_byte(m_is);
1207 m_is = (m_is & 0x38) | ((m_is - 1) & 0x07);
1208 }
1209
1210 /***************************************************
1211 * O Z C S 0101 rrrr
1212 * - - - - LR r,A
1213 ***************************************************/
f8_lr_r_a(int r)1214 void f8_cpu_device::f8_lr_r_a(int r)
1215 {
1216 m_r.write_byte(r, m_a);
1217 }
1218
1219 /***************************************************
1220 * O Z C S 0101 1100
1221 * - - - - LR ISAR,A
1222 ***************************************************/
f8_lr_isar_a()1223 void f8_cpu_device::f8_lr_isar_a()
1224 {
1225 m_r.write_byte(m_is, m_a);
1226 }
1227
1228 /***************************************************
1229 * O Z C S 0101 1101
1230 * - - - - LR ISAR++,A
1231 ***************************************************/
f8_lr_isar_i_a()1232 void f8_cpu_device::f8_lr_isar_i_a()
1233 {
1234 m_r.write_byte(m_is, m_a);
1235 m_is = (m_is & 0x38) | ((m_is + 1) & 0x07);
1236 }
1237
1238 /***************************************************
1239 * O Z C S 0101 1110
1240 * - - - - LR ISAR--,A
1241 ***************************************************/
f8_lr_isar_d_a()1242 void f8_cpu_device::f8_lr_isar_d_a()
1243 {
1244 m_r.write_byte(m_is, m_a);
1245 m_is = (m_is & 0x38) | ((m_is - 1) & 0x07);
1246 }
1247
1248 /***************************************************
1249 * O Z C S 0110 0eee
1250 * - - - - LISU e
1251 ***************************************************/
f8_lisu(int e)1252 void f8_cpu_device::f8_lisu(int e)
1253 {
1254 m_is = (m_is & 0x07) | e;
1255 }
1256
1257 /***************************************************
1258 * O Z C S 0110 1eee
1259 * - - - - LISL e
1260 ***************************************************/
f8_lisl(int e)1261 void f8_cpu_device::f8_lisl(int e)
1262 {
1263 m_is = (m_is & 0x38) | e;
1264 }
1265
1266 /***************************************************
1267 * O Z C S 0111 iiii
1268 * - - - - LIS i
1269 ***************************************************/
f8_lis(int i)1270 void f8_cpu_device::f8_lis(int i)
1271 {
1272 m_a = i;
1273 }
1274
1275 /***************************************************
1276 * O Z C S 1000 0eee aaaa aaaa
1277 * BT e,aa
1278 ***************************************************/
f8_bt(int e)1279 void f8_cpu_device::f8_bt(int e)
1280 {
1281 ROMC_1C(cS);
1282 if (m_w & e)
1283 ROMC_01(); // take the relative branch
1284 else
1285 ROMC_03(cS); // just read the argument on the data bus
1286 }
1287
1288 /***************************************************
1289 * O Z C S 1000 1000
1290 * x x x x AM
1291 ***************************************************/
f8_am()1292 void f8_cpu_device::f8_am()
1293 {
1294 ROMC_02();
1295 CLR_OZCS();
1296 m_a = do_add(m_a, m_dbus);
1297 SET_SZ(m_a);
1298 }
1299
1300 /***************************************************
1301 * O Z C S 1000 1001
1302 * x x x x AMD
1303 ***************************************************/
f8_amd()1304 void f8_cpu_device::f8_amd()
1305 {
1306 ROMC_02();
1307 m_a = do_add_decimal(m_a, m_dbus);
1308 }
1309
1310 /***************************************************
1311 * O Z C S 1000 1010
1312 * 0 x 0 x NM
1313 ***************************************************/
f8_nm()1314 void f8_cpu_device::f8_nm()
1315 {
1316 ROMC_02();
1317 CLR_OZCS();
1318 m_a &= m_dbus;
1319 SET_SZ(m_a);
1320 }
1321
1322 /***************************************************
1323 * O Z C S 1000 1011
1324 * 0 x 0 x OM
1325 ***************************************************/
f8_om()1326 void f8_cpu_device::f8_om()
1327 {
1328 ROMC_02();
1329 CLR_OZCS();
1330 m_a |= m_dbus;
1331 SET_SZ(m_a);
1332 }
1333
1334 /***************************************************
1335 * O Z C S 1000 1100
1336 * 0 x 0 x XM
1337 ***************************************************/
f8_xm()1338 void f8_cpu_device::f8_xm()
1339 {
1340 ROMC_02();
1341 CLR_OZCS();
1342 m_a ^= m_dbus;
1343 SET_SZ(m_a);
1344 }
1345
1346 /***************************************************
1347 * O Z C S 1000 1101
1348 * x x x x CM
1349 ***************************************************/
f8_cm()1350 void f8_cpu_device::f8_cm()
1351 {
1352 ROMC_02();
1353 CLR_OZCS();
1354 SET_SZ(do_add(~m_a,m_dbus,1));
1355 }
1356
1357 /***************************************************
1358 * O Z C S 1000 1110
1359 * - - - - ADC
1360 ***************************************************/
f8_adc()1361 void f8_cpu_device::f8_adc()
1362 {
1363 m_dbus = m_a;
1364 ROMC_0A(); // add data bus value to DC0
1365 }
1366
1367 /***************************************************
1368 * O Z C S 1000 1111
1369 * - - - - BR7
1370 ***************************************************/
f8_br7()1371 void f8_cpu_device::f8_br7()
1372 {
1373 if ((m_is & 7) == 7)
1374 ROMC_03(cS); // just read the argument on the data bus
1375 else
1376 ROMC_01(); // take the relative branch
1377 }
1378
1379 /***************************************************
1380 * O Z C S 1001 tttt aaaa aaaa
1381 * - - - - BF t,aa
1382 ***************************************************/
f8_bf(int t)1383 void f8_cpu_device::f8_bf(int t)
1384 {
1385 ROMC_1C(cS);
1386 if (m_w & t)
1387 ROMC_03(cS); // just read the argument on the data bus
1388 else
1389 ROMC_01(); // take the relative branch
1390 }
1391
1392 /***************************************************
1393 * O Z C S 1010 000n
1394 * 0 x 0 x INS n (n = 0-1)
1395 ***************************************************/
f8_ins_0(int n)1396 void f8_cpu_device::f8_ins_0(int n)
1397 {
1398 ROMC_1C(cS);
1399 CLR_OZCS();
1400 m_a = m_ios.read_byte(n);
1401 SET_SZ(m_a);
1402 }
1403
1404 /***************************************************
1405 * O Z C S 1010 nnnn
1406 * 0 x 0 x INS n (n = 4-F)
1407 ***************************************************/
f8_ins_1(int n)1408 void f8_cpu_device::f8_ins_1(int n)
1409 {
1410 ROMC_1C(cL);
1411 m_io = n;
1412 ROMC_1B();
1413 CLR_OZCS();
1414 m_a = m_dbus;
1415 SET_SZ(m_a);
1416 }
1417
1418 /***************************************************
1419 * O Z C S 1011 000n
1420 * - - - - OUTS n (n = 0-1)
1421 ***************************************************/
f8_outs_0(int n)1422 void f8_cpu_device::f8_outs_0(int n)
1423 {
1424 ROMC_1C(cS);
1425 m_ios.write_byte(n, m_a);
1426 }
1427
1428 /***************************************************
1429 * O Z C S 1011 nnnn
1430 * - - - - OUTS n (n = 4-F)
1431 ***************************************************/
f8_outs_1(int n)1432 void f8_cpu_device::f8_outs_1(int n)
1433 {
1434 ROMC_1C(cL);
1435 m_io = n;
1436 m_dbus = m_a;
1437 ROMC_1A();
1438 }
1439
1440 /***************************************************
1441 * O Z C S 1100 rrrr
1442 * x x x x AS r
1443 ***************************************************/
f8_as(int r)1444 void f8_cpu_device::f8_as(int r)
1445 {
1446 CLR_OZCS();
1447 m_a = do_add(m_a, m_r.read_byte(r));
1448 SET_SZ(m_a);
1449 }
1450
1451 /***************************************************
1452 * O Z C S 1100 1100
1453 * x x x x AS ISAR
1454 ***************************************************/
f8_as_isar()1455 void f8_cpu_device::f8_as_isar()
1456 {
1457 CLR_OZCS();
1458 m_a = do_add(m_a, m_r.read_byte(m_is));
1459 SET_SZ(m_a);
1460 }
1461
1462 /***************************************************
1463 * O Z C S 1100 1101
1464 * x x x x AS ISAR++
1465 ***************************************************/
f8_as_isar_i()1466 void f8_cpu_device::f8_as_isar_i()
1467 {
1468 CLR_OZCS();
1469 m_a = do_add(m_a, m_r.read_byte(m_is));
1470 SET_SZ(m_a);
1471 m_is = (m_is & 0x38) | ((m_is + 1) & 0x07);
1472 }
1473
1474 /***************************************************
1475 * O Z C S 1100 1110
1476 * x x x x AS ISAR--
1477 ***************************************************/
f8_as_isar_d()1478 void f8_cpu_device::f8_as_isar_d()
1479 {
1480 CLR_OZCS();
1481 m_a = do_add(m_a, m_r.read_byte(m_is));
1482 SET_SZ(m_a);
1483 m_is = (m_is & 0x38) | ((m_is - 1) & 0x07);
1484 }
1485
1486 /***************************************************
1487 * O Z C S 1101 rrrr
1488 * x x x x ASD r
1489 ***************************************************/
f8_asd(int r)1490 void f8_cpu_device::f8_asd(int r)
1491 {
1492 ROMC_1C(cS);
1493 m_a = do_add_decimal(m_a, m_r.read_byte(r));
1494 }
1495
1496 /***************************************************
1497 * O Z C S 1101 1100
1498 * x x x x ASD ISAR
1499 ***************************************************/
f8_asd_isar()1500 void f8_cpu_device::f8_asd_isar()
1501 {
1502 ROMC_1C(cS);
1503 m_a = do_add_decimal(m_a, m_r.read_byte(m_is));
1504 }
1505
1506 /***************************************************
1507 * O Z C S 1101 1101
1508 * x x x x ASD ISAR++
1509 ***************************************************/
f8_asd_isar_i()1510 void f8_cpu_device::f8_asd_isar_i()
1511 {
1512 ROMC_1C(cS);
1513 m_a = do_add_decimal(m_a, m_r.read_byte(m_is));
1514 m_is = (m_is & 0x38) | ((m_is + 1) & 0x07);
1515 }
1516
1517 /***************************************************
1518 * O Z C S 1101 1110
1519 * x x x x ASD ISAR--
1520 ***************************************************/
f8_asd_isar_d()1521 void f8_cpu_device::f8_asd_isar_d()
1522 {
1523 ROMC_1C(cS);
1524 m_a = do_add_decimal(m_a, m_r.read_byte(m_is));
1525 m_is = (m_is & 0x38) | ((m_is - 1) & 0x07);
1526 }
1527
1528 /***************************************************
1529 * O Z C S 1110 rrrr
1530 * 0 x 0 x XS r
1531 ***************************************************/
f8_xs(int r)1532 void f8_cpu_device::f8_xs(int r)
1533 {
1534 CLR_OZCS();
1535 m_a ^= m_r.read_byte(r);
1536 SET_SZ(m_a);
1537 }
1538
1539 /***************************************************
1540 * O Z C S 1110 1100
1541 * 0 x 0 x XS ISAR
1542 ***************************************************/
f8_xs_isar()1543 void f8_cpu_device::f8_xs_isar()
1544 {
1545 CLR_OZCS();
1546 m_a ^= m_r.read_byte(m_is);
1547 SET_SZ(m_a);
1548 }
1549
1550 /***************************************************
1551 * O Z C S 1110 1101
1552 * 0 x 0 x XS ISAR++
1553 ***************************************************/
f8_xs_isar_i()1554 void f8_cpu_device::f8_xs_isar_i()
1555 {
1556 CLR_OZCS();
1557 m_a ^= m_r.read_byte(m_is);
1558 SET_SZ(m_a);
1559 m_is = (m_is & 0x38) | ((m_is + 1) & 0x07);
1560 }
1561
1562 /***************************************************
1563 * O Z C S 1110 1110
1564 * 0 x 0 x XS ISAR--
1565 ***************************************************/
f8_xs_isar_d()1566 void f8_cpu_device::f8_xs_isar_d()
1567 {
1568 CLR_OZCS();
1569 m_a ^= m_r.read_byte(m_is);
1570 SET_SZ(m_a);
1571 m_is = (m_is & 0x38) | ((m_is - 1) & 0x07);
1572 }
1573
1574 /***************************************************
1575 * O Z C S 1111 rrrr
1576 * 0 x 0 x NS r
1577 ***************************************************/
f8_ns(int r)1578 void f8_cpu_device::f8_ns(int r)
1579 {
1580 CLR_OZCS();
1581 m_a &= m_r.read_byte(r);
1582 SET_SZ(m_a);
1583 }
1584
1585 /***************************************************
1586 * O Z C S 1111 1100
1587 * 0 x 0 x NS ISAR
1588 ***************************************************/
f8_ns_isar()1589 void f8_cpu_device::f8_ns_isar()
1590 {
1591 CLR_OZCS();
1592 m_a &= m_r.read_byte(m_is);
1593 SET_SZ(m_a);
1594 }
1595
1596 /***************************************************
1597 * O Z C S 1111 1101
1598 * 0 x 0 x NS ISAR++
1599 ***************************************************/
f8_ns_isar_i()1600 void f8_cpu_device::f8_ns_isar_i()
1601 {
1602 CLR_OZCS();
1603 m_a &= m_r.read_byte(m_is);
1604 SET_SZ(m_a);
1605 m_is = (m_is & 0x38) | ((m_is + 1) & 0x07);
1606 }
1607
1608 /***************************************************
1609 * O Z C S 1111 1110
1610 * 0 x 0 x NS ISAR--
1611 ***************************************************/
f8_ns_isar_d()1612 void f8_cpu_device::f8_ns_isar_d()
1613 {
1614 CLR_OZCS();
1615 m_a &= m_r.read_byte(m_is);
1616 SET_SZ(m_a);
1617 m_is = (m_is & 0x38) | ((m_is - 1) & 0x07);
1618 }
1619
1620
1621 /***************************************************
1622 * Execute cycles
1623 ***************************************************/
1624
execute_run()1625 void f8_cpu_device::execute_run()
1626 {
1627 do
1628 {
1629 u8 op = m_dbus;
1630
1631 m_debug_pc = (m_pc0 - 1) & 0xffff;
1632 debugger_instruction_hook(m_debug_pc);
1633
1634 switch (op)
1635 {
1636 case 0x00: f8_lr_a_ku(); break;
1637 case 0x01: f8_lr_a_kl(); break;
1638 case 0x02: f8_lr_a_qu(); break;
1639 case 0x03: f8_lr_a_ql(); break;
1640 case 0x04: f8_lr_ku_a(); break;
1641 case 0x05: f8_lr_kl_a(); break;
1642 case 0x06: f8_lr_qu_a(); break;
1643 case 0x07: f8_lr_ql_a(); break;
1644 case 0x08: f8_lr_k_p(); break;
1645 case 0x09: f8_lr_p_k(); break;
1646 case 0x0a: f8_lr_a_is(); break;
1647 case 0x0b: f8_lr_is_a(); break;
1648 case 0x0c: f8_pk(); break;
1649 case 0x0d: f8_lr_p0_q(); break;
1650 case 0x0e: f8_lr_q_dc(); break;
1651 case 0x0f: f8_lr_dc_q(); break;
1652
1653 case 0x10: f8_lr_dc_h(); break;
1654 case 0x11: f8_lr_h_dc(); break;
1655 case 0x12: f8_sr_1(); break;
1656 case 0x13: f8_sl_1(); break;
1657 case 0x14: f8_sr_4(); break;
1658 case 0x15: f8_sl_4(); break;
1659 case 0x16: f8_lm(); break;
1660 case 0x17: f8_st(); break;
1661 case 0x18: f8_com(); break;
1662 case 0x19: f8_lnk(); break;
1663 case 0x1a: f8_di(); break;
1664 case 0x1b: f8_ei(); break;
1665 case 0x1c: f8_pop(); break;
1666 case 0x1d: f8_lr_w_j(); break;
1667 case 0x1e: f8_lr_j_w(); break;
1668 case 0x1f: f8_inc(); break;
1669
1670 case 0x20: f8_li(); break;
1671 case 0x21: f8_ni(); break;
1672 case 0x22: f8_oi(); break;
1673 case 0x23: f8_xi(); break;
1674 case 0x24: f8_ai(); break;
1675 case 0x25: f8_ci(); break;
1676 case 0x26: f8_in(); break;
1677 case 0x27: f8_out(); break;
1678 case 0x28: f8_pi(); break;
1679 case 0x29: f8_jmp(); break;
1680 case 0x2a: f8_dci(); break;
1681 case 0x2b: f8_nop(); break;
1682 case 0x2c: f8_xdc(); break;
1683 case 0x2d: illegal(); break;
1684 case 0x2e: illegal(); break;
1685 case 0x2f: illegal(); break;
1686
1687 case 0x30: f8_ds_r(0); break;
1688 case 0x31: f8_ds_r(1); break;
1689 case 0x32: f8_ds_r(2); break;
1690 case 0x33: f8_ds_r(3); break;
1691 case 0x34: f8_ds_r(4); break;
1692 case 0x35: f8_ds_r(5); break;
1693 case 0x36: f8_ds_r(6); break;
1694 case 0x37: f8_ds_r(7); break;
1695 case 0x38: f8_ds_r(8); break;
1696 case 0x39: f8_ds_r(9); break;
1697 case 0x3a: f8_ds_r(10); break;
1698 case 0x3b: f8_ds_r(11); break;
1699 case 0x3c: f8_ds_isar(); break;
1700 case 0x3d: f8_ds_isar_i(); break;
1701 case 0x3e: f8_ds_isar_d(); break;
1702 case 0x3f: illegal(); break;
1703
1704 case 0x40: f8_lr_a_r(0); break;
1705 case 0x41: f8_lr_a_r(1); break;
1706 case 0x42: f8_lr_a_r(2); break;
1707 case 0x43: f8_lr_a_r(3); break;
1708 case 0x44: f8_lr_a_r(4); break;
1709 case 0x45: f8_lr_a_r(5); break;
1710 case 0x46: f8_lr_a_r(6); break;
1711 case 0x47: f8_lr_a_r(7); break;
1712 case 0x48: f8_lr_a_r(8); break;
1713 case 0x49: f8_lr_a_r(9); break;
1714 case 0x4a: f8_lr_a_r(10); break;
1715 case 0x4b: f8_lr_a_r(11); break;
1716 case 0x4c: f8_lr_a_isar(); break;
1717 case 0x4d: f8_lr_a_isar_i(); break;
1718 case 0x4e: f8_lr_a_isar_d(); break;
1719 case 0x4f: illegal(); break;
1720
1721 case 0x50: f8_lr_r_a(0); break;
1722 case 0x51: f8_lr_r_a(1); break;
1723 case 0x52: f8_lr_r_a(2); break;
1724 case 0x53: f8_lr_r_a(3); break;
1725 case 0x54: f8_lr_r_a(4); break;
1726 case 0x55: f8_lr_r_a(5); break;
1727 case 0x56: f8_lr_r_a(6); break;
1728 case 0x57: f8_lr_r_a(7); break;
1729 case 0x58: f8_lr_r_a(8); break;
1730 case 0x59: f8_lr_r_a(9); break;
1731 case 0x5a: f8_lr_r_a(10); break;
1732 case 0x5b: f8_lr_r_a(11); break;
1733 case 0x5c: f8_lr_isar_a(); break;
1734 case 0x5d: f8_lr_isar_i_a(); break;
1735 case 0x5e: f8_lr_isar_d_a(); break;
1736 case 0x5f: illegal(); break;
1737
1738 case 0x60: f8_lisu(0x00); break;
1739 case 0x61: f8_lisu(0x08); break;
1740 case 0x62: f8_lisu(0x10); break;
1741 case 0x63: f8_lisu(0x18); break;
1742 case 0x64: f8_lisu(0x20); break;
1743 case 0x65: f8_lisu(0x28); break;
1744 case 0x66: f8_lisu(0x30); break;
1745 case 0x67: f8_lisu(0x38); break;
1746 case 0x68: f8_lisl(0x00); break;
1747 case 0x69: f8_lisl(0x01); break;
1748 case 0x6a: f8_lisl(0x02); break;
1749 case 0x6b: f8_lisl(0x03); break;
1750 case 0x6c: f8_lisl(0x04); break;
1751 case 0x6d: f8_lisl(0x05); break;
1752 case 0x6e: f8_lisl(0x06); break;
1753 case 0x6f: f8_lisl(0x07); break;
1754
1755 case 0x70: f8_lis(0x0); break;
1756 case 0x71: f8_lis(0x1); break;
1757 case 0x72: f8_lis(0x2); break;
1758 case 0x73: f8_lis(0x3); break;
1759 case 0x74: f8_lis(0x4); break;
1760 case 0x75: f8_lis(0x5); break;
1761 case 0x76: f8_lis(0x6); break;
1762 case 0x77: f8_lis(0x7); break;
1763 case 0x78: f8_lis(0x8); break;
1764 case 0x79: f8_lis(0x9); break;
1765 case 0x7a: f8_lis(0xa); break;
1766 case 0x7b: f8_lis(0xb); break;
1767 case 0x7c: f8_lis(0xc); break;
1768 case 0x7d: f8_lis(0xd); break;
1769 case 0x7e: f8_lis(0xe); break;
1770 case 0x7f: f8_lis(0xf); break;
1771
1772 case 0x80: f8_bt(0); break;
1773 case 0x81: f8_bt(1); break;
1774 case 0x82: f8_bt(2); break;
1775 case 0x83: f8_bt(3); break;
1776 case 0x84: f8_bt(4); break;
1777 case 0x85: f8_bt(5); break;
1778 case 0x86: f8_bt(6); break;
1779 case 0x87: f8_bt(7); break;
1780 case 0x88: f8_am(); break;
1781 case 0x89: f8_amd(); break;
1782 case 0x8a: f8_nm(); break;
1783 case 0x8b: f8_om(); break;
1784 case 0x8c: f8_xm(); break;
1785 case 0x8d: f8_cm(); break;
1786 case 0x8e: f8_adc(); break;
1787 case 0x8f: f8_br7(); break;
1788
1789 case 0x90: f8_bf(0x0); break;
1790 case 0x91: f8_bf(0x1); break;
1791 case 0x92: f8_bf(0x2); break;
1792 case 0x93: f8_bf(0x3); break;
1793 case 0x94: f8_bf(0x4); break;
1794 case 0x95: f8_bf(0x5); break;
1795 case 0x96: f8_bf(0x6); break;
1796 case 0x97: f8_bf(0x7); break;
1797 case 0x98: f8_bf(0x8); break;
1798 case 0x99: f8_bf(0x9); break;
1799 case 0x9a: f8_bf(0xa); break;
1800 case 0x9b: f8_bf(0xb); break;
1801 case 0x9c: f8_bf(0xc); break;
1802 case 0x9d: f8_bf(0xd); break;
1803 case 0x9e: f8_bf(0xe); break;
1804 case 0x9f: f8_bf(0xf); break;
1805
1806 case 0xa0: f8_ins_0(0x0); break;
1807 case 0xa1: f8_ins_0(0x1); break;
1808 case 0xa2: illegal(); break;
1809 case 0xa3: illegal(); break;
1810 case 0xa4: f8_ins_1(0x4); break;
1811 case 0xa5: f8_ins_1(0x5); break;
1812 case 0xa6: f8_ins_1(0x6); break;
1813 case 0xa7: f8_ins_1(0x7); break;
1814 case 0xa8: f8_ins_1(0x8); break;
1815 case 0xa9: f8_ins_1(0x9); break;
1816 case 0xaa: f8_ins_1(0xa); break;
1817 case 0xab: f8_ins_1(0xb); break;
1818 case 0xac: f8_ins_1(0xc); break;
1819 case 0xad: f8_ins_1(0xd); break;
1820 case 0xae: f8_ins_1(0xe); break;
1821 case 0xaf: f8_ins_1(0xf); break;
1822
1823 case 0xb0: f8_outs_0(0x0); break;
1824 case 0xb1: f8_outs_0(0x1); break;
1825 case 0xb2: illegal(); break;
1826 case 0xb3: illegal(); break;
1827 case 0xb4: f8_outs_1(0x4); break;
1828 case 0xb5: f8_outs_1(0x5); break;
1829 case 0xb6: f8_outs_1(0x6); break;
1830 case 0xb7: f8_outs_1(0x7); break;
1831 case 0xb8: f8_outs_1(0x8); break;
1832 case 0xb9: f8_outs_1(0x9); break;
1833 case 0xba: f8_outs_1(0xa); break;
1834 case 0xbb: f8_outs_1(0xb); break;
1835 case 0xbc: f8_outs_1(0xc); break;
1836 case 0xbd: f8_outs_1(0xd); break;
1837 case 0xbe: f8_outs_1(0xe); break;
1838 case 0xbf: f8_outs_1(0xf); break;
1839
1840 case 0xc0: f8_as(0x0); break;
1841 case 0xc1: f8_as(0x1); break;
1842 case 0xc2: f8_as(0x2); break;
1843 case 0xc3: f8_as(0x3); break;
1844 case 0xc4: f8_as(0x4); break;
1845 case 0xc5: f8_as(0x5); break;
1846 case 0xc6: f8_as(0x6); break;
1847 case 0xc7: f8_as(0x7); break;
1848 case 0xc8: f8_as(0x8); break;
1849 case 0xc9: f8_as(0x9); break;
1850 case 0xca: f8_as(0xa); break;
1851 case 0xcb: f8_as(0xb); break;
1852 case 0xcc: f8_as_isar(); break;
1853 case 0xcd: f8_as_isar_i(); break;
1854 case 0xce: f8_as_isar_d(); break;
1855 case 0xcf: illegal(); break;
1856
1857 case 0xd0: f8_asd(0x0); break;
1858 case 0xd1: f8_asd(0x1); break;
1859 case 0xd2: f8_asd(0x2); break;
1860 case 0xd3: f8_asd(0x3); break;
1861 case 0xd4: f8_asd(0x4); break;
1862 case 0xd5: f8_asd(0x5); break;
1863 case 0xd6: f8_asd(0x6); break;
1864 case 0xd7: f8_asd(0x7); break;
1865 case 0xd8: f8_asd(0x8); break;
1866 case 0xd9: f8_asd(0x9); break;
1867 case 0xda: f8_asd(0xa); break;
1868 case 0xdb: f8_asd(0xb); break;
1869 case 0xdc: f8_asd_isar(); break;
1870 case 0xdd: f8_asd_isar_i(); break;
1871 case 0xde: f8_asd_isar_d(); break;
1872 case 0xdf: illegal(); break;
1873
1874 case 0xe0: f8_xs(0x0); break;
1875 case 0xe1: f8_xs(0x1); break;
1876 case 0xe2: f8_xs(0x2); break;
1877 case 0xe3: f8_xs(0x3); break;
1878 case 0xe4: f8_xs(0x4); break;
1879 case 0xe5: f8_xs(0x5); break;
1880 case 0xe6: f8_xs(0x6); break;
1881 case 0xe7: f8_xs(0x7); break;
1882 case 0xe8: f8_xs(0x8); break;
1883 case 0xe9: f8_xs(0x9); break;
1884 case 0xea: f8_xs(0xa); break;
1885 case 0xeb: f8_xs(0xb); break;
1886 case 0xec: f8_xs_isar(); break;
1887 case 0xed: f8_xs_isar_i(); break;
1888 case 0xee: f8_xs_isar_d(); break;
1889 case 0xef: illegal(); break;
1890
1891 case 0xf0: f8_ns(0x0); break;
1892 case 0xf1: f8_ns(0x1); break;
1893 case 0xf2: f8_ns(0x2); break;
1894 case 0xf3: f8_ns(0x3); break;
1895 case 0xf4: f8_ns(0x4); break;
1896 case 0xf5: f8_ns(0x5); break;
1897 case 0xf6: f8_ns(0x6); break;
1898 case 0xf7: f8_ns(0x7); break;
1899 case 0xf8: f8_ns(0x8); break;
1900 case 0xf9: f8_ns(0x9); break;
1901 case 0xfa: f8_ns(0xa); break;
1902 case 0xfb: f8_ns(0xb); break;
1903 case 0xfc: f8_ns_isar(); break;
1904 case 0xfd: f8_ns_isar_i(); break;
1905 case 0xfe: f8_ns_isar_d(); break;
1906 case 0xff: illegal(); break;
1907 }
1908 switch (op)
1909 {
1910 case 0x0c: case 0x1b: case 0x1c: case 0x1d:
1911 case 0x27: case 0x28: case 0x29:
1912 case 0xb4: case 0xb5: case 0xb6: case 0xb7:
1913 case 0xb8: case 0xb9: case 0xba: case 0xbb:
1914 case 0xbc: case 0xbd: case 0xbe: case 0xbf:
1915 // don't handle irq after privileged instruction
1916 ROMC_00(cS);
1917 break;
1918
1919 default:
1920 // 'freeze cycle' for handling interrupts
1921 if (m_w&I && m_irq_request)
1922 {
1923 ROMC_10();
1924 ROMC_1C(cL);
1925 ROMC_0F();
1926 ROMC_13();
1927 }
1928
1929 // fetch next instruction (DS is long cycle)
1930 if ((op >= 0x30) && (op <= 0x3f))
1931 ROMC_00(cL);
1932 else
1933 ROMC_00(cS);
1934
1935 break;
1936 }
1937 } while( m_icount > 0 );
1938 }
1939