Previous 199869 Revisions Next

r26677 Friday 20th December, 2013 at 21:18:51 UTC by Wilbert Pol
z8.c: Modernized cpu core.  [Wilbert Pol]
[src/emu/cpu/z8]z8.c z8.h z8ops.c

trunk/src/emu/cpu/z8/z8.c
r26676r26677
144144    MACROS
145145***************************************************************************/
146146
147#define P01M        cpustate->r[Z8_REGISTER_P01M]
148#define P2M         cpustate->r[Z8_REGISTER_P2M]
149#define P3M         cpustate->r[Z8_REGISTER_P3M]
150#define T0          cpustate->r[Z8_REGISTER_T0]
151#define T1          cpustate->r[Z8_REGISTER_T1]
152#define PRE0        cpustate->r[Z8_REGISTER_PRE0]
153#define PRE1        cpustate->r[Z8_REGISTER_PRE1]
147#define P01M        m_r[Z8_REGISTER_P01M]
148#define P2M         m_r[Z8_REGISTER_P2M]
149#define P3M         m_r[Z8_REGISTER_P3M]
150#define T0          m_r[Z8_REGISTER_T0]
151#define T1          m_r[Z8_REGISTER_T1]
152#define PRE0        m_r[Z8_REGISTER_PRE0]
153#define PRE1        m_r[Z8_REGISTER_PRE1]
154154
155
156const device_type Z8601 = &device_creator<z8601_device>;
157const device_type UB8830D = &device_creator<ub8830d_device>;
158const device_type Z8611 = &device_creator<z8611_device>;
159
160
155161/***************************************************************************
156    TYPE DEFINITIONS
162    ADDRESS MAPS
157163***************************************************************************/
158164
159struct z8_state
165static ADDRESS_MAP_START( program_2kb, AS_PROGRAM, 8, z8_device )
166    AM_RANGE(0x0000, 0x07ff) AM_ROM
167ADDRESS_MAP_END
168
169static ADDRESS_MAP_START( program_4kb, AS_PROGRAM, 8, z8_device )
170    AM_RANGE(0x0000, 0x0fff) AM_ROM
171ADDRESS_MAP_END
172
173
174z8_device::z8_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source, int size)
175   : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
176   , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0, ( size == 4 ) ? ADDRESS_MAP_NAME(program_4kb) : ADDRESS_MAP_NAME(program_2kb))
177   , m_data_config("data", ENDIANNESS_LITTLE, 8, 16, 0)
178   , m_io_config("io", ENDIANNESS_LITTLE, 8, 2, 0)
160179{
161   address_space *program;
162   direct_read_data *direct;
163   address_space *data;
164   address_space *io;
180}
165181
166   /* registers */
167   UINT16 pc;              /* program counter */
168   UINT8 r[256];           /* register file */
169   UINT8 input[4];         /* port input latches */
170   UINT8 output[4];        /* port output latches */
171   UINT8 t0;               /* timer 0 current count */
172   UINT8 t1;               /* timer 1 current count */
173182
174   /* fake registers */
175   UINT16 fake_sp;         /* fake stack pointer */
176   UINT8 fake_r[16];       /* fake working registers */
183z8601_device::z8601_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock)
184   : z8_device(mconfig, Z8601, "Z8601", _tag, _owner, _clock, "z8601", __FILE__, 2)
185{
186}
177187
178   /* interrupts */
179   int irq[6];             /* interrupts */
180188
181   /* execution logic */
182   int clock;              /* clock */
183   int icount;             /* instruction counter */
189ub8830d_device::ub8830d_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock)
190   : z8_device(mconfig, UB8830D, "UB8830D", _tag, _owner, _clock, "ub8830d", __FILE__, 2)
191{
192}
184193
185   /* timers */
186   emu_timer *t0_timer;
187   emu_timer *t1_timer;
188};
189194
195z8611_device::z8611_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock)
196   : z8_device(mconfig, Z8611, "Z8611", _tag, _owner, _clock, "z8611", __FILE__, 4)
197{
198}
199
200
201offs_t z8_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
202{
203   extern CPU_DISASSEMBLE( z8 );
204   return CPU_DISASSEMBLE_NAME(z8)(this, buffer, pc, oprom, opram, options);
205}
206
207
190208/***************************************************************************
191209    INLINE FUNCTIONS
192210***************************************************************************/
193211
194INLINE z8_state *get_safe_token(device_t *device)
212UINT8 z8_device::fetch()
195213{
196   assert(device != NULL);
197   assert((device->type() == Z8601) ||
198      (device->type() == UB8830D) ||
199      (device->type() == Z8611));
200   return (z8_state *)downcast<legacy_cpu_device *>(device)->token();
201}
214   UINT8 data = m_direct->read_decrypted_byte(m_pc);
202215
203INLINE UINT8 fetch(z8_state *cpustate)
204{
205   UINT8 data = cpustate->direct->read_decrypted_byte(cpustate->pc);
216   m_pc++;
206217
207   cpustate->pc++;
208
209218   return data;
210219}
211220
212INLINE UINT8 register_read(z8_state *cpustate, UINT8 offset)
221
222UINT8 z8_device::register_read(UINT8 offset)
213223{
214224   UINT8 data = 0xff;
215225   UINT8 mask = 0;
r26676r26677
219229   case Z8_REGISTER_P0:
220230      switch (P01M & Z8_P01M_P0L_MODE_MASK)
221231      {
222      case Z8_P01M_P0L_MODE_OUTPUT:   data = cpustate->output[offset] & 0x0f;     break;
232      case Z8_P01M_P0L_MODE_OUTPUT:   data = m_output[offset] & 0x0f;     break;
223233      case Z8_P01M_P0L_MODE_INPUT:    mask = 0x0f;                                break;
224234      default: /* A8...A11 */         data = 0x0f;                                break;
225235      }
226236
227237      switch (P01M & Z8_P01M_P0H_MODE_MASK)
228238      {
229      case Z8_P01M_P0H_MODE_OUTPUT:   data |= cpustate->output[offset] & 0xf0;    break;
239      case Z8_P01M_P0H_MODE_OUTPUT:   data |= m_output[offset] & 0xf0;    break;
230240      case Z8_P01M_P0H_MODE_INPUT:    mask |= 0xf0;                               break;
231241      default: /* A12...A15 */        data |= 0xf0;                               break;
232242      }
233243
234244      if (!(P3M & Z8_P3M_P0_STROBED))
235245      {
236         if (mask) cpustate->input[offset] = cpustate->io->read_byte(offset);
246         if (mask) m_input[offset] = m_io->read_byte(offset);
237247      }
238248
239      data |= cpustate->input[offset] & mask;
249      data |= m_input[offset] & mask;
240250      break;
241251
242252   case Z8_REGISTER_P1:
243253      switch (P01M & Z8_P01M_P1_MODE_MASK)
244254      {
245      case Z8_P01M_P1_MODE_OUTPUT:    data = cpustate->output[offset];            break;
255      case Z8_P01M_P1_MODE_OUTPUT:    data = m_output[offset];            break;
246256      case Z8_P01M_P1_MODE_INPUT:     mask = 0xff;                                break;
247257      default: /* AD0..AD7 */         data = 0xff;                                break;
248258      }
249259
250260      if ((P3M & Z8_P3M_P33_P34_MASK) != Z8_P3M_P33_P34_DAV1_RDY1)
251261      {
252         if (mask) cpustate->input[offset] = cpustate->io->read_byte(offset);
262         if (mask) m_input[offset] = m_io->read_byte(offset);
253263      }
254264
255      data |= cpustate->input[offset] & mask;
265      data |= m_input[offset] & mask;
256266      break;
257267
258268   case Z8_REGISTER_P2:
259      mask = cpustate->r[Z8_REGISTER_P2M];
269      mask = m_r[Z8_REGISTER_P2M];
260270
261271      if (!(P3M & Z8_P3M_P2_STROBED))
262272      {
263         if (mask) cpustate->input[offset] = cpustate->io->read_byte(offset);
273         if (mask) m_input[offset] = m_io->read_byte(offset);
264274      }
265275
266      data = (cpustate->input[offset] & mask) | (cpustate->output[offset] & ~mask);
276      data = (m_input[offset] & mask) | (m_output[offset] & ~mask);
267277      break;
268278
269279   case Z8_REGISTER_P3:
r26676r26677
273283         mask = 0x0f;
274284      }
275285
276      if (mask) cpustate->input[offset] = cpustate->io->read_byte(offset);
286      if (mask) m_input[offset] = m_io->read_byte(offset);
277287
278      data = (cpustate->input[offset] & mask) | (cpustate->output[offset] & ~mask);
288      data = (m_input[offset] & mask) | (m_output[offset] & ~mask);
279289      break;
280290
281291   case Z8_REGISTER_T0:
282      data = cpustate->t0;
292      data = m_t0;
283293      break;
284294
285295   case Z8_REGISTER_T1:
286      data = cpustate->t1;
296      data = m_t1;
287297      break;
288298
289299   case Z8_REGISTER_PRE1:
r26676r26677
296306      break;
297307
298308   default:
299      data = cpustate->r[offset];
309      data = m_r[offset];
300310      break;
301311   }
302312
303313   return data;
304314}
305315
306INLINE UINT16 register_pair_read(z8_state *cpustate, UINT8 offset)
316UINT16 z8_device::register_pair_read(UINT8 offset)
307317{
308   return (register_read(cpustate, offset) << 8) | register_read(cpustate, offset + 1);
318   return (register_read(offset) << 8) | register_read(offset + 1);
309319}
310320
311INLINE void register_write(z8_state *cpustate, UINT8 offset, UINT8 data)
321void z8_device::register_write(UINT8 offset, UINT8 data)
312322{
313323   UINT8 mask = 0;
314324
315325   switch (offset)
316326   {
317327   case Z8_REGISTER_P0:
318      cpustate->output[offset] = data;
328      m_output[offset] = data;
319329      if ((P01M & Z8_P01M_P0L_MODE_MASK) == Z8_P01M_P0L_MODE_OUTPUT) mask |= 0x0f;
320330      if ((P01M & Z8_P01M_P0H_MODE_MASK) == Z8_P01M_P0H_MODE_OUTPUT) mask |= 0xf0;
321      if (mask) cpustate->io->write_byte(offset, data & mask);
331      if (mask) m_io->write_byte(offset, data & mask);
322332      break;
323333
324334   case Z8_REGISTER_P1:
325      cpustate->output[offset] = data;
335      m_output[offset] = data;
326336      if ((P01M & Z8_P01M_P1_MODE_MASK) == Z8_P01M_P1_MODE_OUTPUT) mask = 0xff;
327      if (mask) cpustate->io->write_byte(offset, data & mask);
337      if (mask) m_io->write_byte(offset, data & mask);
328338      break;
329339
330340   case Z8_REGISTER_P2:
331      cpustate->output[offset] = data;
332      mask = cpustate->r[Z8_REGISTER_P2M] ^ 0xff;
333      if (mask) cpustate->io->write_byte(offset, data & mask);
341      m_output[offset] = data;
342      mask = m_r[Z8_REGISTER_P2M] ^ 0xff;
343      if (mask) m_io->write_byte(offset, data & mask);
334344      break;
335345
336346   case Z8_REGISTER_P3:
337      cpustate->output[offset] = data;
347      m_output[offset] = data;
338348
339349      // TODO: special port 3 modes
340350      if (!(P3M & 0x7c))
r26676r26677
342352         mask = 0xf0;
343353      }
344354
345      if (mask) cpustate->io->write_byte(offset, data & mask);
355      if (mask) m_io->write_byte(offset, data & mask);
346356      break;
347357
348358   case Z8_REGISTER_SIO:
r26676r26677
351361   case Z8_REGISTER_TMR:
352362      if (data & Z8_TMR_LOAD_T0)
353363      {
354         cpustate->t0 = T0;
355         cpustate->t0_timer->adjust(attotime::zero, 0, attotime::from_hz(cpustate->clock / 2 / 4 / ((PRE0 >> 2) + 1)));
364         m_t0 = T0;
365         m_t0_timer->adjust(attotime::zero, 0, attotime::from_hz(m_clock / 2 / 4 / ((PRE0 >> 2) + 1)));
356366      }
357367
358      cpustate->t0_timer->enable(data & Z8_TMR_ENABLE_T0);
368      m_t0_timer->enable(data & Z8_TMR_ENABLE_T0);
359369
360370      if (data & Z8_TMR_LOAD_T1)
361371      {
362         cpustate->t1 = T1;
363         cpustate->t1_timer->adjust(attotime::zero, 0, attotime::from_hz(cpustate->clock / 2 / 4 / ((PRE1 >> 2) + 1)));
372         m_t1 = T1;
373         m_t1_timer->adjust(attotime::zero, 0, attotime::from_hz(m_clock / 2 / 4 / ((PRE1 >> 2) + 1)));
364374      }
365375
366      cpustate->t1_timer->enable(data & Z8_TMR_ENABLE_T1);
376      m_t1_timer->enable(data & Z8_TMR_ENABLE_T1);
367377      break;
368378
369379   case Z8_REGISTER_P2M:
r26676r26677
391401      break;
392402   }
393403
394   cpustate->r[offset] = data;
404   m_r[offset] = data;
395405}
396406
397INLINE void register_pair_write(z8_state *cpustate, UINT8 offset, UINT16 data)
407void z8_device::register_pair_write(UINT8 offset, UINT16 data)
398408{
399   register_write(cpustate, offset, data >> 8);
400   register_write(cpustate, offset + 1, data & 0xff);
409   register_write(offset, data >> 8);
410   register_write(offset + 1, data & 0xff);
401411}
402412
403INLINE UINT8 get_working_register(z8_state *cpustate, int offset)
413UINT8 z8_device::get_working_register(int offset)
404414{
405   return (cpustate->r[Z8_REGISTER_RP] & 0xf0) | (offset & 0x0f);
415   return (m_r[Z8_REGISTER_RP] & 0xf0) | (offset & 0x0f);
406416}
407417
408INLINE UINT8 get_register(z8_state *cpustate, UINT8 offset)
418UINT8 z8_device::get_register(UINT8 offset)
409419{
410420   if ((offset & 0xf0) == 0xe0)
411      return get_working_register(cpustate, offset & 0x0f);
421      return get_working_register(offset & 0x0f);
412422   else
413423      return offset;
414424}
415425
416INLINE UINT8 get_intermediate_register(z8_state *cpustate, int offset)
426UINT8 z8_device::get_intermediate_register(int offset)
417427{
418   return register_read(cpustate, get_register(cpustate, offset));
428   return register_read(get_register(offset));
419429}
420430
421INLINE void stack_push_byte(z8_state *cpustate, UINT8 src)
431void z8_device::stack_push_byte(UINT8 src)
422432{
423   if (register_read(cpustate, Z8_REGISTER_P01M) & Z8_P01M_INTERNAL_STACK)
433   if (register_read(Z8_REGISTER_P01M) & Z8_P01M_INTERNAL_STACK)
424434   {
425435      /* SP <- SP - 1 */
426      UINT8 sp = register_read(cpustate, Z8_REGISTER_SPL) - 1;
427      register_write(cpustate, Z8_REGISTER_SPL, sp);
436      UINT8 sp = register_read(Z8_REGISTER_SPL) - 1;
437      register_write(Z8_REGISTER_SPL, sp);
428438
429439      /* @SP <- src */
430      register_write(cpustate, sp, src);
440      register_write(sp, src);
431441   }
432442   else
433443   {
434444      /* SP <- SP - 1 */
435      UINT16 sp = register_pair_read(cpustate, Z8_REGISTER_SPH) - 1;
436      register_pair_write(cpustate, Z8_REGISTER_SPH, sp);
445      UINT16 sp = register_pair_read(Z8_REGISTER_SPH) - 1;
446      register_pair_write(Z8_REGISTER_SPH, sp);
437447
438448      /* @SP <- src */
439      cpustate->data->write_byte(sp, src);
449      m_data->write_byte(sp, src);
440450   }
441451}
442452
443INLINE void stack_push_word(z8_state *cpustate, UINT16 src)
453void z8_device::stack_push_word(UINT16 src)
444454{
445   if (register_read(cpustate, Z8_REGISTER_P01M) & Z8_P01M_INTERNAL_STACK)
455   if (register_read(Z8_REGISTER_P01M) & Z8_P01M_INTERNAL_STACK)
446456   {
447457      /* SP <- SP - 2 */
448      UINT8 sp = register_read(cpustate, Z8_REGISTER_SPL) - 2;
449      register_write(cpustate, Z8_REGISTER_SPL, sp);
458      UINT8 sp = register_read(Z8_REGISTER_SPL) - 2;
459      register_write(Z8_REGISTER_SPL, sp);
450460
451461      /* @SP <- src */
452      register_pair_write(cpustate, sp, src);
462      register_pair_write(sp, src);
453463   }
454464   else
455465   {
456466      /* SP <- SP - 2 */
457      UINT16 sp = register_pair_read(cpustate, Z8_REGISTER_SPH) - 2;
458      register_pair_write(cpustate, Z8_REGISTER_SPH, sp);
467      UINT16 sp = register_pair_read(Z8_REGISTER_SPH) - 2;
468      register_pair_write(Z8_REGISTER_SPH, sp);
459469
460470      /* @SP <- src */
461      cpustate->data->write_word(sp, src);
471      m_data->write_word(sp, src);
462472   }
463473}
464474
465INLINE UINT8 stack_pop_byte(z8_state *cpustate)
475UINT8 z8_device::stack_pop_byte()
466476{
467   if (register_read(cpustate, Z8_REGISTER_P01M) & Z8_P01M_INTERNAL_STACK)
477   if (register_read(Z8_REGISTER_P01M) & Z8_P01M_INTERNAL_STACK)
468478   {
469479      /* SP <- SP + 1 */
470      UINT8 sp = register_read(cpustate, Z8_REGISTER_SPL) + 1;
471      register_write(cpustate, Z8_REGISTER_SPL, sp);
480      UINT8 sp = register_read(Z8_REGISTER_SPL) + 1;
481      register_write(Z8_REGISTER_SPL, sp);
472482
473483      /* @SP <- src */
474      return register_read(cpustate, sp);
484      return register_read(sp);
475485   }
476486   else
477487   {
478488      /* SP <- SP + 1 */
479      UINT16 sp = register_pair_read(cpustate, Z8_REGISTER_SPH) + 1;
480      register_pair_write(cpustate, Z8_REGISTER_SPH, sp);
489      UINT16 sp = register_pair_read(Z8_REGISTER_SPH) + 1;
490      register_pair_write(Z8_REGISTER_SPH, sp);
481491
482492      /* @SP <- src */
483      return cpustate->data->read_byte(sp);
493      return m_data->read_byte(sp);
484494   }
485495}
486496
487INLINE UINT16 stack_pop_word(z8_state *cpustate)
497UINT16 z8_device::stack_pop_word()
488498{
489   if (register_read(cpustate, Z8_REGISTER_P01M) & Z8_P01M_INTERNAL_STACK)
499   if (register_read(Z8_REGISTER_P01M) & Z8_P01M_INTERNAL_STACK)
490500   {
491501      /* SP <- SP + 2 */
492      UINT8 sp = register_read(cpustate, Z8_REGISTER_SPL) + 2;
493      register_write(cpustate, Z8_REGISTER_SPL, sp);
502      UINT8 sp = register_read(Z8_REGISTER_SPL) + 2;
503      register_write(Z8_REGISTER_SPL, sp);
494504
495505      /* @SP <- src */
496      return register_read(cpustate, sp);
506      return register_read(sp);
497507   }
498508   else
499509   {
500510      /* SP <- SP + 2 */
501      UINT16 sp = register_pair_read(cpustate, Z8_REGISTER_SPH) + 2;
502      register_pair_write(cpustate, Z8_REGISTER_SPH, sp);
511      UINT16 sp = register_pair_read(Z8_REGISTER_SPH) + 2;
512      register_pair_write(Z8_REGISTER_SPH, sp);
503513
504514      /* @SP <- src */
505      return cpustate->data->read_word(sp);
515      return m_data->read_word(sp);
506516   }
507517}
508518
509INLINE void set_flag(z8_state *cpustate, UINT8 flag, int state)
519void z8_device::set_flag(UINT8 flag, int state)
510520{
511521   if (state)
512      cpustate->r[Z8_REGISTER_FLAGS] |= flag;
522      m_r[Z8_REGISTER_FLAGS] |= flag;
513523   else
514      cpustate->r[Z8_REGISTER_FLAGS] &= ~flag;
524      m_r[Z8_REGISTER_FLAGS] &= ~flag;
515525}
516526
517#define set_flag_h(state)   set_flag(cpustate, Z8_FLAGS_H, state);
518#define set_flag_d(state)   set_flag(cpustate, Z8_FLAGS_D, state);
519#define set_flag_v(state)   set_flag(cpustate, Z8_FLAGS_V, state);
520#define set_flag_s(state)   set_flag(cpustate, Z8_FLAGS_S, state);
521#define set_flag_z(state)   set_flag(cpustate, Z8_FLAGS_Z, state);
522#define set_flag_c(state)   set_flag(cpustate, Z8_FLAGS_C, state);
527#define set_flag_h(state)   set_flag(Z8_FLAGS_H, state);
528#define set_flag_d(state)   set_flag(Z8_FLAGS_D, state);
529#define set_flag_v(state)   set_flag(Z8_FLAGS_V, state);
530#define set_flag_s(state)   set_flag(Z8_FLAGS_S, state);
531#define set_flag_z(state)   set_flag(Z8_FLAGS_Z, state);
532#define set_flag_c(state)   set_flag(Z8_FLAGS_C, state);
523533
524534/***************************************************************************
525535    OPCODE HANDLERS
526536***************************************************************************/
527537
528#define INSTRUCTION(mnemonic) INLINE void (mnemonic)(z8_state *cpustate, UINT8 opcode, int *cycles)
538#define INSTRUCTION(mnemonic) void z8_device::mnemonic(UINT8 opcode, int *cycles)
529539
530540INSTRUCTION( illegal )
531541{
532   logerror("Z8: PC = %04x, Illegal opcode = %02x\n", cpustate->pc - 1, opcode);
542   logerror("Z8: PC = %04x, Illegal opcode = %02x\n", m_pc - 1, opcode);
533543}
534544
535545#include "z8ops.c"
r26676r26677
538548    OPCODE TABLES
539549***************************************************************************/
540550
541typedef void (*z8_opcode_func) (z8_state *cpustate, UINT8 opcode, int *cycles);
542
543struct z8_opcode_map
551const z8_device::z8_opcode_map z8_device::Z8601_OPCODE_MAP[256] =
544552{
545   z8_opcode_func  function;
546   int             execution_cycles;
547   int             pipeline_cycles;
548};
553   { &z8_device::dec_R1, 6, 5 },   { &z8_device::dec_IR1, 6, 5 },  { &z8_device::add_r1_r2, 10, 5 },   { &z8_device::add_r1_Ir2, 10, 5 },
554   { &z8_device::add_R2_R1, 10, 5 },   { &z8_device::add_IR2_R1, 10, 5 },  { &z8_device::add_R1_IM, 10, 5 },   { &z8_device::add_IR1_IM, 10, 5 },
555   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
556   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::illegal, 0, 0 },
549557
550static const z8_opcode_map Z8601_OPCODE_MAP[] =
551{
552   { dec_R1, 6, 5 },   { dec_IR1, 6, 5 },  { add_r1_r2, 10, 5 },   { add_r1_Ir2, 10, 5 },  { add_R2_R1, 10, 5 },   { add_IR2_R1, 10, 5 },  { add_R1_IM, 10, 5 },   { add_IR1_IM, 10, 5 },
553   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { illegal, 0, 0 },
558   { &z8_device::rlc_R1, 6, 5 },   { &z8_device::rlc_IR1, 6, 5 },  { &z8_device::adc_r1_r2, 6, 5 },    { &z8_device::adc_r1_Ir2, 6, 5 },
559   { &z8_device::adc_R2_R1, 10, 5 },   { &z8_device::adc_IR2_R1, 10, 5 },  { &z8_device::adc_R1_IM, 10, 5 },   { &z8_device::adc_IR1_IM, 10, 5 },
560   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
561   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::illegal, 0, 0 },
554562
555   { rlc_R1, 6, 5 },   { rlc_IR1, 6, 5 },  { adc_r1_r2, 6, 5 },    { adc_r1_Ir2, 6, 5 },   { adc_R2_R1, 10, 5 },   { adc_IR2_R1, 10, 5 },  { adc_R1_IM, 10, 5 },   { adc_IR1_IM, 10, 5 },
556   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { illegal, 0, 0 },
563   { &z8_device::inc_R1, 6, 5 },   { &z8_device::inc_IR1, 6, 5 },  { &z8_device::sub_r1_r2, 6, 5 },    { &z8_device::sub_r1_Ir2, 6, 5 },
564   { &z8_device::sub_R2_R1, 10, 5 },   { &z8_device::sub_IR2_R1, 10, 5 },  { &z8_device::sub_R1_IM, 10, 5 },   { &z8_device::sub_IR1_IM, 10, 5 },
565   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
566   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::illegal, 0, 0 },
557567
558   { inc_R1, 6, 5 },   { inc_IR1, 6, 5 },  { sub_r1_r2, 6, 5 },    { sub_r1_Ir2, 6, 5 },   { sub_R2_R1, 10, 5 },   { sub_IR2_R1, 10, 5 },  { sub_R1_IM, 10, 5 },   { sub_IR1_IM, 10, 5 },
559   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { illegal, 0, 0 },
568   { &z8_device::jp_IRR1, 8, 0 },  { &z8_device::srp_IM, 6, 1 },   { &z8_device::sbc_r1_r2, 6, 5 },    { &z8_device::sbc_r1_Ir2, 6, 5 },
569   { &z8_device::sbc_R2_R1, 10, 5 },   { &z8_device::sbc_IR2_R1, 10, 5 },  { &z8_device::sbc_R1_IM, 10, 5 },   { &z8_device::sbc_IR1_IM, 10, 5 },
570   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
571   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::illegal, 0, 0 },
560572
561   { jp_IRR1, 8, 0 },  { srp_IM, 6, 1 },   { sbc_r1_r2, 6, 5 },    { sbc_r1_Ir2, 6, 5 },   { sbc_R2_R1, 10, 5 },   { sbc_IR2_R1, 10, 5 },  { sbc_R1_IM, 10, 5 },   { sbc_IR1_IM, 10, 5 },
562   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { illegal, 0, 0 },
573   { &z8_device::da_R1, 8, 5 },    { &z8_device::da_IR1, 8, 5 },   { &z8_device::or_r1_r2, 6, 5 },     { &z8_device::or_r1_Ir2, 6, 5 },
574   { &z8_device::or_R2_R1, 10, 5 },    { &z8_device::or_IR2_R1, 10, 5 },   { &z8_device::or_R1_IM, 10, 5 },    { &z8_device::or_IR1_IM, 10, 5 },
575   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
576   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::illegal, 0, 0 },
563577
564   { da_R1, 8, 5 },    { da_IR1, 8, 5 },   { or_r1_r2, 6, 5 },     { or_r1_Ir2, 6, 5 },    { or_R2_R1, 10, 5 },    { or_IR2_R1, 10, 5 },   { or_R1_IM, 10, 5 },    { or_IR1_IM, 10, 5 },
565   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { illegal, 0, 0 },
578   { &z8_device::pop_R1, 10, 5 },  { &z8_device::pop_IR1, 10, 5 }, { &z8_device::and_r1_r2, 6, 5 },    { &z8_device::and_r1_Ir2, 6, 5 },
579   { &z8_device::and_R2_R1, 10, 5 },   { &z8_device::and_IR2_R1, 10, 5 },  { &z8_device::and_R1_IM, 10, 5 },   { &z8_device::and_IR1_IM, 10, 5 },
580   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
581   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::illegal, 0, 0 },
566582
567   { pop_R1, 10, 5 },  { pop_IR1, 10, 5 }, { and_r1_r2, 6, 5 },    { and_r1_Ir2, 6, 5 },   { and_R2_R1, 10, 5 },   { and_IR2_R1, 10, 5 },  { and_R1_IM, 10, 5 },   { and_IR1_IM, 10, 5 },
568   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { illegal, 0, 0 },
583   { &z8_device::com_R1, 6, 5 },   { &z8_device::com_IR1, 6, 5 },  { &z8_device::tcm_r1_r2, 6, 5 },    { &z8_device::tcm_r1_Ir2, 6, 5 },
584   { &z8_device::tcm_R2_R1, 10, 5 },   { &z8_device::tcm_IR2_R1, 10, 5 },  { &z8_device::tcm_R1_IM, 10, 5 },   { &z8_device::tcm_IR1_IM, 10, 5 },
585   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
586   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::illegal, 0, 0 },
569587
570   { com_R1, 6, 5 },   { com_IR1, 6, 5 },  { tcm_r1_r2, 6, 5 },    { tcm_r1_Ir2, 6, 5 },   { tcm_R2_R1, 10, 5 },   { tcm_IR2_R1, 10, 5 },  { tcm_R1_IM, 10, 5 },   { tcm_IR1_IM, 10, 5 },
571   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { illegal, 0, 0 },
588   { &z8_device::push_R2, 10, 1 }, { &z8_device::push_IR2, 12, 1 },{ &z8_device::tm_r1_r2, 6, 5 },     { &z8_device::tm_r1_Ir2, 6, 5 },
589   { &z8_device::tm_R2_R1, 10, 5 },    { &z8_device::tm_IR2_R1, 10, 5 },   { &z8_device::tm_R1_IM, 10, 5 },    { &z8_device::tm_IR1_IM, 10, 5 },
590   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
591   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::illegal, 0, 0 },
572592
573   { push_R2, 10, 1 }, { push_IR2, 12, 1 },{ tm_r1_r2, 6, 5 },     { tm_r1_Ir2, 6, 5 },    { tm_R2_R1, 10, 5 },    { tm_IR2_R1, 10, 5 },   { tm_R1_IM, 10, 5 },    { tm_IR1_IM, 10, 5 },
574   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { illegal, 0, 0 },
593   { &z8_device::decw_RR1, 10, 5 },{ &z8_device::decw_IR1, 10, 5 },{ &z8_device::lde_r1_Irr2, 12, 0 }, { &z8_device::ldei_Ir1_Irr2, 18, 0 },
594   { &z8_device::illegal, 0, 0 },     { &z8_device::illegal, 0, 0 },      { &z8_device::illegal, 0, 0 },      { &z8_device::illegal, 0, 0 },
595   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
596   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::di, 6, 1 },
575597
576   { decw_RR1, 10, 5 },{ decw_IR1, 10, 5 },{ lde_r1_Irr2, 12, 0 }, { ldei_Ir1_Irr2, 18, 0 },{ illegal, 0, 0 },     { illegal, 0, 0 },      { illegal, 0, 0 },      { illegal, 0, 0 },
577   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { di, 6, 1 },
598   { &z8_device::rl_R1, 6, 5 },    { &z8_device::rl_IR1, 6, 5 },   { &z8_device::lde_r2_Irr1, 12, 0 }, { &z8_device::ldei_Ir2_Irr1, 18, 0 },
599   { &z8_device::illegal, 0, 0 },     { &z8_device::illegal, 0, 0 },      { &z8_device::illegal, 0, 0 },      { &z8_device::illegal, 0, 0 },
600   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
601   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::ei, 6, 1 },
578602
579   { rl_R1, 6, 5 },    { rl_IR1, 6, 5 },   { lde_r2_Irr1, 12, 0 }, { ldei_Ir2_Irr1, 18, 0 },{ illegal, 0, 0 },     { illegal, 0, 0 },      { illegal, 0, 0 },      { illegal, 0, 0 },
580   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { ei, 6, 1 },
603   { &z8_device::incw_RR1, 10, 5 },{ &z8_device::incw_IR1, 10, 5 },{ &z8_device::cp_r1_r2, 6, 5 },     { &z8_device::cp_r1_Ir2, 6, 5 },
604   { &z8_device::cp_R2_R1, 10, 5 },    { &z8_device::cp_IR2_R1, 10, 5 },   { &z8_device::cp_R1_IM, 10, 5 },    { &z8_device::cp_IR1_IM, 10, 5 },
605   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
606   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::ret, 14, 0 },
581607
582   { incw_RR1, 10, 5 },{ incw_IR1, 10, 5 },{ cp_r1_r2, 6, 5 },     { cp_r1_Ir2, 6, 5 },    { cp_R2_R1, 10, 5 },    { cp_IR2_R1, 10, 5 },   { cp_R1_IM, 10, 5 },    { cp_IR1_IM, 10, 5 },
583   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { ret, 14, 0 },
608   { &z8_device::clr_R1, 6, 5 },   { &z8_device::clr_IR1, 6, 5 },  { &z8_device::xor_r1_r2, 6, 5 },    { &z8_device::xor_r1_Ir2, 6, 5 },
609   { &z8_device::xor_R2_R1, 10, 5 },   { &z8_device::xor_IR2_R1, 10, 5 },  { &z8_device::xor_R1_IM, 10, 5 },   { &z8_device::xor_IR1_IM, 10, 5 },
610   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
611   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::iret, 16, 0 },
584612
585   { clr_R1, 6, 5 },   { clr_IR1, 6, 5 },  { xor_r1_r2, 6, 5 },    { xor_r1_Ir2, 6, 5 },   { xor_R2_R1, 10, 5 },   { xor_IR2_R1, 10, 5 },  { xor_R1_IM, 10, 5 },   { xor_IR1_IM, 10, 5 },
586   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { iret, 16, 0 },
613   { &z8_device::rrc_R1, 6, 5 },   { &z8_device::rrc_IR1, 6, 5 },  { &z8_device::ldc_r1_Irr2, 12, 0 }, { &z8_device::ldci_Ir1_Irr2, 18, 0 },
614   { &z8_device::illegal, 0, 0 },     { &z8_device::illegal, 0, 0 },      { &z8_device::illegal, 0, 0 },      { &z8_device::ld_r1_x_R2, 10, 5 },
615   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
616   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::rcf, 6, 5 },
587617
588   { rrc_R1, 6, 5 },   { rrc_IR1, 6, 5 },  { ldc_r1_Irr2, 12, 0 }, { ldci_Ir1_Irr2, 18, 0 },{ illegal, 0, 0 },     { illegal, 0, 0 },      { illegal, 0, 0 },      { ld_r1_x_R2, 10, 5 },
589   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { rcf, 6, 5 },
618   { &z8_device::sra_R1, 6, 5 },   { &z8_device::sra_IR1, 6, 5 },  { &z8_device::ldc_r2_Irr1, 12, 0 }, { &z8_device::ldci_Ir2_Irr1, 18, 0 },
619   { &z8_device::call_IRR1, 20, 0 },  { &z8_device::illegal, 0, 0 },      { &z8_device::call_DA, 20, 0 },     { &z8_device::ld_r2_x_R1, 10, 5 },
620   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
621   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::scf, 6, 5 },
590622
591   { sra_R1, 6, 5 },   { sra_IR1, 6, 5 },  { ldc_r2_Irr1, 12, 0 }, { ldci_Ir2_Irr1, 18, 0 },{ call_IRR1, 20, 0 },  { illegal, 0, 0 },      { call_DA, 20, 0 },     { ld_r2_x_R1, 10, 5 },
592   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { scf, 6, 5 },
623   { &z8_device::rr_R1, 6, 5 },    { &z8_device::rr_IR1, 6, 5 },   { &z8_device::illegal, 0, 0 },      { &z8_device::ld_r1_Ir2, 6, 5 },
624   { &z8_device::ld_R2_R1, 10, 5 },    { &z8_device::ld_IR2_R1, 10, 5 },   { &z8_device::ld_R1_IM, 10, 5 },    { &z8_device::ld_IR1_IM, 10, 5 },
625   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
626   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::ccf, 6, 5 },
593627
594   { rr_R1, 6, 5 },    { rr_IR1, 6, 5 },   { illegal, 0, 0 },      { ld_r1_Ir2, 6, 5 },    { ld_R2_R1, 10, 5 },    { ld_IR2_R1, 10, 5 },   { ld_R1_IM, 10, 5 },    { ld_IR1_IM, 10, 5 },
595   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { ccf, 6, 5 },
596
597   { swap_R1, 8, 5 },  { swap_IR1, 8, 5 }, { illegal, 0, 0 },      { ld_Ir1_r2, 6, 5 },    { illegal, 0, 0 },      { ld_R2_IR1, 10, 5 },   { illegal, 0, 0 },      { illegal, 0, 0 },
598   { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },     { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },       { nop, 6, 0 },
628   { &z8_device::swap_R1, 8, 5 },  { &z8_device::swap_IR1, 8, 5 }, { &z8_device::illegal, 0, 0 },      { &z8_device::ld_Ir1_r2, 6, 5 },
629   { &z8_device::illegal, 0, 0 },      { &z8_device::ld_R2_IR1, 10, 5 },   { &z8_device::illegal, 0, 0 },      { &z8_device::illegal, 0, 0 },
630   { &z8_device::ld_r1_R2, 6, 5 }, { &z8_device::ld_r2_R1, 6, 5 }, { &z8_device::djnz_r1_RA, 10, 5 },  { &z8_device::jr_cc_RA, 10, 0 },
631   { &z8_device::ld_r1_IM, 6, 5 },     { &z8_device::jp_cc_DA, 10, 0 },    { &z8_device::inc_r1, 6, 5 },       { &z8_device::nop, 6, 0 }
599632};
600633
601634/***************************************************************************
602635    TIMER CALLBACKS
603636***************************************************************************/
604637
605static TIMER_CALLBACK( t0_tick )
638TIMER_CALLBACK_MEMBER( z8_device::t0_tick )
606639{
607   z8_state *cpustate = (z8_state *)ptr;
640   m_t0--;
608641
609   cpustate->t0--;
610
611   if (cpustate->t0 == 0)
642   if (m_t0 == 0)
612643   {
613      cpustate->t0 = T0;
614      cpustate->t0_timer->adjust(attotime::zero, 0, attotime::from_hz(cpustate->clock / 2 / 4 / ((PRE0 >> 2) + 1)));
615      cpustate->t0_timer->enable(PRE0 & Z8_PRE0_COUNT_MODULO_N);
616      cpustate->irq[4] = ASSERT_LINE;
644      m_t0 = T0;
645      m_t0_timer->adjust(attotime::zero, 0, attotime::from_hz(m_clock / 2 / 4 / ((PRE0 >> 2) + 1)));
646      m_t0_timer->enable(PRE0 & Z8_PRE0_COUNT_MODULO_N);
647      m_irq[4] = ASSERT_LINE;
617648   }
618649}
619650
620static TIMER_CALLBACK( t1_tick )
651TIMER_CALLBACK_MEMBER( z8_device::t1_tick )
621652{
622   z8_state *cpustate = (z8_state *)ptr;
653   m_t1--;
623654
624   cpustate->t1--;
625
626   if (cpustate->t1 == 0)
655   if (m_t1 == 0)
627656   {
628      cpustate->t1 = T1;
629      cpustate->t1_timer->adjust(attotime::zero, 0, attotime::from_hz(cpustate->clock / 2 / 4 / ((PRE1 >> 2) + 1)));
630      cpustate->t1_timer->enable(PRE1 & Z8_PRE0_COUNT_MODULO_N);
631      cpustate->irq[5] = ASSERT_LINE;
657      m_t1 = T1;
658      m_t1_timer->adjust(attotime::zero, 0, attotime::from_hz(m_clock / 2 / 4 / ((PRE1 >> 2) + 1)));
659      m_t1_timer->enable(PRE1 & Z8_PRE0_COUNT_MODULO_N);
660      m_irq[5] = ASSERT_LINE;
632661   }
633662}
634663
r26676r26677
636665    INITIALIZATION
637666***************************************************************************/
638667
639static CPU_INIT( z8 )
668void z8_device::device_start()
640669{
641   z8_state *cpustate = get_safe_token(device);
642
643670   /* set up the state table */
644671   {
645      device_state_interface *state;
646      device->interface(state);
647      state->state_add(Z8_PC,         "PC",        cpustate->pc);
648      state->state_add(STATE_GENPC,   "GENPC",     cpustate->pc).noshow();
649      state->state_add(Z8_SP,         "SP",        cpustate->fake_sp).callimport().callexport();
650      state->state_add(STATE_GENSP,   "GENSP",     cpustate->fake_sp).callimport().callexport().noshow();
651      state->state_add(Z8_RP,         "RP",        cpustate->r[Z8_REGISTER_RP]);
652      state->state_add(Z8_T0,         "T0",        cpustate->t0);
653      state->state_add(Z8_T1,         "T1",        cpustate->t1);
654      state->state_add(STATE_GENFLAGS, "GENFLAGS", cpustate->r[Z8_REGISTER_FLAGS]).noshow().formatstr("%6s");
672      state_add(Z8_PC,         "PC",        m_pc);
673      state_add(STATE_GENPC,   "GENPC",     m_pc).noshow();
674      state_add(Z8_SP,         "SP",        m_fake_sp).callimport().callexport();
675      state_add(STATE_GENSP,   "GENSP",     m_fake_sp).callimport().callexport().noshow();
676      state_add(Z8_RP,         "RP",        m_r[Z8_REGISTER_RP]);
677      state_add(Z8_T0,         "T0",        m_t0);
678      state_add(Z8_T1,         "T1",        m_t1);
679      state_add(STATE_GENFLAGS, "GENFLAGS", m_r[Z8_REGISTER_FLAGS]).noshow().formatstr("%6s");
655680
656681      astring tempstr;
657682      for (int regnum = 0; regnum < 16; regnum++)
658         state->state_add(Z8_R0 + regnum, tempstr.format("R%d", regnum), cpustate->fake_r[regnum]).callimport().callexport();
683         state_add(Z8_R0 + regnum, tempstr.format("R%d", regnum), m_fake_r[regnum]).callimport().callexport();
659684   }
660685
661   cpustate->clock = device->clock();
662
663686   /* find address spaces */
664   cpustate->program = &device->space(AS_PROGRAM);
665   cpustate->direct = &cpustate->program->direct();
666   cpustate->data = &device->space(AS_DATA);
667   cpustate->io = &device->space(AS_IO);
687   m_program = &space(AS_PROGRAM);
688   m_direct = &m_program->direct();
689   m_data = &space(AS_DATA);
690   m_io = &space(AS_IO);
668691
669692   /* allocate timers */
670   cpustate->t0_timer = device->machine().scheduler().timer_alloc(FUNC(t0_tick), cpustate);
671   cpustate->t1_timer = device->machine().scheduler().timer_alloc(FUNC(t1_tick), cpustate);
693   m_t0_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(z8_device::t0_tick), this));
694   m_t1_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(z8_device::t1_tick), this));
672695
696   /* Clear state */
697   for ( int i = 0; i < 6; i++ )
698      m_irq[i] = 0;
699   for ( int i = 0; i < 256; i++ )
700      m_r[i] = 0;
701   for ( int i = 0; i < 4; i++ )
702   {
703      m_input[i] = 0;
704      m_output[i] = 0;
705   }
706   for ( int i = 0; i < 16; i++ )
707      m_fake_r[i] = 0;
708   m_fake_sp = 0;
709   m_t0 = 0;
710   m_t1 = 0;
711
673712   /* register for state saving */
674   device->save_item(NAME(cpustate->pc));
675   device->save_item(NAME(cpustate->r));
676   device->save_item(NAME(cpustate->input));
677   device->save_item(NAME(cpustate->output));
678   device->save_item(NAME(cpustate->irq));
713   save_item(NAME(m_pc));
714   save_item(NAME(m_r));
715   save_item(NAME(m_input));
716   save_item(NAME(m_output));
717   save_item(NAME(m_irq));
718
719   m_icountptr = &m_icount;
679720}
680721
681722/***************************************************************************
682723    EXECUTION
683724***************************************************************************/
684725
685static CPU_EXECUTE( z8 )
726void z8_device::execute_run()
686727{
687   z8_state *cpustate = get_safe_token(device);
688
689728   do
690729   {
691730      UINT8 opcode;
692731      int cycles;
693732
694      debugger_instruction_hook(device, cpustate->pc);
733      debugger_instruction_hook(this, m_pc);
695734
696735      /* TODO: sample interrupts */
697      cpustate->input[3] = cpustate->io->read_byte(3);
736      m_input[3] = m_io->read_byte(3);
698737
699738      /* fetch opcode */
700      opcode = fetch(cpustate);
739      opcode = fetch();
701740      cycles = Z8601_OPCODE_MAP[opcode].execution_cycles;
702741
703742      /* execute instruction */
704      (*(Z8601_OPCODE_MAP[opcode].function))(cpustate, opcode, &cycles);
743      (this->*(Z8601_OPCODE_MAP[opcode].function))(opcode, &cycles);
705744
706      cpustate->icount -= cycles;
745      m_icount -= cycles;
707746   }
708   while (cpustate->icount > 0);
747   while (m_icount > 0);
709748}
710749
711750/***************************************************************************
712751    RESET
713752***************************************************************************/
714753
715static CPU_RESET( z8 )
754void z8_device::device_reset()
716755{
717   z8_state *cpustate = get_safe_token(device);
756   m_pc = 0x000c;
718757
719   cpustate->pc = 0x000c;
720
721   register_write(cpustate, Z8_REGISTER_TMR, 0x00);
722   register_write(cpustate, Z8_REGISTER_PRE1, register_read(cpustate, Z8_REGISTER_PRE1) & 0xfc);
723   register_write(cpustate, Z8_REGISTER_PRE0, register_read(cpustate, Z8_REGISTER_PRE0) & 0xfe);
724   register_write(cpustate, Z8_REGISTER_P2M, 0xff);
725   register_write(cpustate, Z8_REGISTER_P3M, 0x00);
726   register_write(cpustate, Z8_REGISTER_P01M, 0x4d);
727   register_write(cpustate, Z8_REGISTER_IRQ, 0x00);
728   register_write(cpustate, Z8_REGISTER_RP, 0x00);
758   register_write(Z8_REGISTER_TMR, 0x00);
759   register_write(Z8_REGISTER_PRE1, register_read(Z8_REGISTER_PRE1) & 0xfc);
760   register_write(Z8_REGISTER_PRE0, register_read(Z8_REGISTER_PRE0) & 0xfe);
761   register_write(Z8_REGISTER_P2M, 0xff);
762   register_write(Z8_REGISTER_P3M, 0x00);
763   register_write(Z8_REGISTER_P01M, 0x4d);
764   register_write(Z8_REGISTER_IRQ, 0x00);
765   register_write(Z8_REGISTER_RP, 0x00);
729766}
730767
731/***************************************************************************
732    ADDRESS MAPS
733***************************************************************************/
734768
735static ADDRESS_MAP_START( program_2kb, AS_PROGRAM, 8, legacy_cpu_device )
736   AM_RANGE(0x0000, 0x07ff) AM_ROM
737ADDRESS_MAP_END
738
739static ADDRESS_MAP_START( program_4kb, AS_PROGRAM, 8, legacy_cpu_device )
740   AM_RANGE(0x0000, 0x0fff) AM_ROM
741ADDRESS_MAP_END
742
743769/**************************************************************************
744770 * STATE IMPORT/EXPORT
745771 **************************************************************************/
746772
747static CPU_IMPORT_STATE( z8 )
773void z8_device::state_import(const device_state_entry &entry)
748774{
749   z8_state *cpustate = get_safe_token(device);
750
751775   switch (entry.index())
752776   {
753777      case Z8_SP:
754778      case Z8_GENSP:
755         cpustate->r[Z8_REGISTER_SPH] = cpustate->fake_sp >> 8;
756         cpustate->r[Z8_REGISTER_SPL] = cpustate->fake_sp & 0xff;
779         m_r[Z8_REGISTER_SPH] = m_fake_sp >> 8;
780         m_r[Z8_REGISTER_SPL] = m_fake_sp & 0xff;
757781         break;
758782
759783      case Z8_R0: case Z8_R1: case Z8_R2: case Z8_R3: case Z8_R4: case Z8_R5: case Z8_R6: case Z8_R7: case Z8_R8: case Z8_R9: case Z8_R10: case Z8_R11: case Z8_R12: case Z8_R13: case Z8_R14: case Z8_R15:
760         cpustate->r[cpustate->r[Z8_REGISTER_RP] + (entry.index() - Z8_R0)] = cpustate->fake_r[entry.index() - Z8_R0];
784         m_r[m_r[Z8_REGISTER_RP] + (entry.index() - Z8_R0)] = m_fake_r[entry.index() - Z8_R0];
761785         break;
762786
763787      default:
r26676r26677
766790   }
767791}
768792
769static CPU_EXPORT_STATE( z8 )
793void z8_device::state_export(const device_state_entry &entry)
770794{
771   z8_state *cpustate = get_safe_token(device);
772
773795   switch (entry.index())
774796   {
775797      case Z8_SP:
776798      case Z8_GENSP:
777         cpustate->fake_sp = (cpustate->r[Z8_REGISTER_SPH] << 8) | cpustate->r[Z8_REGISTER_SPL];
799         m_fake_sp = (m_r[Z8_REGISTER_SPH] << 8) | m_r[Z8_REGISTER_SPL];
778800         break;
779801
780802      case Z8_R0: case Z8_R1: case Z8_R2: case Z8_R3: case Z8_R4: case Z8_R5: case Z8_R6: case Z8_R7: case Z8_R8: case Z8_R9: case Z8_R10: case Z8_R11: case Z8_R12: case Z8_R13: case Z8_R14: case Z8_R15:
781         cpustate->fake_r[entry.index() - Z8_R0] = cpustate->r[cpustate->r[Z8_REGISTER_RP] + (entry.index() - Z8_R0)];
803         m_fake_r[entry.index() - Z8_R0] = m_r[m_r[Z8_REGISTER_RP] + (entry.index() - Z8_R0)];
782804         break;
783805
784806      default:
r26676r26677
787809   }
788810}
789811
790static CPU_EXPORT_STRING( z8 )
812void z8_device::state_string_export(const device_state_entry &entry, astring &string)
791813{
792   z8_state *cpustate = get_safe_token(device);
793
794814   switch (entry.index())
795815   {
796816      case STATE_GENFLAGS: string.printf("%c%c%c%c%c%c",
797                              cpustate->r[Z8_REGISTER_FLAGS] & Z8_FLAGS_C ? 'C' : '.',
798                              cpustate->r[Z8_REGISTER_FLAGS] & Z8_FLAGS_Z ? 'Z' : '.',
799                              cpustate->r[Z8_REGISTER_FLAGS] & Z8_FLAGS_S ? 'S' : '.',
800                              cpustate->r[Z8_REGISTER_FLAGS] & Z8_FLAGS_V ? 'V' : '.',
801                              cpustate->r[Z8_REGISTER_FLAGS] & Z8_FLAGS_D ? 'D' : '.',
802                              cpustate->r[Z8_REGISTER_FLAGS] & Z8_FLAGS_H ? 'H' : '.');   break;
817                              m_r[Z8_REGISTER_FLAGS] & Z8_FLAGS_C ? 'C' : '.',
818                              m_r[Z8_REGISTER_FLAGS] & Z8_FLAGS_Z ? 'Z' : '.',
819                              m_r[Z8_REGISTER_FLAGS] & Z8_FLAGS_S ? 'S' : '.',
820                              m_r[Z8_REGISTER_FLAGS] & Z8_FLAGS_V ? 'V' : '.',
821                              m_r[Z8_REGISTER_FLAGS] & Z8_FLAGS_D ? 'D' : '.',
822                              m_r[Z8_REGISTER_FLAGS] & Z8_FLAGS_H ? 'H' : '.');   break;
803823   }
804824}
805825
806/***************************************************************************
807    GENERAL CONTEXT ACCESS
808***************************************************************************/
809826
810static CPU_SET_INFO( z8 )
827void z8_device::execute_set_input(int inputnum, int state)
811828{
812   z8_state *cpustate = get_safe_token(device);
813
814   switch (state)
829   switch ( inputnum )
815830   {
816      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_IRQ0: cpustate->irq[0] = info->i;             break;
817      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_IRQ1: cpustate->irq[1] = info->i;             break;
818      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_IRQ2: cpustate->irq[2] = info->i;             break;
819      case CPUINFO_INT_INPUT_STATE + INPUT_LINE_IRQ3: cpustate->irq[3] = info->i;             break;
820   }
821}
831      case INPUT_LINE_IRQ0:
832         m_irq[0] = state;
833         break;
822834
823static CPU_GET_INFO( z8 )
824{
825   z8_state *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
835      case INPUT_LINE_IRQ1:
836         m_irq[1] = state;
837         break;
826838
827   switch (state)
828   {
829      /* --- the following bits of info are returned as 64-bit signed integers --- */
830      case CPUINFO_INT_CONTEXT_SIZE:                  info->i = sizeof(z8_state);             break;
831      case CPUINFO_INT_INPUT_LINES:                   info->i = 4;                            break;
832      case CPUINFO_INT_DEFAULT_IRQ_VECTOR:            info->i = 0;                            break;
833      case CPUINFO_INT_ENDIANNESS:                    info->i = ENDIANNESS_LITTLE;            break;
834      case CPUINFO_INT_CLOCK_MULTIPLIER:              info->i = 1;                            break;
835      case CPUINFO_INT_CLOCK_DIVIDER:                 info->i = 2;                            break;
836      case CPUINFO_INT_MIN_INSTRUCTION_BYTES:         info->i = 1;                            break;
837      case CPUINFO_INT_MAX_INSTRUCTION_BYTES:         info->i = 3;                            break;
838      case CPUINFO_INT_MIN_CYCLES:                    info->i = 6;                            break;
839      case CPUINFO_INT_MAX_CYCLES:                    info->i = 20;                           break;
839      case INPUT_LINE_IRQ2:
840         m_irq[2] = state;
841         break;
840842
841      case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM:            info->i = 8;                            break;
842      case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM:            info->i = 16;                           break;
843      case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM:            info->i = 0;                            break;
844      case CPUINFO_INT_DATABUS_WIDTH + AS_DATA:           info->i = 8;                            break;
845      case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA:           info->i = 16;                           break;
846      case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA:           info->i = 0;                            break;
847      case CPUINFO_INT_DATABUS_WIDTH + AS_IO:             info->i = 8;                            break;
848      case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO:             info->i = 2;                            break;
849      case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO:             info->i = 0;                            break;
843      case INPUT_LINE_IRQ3:
844         m_irq[3] = state;
845         break;
850846
851      /* --- the following bits of info are returned as pointers to functions --- */
852      case CPUINFO_FCT_SET_INFO:              info->setinfo = CPU_SET_INFO_NAME(z8);          break;
853      case CPUINFO_FCT_INIT:                  info->init = CPU_INIT_NAME(z8);                 break;
854      case CPUINFO_FCT_RESET:                 info->reset = CPU_RESET_NAME(z8);               break;
855      case CPUINFO_FCT_EXECUTE:               info->execute = CPU_EXECUTE_NAME(z8);           break;
856      case CPUINFO_FCT_DISASSEMBLE:           info->disassemble = CPU_DISASSEMBLE_NAME(z8);   break;
857      case CPUINFO_FCT_IMPORT_STATE:          info->import_state = CPU_IMPORT_STATE_NAME(z8); break;
858      case CPUINFO_FCT_EXPORT_STATE:          info->export_state = CPU_EXPORT_STATE_NAME(z8); break;
859      case CPUINFO_FCT_EXPORT_STRING:         info->export_string = CPU_EXPORT_STRING_NAME(z8);   break;
860
861      /* --- the following bits of info are returned as pointers --- */
862      case CPUINFO_PTR_INSTRUCTION_COUNTER:   info->icount = &cpustate->icount;               break;
863
864      /* --- the following bits of info are returned as NULL-terminated strings --- */
865      case CPUINFO_STR_NAME:                          strcpy(info->s, "Z8");                  break;
866      case CPUINFO_STR_SHORTNAME:                     strcpy(info->s, "z8");                  break;
867      case CPUINFO_STR_FAMILY:                        strcpy(info->s, "Zilog Z8");            break;
868      case CPUINFO_STR_VERSION:                       strcpy(info->s, "1.0");                 break;
869      case CPUINFO_STR_SOURCE_FILE:                   strcpy(info->s, __FILE__);              break;
870      case CPUINFO_STR_CREDITS:                       strcpy(info->s, "Copyright MESS Team"); break;
871847   }
872848}
873849
874/***************************************************************************
875    CPU-SPECIFIC CONTEXT ACCESS
876***************************************************************************/
877
878CPU_GET_INFO( z8601 )
879{
880   switch (state)
881   {
882      /* --- the following bits of info are returned as pointers --- */
883      case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM:  info->internal_map8 = ADDRESS_MAP_NAME(program_2kb);    break;
884
885      /* --- the following bits of info are returned as NULL-terminated strings --- */
886      case CPUINFO_STR_NAME:                          strcpy(info->s, "Z8601");                               break;
887      case CPUINFO_STR_SHORTNAME:                     strcpy(info->s, "z8601");                               break;
888
889      default:                                        CPU_GET_INFO_CALL(z8);                                  break;
890   }
891}
892
893CPU_GET_INFO( ub8830d )
894{
895   switch (state)
896   {
897      /* --- the following bits of info are returned as pointers --- */
898      case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM:  info->internal_map8 = ADDRESS_MAP_NAME(program_2kb);    break;
899
900      /* --- the following bits of info are returned as NULL-terminated strings --- */
901      case CPUINFO_STR_NAME:                          strcpy(info->s, "UB8830D");                             break;
902      case CPUINFO_STR_SHORTNAME:                     strcpy(info->s, "ub8830d");                             break;
903
904      default:                                        CPU_GET_INFO_CALL(z8);                                  break;
905   }
906}
907
908CPU_GET_INFO( z8611 )
909{
910   switch (state)
911   {
912      /* --- the following bits of info are returned as pointers --- */
913      case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM:  info->internal_map8 = ADDRESS_MAP_NAME(program_4kb);    break;
914
915      /* --- the following bits of info are returned as NULL-terminated strings --- */
916      case CPUINFO_STR_NAME:                          strcpy(info->s, "Z8611");                               break;
917      case CPUINFO_STR_SHORTNAME:                     strcpy(info->s, "z8611");                               break;
918
919      default:                                        CPU_GET_INFO_CALL(z8);                                  break;
920   }
921}
922
923DEFINE_LEGACY_CPU_DEVICE(Z8601, z8601);
924DEFINE_LEGACY_CPU_DEVICE(UB8830D, ub8830d);
925DEFINE_LEGACY_CPU_DEVICE(Z8611, z8611);
trunk/src/emu/cpu/z8/z8ops.c
r26676r26677
1111    MACROS
1212***************************************************************************/
1313
14#define read(_reg)      register_read(cpustate, _reg)
15#define r(_data)        get_working_register(cpustate, _data)
16#define Ir(_data)       get_intermediate_register(cpustate, get_working_register(cpustate, _data))
17#define R               get_register(cpustate, fetch(cpustate))
18#define IR              get_intermediate_register(cpustate, get_register(cpustate, fetch(cpustate)))
19#define RR              get_intermediate_register(cpustate, get_register(cpustate, fetch(cpustate)))
20#define IM              fetch(cpustate)
21#define flag(_flag)     ((cpustate->r[Z8_REGISTER_FLAGS] & Z8_FLAGS##_##_flag) ? 1 : 0)
14#define read(_reg)      register_read(_reg)
15#define r(_data)        get_working_register(_data)
16#define Ir(_data)       get_intermediate_register(get_working_register(_data))
17#define R               get_register(fetch())
18#define IR              get_intermediate_register(get_register(fetch()))
19#define RR              get_intermediate_register(get_register(fetch()))
20#define IM              fetch()
21#define flag(_flag)     ((m_r[Z8_REGISTER_FLAGS] & Z8_FLAGS##_##_flag) ? 1 : 0)
2222
2323#define mode_r1_r2(_func)   \
24   UINT8 dst_src = fetch(cpustate);\
24   UINT8 dst_src = fetch();\
2525   UINT8 dst = r(dst_src >> 4);\
2626   UINT8 src = read(r(dst_src & 0x0f));\
27   _func(cpustate, dst, src);
27   _func(dst, src);
2828
2929#define mode_r1_Ir2(_func) \
30   UINT8 dst_src = fetch(cpustate);\
30   UINT8 dst_src = fetch();\
3131   UINT8 dst = r(dst_src >> 4);\
3232   UINT8 src = read(Ir(dst_src & 0x0f));\
33   _func(cpustate, dst, src);
33   _func(dst, src);
3434
3535#define mode_R2_R1(_func) \
3636   UINT8 src = read(R);\
3737   UINT8 dst = R;\
38   _func(cpustate, dst, src);
38   _func(dst, src);
3939
4040#define mode_IR2_R1(_func) \
4141   UINT8 src = read(R);\
4242   UINT8 dst = IR;\
43   _func(cpustate, dst, src);
43   _func(dst, src);
4444
4545#define mode_R1_IM(_func) \
4646   UINT8 dst = R;\
4747   UINT8 src = IM;\
48   _func(cpustate, dst, src);
48   _func(dst, src);
4949
5050#define mode_IR1_IM(_func) \
5151   UINT8 dst = IR;\
5252   UINT8 src = IM;\
53   _func(cpustate, dst, src);
53   _func(dst, src);
5454
5555#define mode_r1(_func) \
5656   UINT8 dst = r(opcode >> 4);\
57   _func(cpustate, dst);
57   _func(dst);
5858
5959#define mode_R1(_func) \
6060   UINT8 dst = R;\
61   _func(cpustate, dst);
61   _func(dst);
6262
6363#define mode_RR1(_func) \
6464   UINT8 dst = R;\
65   _func(cpustate, dst);
65   _func(dst);
6666
6767#define mode_IR1(_func) \
6868   UINT8 dst = IR;\
69   _func(cpustate, dst);
69   _func(dst);
7070
7171#define mode_r1_IM(_func) \
7272   UINT8 dst = r(opcode >> 4);\
7373   UINT8 src = IM;\
74   _func(cpustate, dst, src);
74   _func(dst, src);
7575
7676#define mode_r1_R2(_func) \
7777   UINT8 dst = r(opcode >> 4);\
7878   UINT8 src = read(R);\
79   _func(cpustate, dst, src);
79   _func(dst, src);
8080
8181#define mode_r2_R1(_func) \
8282   UINT8 src = read(r(opcode >> 4));\
8383   UINT8 dst = R;\
84   _func(cpustate, dst, src);
84   _func(dst, src);
8585
8686#define mode_Ir1_r2(_func) \
87   UINT8 dst_src = fetch(cpustate);\
87   UINT8 dst_src = fetch();\
8888   UINT8 dst = Ir(dst_src >> 4);\
8989   UINT8 src = read(r(dst_src & 0x0f));\
90   _func(cpustate, dst, src);
90   _func(dst, src);
9191
9292#define mode_R2_IR1(_func) \
9393   UINT8 src = read(R);\
9494   UINT8 dst = IR;\
95   _func(cpustate, dst, src);
95   _func(dst, src);
9696
9797#define mode_r1_x_R2(_func) \
98   UINT8 dst_src = fetch(cpustate);\
98   UINT8 dst_src = fetch();\
9999   UINT8 dst = r(dst_src >> 4);\
100100   UINT8 src = read(read(r(dst_src & 0x0f)) + R);\
101   _func(cpustate, dst, src);
101   _func(dst, src);
102102
103103#define mode_r2_x_R1(_func) \
104   UINT8 dst_src = fetch(cpustate);\
104   UINT8 dst_src = fetch();\
105105   UINT8 dst = R + read(r(dst_src & 0x0f));\
106106   UINT8 src = read(r(dst_src >> 4));\
107   _func(cpustate, dst, src);
107   _func(dst, src);
108108
109109/***************************************************************************
110110    LOAD INSTRUCTIONS
111111***************************************************************************/
112112
113static void clear(z8_state *cpustate, UINT8 dst)
113void z8_device::clear(UINT8 dst)
114114{
115115   /* dst <- 0 */
116   register_write(cpustate, dst, 0);
116   register_write(dst, 0);
117117}
118118
119119INSTRUCTION( clr_R1 )           { mode_R1(clear) }
120120INSTRUCTION( clr_IR1 )          { mode_IR1(clear) }
121121
122static void load(z8_state *cpustate, UINT8 dst, UINT8 src)
122void z8_device::load(UINT8 dst, UINT8 src)
123123{
124124   /* dst <- src */
125   register_write(cpustate, dst, src);
125   register_write(dst, src);
126126}
127127
128128INSTRUCTION( ld_r1_IM )         { mode_r1_IM(load) }
r26676r26677
140140INSTRUCTION( ld_R1_IM )         { mode_R1_IM(load) }
141141INSTRUCTION( ld_IR1_IM )        { mode_IR1_IM(load) }
142142
143static void load_from_memory(z8_state *cpustate, address_space *space)
143void z8_device::load_from_memory(address_space *space)
144144{
145   UINT8 operands = fetch(cpustate);
146   UINT8 dst = get_working_register(cpustate, operands >> 4);
147   UINT8 src = get_working_register(cpustate, operands & 0x0f);
145   UINT8 operands = fetch();
146   UINT8 dst = get_working_register(operands >> 4);
147   UINT8 src = get_working_register(operands & 0x0f);
148148
149   UINT16 address = register_pair_read(cpustate, src);
150   UINT8 data = cpustate->direct->read_decrypted_byte(address);
149   UINT16 address = register_pair_read(src);
150   UINT8 data = m_direct->read_decrypted_byte(address);
151151
152   register_write(cpustate, dst, data);
152   register_write(dst, data);
153153}
154154
155static void load_to_memory(z8_state *cpustate, address_space *space)
155void z8_device::load_to_memory(address_space *space)
156156{
157   UINT8 operands = fetch(cpustate);
158   UINT8 src = get_working_register(cpustate, operands >> 4);
159   UINT8 dst = get_working_register(cpustate, operands & 0x0f);
157   UINT8 operands = fetch();
158   UINT8 src = get_working_register(operands >> 4);
159   UINT8 dst = get_working_register(operands & 0x0f);
160160
161   UINT16 address = register_pair_read(cpustate, dst);
162   UINT8 data = register_read(cpustate, src);
161   UINT16 address = register_pair_read(dst);
162   UINT8 data = register_read(src);
163163
164   cpustate->program->write_byte(address, data);
164   m_program->write_byte(address, data);
165165}
166166
167static void load_from_memory_autoinc(z8_state *cpustate, address_space *space)
167void z8_device::load_from_memory_autoinc(address_space *space)
168168{
169   UINT8 operands = fetch(cpustate);
170   UINT8 dst = get_working_register(cpustate, operands >> 4);
171   UINT8 real_dst = get_intermediate_register(cpustate, dst);
172   UINT8 src = get_working_register(cpustate, operands & 0x0f);
169   UINT8 operands = fetch();
170   UINT8 dst = get_working_register(operands >> 4);
171   UINT8 real_dst = get_intermediate_register(dst);
172   UINT8 src = get_working_register(operands & 0x0f);
173173
174   UINT16 address = register_pair_read(cpustate, src);
175   UINT8 data = cpustate->direct->read_decrypted_byte(address);
174   UINT16 address = register_pair_read(src);
175   UINT8 data = m_direct->read_decrypted_byte(address);
176176
177   register_write(cpustate, real_dst, data);
177   register_write(real_dst, data);
178178
179   register_write(cpustate, dst, real_dst + 1);
180   register_pair_write(cpustate, src, address + 1);
179   register_write(dst, real_dst + 1);
180   register_pair_write(src, address + 1);
181181}
182182
183static void load_to_memory_autoinc(z8_state *cpustate, address_space *space)
183void z8_device::load_to_memory_autoinc(address_space *space)
184184{
185   UINT8 operands = fetch(cpustate);
186   UINT8 src = get_working_register(cpustate, operands >> 4);
187   UINT8 dst = get_working_register(cpustate, operands & 0x0f);
188   UINT8 real_src = get_intermediate_register(cpustate, src);
185   UINT8 operands = fetch();
186   UINT8 src = get_working_register(operands >> 4);
187   UINT8 dst = get_working_register(operands & 0x0f);
188   UINT8 real_src = get_intermediate_register(src);
189189
190   UINT16 address = register_pair_read(cpustate, dst);
191   UINT8 data = register_read(cpustate, real_src);
190   UINT16 address = register_pair_read(dst);
191   UINT8 data = register_read(real_src);
192192
193   cpustate->program->write_byte(address, data);
193   m_program->write_byte(address, data);
194194
195   register_pair_write(cpustate, dst, address + 1);
196   register_write(cpustate, src, real_src + 1);
195   register_pair_write(dst, address + 1);
196   register_write(src, real_src + 1);
197197}
198198
199INSTRUCTION( ldc_r1_Irr2 )      { load_from_memory(cpustate, cpustate->program); }
200INSTRUCTION( ldc_r2_Irr1 )      { load_to_memory(cpustate, cpustate->program); }
201INSTRUCTION( ldci_Ir1_Irr2 )    { load_from_memory_autoinc(cpustate, cpustate->program); }
202INSTRUCTION( ldci_Ir2_Irr1 )    { load_to_memory_autoinc(cpustate, cpustate->program); }
203INSTRUCTION( lde_r1_Irr2 )      { load_from_memory(cpustate, cpustate->data); }
204INSTRUCTION( lde_r2_Irr1 )      { load_to_memory(cpustate, cpustate->data); }
205INSTRUCTION( ldei_Ir1_Irr2 )    { load_from_memory_autoinc(cpustate, cpustate->data); }
206INSTRUCTION( ldei_Ir2_Irr1 )    { load_to_memory_autoinc(cpustate, cpustate->data); }
199INSTRUCTION( ldc_r1_Irr2 )      { load_from_memory(m_program); }
200INSTRUCTION( ldc_r2_Irr1 )      { load_to_memory(m_program); }
201INSTRUCTION( ldci_Ir1_Irr2 )    { load_from_memory_autoinc(m_program); }
202INSTRUCTION( ldci_Ir2_Irr1 )    { load_to_memory_autoinc(m_program); }
203INSTRUCTION( lde_r1_Irr2 )      { load_from_memory(m_data); }
204INSTRUCTION( lde_r2_Irr1 )      { load_to_memory(m_data); }
205INSTRUCTION( ldei_Ir1_Irr2 )    { load_from_memory_autoinc(m_data); }
206INSTRUCTION( ldei_Ir2_Irr1 )    { load_to_memory_autoinc(m_data); }
207207
208static void pop(z8_state *cpustate, UINT8 dst)
208void z8_device::pop(UINT8 dst)
209209{
210210   /* dst <- @SP
211211      SP <- SP + 1 */
212   register_write(cpustate, dst, stack_pop_byte(cpustate));
212   register_write(dst, stack_pop_byte());
213213}
214214
215215INSTRUCTION( pop_R1 )           { mode_R1(pop) }
216216INSTRUCTION( pop_IR1 )          { mode_IR1(pop) }
217217
218static void push(z8_state *cpustate, UINT8 src)
218void z8_device::push(UINT8 src)
219219{
220220   /* SP <- SP - 1
221221      @SP <- src */
222   stack_push_byte(cpustate, read(src));
222   stack_push_byte(read(src));
223223}
224224
225225INSTRUCTION( push_R2 )          { mode_R1(push) }
r26676r26677
229229    ARITHMETIC INSTRUCTIONS
230230***************************************************************************/
231231
232static void add_carry(z8_state *cpustate, UINT8 dst, INT8 src)
232void z8_device::add_carry(UINT8 dst, INT8 src)
233233{
234234   /* dst <- dst + src + C */
235   UINT8 data = register_read(cpustate, dst);
235   UINT8 data = register_read(dst);
236236   UINT16 new_data = data + src + flag(C);
237237
238238   set_flag_c(new_data & 0x100);
r26676r26677
242242   set_flag_d(0);
243243   set_flag_h(((data & 0x1f) == 0x0f) && ((new_data & 0x1f) == 0x10));
244244
245   register_write(cpustate, dst, new_data & 0xff);
245   register_write(dst, new_data & 0xff);
246246}
247247
248248INSTRUCTION( adc_r1_r2 )        { mode_r1_r2(add_carry) }
r26676r26677
252252INSTRUCTION( adc_R1_IM )        { mode_R1_IM(add_carry) }
253253INSTRUCTION( adc_IR1_IM )       { mode_IR1_IM(add_carry) }
254254
255static void add(z8_state *cpustate, UINT8 dst, INT8 src)
255void z8_device::add(UINT8 dst, INT8 src)
256256{
257257   /* dst <- dst + src */
258   UINT8 data = register_read(cpustate, dst);
258   UINT8 data = register_read(dst);
259259   UINT16 new_data = data + src;
260260
261261   set_flag_c(new_data & 0x100);
r26676r26677
265265   set_flag_d(0);
266266   set_flag_h(((data & 0x1f) == 0x0f) && ((new_data & 0x1f) == 0x10));
267267
268   register_write(cpustate, dst, new_data & 0xff);
268   register_write(dst, new_data & 0xff);
269269}
270270
271271INSTRUCTION( add_r1_r2 )        { mode_r1_r2(add) }
r26676r26677
275275INSTRUCTION( add_R1_IM )        { mode_R1_IM(add) }
276276INSTRUCTION( add_IR1_IM )       { mode_IR1_IM(add) }
277277
278static void compare(z8_state *cpustate, UINT8 dst, UINT8 src)
278void z8_device::compare(UINT8 dst, UINT8 src)
279279{
280280   /* dst - src */
281   UINT8 data = register_read(cpustate, dst);
281   UINT8 data = register_read(dst);
282282   UINT16 new_data = data - src;
283283
284284   set_flag_c(!(new_data & 0x100));
r26676r26677
294294INSTRUCTION( cp_R1_IM )         { mode_R1_IM(compare) }
295295INSTRUCTION( cp_IR1_IM )        { mode_IR1_IM(compare) }
296296
297static void decimal_adjust(z8_state *cpustate, UINT8 dst)
297void z8_device::decimal_adjust(UINT8 dst)
298298{
299299}
300300
301301INSTRUCTION( da_R1 )            { mode_R1(decimal_adjust) }
302302INSTRUCTION( da_IR1 )           { mode_IR1(decimal_adjust) }
303303
304static void decrement(z8_state *cpustate, UINT8 dst)
304void z8_device::decrement(UINT8 dst)
305305{
306306   /* dst <- dst - 1 */
307   UINT8 data = register_read(cpustate, dst) - 1;
307   UINT8 data = register_read(dst) - 1;
308308
309309   set_flag_z(data == 0);
310310   set_flag_s(data & 0x80);
311311   set_flag_v(data == 0x7f);
312312
313   register_write(cpustate, dst, data);
313   register_write(dst, data);
314314}
315315
316316INSTRUCTION( dec_R1 )           { mode_R1(decrement) }
317317INSTRUCTION( dec_IR1 )          { mode_IR1(decrement) }
318318
319static void decrement_word(z8_state *cpustate, UINT8 dst)
319void z8_device::decrement_word(UINT8 dst)
320320{
321321   /* dst <- dst - 1 */
322   UINT16 data = register_pair_read(cpustate, dst) - 1;
322   UINT16 data = register_pair_read(dst) - 1;
323323
324324   set_flag_z(data == 0);
325325   set_flag_s(data & 0x8000);
326326   set_flag_v(data == 0x7fff);
327327
328   register_pair_write(cpustate, dst, data);
328   register_pair_write(dst, data);
329329}
330330
331331INSTRUCTION( decw_RR1 )         { mode_RR1(decrement_word) }
332332INSTRUCTION( decw_IR1 )         { mode_IR1(decrement_word) }
333333
334static void increment(z8_state *cpustate, UINT8 dst)
334void z8_device::increment(UINT8 dst)
335335{
336336   /* dst <- dst + 1 */
337   UINT8 data = register_read(cpustate, dst) + 1;
337   UINT8 data = register_read(dst) + 1;
338338
339339   set_flag_z(data == 0);
340340   set_flag_s(data & 0x80);
341341   set_flag_v(data == 0x80);
342342
343   register_write(cpustate, dst, data);
343   register_write(dst, data);
344344}
345345
346346INSTRUCTION( inc_r1 )           { mode_r1(increment) }
347347INSTRUCTION( inc_R1 )           { mode_R1(increment) }
348348INSTRUCTION( inc_IR1 )          { mode_IR1(increment) }
349349
350static void increment_word(z8_state *cpustate, UINT8 dst)
350void z8_device::increment_word(UINT8 dst)
351351{
352352   /* dst <- dst + 1 */
353   UINT16 data = register_pair_read(cpustate, dst) + 1;
353   UINT16 data = register_pair_read(dst) + 1;
354354
355355   set_flag_z(data == 0);
356356   set_flag_s(data & 0x8000);
357357   set_flag_v(data == 0x8000);
358358
359   register_pair_write(cpustate, dst, data);
359   register_pair_write(dst, data);
360360}
361361
362362INSTRUCTION( incw_RR1 )         { mode_RR1(increment_word) }
363363INSTRUCTION( incw_IR1 )         { mode_IR1(increment_word) }
364364
365static void subtract_carry(z8_state *cpustate, UINT8 dst, UINT8 src)
365void z8_device::subtract_carry(UINT8 dst, UINT8 src)
366366{
367367   /* dst <- dst - src - C */
368   UINT8 data = register_read(cpustate, dst);
368   UINT8 data = register_read(dst);
369369   UINT16 new_data = data - src;
370370
371371   set_flag_c(!(new_data & 0x100));
r26676r26677
375375   set_flag_d(1);
376376   set_flag_h(!(((data & 0x1f) == 0x0f) && ((new_data & 0x1f) == 0x10)));
377377
378   register_write(cpustate, dst, new_data & 0xff);
378   register_write(dst, new_data & 0xff);
379379}
380380
381381INSTRUCTION( sbc_r1_r2 )        { mode_r1_r2(subtract_carry) }
r26676r26677
385385INSTRUCTION( sbc_R1_IM )        { mode_R1_IM(subtract_carry) }
386386INSTRUCTION( sbc_IR1_IM )       { mode_IR1_IM(subtract_carry) }
387387
388static void subtract(z8_state *cpustate, UINT8 dst, UINT8 src)
388void z8_device::subtract(UINT8 dst, UINT8 src)
389389{
390390   /* dst <- dst - src */
391   UINT8 data = register_read(cpustate, dst);
391   UINT8 data = register_read(dst);
392392   UINT16 new_data = data - src;
393393
394394   set_flag_c(!(new_data & 0x100));
r26676r26677
398398   set_flag_d(1);
399399   set_flag_h(!(((data & 0x1f) == 0x0f) && ((new_data & 0x1f) == 0x10)));
400400
401   register_write(cpustate, dst, new_data & 0xff);
401   register_write(dst, new_data & 0xff);
402402}
403403
404404INSTRUCTION( sub_r1_r2 )        { mode_r1_r2(subtract) }
r26676r26677
412412    LOGICAL INSTRUCTIONS
413413***************************************************************************/
414414
415static void _and(z8_state *cpustate, UINT8 dst, UINT8 src)
415void z8_device::_and(UINT8 dst, UINT8 src)
416416{
417417   /* dst <- dst AND src */
418   UINT8 data = register_read(cpustate, dst) & src;
419   register_write(cpustate, dst, data);
418   UINT8 data = register_read(dst) & src;
419   register_write(dst, data);
420420
421421   set_flag_z(data == 0);
422422   set_flag_s(data & 0x80);
r26676r26677
430430INSTRUCTION( and_R1_IM )        { mode_R1_IM(_and) }
431431INSTRUCTION( and_IR1_IM )       { mode_IR1_IM(_and) }
432432
433static void complement(z8_state *cpustate, UINT8 dst)
433void z8_device::complement(UINT8 dst)
434434{
435435   /* dst <- NOT dst */
436   UINT8 data = register_read(cpustate, dst) ^ 0xff;
437   register_write(cpustate, dst, data);
436   UINT8 data = register_read(dst) ^ 0xff;
437   register_write(dst, data);
438438
439439   set_flag_z(data == 0);
440440   set_flag_s(data & 0x80);
r26676r26677
444444INSTRUCTION( com_R1 )           { mode_R1(complement) }
445445INSTRUCTION( com_IR1 )          { mode_IR1(complement) }
446446
447static void _or(z8_state *cpustate, UINT8 dst, UINT8 src)
447void z8_device::_or(UINT8 dst, UINT8 src)
448448{
449449   /* dst <- dst OR src */
450   UINT8 data = register_read(cpustate, dst) | src;
451   register_write(cpustate, dst, data);
450   UINT8 data = register_read(dst) | src;
451   register_write(dst, data);
452452
453453   set_flag_z(data == 0);
454454   set_flag_s(data & 0x80);
r26676r26677
462462INSTRUCTION( or_R1_IM )         { mode_R1_IM(_or) }
463463INSTRUCTION( or_IR1_IM )        { mode_IR1_IM(_or) }
464464
465static void _xor(z8_state *cpustate, UINT8 dst, UINT8 src)
465void z8_device::_xor(UINT8 dst, UINT8 src)
466466{
467467   /* dst <- dst XOR src */
468   UINT8 data = register_read(cpustate, dst) ^ src;
469   register_write(cpustate, dst, data);
468   UINT8 data = register_read(dst) ^ src;
469   register_write(dst, data);
470470
471471   set_flag_z(data == 0);
472472   set_flag_s(data & 0x80);
r26676r26677
484484    PROGRAM CONTROL INSTRUCTIONS
485485***************************************************************************/
486486
487static void call(z8_state *cpustate, UINT16 dst)
487void z8_device::call(UINT16 dst)
488488{
489   stack_push_word(cpustate, cpustate->pc);
490   cpustate->pc = dst;
489   stack_push_word(m_pc);
490   m_pc = dst;
491491}
492492
493INSTRUCTION( call_IRR1 )        { UINT16 dst = register_pair_read(cpustate, get_intermediate_register(cpustate, get_register(cpustate, fetch(cpustate)))); call(cpustate, dst); }
494INSTRUCTION( call_DA )          { UINT16 dst = (fetch(cpustate) << 8) | fetch(cpustate); call(cpustate, dst); }
493INSTRUCTION( call_IRR1 )        { UINT16 dst = register_pair_read(get_intermediate_register(get_register(fetch()))); call(dst); }
494INSTRUCTION( call_DA )          { UINT16 dst = (fetch() << 8) | fetch(); call(dst); }
495495
496496INSTRUCTION( djnz_r1_RA )
497497{
498   INT8 ra = (INT8)fetch(cpustate);
498   INT8 ra = (INT8)fetch();
499499
500500   /* r <- r - 1 */
501   int r = get_working_register(cpustate, opcode >> 4);
502   UINT8 data = register_read(cpustate, r) - 1;
503   register_write(cpustate, r, data);
501   int r = get_working_register(opcode >> 4);
502   UINT8 data = register_read(r) - 1;
503   register_write(r, data);
504504
505505   /* if r<>0, PC <- PC + dst */
506506   if (data != 0)
507507   {
508      cpustate->pc += ra;
508      m_pc += ra;
509509      *cycles += 2;
510510   }
511511}
r26676r26677
514514{
515515   /* FLAGS <- @SP
516516      SP <- SP + 1 */
517   register_write(cpustate, Z8_REGISTER_FLAGS, stack_pop_byte(cpustate));
517   register_write(Z8_REGISTER_FLAGS, stack_pop_byte());
518518
519519   /* PC <- @SP
520520      SP <- SP + 2 */
521   cpustate->pc = stack_pop_word(cpustate);
521   m_pc = stack_pop_word();
522522
523523   /* IMR (7) <- 1 */
524   cpustate->r[Z8_REGISTER_IMR] |= Z8_IMR_ENABLE;
524   m_r[Z8_REGISTER_IMR] |= Z8_IMR_ENABLE;
525525}
526526
527527INSTRUCTION( ret )
528528{
529529   /* PC <- @SP
530530      SP <- SP + 2 */
531   cpustate->pc = stack_pop_word(cpustate);
531   m_pc = stack_pop_word();
532532}
533533
534static void jump(z8_state *cpustate, UINT16 dst)
534void z8_device::jump(UINT16 dst)
535535{
536536   /* PC <- dst */
537   cpustate->pc = dst;
537   m_pc = dst;
538538}
539539
540INSTRUCTION( jp_IRR1 )          { jump(cpustate, register_pair_read(cpustate, IR)); }
540INSTRUCTION( jp_IRR1 )          { jump(register_pair_read(IR)); }
541541
542static int check_condition_code(z8_state *cpustate, int cc)
542int z8_device::check_condition_code(int cc)
543543{
544544   int truth = 0;
545545
r26676r26677
568568
569569INSTRUCTION( jp_cc_DA )
570570{
571   UINT16 dst = (fetch(cpustate) << 8) | fetch(cpustate);
571   UINT16 dst = (fetch() << 8) | fetch();
572572
573573   /* if cc is true, then PC <- dst */
574   if (check_condition_code(cpustate, opcode >> 4))
574   if (check_condition_code(opcode >> 4))
575575   {
576      jump(cpustate, dst);
576      jump(dst);
577577      *cycles += 2;
578578   }
579579}
580580
581581INSTRUCTION( jr_cc_RA )
582582{
583   INT8 ra = (INT8)fetch(cpustate);
584   UINT16 dst = cpustate->pc + ra;
583   INT8 ra = (INT8)fetch();
584   UINT16 dst = m_pc + ra;
585585
586586   /* if cc is true, then PC <- dst */
587   if (check_condition_code(cpustate, opcode >> 4))
587   if (check_condition_code(opcode >> 4))
588588   {
589      jump(cpustate, dst);
589      jump(dst);
590590      *cycles += 2;
591591   }
592592}
r26676r26677
595595    BIT MANIPULATION INSTRUCTIONS
596596***************************************************************************/
597597
598static void test_complement_under_mask(z8_state *cpustate, UINT8 dst, UINT8 src)
598void z8_device::test_complement_under_mask(UINT8 dst, UINT8 src)
599599{
600600   /* NOT(dst) AND src */
601   UINT8 data = (register_read(cpustate, dst) ^ 0xff) & src;
601   UINT8 data = (register_read(dst) ^ 0xff) & src;
602602
603603   set_flag_z(data == 0);
604604   set_flag_s(data & 0x80);
r26676r26677
612612INSTRUCTION( tcm_R1_IM )        { mode_R1_IM(test_complement_under_mask) }
613613INSTRUCTION( tcm_IR1_IM )       { mode_IR1_IM(test_complement_under_mask) }
614614
615static void test_under_mask(z8_state *cpustate, UINT8 dst, UINT8 src)
615void z8_device::test_under_mask(UINT8 dst, UINT8 src)
616616{
617617   /* dst AND src */
618   UINT8 data = register_read(cpustate, dst) & src;
618   UINT8 data = register_read(dst) & src;
619619
620620   set_flag_z(data == 0);
621621   set_flag_s(data & 0x80);
r26676r26677
633633    ROTATE AND SHIFT INSTRUCTIONS
634634***************************************************************************/
635635
636static void rotate_left(z8_state *cpustate, UINT8 dst)
636void z8_device::rotate_left(UINT8 dst)
637637{
638638   /* << */
639   UINT8 data = register_read(cpustate, dst);
639   UINT8 data = register_read(dst);
640640   UINT8 new_data = (data << 1) | BIT(data, 7);
641641
642642   set_flag_c(data & 0x80);
r26676r26677
644644   set_flag_s(new_data & 0x80);
645645   set_flag_v((data & 0x80) != (new_data & 0x80));
646646
647   register_write(cpustate, dst, new_data);
647   register_write(dst, new_data);
648648}
649649
650650INSTRUCTION( rl_R1 )            { mode_R1(rotate_left) }
651651INSTRUCTION( rl_IR1 )           { mode_IR1(rotate_left) }
652652
653static void rotate_left_carry(z8_state *cpustate, UINT8 dst)
653void z8_device::rotate_left_carry(UINT8 dst)
654654{
655655   /* << C */
656   UINT8 data = register_read(cpustate, dst);
656   UINT8 data = register_read(dst);
657657   UINT8 new_data = (data << 1) | flag(C);
658658
659659   set_flag_c(data & 0x80);
r26676r26677
661661   set_flag_s(new_data & 0x80);
662662   set_flag_v((data & 0x80) != (new_data & 0x80));
663663
664   register_write(cpustate, dst, new_data);
664   register_write(dst, new_data);
665665}
666666
667667INSTRUCTION( rlc_R1 )           { mode_R1(rotate_left_carry) }
668668INSTRUCTION( rlc_IR1 )          { mode_IR1(rotate_left_carry) }
669669
670static void rotate_right(z8_state *cpustate, UINT8 dst)
670void z8_device::rotate_right(UINT8 dst)
671671{
672672   /* >> */
673   UINT8 data = register_read(cpustate, dst);
673   UINT8 data = register_read(dst);
674674   UINT8 new_data = ((data & 0x01) << 7) | (data >> 1);
675675
676676   set_flag_c(data & 0x01);
r26676r26677
678678   set_flag_s(new_data & 0x80);
679679   set_flag_v((data & 0x80) != (new_data & 0x80));
680680
681   register_write(cpustate, dst, new_data);
681   register_write(dst, new_data);
682682}
683683
684684INSTRUCTION( rr_R1 )            { mode_R1(rotate_right) }
685685INSTRUCTION( rr_IR1 )           { mode_IR1(rotate_right) }
686686
687static void rotate_right_carry(z8_state *cpustate, UINT8 dst)
687void z8_device::rotate_right_carry(UINT8 dst)
688688{
689689   /* >> C */
690   UINT8 data = register_read(cpustate, dst);
690   UINT8 data = register_read(dst);
691691   UINT8 new_data = (flag(C) << 7) | (data >> 1);
692692
693693   set_flag_c(data & 0x01);
r26676r26677
695695   set_flag_s(new_data & 0x80);
696696   set_flag_v((data & 0x80) != (new_data & 0x80));
697697
698   register_write(cpustate, dst, new_data);
698   register_write(dst, new_data);
699699}
700700
701701INSTRUCTION( rrc_R1 )           { mode_R1(rotate_right_carry) }
702702INSTRUCTION( rrc_IR1 )          { mode_IR1(rotate_right_carry) }
703703
704static void shift_right_arithmetic(z8_state *cpustate, UINT8 dst)
704void z8_device::shift_right_arithmetic(UINT8 dst)
705705{
706706   /* */
707   UINT8 data = register_read(cpustate, dst);
707   UINT8 data = register_read(dst);
708708   UINT8 new_data = (data & 0x80) | ((data >> 1) & 0x7f);
709709
710710   set_flag_c(data & 0x01);
r26676r26677
712712   set_flag_s(new_data & 0x80);
713713   set_flag_v(0);
714714
715   register_write(cpustate, dst, new_data);
715   register_write(dst, new_data);
716716}
717717
718718INSTRUCTION( sra_R1 )           { mode_R1(shift_right_arithmetic) }
719719INSTRUCTION( sra_IR1 )          { mode_IR1(shift_right_arithmetic) }
720720
721static void swap(z8_state *cpustate, UINT8 dst)
721void z8_device::swap(UINT8 dst)
722722{
723723   /* dst(7-4) <-> dst(3-0) */
724   UINT8 data = register_read(cpustate, dst);
724   UINT8 data = register_read(dst);
725725   data = (data << 4) | (data >> 4);
726   register_write(cpustate, dst, data);
726   register_write(dst, data);
727727
728728   set_flag_z(data == 0);
729729   set_flag_s(data & 0x80);
r26676r26677
737737    CPU CONTROL INSTRUCTIONS
738738***************************************************************************/
739739
740INSTRUCTION( ccf )              { cpustate->r[Z8_REGISTER_FLAGS] ^= Z8_FLAGS_C; }
741INSTRUCTION( di )               { cpustate->r[Z8_REGISTER_IMR] &= ~Z8_IMR_ENABLE; }
742INSTRUCTION( ei )               { cpustate->r[Z8_REGISTER_IMR] |= Z8_IMR_ENABLE; }
740INSTRUCTION( ccf )              { m_r[Z8_REGISTER_FLAGS] ^= Z8_FLAGS_C; }
741INSTRUCTION( di )               { m_r[Z8_REGISTER_IMR] &= ~Z8_IMR_ENABLE; }
742INSTRUCTION( ei )               { m_r[Z8_REGISTER_IMR] |= Z8_IMR_ENABLE; }
743743INSTRUCTION( nop )              { /* no operation */ }
744744INSTRUCTION( rcf )              { set_flag_c(0); }
745745INSTRUCTION( scf )              { set_flag_c(1); }
746INSTRUCTION( srp_IM )           { cpustate->r[Z8_REGISTER_RP] = fetch(cpustate); }
746INSTRUCTION( srp_IM )           { m_r[Z8_REGISTER_RP] = fetch(); }
trunk/src/emu/cpu/z8/z8.h
r26676r26677
2323   Z8_GENSP = STATE_GENSP
2424};
2525
26
27class z8_device :  public cpu_device
28{
29public:
30   // construction/destruction
31   z8_device(const machine_config &mconfig, device_type type, const char *name, const char *_tag, device_t *_owner, UINT32 _clock, const char *shortname, const char *source, int size);
32
33protected:
34   // device-level overrides
35   virtual void device_start();
36   virtual void device_reset();
37
38   // device_execute_interface overrides
39   virtual UINT32 execute_min_cycles() const { return 6; }
40   virtual UINT32 execute_max_cycles() const { return 20; }
41   virtual UINT32 execute_input_lines() const { return 4; }
42   virtual UINT64 execute_clocks_to_cycles(UINT64 clocks) const { return (clocks + 2 - 1) / 2; }
43   virtual UINT64 execute_cycles_to_clocks(UINT64 cycles) const { return (cycles * 2); }
44   virtual void execute_run();
45   virtual void execute_set_input(int inputnum, int state);
46
47   // device_memory_interface overrides
48   virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const
49   {
50      switch ( spacenum )
51      {
52         case AS_PROGRAM:   return &m_program_config;
53         case AS_DATA:      return &m_data_config;
54         case AS_IO:        return &m_io_config;
55         default:           return NULL;
56      }
57      return NULL;
58   }
59
60   // device_state_interface overrides
61   virtual void state_import(const device_state_entry &entry);
62   virtual void state_export(const device_state_entry &entry);
63   void state_string_export(const device_state_entry &entry, astring &string);
64
65   // device_disasm_interface overrides
66   virtual UINT32 disasm_min_opcode_bytes() const { return 1; }
67   virtual UINT32 disasm_max_opcode_bytes() const { return 3; }
68   virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
69
70
71private:
72   address_space_config m_program_config;
73   address_space_config m_data_config;
74   address_space_config m_io_config;
75
76   address_space *m_program;
77   direct_read_data *m_direct;
78   address_space *m_data;
79   address_space *m_io;
80
81   /* registers */
82   UINT16 m_pc;              /* program counter */
83   UINT8 m_r[256];           /* register file */
84   UINT8 m_input[4];         /* port input latches */
85   UINT8 m_output[4];        /* port output latches */
86   UINT8 m_t0;               /* timer 0 current count */
87   UINT8 m_t1;               /* timer 1 current count */
88
89   /* fake registers */
90   UINT16 m_fake_sp;         /* fake stack pointer */
91   UINT8 m_fake_r[16];       /* fake working registers */
92
93   /* interrupts */
94   int m_irq[6];             /* interrupts */
95
96   /* execution logic */
97   int m_icount;             /* instruction counter */
98
99   /* timers */
100   emu_timer *m_t0_timer;
101   emu_timer *m_t1_timer;
102
103   TIMER_CALLBACK_MEMBER( t0_tick );
104   TIMER_CALLBACK_MEMBER( t1_tick );
105
106   inline UINT8 fetch();
107   inline UINT8 register_read(UINT8 offset);
108   inline UINT16 register_pair_read(UINT8 offset);
109   inline void register_write(UINT8 offset, UINT8 data);
110   inline void register_pair_write(UINT8 offset, UINT16 data);
111   inline UINT8 get_working_register(int offset);
112   inline UINT8 get_register(UINT8 offset);
113   inline UINT8 get_intermediate_register(int offset);
114   inline void stack_push_byte(UINT8 src);
115   inline void stack_push_word(UINT16 src);
116   inline UINT8 stack_pop_byte();
117   inline UINT16 stack_pop_word();
118   inline void set_flag(UINT8 flag, int state);
119   inline void clear(UINT8 dst);
120   inline void load(UINT8 dst, UINT8 src);
121   inline void load_from_memory(address_space *space);
122   inline void load_to_memory(address_space *space);
123   inline void load_from_memory_autoinc(address_space *space);
124   inline void load_to_memory_autoinc(address_space *space);
125   inline void pop(UINT8 dst);
126   inline void push(UINT8 src);
127   inline void add_carry(UINT8 dst, INT8 src);
128   inline void add(UINT8 dst, INT8 src);
129   inline void compare(UINT8 dst, UINT8 src);
130   inline void decimal_adjust(UINT8 dst);
131   inline void decrement(UINT8 dst);
132   inline void decrement_word(UINT8 dst);
133   inline void increment(UINT8 dst);
134   inline void increment_word(UINT8 dst);
135   inline void subtract_carry(UINT8 dst, UINT8 src);
136   inline void subtract(UINT8 dst, UINT8 src);
137   inline void _and(UINT8 dst, UINT8 src);
138   inline void complement(UINT8 dst);
139   inline void _or(UINT8 dst, UINT8 src);
140   inline void _xor(UINT8 dst, UINT8 src);
141   inline void call(UINT16 dst);
142   inline void jump(UINT16 dst);
143   inline int check_condition_code(int cc);
144   inline void test_complement_under_mask(UINT8 dst, UINT8 src);
145   inline void test_under_mask(UINT8 dst, UINT8 src);
146   inline void rotate_left(UINT8 dst);
147   inline void rotate_left_carry(UINT8 dst);
148   inline void rotate_right(UINT8 dst);
149   inline void rotate_right_carry(UINT8 dst);
150   inline void shift_right_arithmetic(UINT8 dst);
151   inline void swap(UINT8 dst);
152
153   #define INSTRUCTION(inst) void inst(UINT8 opcode, int *cycles);
154   INSTRUCTION( illegal );
155   INSTRUCTION( clr_R1 );
156   INSTRUCTION( clr_IR1 );
157   INSTRUCTION( ld_r1_IM );
158   INSTRUCTION( ld_r1_R2 );
159   INSTRUCTION( ld_r2_R1 );
160   INSTRUCTION( ld_Ir1_r2 );
161   INSTRUCTION( ld_R2_IR1 );
162   INSTRUCTION( ld_r1_x_R2 );
163   INSTRUCTION( ld_r2_x_R1 );
164   INSTRUCTION( ld_r1_r2 );
165   INSTRUCTION( ld_r1_Ir2 );
166   INSTRUCTION( ld_R2_R1 );
167   INSTRUCTION( ld_IR2_R1 );
168   INSTRUCTION( ld_R1_IM );
169   INSTRUCTION( ld_IR1_IM );
170   INSTRUCTION( ldc_r1_Irr2 );
171   INSTRUCTION( ldc_r2_Irr1 );
172   INSTRUCTION( ldci_Ir1_Irr2 );
173   INSTRUCTION( ldci_Ir2_Irr1 );
174   INSTRUCTION( lde_r1_Irr2 );
175   INSTRUCTION( lde_r2_Irr1 );
176   INSTRUCTION( ldei_Ir1_Irr2 );
177   INSTRUCTION( ldei_Ir2_Irr1 );
178   INSTRUCTION( pop_R1 );
179   INSTRUCTION( pop_IR1 );
180   INSTRUCTION( push_R2 );
181   INSTRUCTION( push_IR2 );
182   INSTRUCTION( adc_r1_r2 );
183   INSTRUCTION( adc_r1_Ir2 );
184   INSTRUCTION( adc_R2_R1 );
185   INSTRUCTION( adc_IR2_R1 );
186   INSTRUCTION( adc_R1_IM );
187   INSTRUCTION( adc_IR1_IM );
188   INSTRUCTION( add_r1_r2 );
189   INSTRUCTION( add_r1_Ir2 );
190   INSTRUCTION( add_R2_R1 );
191   INSTRUCTION( add_IR2_R1 );
192   INSTRUCTION( add_R1_IM );
193   INSTRUCTION( add_IR1_IM );
194   INSTRUCTION( cp_r1_r2 );
195   INSTRUCTION( cp_r1_Ir2 );
196   INSTRUCTION( cp_R2_R1 );
197   INSTRUCTION( cp_IR2_R1 );
198   INSTRUCTION( cp_R1_IM );
199   INSTRUCTION( cp_IR1_IM );
200   INSTRUCTION( da_R1 );
201   INSTRUCTION( da_IR1 );
202   INSTRUCTION( dec_R1 );
203   INSTRUCTION( dec_IR1 );
204   INSTRUCTION( decw_RR1 );
205   INSTRUCTION( decw_IR1 );
206   INSTRUCTION( inc_r1 );
207   INSTRUCTION( inc_R1 );
208   INSTRUCTION( inc_IR1 );
209   INSTRUCTION( incw_RR1 );
210   INSTRUCTION( incw_IR1 );
211   INSTRUCTION( sbc_r1_r2 );
212   INSTRUCTION( sbc_r1_Ir2 );
213   INSTRUCTION( sbc_R2_R1 );
214   INSTRUCTION( sbc_IR2_R1 );
215   INSTRUCTION( sbc_R1_IM );
216   INSTRUCTION( sbc_IR1_IM );
217   INSTRUCTION( sub_r1_r2 );
218   INSTRUCTION( sub_r1_Ir2 );
219   INSTRUCTION( sub_R2_R1 );
220   INSTRUCTION( sub_IR2_R1 );
221   INSTRUCTION( sub_R1_IM );
222   INSTRUCTION( sub_IR1_IM );
223   INSTRUCTION( and_r1_r2 );
224   INSTRUCTION( and_r1_Ir2 );
225   INSTRUCTION( and_R2_R1 );
226   INSTRUCTION( and_IR2_R1 );
227   INSTRUCTION( and_R1_IM );
228   INSTRUCTION( and_IR1_IM );
229   INSTRUCTION( com_R1 );
230   INSTRUCTION( com_IR1 );
231   INSTRUCTION( or_r1_r2 );
232   INSTRUCTION( or_r1_Ir2 );
233   INSTRUCTION( or_R2_R1 );
234   INSTRUCTION( or_IR2_R1 );
235   INSTRUCTION( or_R1_IM );
236   INSTRUCTION( or_IR1_IM );
237   INSTRUCTION( xor_r1_r2 );
238   INSTRUCTION( xor_r1_Ir2 );
239   INSTRUCTION( xor_R2_R1 );
240   INSTRUCTION( xor_IR2_R1 );
241   INSTRUCTION( xor_R1_IM );
242   INSTRUCTION( xor_IR1_IM );
243   INSTRUCTION( call_IRR1 );
244   INSTRUCTION( call_DA );
245   INSTRUCTION( djnz_r1_RA );
246   INSTRUCTION( iret );
247   INSTRUCTION( ret );
248   INSTRUCTION( jp_IRR1 );
249   INSTRUCTION( jp_cc_DA )
250   INSTRUCTION( jr_cc_RA )
251   INSTRUCTION( tcm_r1_r2 );
252   INSTRUCTION( tcm_r1_Ir2 );
253   INSTRUCTION( tcm_R2_R1 );
254   INSTRUCTION( tcm_IR2_R1 );
255   INSTRUCTION( tcm_R1_IM );
256   INSTRUCTION( tcm_IR1_IM );
257   INSTRUCTION( tm_r1_r2 );
258   INSTRUCTION( tm_r1_Ir2 );
259   INSTRUCTION( tm_R2_R1 );
260   INSTRUCTION( tm_IR2_R1 );
261   INSTRUCTION( tm_R1_IM );
262   INSTRUCTION( tm_IR1_IM );
263   INSTRUCTION( rl_R1 );
264   INSTRUCTION( rl_IR1 );
265   INSTRUCTION( rlc_R1 );
266   INSTRUCTION( rlc_IR1 );
267   INSTRUCTION( rr_R1 );
268   INSTRUCTION( rr_IR1 );
269   INSTRUCTION( rrc_R1 );
270   INSTRUCTION( rrc_IR1 );
271   INSTRUCTION( sra_R1 );
272   INSTRUCTION( sra_IR1 );
273   INSTRUCTION( swap_R1 );
274   INSTRUCTION( swap_IR1 );
275   INSTRUCTION( ccf );
276   INSTRUCTION( di );
277   INSTRUCTION( ei );
278   INSTRUCTION( nop );
279   INSTRUCTION( rcf );
280   INSTRUCTION( scf );
281   INSTRUCTION( srp_IM );
282   #undef INSTRUCTION
283
284   typedef void (z8_device::*z8_opcode_func) (UINT8 opcode, int *cycles);
285   struct z8_opcode_map
286   {
287      z8_opcode_func  function;
288      int             execution_cycles;
289      int             pipeline_cycles;
290   };
291   static const z8_opcode_map Z8601_OPCODE_MAP[256];
292
293};
294
295
296class z8601_device : public z8_device
297{
298public:
299   z8601_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
300};
301
302
303class ub8830d_device : public z8_device
304{
305public:
306   ub8830d_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
307};
308
309
310class z8611_device : public z8_device
311{
312public:
313   z8611_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
314};
315
316
26317/* Zilog Z8601 */
27DECLARE_LEGACY_CPU_DEVICE(Z8601, z8601);
318extern const device_type Z8601;
28319
29320/* VEB Mikroelektronik Erfurt UB8830D MME */
30DECLARE_LEGACY_CPU_DEVICE(UB8830D, ub8830d);
321extern const device_type UB8830D;
31322
32323/* Zilog Z8611 */
33DECLARE_LEGACY_CPU_DEVICE(Z8611, z8611);
324extern const device_type Z8611;
34325
35CPU_DISASSEMBLE( z8 );
36326
37327#endif

Previous 199869 Revisions Next


© 1997-2024 The MAME Team