(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:
R. Belmont 2013-04-18 20:11:46 +00:00
parent 9367e669bb
commit 46fb72a3c6
7 changed files with 146 additions and 85 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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__ */

View File

@ -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 */

View File

@ -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: ------

View File

@ -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},

View File

@ -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