mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
(MESS) Z800x and M20 improvements to boot CP/M-8000 [Christian Groessler]
Z800x: Push the correct word on internal traps. Z800x: Fix FCW handling in system non-segmented mode. Z800x: Add missing form of ldb reg, #imm. Z800x: Show previous PC, NSPSEG, and PSAPSEG in the debugger. Z800x: Improved flags display in the debugger. Z800x: Add debugger command z8k_disass_mode to toggle segmented/non-segmented. Default "auto" tracks the current execution state. Z800x: Don't block nested exceptions if the priority and the FCW allows it. M20: Initialize memory to 0x00. M20: Some keyboard fixes.
This commit is contained in:
parent
9367e669bb
commit
46fb72a3c6
@ -47,6 +47,9 @@
|
||||
#include "emu.h"
|
||||
#include "z8000.h"
|
||||
#include "z8000cpu.h"
|
||||
#include "debugger.h"
|
||||
#include "debug/debugvw.h"
|
||||
#include "debug/debugcon.h"
|
||||
|
||||
static int n[16]; /* opcode nibbles */
|
||||
static int b[8]; /* opcode bytes */
|
||||
@ -78,6 +81,48 @@ static const char *const ints[4] = {
|
||||
"", "vi", "nvi", "vi,nvi"
|
||||
};
|
||||
|
||||
int z8k_segm; /* Current disassembler mode: 0 - non-segmented, 1 - segmented */
|
||||
int z8k_segm_mode = Z8K_SEGM_MODE_AUTO; /* User disassembler mode setting: segmented, non-segmented, auto */
|
||||
|
||||
void z8k_disass_mode(running_machine &machine, int ref, int params, const char *param[])
|
||||
{
|
||||
size_t len;
|
||||
if (params == 1)
|
||||
{
|
||||
len = strlen(param[0]);
|
||||
if (!mame_strnicmp(param[0], "segmented", len) || !mame_stricmp(param[0], "z8001")) {
|
||||
z8k_segm = true;
|
||||
z8k_segm_mode = Z8K_SEGM_MODE_SEG;
|
||||
debug_console_printf(machine, "Disassembler mode set to Z8001/segmented\n");
|
||||
}
|
||||
else if (!mame_strnicmp(param[0], "non-segmented", len) || !mame_stricmp(param[0], "z8002")) {
|
||||
z8k_segm = false;
|
||||
z8k_segm_mode = Z8K_SEGM_MODE_NONSEG;
|
||||
debug_console_printf(machine, "Disassembler mode set to Z8002/non-segmented\n");
|
||||
}
|
||||
else if (!mame_strnicmp(param[0], "automatic", len)) {
|
||||
z8k_segm_mode = Z8K_SEGM_MODE_AUTO;
|
||||
debug_console_printf(machine, "Disassembler mode set to automatic\n");
|
||||
}
|
||||
else
|
||||
goto usage;
|
||||
}
|
||||
else if (params > 1) {
|
||||
usage:
|
||||
debug_console_printf(machine, "Usage: z8k_disass_mode <mode>\n");
|
||||
debug_console_printf(machine, " set disassembler mode\n");
|
||||
debug_console_printf(machine, " mode: \"segmented\" or \"z8001\" - Z8001 mode\n");
|
||||
debug_console_printf(machine, " \"non-segmented\" or \"z8002\" - Z8002 mode\n");
|
||||
debug_console_printf(machine, " \"automatic\" - automatic mode\n");
|
||||
}
|
||||
else {
|
||||
debug_console_printf(machine, "Current disassembler mode: ");
|
||||
if (z8k_segm_mode == Z8K_SEGM_MODE_AUTO)
|
||||
debug_console_printf(machine, "automatic, currently ");
|
||||
debug_console_printf(machine, "%s\n", z8k_segm ? "Z8001/segmented" : "Z8002/non-segmented");
|
||||
}
|
||||
}
|
||||
|
||||
CPU_DISASSEMBLE( z8000 )
|
||||
{
|
||||
int new_pc = pc, i, j, tmp;
|
||||
@ -87,8 +132,6 @@ CPU_DISASSEMBLE( z8000 )
|
||||
UINT32 flags = 0;
|
||||
UINT32 old_w;
|
||||
|
||||
int segm = device->type() == Z8001;
|
||||
|
||||
/* already initialized? */
|
||||
if(z8000_exec == NULL)
|
||||
z8000_init_tables();
|
||||
@ -228,7 +271,7 @@ CPU_DISASSEMBLE( z8000 )
|
||||
/* address */
|
||||
src++;
|
||||
i = *src++ - '0';
|
||||
if (segm) {
|
||||
if (z8k_segm) {
|
||||
if (w[i] & 0x8000) {
|
||||
old_w = w[i];
|
||||
for (j = i; j < o->size; j++)
|
||||
@ -277,7 +320,7 @@ CPU_DISASSEMBLE( z8000 )
|
||||
tmp = 0;
|
||||
abort();
|
||||
}
|
||||
if (segm)
|
||||
if (z8k_segm)
|
||||
dst += sprintf(dst, "<%%%02X>%%%04X", (tmp >> 16) & 0xff, tmp & 0xffff);
|
||||
else
|
||||
dst += sprintf(dst, "%%%04x", tmp);
|
||||
|
@ -49,6 +49,7 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "debugger.h"
|
||||
#include "debug/debugcon.h"
|
||||
#include "z8000.h"
|
||||
|
||||
#define VERBOSE 0
|
||||
@ -76,7 +77,6 @@ struct z8000_state
|
||||
UINT16 nspseg; /* system stack pointer, segment (Z8001 only) */
|
||||
UINT16 nspoff; /* system stack pointer, offset */
|
||||
UINT16 irq_req; /* CPU is halted, interrupt or trap request */
|
||||
UINT16 irq_srv; /* serviced interrupt request */
|
||||
UINT16 irq_vec; /* interrupt vector */
|
||||
unsigned int op_valid; /* bit field indicating if given op[] field is already initialized */
|
||||
z8000_reg_file regs;/* registers */
|
||||
@ -211,7 +211,6 @@ INLINE UINT32 get_raw_addr_operand (z8000_state *cpustate, int opnum)
|
||||
INLINE UINT32 adjust_addr_for_nonseg_mode(z8000_state *cpustate, UINT32 addr)
|
||||
{
|
||||
if (cpustate->device->type() == Z8001 && !(cpustate->fcw & F_SEG))
|
||||
/*return (addr & 0xffff) | (cpustate->pc & 0xffff0000);*/
|
||||
return (addr & 0xffff) | (cpustate->pc & 0x7f0000);
|
||||
else
|
||||
return addr;
|
||||
@ -372,33 +371,21 @@ INLINE void set_irq(z8000_state *cpustate, int type)
|
||||
switch ((type >> 8) & 255)
|
||||
{
|
||||
case Z8000_EPU >> 8:
|
||||
if (cpustate->irq_srv >= Z8000_EPU)
|
||||
return;
|
||||
cpustate->irq_req = type;
|
||||
break;
|
||||
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:
|
||||
@ -446,8 +433,7 @@ INLINE void Interrupt(z8000_state *cpustate)
|
||||
CHANGE_FCW(cpustate, fcw | F_S_N | F_SEG_Z8001);/* switch to segmented (on Z8001) system mode */
|
||||
PUSH_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;
|
||||
PUSHW(cpustate, SP, RDMEM_W(cpustate, AS_PROGRAM, cpustate->ppc)); /* for internal traps, the 1st word of the instruction is pushed */
|
||||
cpustate->irq_req &= ~Z8000_EPU;
|
||||
CHANGE_FCW(cpustate, GET_FCW(EPU));
|
||||
cpustate->pc = GET_PC(EPU);
|
||||
@ -459,8 +445,7 @@ INLINE void Interrupt(z8000_state *cpustate)
|
||||
CHANGE_FCW(cpustate, fcw | F_S_N | F_SEG_Z8001);/* switch to segmented (on Z8001) system mode */
|
||||
PUSH_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;
|
||||
PUSHW(cpustate, SP, RDMEM_W(cpustate, AS_PROGRAM, cpustate->ppc)); /* for internal traps, the 1st word of the instruction is pushed */
|
||||
cpustate->irq_req &= ~Z8000_TRAP;
|
||||
CHANGE_FCW(cpustate, GET_FCW(TRAP));
|
||||
cpustate->pc = GET_PC(TRAP);
|
||||
@ -472,8 +457,7 @@ INLINE void Interrupt(z8000_state *cpustate)
|
||||
CHANGE_FCW(cpustate, fcw | F_S_N | F_SEG_Z8001);/* switch to segmented (on Z8001) system mode */
|
||||
PUSH_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;
|
||||
PUSHW(cpustate, SP, RDMEM_W(cpustate, AS_PROGRAM, cpustate->ppc)); /* for internal traps, the 1st word of the instruction is pushed */
|
||||
cpustate->irq_req &= ~Z8000_SYSCALL;
|
||||
CHANGE_FCW(cpustate, GET_FCW(SYSCALL));
|
||||
cpustate->pc = GET_PC(SYSCALL);
|
||||
@ -486,7 +470,6 @@ INLINE void Interrupt(z8000_state *cpustate)
|
||||
PUSH_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;
|
||||
CHANGE_FCW(cpustate, GET_FCW(SEGTRAP));
|
||||
cpustate->pc = GET_PC(SEGTRAP);
|
||||
@ -499,7 +482,6 @@ INLINE void Interrupt(z8000_state *cpustate)
|
||||
PUSH_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->pc = RDMEM_W(cpustate, AS_PROGRAM, NMI);
|
||||
cpustate->irq_req &= ~Z8000_NMI;
|
||||
CHANGE_FCW(cpustate, GET_FCW(NMI));
|
||||
@ -513,7 +495,6 @@ INLINE void Interrupt(z8000_state *cpustate)
|
||||
PUSH_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->pc = GET_PC(NVI);
|
||||
cpustate->irq_req &= ~Z8000_NVI;
|
||||
CHANGE_FCW(cpustate, GET_FCW(NVI));
|
||||
@ -526,14 +507,12 @@ INLINE void Interrupt(z8000_state *cpustate)
|
||||
PUSH_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;
|
||||
if (cpustate->device->type() == Z8001)
|
||||
cpustate->pc = segmented_addr(RDMEM_L(cpustate, AS_PROGRAM, VEC00 + 4 * (cpustate->irq_req & 0xff)));
|
||||
else
|
||||
cpustate->pc = RDMEM_W(cpustate, AS_PROGRAM, VEC00 + 2 * (cpustate->irq_req & 0xff));
|
||||
cpustate->irq_req &= ~Z8000_VI;
|
||||
CHANGE_FCW(cpustate, GET_FCW(VI));
|
||||
//printf ("z8k VI (vec 0x%x)\n", cpustate->irq_req & 0xff);
|
||||
LOG(("Z8K '%s' VI [$%04x/$%04x] fcw $%04x, pc $%04x\n", cpustate->device->tag(), cpustate->irq_vec, VEC00 + (cpustate->device->type() == Z8001 ? 4 : 2) * (cpustate->irq_req & 0xff), cpustate->fcw, cpustate->pc));
|
||||
}
|
||||
}
|
||||
@ -559,6 +538,11 @@ static CPU_INIT( z8001 )
|
||||
/* already initialized? */
|
||||
if(z8000_exec == NULL)
|
||||
z8000_init_tables();
|
||||
|
||||
if (device->machine().debug_flags & DEBUG_FLAG_ENABLED)
|
||||
debug_console_register_command(device->machine(), "z8k_disass_mode", CMDFLAG_NONE, 0, 0, 1, z8k_disass_mode);
|
||||
|
||||
z8k_segm = true;
|
||||
}
|
||||
|
||||
static CPU_INIT( z8002 )
|
||||
@ -582,6 +566,8 @@ static CPU_INIT( z8002 )
|
||||
/* already initialized? */
|
||||
if(z8000_exec == NULL)
|
||||
z8000_init_tables();
|
||||
|
||||
z8k_segm = false;
|
||||
}
|
||||
|
||||
static CPU_RESET( z8001 )
|
||||
@ -597,6 +583,7 @@ static CPU_RESET( z8001 )
|
||||
{
|
||||
cpustate->pc = RDMEM_W(cpustate, AS_PROGRAM, 4); /* get reset cpustate->pc */
|
||||
}
|
||||
cpustate->ppc = cpustate->pc;
|
||||
}
|
||||
|
||||
static CPU_RESET( z8002 )
|
||||
@ -605,6 +592,7 @@ static CPU_RESET( z8002 )
|
||||
|
||||
cpustate->fcw = RDMEM_W(cpustate, AS_PROGRAM, 2); /* get reset cpustate->fcw */
|
||||
cpustate->pc = RDMEM_W(cpustate, AS_PROGRAM, 4); /* get reset cpustate->pc */
|
||||
cpustate->ppc = cpustate->pc;
|
||||
}
|
||||
|
||||
static CPU_EXIT( z8000 )
|
||||
@ -622,6 +610,9 @@ static CPU_EXECUTE( z8000 )
|
||||
if (cpustate->irq_req)
|
||||
Interrupt(cpustate);
|
||||
|
||||
if (z8k_segm_mode == Z8K_SEGM_MODE_AUTO)
|
||||
z8k_segm = (cpustate->fcw & F_SEG_Z8001) ? 1 : 0;
|
||||
|
||||
debugger_instruction_hook(device, cpustate->pc);
|
||||
|
||||
if (cpustate->irq_req & Z8000_HALT)
|
||||
@ -632,6 +623,7 @@ static CPU_EXECUTE( z8000 )
|
||||
{
|
||||
Z8000_exec *exec;
|
||||
|
||||
cpustate->ppc = cpustate->pc;
|
||||
cpustate->op[0] = RDOP(cpustate);
|
||||
cpustate->op_valid = 1;
|
||||
exec = &z8000_exec[cpustate->op[0]];
|
||||
@ -655,8 +647,6 @@ static void set_irq_line(z8000_state *cpustate, int irqline, int 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;
|
||||
}
|
||||
@ -710,15 +700,18 @@ static CPU_SET_INFO( z8002 )
|
||||
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_PREVIOUSPC: cpustate->ppc = info->i; break;
|
||||
case CPUINFO_INT_REGISTER + Z8000_PPC: cpustate->ppc = 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->nspoff = info->i; break;
|
||||
case CPUINFO_INT_REGISTER + Z8000_NSPOFF: cpustate->nspoff = info->i; break;
|
||||
case CPUINFO_INT_REGISTER + Z8000_NSPSEG: cpustate->nspseg = info->i; break;
|
||||
case CPUINFO_INT_REGISTER + Z8000_FCW: cpustate->fcw = info->i; break;
|
||||
case CPUINFO_INT_REGISTER + Z8000_PSAP: cpustate->psapoff = info->i; break;
|
||||
case CPUINFO_INT_REGISTER + Z8000_PSAPOFF: cpustate->psapoff = info->i; break;
|
||||
case CPUINFO_INT_REGISTER + Z8000_PSAPSEG: cpustate->psapseg = 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;
|
||||
@ -777,17 +770,19 @@ CPU_GET_INFO( z8002 )
|
||||
case CPUINFO_INT_INPUT_STATE + 0: info->i = cpustate->irq_state[0]; break; /* NVI */
|
||||
case CPUINFO_INT_INPUT_STATE + 1: info->i = cpustate->irq_state[1]; break; /* VI */
|
||||
|
||||
case CPUINFO_INT_REGISTER + Z8000_PPC:
|
||||
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->nspoff; break;
|
||||
case CPUINFO_INT_REGISTER + Z8000_NSPOFF: info->i = cpustate->nspoff; break;
|
||||
case CPUINFO_INT_REGISTER + Z8000_NSPSEG: info->i = cpustate->nspseg; break;
|
||||
case CPUINFO_INT_REGISTER + Z8000_FCW: info->i = cpustate->fcw; break;
|
||||
case CPUINFO_INT_REGISTER + Z8000_PSAP: info->i = cpustate->psapoff; break;
|
||||
case CPUINFO_INT_REGISTER + Z8000_PSAPOFF: info->i = cpustate->psapoff; break;
|
||||
case CPUINFO_INT_REGISTER + Z8000_PSAPSEG: info->i = cpustate->psapseg; 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;
|
||||
@ -825,31 +820,33 @@ CPU_GET_INFO( z8002 )
|
||||
|
||||
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 & 0x8000 ? 'S':'s',
|
||||
cpustate->fcw & 0x4000 ? 'n':'N',
|
||||
cpustate->fcw & 0x2000 ? 'E':'e',
|
||||
cpustate->fcw & 0x1000 ? 'V':'v',
|
||||
cpustate->fcw & 0x0800 ? 'N':'n',
|
||||
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 & 0x0080 ? 'C':'c',
|
||||
cpustate->fcw & 0x0040 ? 'Z':'z',
|
||||
cpustate->fcw & 0x0020 ? 'S':'s',
|
||||
cpustate->fcw & 0x0010 ? 'V':'v',
|
||||
cpustate->fcw & 0x0008 ? 'D':'d',
|
||||
cpustate->fcw & 0x0004 ? 'H':'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->nspoff); break;
|
||||
case CPUINFO_STR_REGISTER + Z8000_FCW: sprintf(info->s, "fcw:%04X", cpustate->fcw); break;
|
||||
case CPUINFO_STR_REGISTER + Z8000_PSAP: sprintf(info->s, "psapoff:%04X", cpustate->psapoff); break;
|
||||
case CPUINFO_STR_REGISTER + Z8000_PPC: sprintf(info->s, "prev PC :%08X", cpustate->ppc); break;
|
||||
case CPUINFO_STR_REGISTER + Z8000_PC: sprintf(info->s, "PC :%08X", cpustate->pc); break;
|
||||
case CPUINFO_STR_REGISTER + Z8000_NSPOFF: sprintf(info->s, "NSPOFF :%04X", cpustate->nspoff); break;
|
||||
case CPUINFO_STR_REGISTER + Z8000_NSPSEG: sprintf(info->s, "NSPSEG :%04X", cpustate->nspseg); break;
|
||||
case CPUINFO_STR_REGISTER + Z8000_FCW: sprintf(info->s, "FCW:%04X", cpustate->fcw); break;
|
||||
case CPUINFO_STR_REGISTER + Z8000_PSAPOFF: sprintf(info->s, "PSAPOFF:%04X", cpustate->psapoff); break;
|
||||
case CPUINFO_STR_REGISTER + Z8000_PSAPSEG: sprintf(info->s, "PSAPSEG:%04X", cpustate->psapseg); 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;
|
||||
|
@ -6,7 +6,9 @@
|
||||
|
||||
enum
|
||||
{
|
||||
Z8000_PC=1, Z8000_NSP, Z8000_FCW, Z8000_PSAP, Z8000_REFRESH,
|
||||
Z8000_PC=1,
|
||||
Z8000_PPC, Z8000_NSPSEG, Z8000_NSPOFF, Z8000_FCW,
|
||||
Z8000_PSAPSEG, Z8000_PSAPOFF, Z8000_REFRESH,
|
||||
Z8000_IRQ_REQ, Z8000_IRQ_SRV, Z8000_IRQ_VEC,
|
||||
Z8000_R0, Z8000_R1, Z8000_R2, Z8000_R3,
|
||||
Z8000_R4, Z8000_R5, Z8000_R6, Z8000_R7,
|
||||
@ -30,4 +32,13 @@ DECLARE_LEGACY_CPU_DEVICE(Z8002, z8002);
|
||||
|
||||
CPU_DISASSEMBLE( z8000 );
|
||||
|
||||
extern int z8k_segm;
|
||||
extern int z8k_segm_mode;
|
||||
extern void z8k_disass_mode(running_machine &machine, int ref, int params, const char *param[]);
|
||||
|
||||
/* possible values for z8k_segm_mode */
|
||||
#define Z8K_SEGM_MODE_NONSEG 0
|
||||
#define Z8K_SEGM_MODE_SEG 1
|
||||
#define Z8K_SEGM_MODE_AUTO 2
|
||||
|
||||
#endif /* __Z8000_H__ */
|
||||
|
@ -59,7 +59,7 @@
|
||||
|
||||
#define PSA_ADDR (cpustate->device->type() == Z8001 ? segmented_addr((cpustate->psapseg << 16) | cpustate->psapoff) : cpustate->psapoff)
|
||||
|
||||
/* these vectors are based on cpustate->psap @@@*/
|
||||
/* these vectors are based on cpustate->psap */
|
||||
#define RST (PSA_ADDR + 0) /* start up cpustate->fcw and cpustate->pc */
|
||||
#define EPU (PSA_ADDR + (cpustate->device->type() == Z8001 ? 0x0008 : 0x0004)) /* extension processor unit? trap */
|
||||
#define TRAP (PSA_ADDR + (cpustate->device->type() == Z8001 ? 0x0010 : 0x0008)) /* privilege violation trap */
|
||||
|
@ -32,39 +32,37 @@
|
||||
******************************************/
|
||||
INLINE void CHANGE_FCW(z8000_state *cpustate, UINT16 fcw)
|
||||
{
|
||||
if (fcw & F_S_N) { /* system mode now? */
|
||||
if (!(cpustate->fcw & F_S_N)) { /* and not before? */
|
||||
if (cpustate->device->type() == Z8001) {
|
||||
UINT16 tmp = cpustate->RW(15);
|
||||
cpustate->RW(15) = cpustate->nspoff;
|
||||
cpustate->nspoff = tmp;
|
||||
UINT16 tmp;
|
||||
if ((fcw ^ cpustate->fcw) & F_S_N) { /* system/user mode change? */
|
||||
tmp = cpustate->RW(15);
|
||||
cpustate->RW(15) = cpustate->nspoff;
|
||||
cpustate->nspoff = tmp;
|
||||
}
|
||||
if (cpustate->device->type() == Z8001) {
|
||||
/* User mode R14 is used in user mode and non-segmented system mode.
|
||||
System mode R14 is only used in segmented system mode.
|
||||
There is no transition from user mode to non-segmented system mode,
|
||||
so this doesn't need to be handled here. */
|
||||
if (fcw & F_S_N) { /* new mode is system mode */
|
||||
if (!(cpustate->fcw & F_S_N) /* old mode was user mode */
|
||||
|| ((fcw ^ cpustate->fcw) & F_SEG)) { /* or switch between segmented and non-segmented */
|
||||
tmp = cpustate->RW(14);
|
||||
cpustate->RW(14) = cpustate->nspseg;
|
||||
cpustate->nspseg = tmp;
|
||||
}
|
||||
else {
|
||||
UINT16 tmp = cpustate->RW(SP);
|
||||
cpustate->RW(SP) = cpustate->nspoff;
|
||||
cpustate->nspoff = tmp;
|
||||
}
|
||||
}
|
||||
} else { /* user mode now */
|
||||
if (cpustate->fcw & F_S_N) { /* and not before? */
|
||||
if (cpustate->device->type() == Z8001) {
|
||||
UINT16 tmp = cpustate->RW(15);
|
||||
cpustate->RW(15) = cpustate->nspoff;
|
||||
cpustate->nspoff = tmp;
|
||||
else { /* new mode is user mode */
|
||||
if (cpustate->fcw & F_S_N /* old mode was system mode */
|
||||
&& cpustate->fcw & F_SEG) { /* and was segmented */
|
||||
tmp = cpustate->RW(14);
|
||||
cpustate->RW(14) = cpustate->nspseg;
|
||||
cpustate->nspseg = tmp;
|
||||
}
|
||||
else {
|
||||
UINT16 tmp = cpustate->RW(SP);
|
||||
cpustate->RW(SP) = cpustate->nspoff;
|
||||
cpustate->nspoff = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
fcw &= ~F_SEG; /* never set segmented mode bit on Z8002 */
|
||||
|
||||
if (!(cpustate->fcw & F_NVIE) && (fcw & F_NVIE) && (cpustate->irq_state[0] != CLEAR_LINE))
|
||||
cpustate->irq_req |= Z8000_NVI;
|
||||
if (!(cpustate->fcw & F_VIE) && (fcw & F_VIE) && (cpustate->irq_state[1] != CLEAR_LINE))
|
||||
@ -2462,7 +2460,7 @@ static void Z39_ssN0_0000(z8000_state *cpustate)
|
||||
fcw = RDMEM_W(cpustate, AS_DATA, cpustate->RW(src));
|
||||
set_pc(cpustate, RDMEM_W(cpustate, AS_DATA, (UINT16)(cpustate->RW(src) + 2)));
|
||||
}
|
||||
if ((fcw ^ cpustate->fcw) & F_SEG) printf("ldps 1 (0x%05x): changing from %ssegmented mode to %ssegmented mode\n", cpustate->pc, (fcw & F_SEG) ? "non-" : "", (fcw & F_SEG) ? "" : "non-");
|
||||
if ((fcw ^ cpustate->fcw) & F_SEG) printf("ldps 1 (0x%05x): changing from %ssegmented mode to %ssegmented mode\n", cpustate->pc, (cpustate->fcw & F_SEG) ? "non-" : "", (fcw & F_SEG) ? "" : "non-");
|
||||
CHANGE_FCW(cpustate, fcw); /* check for user/system mode change */
|
||||
}
|
||||
|
||||
@ -4606,7 +4604,6 @@ static void Z7B_0000_0000(z8000_state *cpustate)
|
||||
set_pc(cpustate, segmented_addr(POPL(cpustate, SP)));
|
||||
else
|
||||
cpustate->pc = POPW(cpustate, SP); /* get cpustate->pc */
|
||||
cpustate->irq_srv &= ~tag; /* remove IRQ serviced flag */
|
||||
CHANGE_FCW(cpustate, fcw); /* check for user/system mode change */
|
||||
LOG(("Z8K '%s' IRET tag $%04x, fcw $%04x, pc $%04x\n", cpustate->device->tag(), tag, fcw, cpustate->pc));
|
||||
}
|
||||
@ -6687,6 +6684,17 @@ static void ZBF_imm8(z8000_state *cpustate)
|
||||
(void)imm8;
|
||||
}
|
||||
|
||||
/******************************************
|
||||
ldb rbd,imm8 (long version)
|
||||
flags: ------
|
||||
******************************************/
|
||||
static void Z20_0000_dddd_imm8(z8000_state *cpustate)
|
||||
{
|
||||
GET_DST(OP0,NIB3);
|
||||
GET_IMM8(OP1);
|
||||
cpustate->RB(dst) = imm8;
|
||||
}
|
||||
|
||||
/******************************************
|
||||
ldb rbd,imm8
|
||||
flags: ------
|
||||
|
@ -89,6 +89,7 @@ static const Z8000_init table[] = {
|
||||
{0x1d10,0x1dff, 1,1, 11,Z1D_ddN0_ssss, "ldl @%rw2,%rl3", 0},
|
||||
{0x1e10,0x1eff, 1,1, 10,Z1E_ddN0_cccc, "jp %c3,@%rl2", 0},
|
||||
{0x1f10,0x1ff0,16,1, 10,Z1F_ddN0_0000, "call %rw2", DASMFLAG_STEP_OVER},
|
||||
{0x2000,0x200f, 1,2, 7,Z20_0000_dddd_imm8, "ldb %rb3,%#b3", 0},
|
||||
{0x2010,0x20ff, 1,1, 7,Z20_ssN0_dddd, "ldb %rb3,@%rw2", 0},
|
||||
{0x2100,0x210f, 1,2, 7,Z21_0000_dddd_imm16, "ld %rw3,%#w1", 0},
|
||||
{0x2110,0x21ff, 1,1, 7,Z21_ssN0_dddd, "ld %rw3,@%rw2", 0},
|
||||
@ -372,7 +373,7 @@ static const Z8000_init table[] = {
|
||||
{0x7d0e,0x7dfe,16,1, 7,Z7D_ssss_1ccc, "ldctl nspseg,%rw2", 0},
|
||||
{0x7d0f,0x7dff,16,1, 7,Z7D_ssss_1ccc, "ldctl nspoff,%rw2", 0},
|
||||
{0x7e00,0x7eff, 1,1, 10,Z7E_imm8, "rsvd7e %#b1", 0},
|
||||
{0x7f00,0x7fff, 1,1, 33,Z7F_imm8, "sc %#b1", 0},
|
||||
{0x7f00,0x7fff, 1,1, 33,Z7F_imm8, "sc %#b1", DASMFLAG_STEP_OVER},
|
||||
{0x8000,0x80ff, 1,1, 4,Z80_ssss_dddd, "addb %rb3,%rb2", 0},
|
||||
{0x8100,0x81ff, 1,1, 4,Z81_ssss_dddd, "add %rw3,%rw2", 0},
|
||||
{0x8200,0x82ff, 1,1, 4,Z82_ssss_dddd, "subb %rb3,%rb2", 0},
|
||||
|
@ -420,8 +420,8 @@ void m20_state::install_memory()
|
||||
pspace.install_readwrite_bank(0x24000, 0x27fff, 0x3fff, 0, "dram0_18000");
|
||||
dspace.install_readwrite_bank(0x24000, 0x27fff, 0x3fff, 0, "dram0_18000");
|
||||
/* <2>8000 */
|
||||
pspace.install_readwrite_bank(0x28000, 0x28fff, 0x3fff, 0, "dram0_1c000");
|
||||
dspace.install_readwrite_bank(0x28000, 0x28fff, 0x3fff, 0, "dram0_1c000");
|
||||
pspace.install_readwrite_bank(0x28000, 0x2bfff, 0x3fff, 0, "dram0_1c000");
|
||||
dspace.install_readwrite_bank(0x28000, 0x2bfff, 0x3fff, 0, "dram0_1c000");
|
||||
/* <2>c000 empty*/
|
||||
/* <3>0000 (video buffer)
|
||||
pspace.install_readwrite_bank(0x30000, 0x33fff, 0x3fff, 0, "dram0_0000");
|
||||
@ -489,7 +489,7 @@ void m20_state::install_memory()
|
||||
*/
|
||||
pspace.install_readwrite_bank(0x2c000, 0x2ffff, 0x3fff, 0, "dram1_0000");
|
||||
pspace.install_readwrite_bank(0x88000, 0x8bfff, 0x3fff, 0, "dram1_4000");
|
||||
pspace.install_readwrite_bank(0xa8000, 0xaffff, 0x3fff, 0, "dram1_4000");
|
||||
pspace.install_readwrite_bank(0xa8000, 0xabfff, 0x3fff, 0, "dram1_4000");
|
||||
|
||||
/*
|
||||
data
|
||||
@ -900,7 +900,8 @@ static unsigned char kbxlat[] =
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'4', '5', '6', '7', '8', '9', '-', '^', '@', '[', ';', ':', ']', ',', '.', '/',
|
||||
0x00, '<', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
|
||||
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
|
||||
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_', '!', '"', '#',
|
||||
'$', '%', '&', '\'','(', ')', '=', 'x', 'x', '{', '+', '*', '}'
|
||||
};
|
||||
|
||||
WRITE8_MEMBER( m20_state::kbd_put )
|
||||
@ -910,7 +911,6 @@ WRITE8_MEMBER( m20_state::kbd_put )
|
||||
else if (data == 0x20) data = 0xc0;
|
||||
else if (data == 8) data = 0x69; /* ^H */
|
||||
else if (data == 3) data = 0x64; /* ^C */
|
||||
else if (data >= '0' && data <= '9') data += 0x1c - '0';
|
||||
else {
|
||||
int i;
|
||||
for (i = 0; i < sizeof(kbxlat); i++)
|
||||
@ -974,6 +974,7 @@ static MACHINE_CONFIG_START( m20, m20_state )
|
||||
|
||||
MCFG_RAM_ADD(RAM_TAG)
|
||||
MCFG_RAM_DEFAULT_SIZE("160K")
|
||||
MCFG_RAM_DEFAULT_VALUE(0)
|
||||
MCFG_RAM_EXTRA_OPTIONS("128K,192K,224K,256K,384K,512K")
|
||||
|
||||
#if 0
|
||||
|
Loading…
Reference in New Issue
Block a user