summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/z8000/z8000.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/z8000/z8000.c')
-rw-r--r--trunk/src/emu/cpu/z8000/z8000.c719
1 files changed, 719 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/z8000/z8000.c b/trunk/src/emu/cpu/z8000/z8000.c
new file mode 100644
index 00000000000..09f69555c83
--- /dev/null
+++ b/trunk/src/emu/cpu/z8000/z8000.c
@@ -0,0 +1,719 @@
+/*****************************************************************************
+ *
+ * z8000.c
+ * Portable Z8000(2) emulator
+ * Z8000 MAME interface
+ *
+ * Copyright Juergen Buchmueller, all rights reserved.
+ * You can contact me at juergen@mame.net or pullmoll@stop1984.com
+ *
+ * - This source code is released as freeware for non-commercial purposes
+ * as part of the M.A.M.E. (Multiple Arcade Machine Emulator) project.
+ * The licensing terms of MAME apply to this piece of code for the MAME
+ * project and derviative works, as defined by the MAME license. You
+ * may opt to make modifications, improvements or derivative works under
+ * that same conditions, and the MAME project may opt to keep
+ * modifications, improvements or derivatives under their terms exclusively.
+ *
+ * - Alternatively you can choose to apply the terms of the "GPL" (see
+ * below) to this - and only this - piece of code or your derivative works.
+ * Note that in no case your choice can have any impact on any other
+ * source code of the MAME project, or binary, or executable, be it closely
+ * or losely related to this piece of code.
+ *
+ * - At your choice you are also free to remove either licensing terms from
+ * this file and continue to use it under only one of the two licenses. Do this
+ * if you think that licenses are not compatible (enough) for you, or if you
+ * consider either license 'too restrictive' or 'too free'.
+ *
+ * - GPL (GNU General Public License)
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * TODO:
+ * - make the z8001 opcodes to be dynamic (i.e. to take segmented mode flag into account and use the non-segmented mode)
+ * - dissassembler doesn't work at all with the z8001
+ *
+ *****************************************************************************/
+
+#include "emu.h"
+#include "debugger.h"
+#include "z8000.h"
+
+#define VERBOSE 0
+
+
+#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
+
+typedef union _z8000_reg_file z8000_reg_file;
+union _z8000_reg_file
+{
+ UINT8 B[16]; /* RL0,RH0,RL1,RH1...RL7,RH7 */
+ UINT16 W[16]; /* R0,R1,R2...R15 */
+ UINT32 L[8]; /* RR0,RR2,RR4..RR14 */
+ UINT64 Q[4]; /* RQ0,RQ4,..RQ12 */
+};
+
+/* In z8000cpu.h: typedef struct _z8000_state z8000_state; */
+struct _z8000_state
+{
+ UINT16 op[4]; /* opcodes/data of current instruction */
+ UINT32 ppc; /* previous program counter */
+ UINT32 pc; /* program counter */
+ UINT16 psap; /* program status pointer */
+ UINT16 fcw; /* flags and control word */
+ UINT16 refresh; /* refresh timer/counter */
+ UINT16 nsp; /* system stack pointer */
+ UINT16 irq_req; /* CPU is halted, interrupt or trap request */
+ UINT16 irq_srv; /* serviced interrupt request */
+ UINT16 irq_vec; /* interrupt vector */
+ z8000_reg_file regs;/* registers */
+ int nmi_state; /* NMI line state */
+ int irq_state[2]; /* IRQ line states (NVI, VI) */
+ device_irq_callback irq_callback;
+ legacy_cpu_device *device;
+ address_space *program;
+ direct_read_data *direct;
+ address_space *io;
+ int icount;
+};
+
+#include "z8000cpu.h"
+
+INLINE z8000_state *get_safe_token(device_t *device)
+{
+ assert(device != NULL);
+ assert(device->type() == Z8001 || device->type() == Z8002);
+ return (z8000_state *)downcast<legacy_cpu_device *>(device)->token();
+}
+
+/* opcode execution table */
+Z8000_exec *z8000_exec = NULL;
+
+/* zero, sign and parity flags for logical byte operations */
+static UINT8 z8000_zsp[256];
+
+/* conversion table for Z8000 DAB opcode */
+#include "z8000dab.h"
+
+INLINE UINT16 RDOP(z8000_state *cpustate)
+{
+ UINT16 res = cpustate->direct->read_decrypted_word(cpustate->pc);
+ cpustate->pc += 2;
+ return res;
+}
+
+INLINE UINT8 RDMEM_B(z8000_state *cpustate, UINT32 addr)
+{
+ return cpustate->program->read_byte(addr);
+}
+
+INLINE UINT16 RDMEM_W(z8000_state *cpustate, UINT32 addr)
+{
+ addr &= ~1;
+ return cpustate->program->read_word(addr);
+}
+
+INLINE UINT32 RDMEM_L(z8000_state *cpustate, UINT32 addr)
+{
+ UINT32 result;
+ addr &= ~1;
+ result = cpustate->program->read_word(addr) << 16;
+ return result + cpustate->program->read_word(addr + 2);
+}
+
+INLINE void WRMEM_B(z8000_state *cpustate, UINT32 addr, UINT8 value)
+{
+ cpustate->program->write_byte(addr, value);
+}
+
+INLINE void WRMEM_W(z8000_state *cpustate, UINT32 addr, UINT16 value)
+{
+ addr &= ~1;
+ cpustate->program->write_word(addr, value);
+}
+
+INLINE void WRMEM_L(z8000_state *cpustate, UINT32 addr, UINT32 value)
+{
+ addr &= ~1;
+ cpustate->program->write_word(addr, value >> 16);
+ cpustate->program->write_word((UINT16)(addr + 2), value & 0xffff);
+}
+
+INLINE UINT8 RDPORT_B(z8000_state *cpustate, int mode, UINT16 addr)
+{
+ if(mode == 0)
+ {
+ return cpustate->io->read_byte(addr);
+ }
+ else
+ {
+ /* how to handle MMU reads? */
+ return 0x00;
+ }
+}
+
+INLINE UINT16 RDPORT_W(z8000_state *cpustate, int mode, UINT16 addr)
+{
+ if(mode == 0)
+ {
+ return cpustate->io->read_byte((UINT16)(addr)) +
+ (cpustate->io->read_byte((UINT16)(addr+1)) << 8);
+ }
+ else
+ {
+ /* how to handle MMU reads? */
+ return 0x0000;
+ }
+}
+
+INLINE void WRPORT_B(z8000_state *cpustate, int mode, UINT16 addr, UINT8 value)
+{
+ if(mode == 0)
+ {
+ cpustate->io->write_byte(addr,value);
+ }
+ else
+ {
+ /* how to handle MMU writes? */
+ }
+}
+
+INLINE void WRPORT_W(z8000_state *cpustate, int mode, UINT16 addr, UINT16 value)
+{
+ if(mode == 0)
+ {
+ cpustate->io->write_byte((UINT16)(addr),value & 0xff);
+ cpustate->io->write_byte((UINT16)(addr+1),(value >> 8) & 0xff);
+ }
+ else
+ {
+ /* how to handle MMU writes? */
+ }
+}
+
+INLINE UINT16 fetch(z8000_state *cpustate)
+{
+ UINT16 data = cpustate->direct->read_decrypted_word(cpustate->pc);
+
+ cpustate->pc+=2;
+
+ return data;
+}
+
+INLINE void cycles(z8000_state *cpustate, int cycles)
+{
+ cpustate->icount -= cycles;
+}
+
+#include "z8000ops.c"
+#include "z8000tbl.c"
+
+INLINE void set_irq(z8000_state *cpustate, int type)
+{
+ switch ((type >> 8) & 255)
+ {
+ case Z8000_TRAP >> 8:
+ if (cpustate->irq_srv >= Z8000_TRAP)
+ return; /* double TRAP.. very bad :( */
+ cpustate->irq_req = type;
+ break;
+ case Z8000_NMI >> 8:
+ if (cpustate->irq_srv >= Z8000_NMI)
+ return; /* no NMIs inside trap */
+ cpustate->irq_req = type;
+ break;
+ case Z8000_SEGTRAP >> 8:
+ if (cpustate->irq_srv >= Z8000_SEGTRAP)
+ return; /* no SEGTRAPs inside NMI/TRAP */
+ cpustate->irq_req = type;
+ break;
+ case Z8000_NVI >> 8:
+ if (cpustate->irq_srv >= Z8000_NVI)
+ return; /* no NVIs inside SEGTRAP/NMI/TRAP */
+ cpustate->irq_req = type;
+ break;
+ case Z8000_VI >> 8:
+ if (cpustate->irq_srv >= Z8000_VI)
+ return; /* no VIs inside NVI/SEGTRAP/NMI/TRAP */
+ cpustate->irq_req = type;
+ break;
+ case Z8000_SYSCALL >> 8:
+ LOG(("Z8K '%s' SYSCALL $%02x\n", cpustate->device->tag(), type & 0xff));
+ cpustate->irq_req = type;
+ break;
+ default:
+ logerror("Z8000 invalid Cause_Interrupt %04x\n", type);
+ return;
+ }
+ /* set interrupt request flag, reset HALT flag */
+ cpustate->irq_req = type & ~Z8000_HALT;
+}
+
+
+INLINE void Interrupt(z8000_state *cpustate)
+{
+ UINT16 fcw = cpustate->fcw;
+
+ if (cpustate->irq_req & Z8000_NVI)
+ {
+ int type = (*cpustate->irq_callback)(cpustate->device, 0);
+ set_irq(cpustate, type);
+ }
+
+ if (cpustate->irq_req & Z8000_VI)
+ {
+ int type = (*cpustate->irq_callback)(cpustate->device, 1);
+ set_irq(cpustate, type);
+ }
+
+ /* trap ? */
+ if (cpustate->irq_req & Z8000_TRAP)
+ {
+ CHANGE_FCW(cpustate, fcw | F_S_N);/* swap to system stack */
+ PUSHW(cpustate, SP, cpustate->pc); /* save current cpustate->pc */
+ PUSHW(cpustate, SP, fcw); /* save current cpustate->fcw */
+ PUSHW(cpustate, SP, cpustate->irq_req); /* save interrupt/trap type tag */
+ cpustate->irq_srv = cpustate->irq_req;
+ cpustate->irq_req &= ~Z8000_TRAP;
+ cpustate->pc = TRAP;
+ LOG(("Z8K '%s' trap $%04x\n", cpustate->device->tag(), cpustate->pc));
+ }
+ else
+ if (cpustate->irq_req & Z8000_SYSCALL)
+ {
+ CHANGE_FCW(cpustate, fcw | F_S_N);/* swap to system stack */
+ PUSHW(cpustate, SP, cpustate->pc); /* save current cpustate->pc */
+ PUSHW(cpustate, SP, fcw); /* save current cpustate->fcw */
+ PUSHW(cpustate, SP, cpustate->irq_req); /* save interrupt/trap type tag */
+ cpustate->irq_srv = cpustate->irq_req;
+ cpustate->irq_req &= ~Z8000_SYSCALL;
+ cpustate->pc = SYSCALL;
+ LOG(("Z8K '%s' syscall $%04x\n", cpustate->device->tag(), cpustate->pc));
+ }
+ else
+ if (cpustate->irq_req & Z8000_SEGTRAP)
+ {
+ CHANGE_FCW(cpustate, fcw | F_S_N);/* swap to system stack */
+ PUSHW(cpustate, SP, cpustate->pc); /* save current cpustate->pc */
+ PUSHW(cpustate, SP, fcw); /* save current cpustate->fcw */
+ PUSHW(cpustate, SP, cpustate->irq_req); /* save interrupt/trap type tag */
+ cpustate->irq_srv = cpustate->irq_req;
+ cpustate->irq_req &= ~Z8000_SEGTRAP;
+ cpustate->pc = SEGTRAP;
+ LOG(("Z8K '%s' segtrap $%04x\n", cpustate->device->tag(), cpustate->pc));
+ }
+ else
+ if (cpustate->irq_req & Z8000_NMI)
+ {
+ CHANGE_FCW(cpustate, fcw | F_S_N);/* swap to system stack */
+ PUSHW(cpustate, SP, cpustate->pc); /* save current cpustate->pc */
+ PUSHW(cpustate, SP, fcw); /* save current cpustate->fcw */
+ PUSHW(cpustate, SP, cpustate->irq_req); /* save interrupt/trap type tag */
+ cpustate->irq_srv = cpustate->irq_req;
+ fcw = RDMEM_W(cpustate, NMI);
+ cpustate->pc = RDMEM_W(cpustate, NMI + 2);
+ cpustate->irq_req &= ~Z8000_NMI;
+ CHANGE_FCW(cpustate, fcw);
+ cpustate->pc = NMI;
+ LOG(("Z8K '%s' NMI $%04x\n", cpustate->device->tag(), cpustate->pc));
+ }
+ else
+ if ((cpustate->irq_req & Z8000_NVI) && (cpustate->fcw & F_NVIE))
+ {
+ CHANGE_FCW(cpustate, fcw | F_S_N);/* swap to system stack */
+ PUSHW(cpustate, SP, cpustate->pc); /* save current cpustate->pc */
+ PUSHW(cpustate, SP, fcw); /* save current cpustate->fcw */
+ PUSHW(cpustate, SP, cpustate->irq_req); /* save interrupt/trap type tag */
+ cpustate->irq_srv = cpustate->irq_req;
+ fcw = RDMEM_W(cpustate, NVI);
+ cpustate->pc = RDMEM_W(cpustate, NVI + 2);
+ cpustate->irq_req &= ~Z8000_NVI;
+ CHANGE_FCW(cpustate, fcw);
+ LOG(("Z8K '%s' NVI $%04x\n", cpustate->device->tag(), cpustate->pc));
+ }
+ else
+ if ((cpustate->irq_req & Z8000_VI) && (cpustate->fcw & F_VIE))
+ {
+ CHANGE_FCW(cpustate, fcw | F_S_N);/* swap to system stack */
+ PUSHW(cpustate, SP, cpustate->pc); /* save current cpustate->pc */
+ PUSHW(cpustate, SP, fcw); /* save current cpustate->fcw */
+ PUSHW(cpustate, SP, cpustate->irq_req); /* save interrupt/trap type tag */
+ cpustate->irq_srv = cpustate->irq_req;
+ fcw = RDMEM_W(cpustate, cpustate->irq_vec);
+ cpustate->pc = RDMEM_W(cpustate, VEC00 + 2 * (cpustate->irq_req & 0xff));
+ cpustate->irq_req &= ~Z8000_VI;
+ CHANGE_FCW(cpustate, fcw);
+ LOG(("Z8K '%s' VI [$%04x/$%04x] fcw $%04x, pc $%04x\n", cpustate->device->tag(), cpustate->irq_vec, VEC00 + VEC00 + 2 * (cpustate->irq_req & 0xff), cpustate->fcw, cpustate->pc));
+ }
+}
+
+static CPU_INIT( z8001 )
+{
+ z8000_state *cpustate = get_safe_token(device);
+
+ cpustate->irq_callback = irqcallback;
+ cpustate->device = device;
+ cpustate->program = device->space(AS_PROGRAM);
+ cpustate->direct = &cpustate->program->direct();
+ cpustate->io = device->space(AS_IO);
+
+ /* already initialized? */
+ if(z8000_exec == NULL)
+ z8001_init_tables();
+}
+
+static CPU_INIT( z8002 )
+{
+ z8000_state *cpustate = get_safe_token(device);
+
+ cpustate->irq_callback = irqcallback;
+ cpustate->device = device;
+ cpustate->program = device->space(AS_PROGRAM);
+ cpustate->direct = &cpustate->program->direct();
+ cpustate->io = device->space(AS_IO);
+
+ /* already initialized? */
+ if(z8000_exec == NULL)
+ z8002_init_tables();
+}
+
+static CPU_RESET( z8001 )
+{
+ z8000_state *cpustate = get_safe_token(device);
+
+ device_irq_callback save_irqcallback = cpustate->irq_callback;
+ memset(cpustate, 0, sizeof(*cpustate));
+ cpustate->irq_callback = save_irqcallback;
+ cpustate->device = device;
+ cpustate->program = device->space(AS_PROGRAM);
+ cpustate->direct = &cpustate->program->direct();
+ cpustate->io = device->space(AS_IO);
+ cpustate->fcw = RDMEM_W(cpustate, 2); /* get reset cpustate->fcw */
+ if(cpustate->fcw & F_SEG)
+ {
+ cpustate->pc = ((RDMEM_W(cpustate, 4) & 0x0700) << 8) | (RDMEM_W(cpustate, 6) & 0xffff); /* get reset cpustate->pc */
+ }
+ else
+ {
+ cpustate->pc = RDMEM_W(cpustate, 4); /* get reset cpustate->pc */
+ }
+}
+
+static CPU_RESET( z8002 )
+{
+ z8000_state *cpustate = get_safe_token(device);
+
+ device_irq_callback save_irqcallback = cpustate->irq_callback;
+ memset(cpustate, 0, sizeof(*cpustate));
+ cpustate->irq_callback = save_irqcallback;
+ cpustate->device = device;
+ cpustate->program = device->space(AS_PROGRAM);
+ cpustate->direct = &cpustate->program->direct();
+ cpustate->io = device->space(AS_IO);
+ cpustate->fcw = RDMEM_W(cpustate, 2); /* get reset cpustate->fcw */
+ cpustate->pc = RDMEM_W(cpustate, 4); /* get reset cpustate->pc */
+}
+
+static CPU_EXIT( z8000 )
+{
+ z8000_deinit_tables();
+}
+
+static CPU_EXECUTE( z8000 )
+{
+ z8000_state *cpustate = get_safe_token(device);
+
+ do
+ {
+ /* any interrupt request pending? */
+ if (cpustate->irq_req)
+ Interrupt(cpustate);
+
+ debugger_instruction_hook(device, cpustate->pc);
+
+ if (cpustate->irq_req & Z8000_HALT)
+ {
+ cpustate->icount = 0;
+ }
+ else
+ {
+ Z8000_exec *exec;
+ cpustate->op[0] = RDOP(cpustate);
+ exec = &z8000_exec[cpustate->op[0]];
+
+ if (exec->size > 1)
+ cpustate->op[1] = RDOP(cpustate);
+ if (exec->size > 2)
+ cpustate->op[2] = RDOP(cpustate);
+
+ cpustate->icount -= exec->cycles;
+ (*exec->opcode)(cpustate);
+ }
+ } while (cpustate->icount > 0);
+
+}
+
+static void set_irq_line(z8000_state *cpustate, int irqline, int state)
+{
+ if (irqline == INPUT_LINE_NMI)
+ {
+ if (cpustate->nmi_state == state)
+ return;
+
+ cpustate->nmi_state = state;
+
+ if (state != CLEAR_LINE)
+ {
+ if (cpustate->irq_srv >= Z8000_NMI) /* no NMIs inside trap */
+ return;
+ cpustate->irq_req = Z8000_NMI;
+ cpustate->irq_vec = NMI;
+ }
+ }
+ else if (irqline < 2)
+ {
+ cpustate->irq_state[irqline] = state;
+ if (irqline == 0)
+ {
+ if (state == CLEAR_LINE)
+ {
+ if (!(cpustate->fcw & F_NVIE))
+ cpustate->irq_req &= ~Z8000_NVI;
+ }
+ else
+ {
+ if (cpustate->fcw & F_NVIE)
+ cpustate->irq_req |= Z8000_NVI;
+ }
+ }
+ else
+ {
+ if (state == CLEAR_LINE)
+ {
+ if (!(cpustate->fcw & F_VIE))
+ cpustate->irq_req &= ~Z8000_VI;
+ }
+ else
+ {
+ if (cpustate->fcw & F_VIE)
+ cpustate->irq_req |= Z8000_VI;
+ }
+ }
+ }
+}
+
+
+
+/**************************************************************************
+ * Generic set_info
+ **************************************************************************/
+
+static CPU_SET_INFO( z8002 )
+{
+ z8000_state *cpustate = get_safe_token(device);
+
+ switch (state)
+ {
+ /* --- the following bits of info are set as 64-bit signed integers --- */
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: set_irq_line(cpustate, INPUT_LINE_NMI, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + 0: set_irq_line(cpustate, 0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + 1: set_irq_line(cpustate, 1, info->i); break;
+
+ case CPUINFO_INT_PC: cpustate->pc = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_PC: cpustate->pc = info->i; break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + Z8000_NSP: cpustate->nsp = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_FCW: cpustate->fcw = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_PSAP: cpustate->psap = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_REFRESH: cpustate->refresh = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_IRQ_REQ: cpustate->irq_req = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_IRQ_SRV: cpustate->irq_srv = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_IRQ_VEC: cpustate->irq_vec = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R0: cpustate->RW( 0) = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R1: cpustate->RW( 1) = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R2: cpustate->RW( 2) = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R3: cpustate->RW( 3) = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R4: cpustate->RW( 4) = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R5: cpustate->RW( 5) = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R6: cpustate->RW( 6) = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R7: cpustate->RW( 7) = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R8: cpustate->RW( 8) = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R9: cpustate->RW( 9) = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R10: cpustate->RW(10) = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R11: cpustate->RW(11) = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R12: cpustate->RW(12) = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R13: cpustate->RW(13) = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R14: cpustate->RW(14) = info->i; break;
+ case CPUINFO_INT_REGISTER + Z8000_R15: cpustate->RW(15) = info->i; break;
+ }
+}
+
+
+
+/**************************************************************************
+ * Generic get_info
+ **************************************************************************/
+
+CPU_GET_INFO( z8002 )
+{
+ z8000_state *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(z8000_state); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 2; break;
+ case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0xff; break;
+ case DEVINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break;
+ case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
+ case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 2; break;
+ case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 6; break;
+ case CPUINFO_INT_MIN_CYCLES: info->i = 2; break;
+ case CPUINFO_INT_MAX_CYCLES: info->i = 744; break;
+
+ case DEVINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 16; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 16; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0; break;
+ case DEVINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 0; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 0; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break;
+ case DEVINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 8; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 16; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break;
+
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: info->i = cpustate->nmi_state; break;
+ case CPUINFO_INT_INPUT_STATE + 0: info->i = cpustate->irq_state[0]; break;
+ case CPUINFO_INT_INPUT_STATE + 1: info->i = cpustate->irq_state[1]; break;
+
+ case CPUINFO_INT_PREVIOUSPC: info->i = cpustate->ppc; break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + Z8000_PC: info->i = cpustate->pc; break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + Z8000_NSP: info->i = cpustate->nsp; break;
+ case CPUINFO_INT_REGISTER + Z8000_FCW: info->i = cpustate->fcw; break;
+ case CPUINFO_INT_REGISTER + Z8000_PSAP: info->i = cpustate->psap; break;
+ case CPUINFO_INT_REGISTER + Z8000_REFRESH: info->i = cpustate->refresh; break;
+ case CPUINFO_INT_REGISTER + Z8000_IRQ_REQ: info->i = cpustate->irq_req; break;
+ case CPUINFO_INT_REGISTER + Z8000_IRQ_SRV: info->i = cpustate->irq_srv; break;
+ case CPUINFO_INT_REGISTER + Z8000_IRQ_VEC: info->i = cpustate->irq_vec; break;
+ case CPUINFO_INT_REGISTER + Z8000_R0: info->i = cpustate->RW( 0); break;
+ case CPUINFO_INT_REGISTER + Z8000_R1: info->i = cpustate->RW( 1); break;
+ case CPUINFO_INT_REGISTER + Z8000_R2: info->i = cpustate->RW( 2); break;
+ case CPUINFO_INT_REGISTER + Z8000_R3: info->i = cpustate->RW( 3); break;
+ case CPUINFO_INT_REGISTER + Z8000_R4: info->i = cpustate->RW( 4); break;
+ case CPUINFO_INT_REGISTER + Z8000_R5: info->i = cpustate->RW( 5); break;
+ case CPUINFO_INT_REGISTER + Z8000_R6: info->i = cpustate->RW( 6); break;
+ case CPUINFO_INT_REGISTER + Z8000_R7: info->i = cpustate->RW( 7); break;
+ case CPUINFO_INT_REGISTER + Z8000_R8: info->i = cpustate->RW( 8); break;
+ case CPUINFO_INT_REGISTER + Z8000_R9: info->i = cpustate->RW( 9); break;
+ case CPUINFO_INT_REGISTER + Z8000_R10: info->i = cpustate->RW(10); break;
+ case CPUINFO_INT_REGISTER + Z8000_R11: info->i = cpustate->RW(11); break;
+ case CPUINFO_INT_REGISTER + Z8000_R12: info->i = cpustate->RW(12); break;
+ case CPUINFO_INT_REGISTER + Z8000_R13: info->i = cpustate->RW(13); break;
+ case CPUINFO_INT_REGISTER + Z8000_R14: info->i = cpustate->RW(14); break;
+ case CPUINFO_INT_REGISTER + Z8000_R15: info->i = cpustate->RW(15); break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(z8002); break;
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(z8002); break;
+ case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(z8002); break;
+ case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(z8000); break;
+ case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(z8000); break;
+ case CPUINFO_FCT_BURN: info->burn = NULL; break;
+ case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(z8000);break;
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "Z8002"); break;
+ case DEVINFO_STR_FAMILY: strcpy(info->s, "Zilog Z8000"); break;
+ case DEVINFO_STR_VERSION: strcpy(info->s, "1.1"); break;
+ case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
+ case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Juergen Buchmueller, all rights reserved."); break;
+
+ case CPUINFO_STR_FLAGS:
+ sprintf(info->s, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
+ cpustate->fcw & 0x8000 ? 's':'.',
+ cpustate->fcw & 0x4000 ? 'n':'.',
+ cpustate->fcw & 0x2000 ? 'e':'.',
+ cpustate->fcw & 0x1000 ? '2':'.',
+ cpustate->fcw & 0x0800 ? '1':'.',
+ cpustate->fcw & 0x0400 ? '?':'.',
+ cpustate->fcw & 0x0200 ? '?':'.',
+ cpustate->fcw & 0x0100 ? '?':'.',
+ cpustate->fcw & 0x0080 ? 'C':'.',
+ cpustate->fcw & 0x0040 ? 'Z':'.',
+ cpustate->fcw & 0x0020 ? 'S':'.',
+ cpustate->fcw & 0x0010 ? 'V':'.',
+ cpustate->fcw & 0x0008 ? 'D':'.',
+ cpustate->fcw & 0x0004 ? 'H':'.',
+ cpustate->fcw & 0x0002 ? '?':'.',
+ cpustate->fcw & 0x0001 ? '?':'.');
+ break;
+
+ case CPUINFO_STR_REGISTER + Z8000_PC: sprintf(info->s, "pc :%08X", cpustate->pc); break;
+ case CPUINFO_STR_REGISTER + Z8000_NSP: sprintf(info->s, "SP :%04X", cpustate->nsp); break;
+ case CPUINFO_STR_REGISTER + Z8000_FCW: sprintf(info->s, "fcw:%04X", cpustate->fcw); break;
+ case CPUINFO_STR_REGISTER + Z8000_PSAP: sprintf(info->s, "nsp:%04X", cpustate->psap); break;
+ case CPUINFO_STR_REGISTER + Z8000_REFRESH: sprintf(info->s, "REFR:%04X", cpustate->refresh); break;
+ case CPUINFO_STR_REGISTER + Z8000_IRQ_REQ: sprintf(info->s, "IRQR:%04X", cpustate->irq_req); break;
+ case CPUINFO_STR_REGISTER + Z8000_IRQ_SRV: sprintf(info->s, "IRQS:%04X", cpustate->irq_srv); break;
+ case CPUINFO_STR_REGISTER + Z8000_IRQ_VEC: sprintf(info->s, "IRQV:%04X", cpustate->irq_vec); break;
+ case CPUINFO_STR_REGISTER + Z8000_R0: sprintf(info->s, "R0 :%04X", cpustate->RW(0)); break;
+ case CPUINFO_STR_REGISTER + Z8000_R1: sprintf(info->s, "R1 :%04X", cpustate->RW(1)); break;
+ case CPUINFO_STR_REGISTER + Z8000_R2: sprintf(info->s, "R2 :%04X", cpustate->RW(2)); break;
+ case CPUINFO_STR_REGISTER + Z8000_R3: sprintf(info->s, "R3 :%04X", cpustate->RW(3)); break;
+ case CPUINFO_STR_REGISTER + Z8000_R4: sprintf(info->s, "R4 :%04X", cpustate->RW(4)); break;
+ case CPUINFO_STR_REGISTER + Z8000_R5: sprintf(info->s, "R5 :%04X", cpustate->RW(5)); break;
+ case CPUINFO_STR_REGISTER + Z8000_R6: sprintf(info->s, "R6 :%04X", cpustate->RW(6)); break;
+ case CPUINFO_STR_REGISTER + Z8000_R7: sprintf(info->s, "R7 :%04X", cpustate->RW(7)); break;
+ case CPUINFO_STR_REGISTER + Z8000_R8: sprintf(info->s, "R8 :%04X", cpustate->RW(8)); break;
+ case CPUINFO_STR_REGISTER + Z8000_R9: sprintf(info->s, "R9 :%04X", cpustate->RW(9)); break;
+ case CPUINFO_STR_REGISTER + Z8000_R10: sprintf(info->s, "R10:%04X", cpustate->RW(10)); break;
+ case CPUINFO_STR_REGISTER + Z8000_R11: sprintf(info->s, "R11:%04X", cpustate->RW(11)); break;
+ case CPUINFO_STR_REGISTER + Z8000_R12: sprintf(info->s, "R12:%04X", cpustate->RW(12)); break;
+ case CPUINFO_STR_REGISTER + Z8000_R13: sprintf(info->s, "R13:%04X", cpustate->RW(13)); break;
+ case CPUINFO_STR_REGISTER + Z8000_R14: sprintf(info->s, "R14:%04X", cpustate->RW(14)); break;
+ case CPUINFO_STR_REGISTER + Z8000_R15: sprintf(info->s, "R15:%04X", cpustate->RW(15)); break;
+ }
+}
+
+/*
+handling for the z8001
+*/
+
+CPU_GET_INFO( z8001 )
+{
+ switch (state)
+ {
+ case DEVINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 16; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 20; break;
+ case DEVINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 8; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 16; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(z8001); break;
+ case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(z8001); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "Zilog Z8001"); break;
+
+ default: CPU_GET_INFO_CALL(z8002); break;
+ }
+}
+
+DEFINE_LEGACY_CPU_DEVICE(Z8001, z8001);
+DEFINE_LEGACY_CPU_DEVICE(Z8002, z8002);