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