summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/pdp1
diff options
context:
space:
mode:
author Wilbert Pol <wilbert@jdg.info>2013-12-25 12:00:22 +0000
committer Wilbert Pol <wilbert@jdg.info>2013-12-25 12:00:22 +0000
commitcc74ef9ade9c64a59df6bf1eff6a1d0d3ee06e16 (patch)
tree4f383303ce6359f12de1991cfee5556c2df53f32 /src/emu/cpu/pdp1
parent9c03593b09938be83736b9ee26cb5b2323e68e6b (diff)
tx0.c: Modernized cpu core. [Wilbert Pol]
Out of whatsnew: Also copied over the support for octal in debugger state from the alto2 branch.
Diffstat (limited to 'src/emu/cpu/pdp1')
-rw-r--r--src/emu/cpu/pdp1/tx0.c867
-rw-r--r--src/emu/cpu/pdp1/tx0.h152
2 files changed, 455 insertions, 564 deletions
diff --git a/src/emu/cpu/pdp1/tx0.c b/src/emu/cpu/pdp1/tx0.c
index de2fc7b8454..459b2b3ee99 100644
--- a/src/emu/cpu/pdp1/tx0.c
+++ b/src/emu/cpu/pdp1/tx0.c
@@ -15,107 +15,83 @@
#define LOG 0
#define LOG_EXTRA 0
-static void execute_instruction_64kw(device_t *device);
-static void execute_instruction_8kw(device_t *device);
-static void pulse_reset(device_t *device);
+#define READ_TX0_18BIT(A) ((signed)m_program->read_dword((A)<<2))
+#define WRITE_TX0_18BIT(A,V) (m_program->write_dword((A)<<2,(V)))
-/* TX-0 Registers */
-struct tx0_state
-{
- const tx0_reset_param_t *iface;
-
- /* processor registers */
- int mbr; /* memory buffer register (18 bits) */
- int ac; /* accumulator (18 bits) */
- int mar; /* memory address register (16 (64kW) or 13 (8kW) bits) */
- int pc; /* program counter (16 (64kW) or 13 (8kW) bits) */
- int ir; /* instruction register (2 (64kW) or 5 (8kW) bits) */
- int lr; /* live register (18 bits) */
- int xr; /* index register (14 bits) (8kW only) */
- int pf; /* program flags (6 bits expandable to 10) (8kW only) */
-
- /* operator panel switches */
- int tbr; /* toggle switch buffer register (18 bits) */
- int tac; /* toggle switch accumulator (18 bits) */
- int tss[16]; /* toggle switch storage (18 bits * 16) */
- unsigned int cm_sel : 16; /* individual cm select (1 bit * 16) */
- unsigned int lr_sel : 16; /* individual lr select (1 bit * 16) */
- unsigned int gbl_cm_sel : 1;/* global cm select (1 bit) */
- unsigned int stop_cyc0 : 1; /* stop on cycle 0 */
- unsigned int stop_cyc1 : 1; /* stop on cycle 1 */
-
- /* processor state flip-flops */
- unsigned int run : 1; /* processor is running */
- unsigned int rim : 1; /* processor is in read-in mode */
- unsigned int cycle : 2; /* 0 -> fetch */
- /* 1 -> execute (except for taken branches) */
- /* 2 -> extra execute cycle for SXA and ADO */
- unsigned int ioh : 1; /* i-o halt: processor is executing an Input-Output Transfer wait */
- unsigned int ios : 1; /* i-o synchronizer: set on i-o operation completion */
+#define io_handler_rim 3
- /* additional emulator state variables */
- int rim_step; /* current step in rim execution */
+#define PC m_pc
+#define IR m_ir
+#define MBR m_mbr
+#define MAR m_mar
+#define AC m_ac
+#define LR m_lr
+#define XR m_xr
+#define PF m_pf
- int address_mask; /* address mask */
- int ir_mask; /* IR mask */
+#define ADDRESS_MASK_64KW 0177777
+#define ADDRESS_MASK_8KW 0017777
- int icount;
+#define INCREMENT_PC_64KW (PC = (PC+1) & ADDRESS_MASK_64KW)
+#define INCREMENT_PC_8KW (PC = (PC+1) & ADDRESS_MASK_8KW)
- legacy_cpu_device *device;
- address_space *program;
-};
-INLINE tx0_state *get_safe_token(device_t *device)
+const device_type TX0_8KW = &device_creator<tx0_8kw_device>;
+const device_type TX0_64KW = &device_creator<tx0_64kw_device>;
+
+
+tx0_device::tx0_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 addr_bits, int address_mask, int ir_mask)
+ : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
+ , m_program_config("program", ENDIANNESS_BIG, 32, addr_bits , -2)
+ , m_address_mask(address_mask)
+ , m_ir_mask(ir_mask)
+ , m_cpy_handler(*this)
+ , m_r1l_handler(*this)
+ , m_dis_handler(*this)
+ , m_r3l_handler(*this)
+ , m_prt_handler(*this)
+ , m_rsv_handler(*this)
+ , m_p6h_handler(*this)
+ , m_p7h_handler(*this)
+ , m_sel_handler(*this)
+ , m_io_reset_callback(*this)
{
- assert(device != NULL);
- assert(device->type() == TX0_64KW ||
- device->type() == TX0_8KW);
- return (tx0_state *)downcast<legacy_cpu_device *>(device)->token();
+ m_is_octal = true;
}
-#define READ_TX0_18BIT(A) ((signed)cpustate->program->read_dword((A)<<2))
-#define WRITE_TX0_18BIT(A,V) (cpustate->program->write_dword((A)<<2,(V)))
-
-
-#define io_handler_rim 3
-
-#define PC cpustate->pc
-#define IR cpustate->ir
-#define MBR cpustate->mbr
-#define MAR cpustate->mar
-#define AC cpustate->ac
-#define LR cpustate->lr
-#define XR cpustate->xr
-#define PF cpustate->pf
+tx0_8kw_device::tx0_8kw_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tx0_device(mconfig, TX0_8KW, "TX-0 8KW", tag, owner, clock, "tx0_8w_cpu", __FILE__, 13, ADDRESS_MASK_8KW, 037)
+{
+}
-#define ADDRESS_MASK_64KW 0177777
-#define ADDRESS_MASK_8KW 0017777
-#define INCREMENT_PC_64KW (PC = (PC+1) & ADDRESS_MASK_64KW)
-#define INCREMENT_PC_8KW (PC = (PC+1) & ADDRESS_MASK_8KW)
+tx0_64kw_device::tx0_64kw_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tx0_device(mconfig, TX0_64KW, "TX-0 64KW", tag, owner, clock, "tx0_64kw_cpu", __FILE__, 16, ADDRESS_MASK_64KW, 03)
+{
+}
-static int tx0_read(tx0_state *cpustate, offs_t address)
+int tx0_device::tx0_read(offs_t address)
{
- if ((address >= 16) || (cpustate->gbl_cm_sel) || ((cpustate->cm_sel >> address) & 1))
+ if ((address >= 16) || (m_gbl_cm_sel) || ((m_cm_sel >> address) & 1))
/* core memory (CM) */
return READ_TX0_18BIT(address);
- else if ((cpustate->lr_sel >> address) & 1)
+ else if ((m_lr_sel >> address) & 1)
/* live register (LR) */
return LR;
/* toggle switch storage (TSS) */
- return cpustate->tss[address];
+ return m_tss[address];
}
-static void tx0_write(tx0_state *cpustate, offs_t address, int data)
+void tx0_device::tx0_write(offs_t address, int data)
{
- if ((address >= 16) || (cpustate->gbl_cm_sel) || ((cpustate->cm_sel >> address) & 1))
+ if ((address >= 16) || (m_gbl_cm_sel) || ((m_cm_sel >> address) & 1))
/* core memory (CM) */
WRITE_TX0_18BIT(address, data);
- else if ((cpustate->lr_sel >> address) & 1)
+ else if ((m_lr_sel >> address) & 1)
/* live register (LR) */
LR = data;
else
@@ -124,93 +100,186 @@ static void tx0_write(tx0_state *cpustate, offs_t address, int data)
;
}
-static void tx0_init_common(legacy_cpu_device *device, device_irq_acknowledge_callback irqcallback, int is_64kw)
+
+void tx0_device::device_start()
{
- tx0_state *cpustate = get_safe_token(device);
+ m_mbr = 0;
+ m_ac = 0;
+ m_mar = 0;
+ m_lr = 0;
+ m_xr = 0;
+ m_pf = 0;
+ m_tbr = 0;
+ m_tac = 0;
+ for ( int i = 0; i < 16; i++ )
+ {
+ m_tss[i] = 0;
+ }
+ m_cm_sel = 0;
+ m_lr_sel = 0;
+ m_gbl_cm_sel = 0;
+ m_stop_cyc0 = 0;
+ m_stop_cyc1 = 0;
+ m_cycle = 0;
+
+ // Resolve callbacks
+ m_cpy_handler.resolve();
+ m_r1l_handler.resolve();
+ m_dis_handler.resolve();
+ m_r3l_handler.resolve();
+ m_prt_handler.resolve();
+ m_rsv_handler.resolve();
+ m_p6h_handler.resolve();
+ m_p7h_handler.resolve();
+ m_sel_handler.resolve();
+ m_io_reset_callback.resolve();
+
+ m_program = &space(AS_PROGRAM);
+
+ save_item(NAME(m_mbr));
+ save_item(NAME(m_ac));
+ save_item(NAME(m_mar));
+ save_item(NAME(m_pc));
+ save_item(NAME(m_ir));
+ save_item(NAME(m_lr));
+ save_item(NAME(m_xr));
+ save_item(NAME(m_pf));
+ save_item(NAME(m_tbr));
+ save_item(NAME(m_tac));
+ save_item(NAME(m_tss));
+ save_item(NAME(m_cm_sel));
+ save_item(NAME(m_lr_sel));
+ save_item(NAME(m_gbl_cm_sel));
+ save_item(NAME(m_stop_cyc0));
+ save_item(NAME(m_stop_cyc1));
+ save_item(NAME(m_run));
+ save_item(NAME(m_rim));
+ save_item(NAME(m_cycle));
+ save_item(NAME(m_ioh));
+ save_item(NAME(m_ios));
+ save_item(NAME(m_rim_step));
+
+ // Register state for debugger
+ state_add( TX0_PC, "PC", m_pc ).mask(m_address_mask).formatstr("0%06O");
+ state_add( TX0_IR, "IR", m_ir ).mask(m_ir_mask) .formatstr("0%02O");
+ state_add( TX0_MBR, "MBR", m_mbr ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_MAR, "MAR", m_mar ).mask(m_address_mask).formatstr("0%06O");
+ state_add( TX0_AC, "AC", m_ac ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_LR, "LR", m_lr ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_XR, "XR", m_xr ).mask(0037777) .formatstr("0%05O");
+ state_add( TX0_PF, "PF", m_pf ).mask(077) .formatstr("0%02O");
+ state_add( TX0_TBR, "TBR", m_tbr ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TAC, "TAC", m_tac ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS00, "TSS00", m_tss[000] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS01, "TSS01", m_tss[001] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS02, "TSS02", m_tss[002] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS03, "TSS03", m_tss[003] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS04, "TSS04", m_tss[004] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS05, "TSS05", m_tss[005] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS06, "TSS06", m_tss[006] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS07, "TSS07", m_tss[007] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS10, "TSS10", m_tss[010] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS11, "TSS11", m_tss[011] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS12, "TSS12", m_tss[012] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS13, "TSS13", m_tss[013] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS14, "TSS14", m_tss[014] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS15, "TSS15", m_tss[015] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS16, "TSS16", m_tss[016] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_TSS17, "TSS17", m_tss[017] ).mask(0777777) .formatstr("0%06O");
+ state_add( TX0_CM_SEL, "CMSEL", m_cm_sel ).mask(0177777) .formatstr("0%06O");
+ state_add( TX0_LR_SEL, "LRSEL", m_lr_sel ).mask(0177777) .formatstr("0%06O");
+ state_add( TX0_GBL_CM_SEL, "GBLCMSEL", m_gbl_cm_sel ).mask(1) .formatstr("%1X");
+ state_add( TX0_STOP_CYC0, "STOPCYC0", m_stop_cyc0 ).mask(1) .formatstr("%1X");
+ state_add( TX0_STOP_CYC1, "STOPCYC1", m_stop_cyc1 ).mask(1) .formatstr("%1X");
+ state_add( TX0_RUN, "RUN", m_run ).mask(1) .formatstr("%1X");
+ state_add( TX0_RIM, "RIM", m_rim ).mask(1) .formatstr("%1X");
+ state_add( TX0_CYCLE, "CYCLE", m_cycle ) .formatstr("%1X");
+ state_add( TX0_IOH, "IOH", m_ioh ) .formatstr("%1X");
+ state_add( TX0_IOS, "IOS", m_ios ).mask(1) .formatstr("%1X");
+
+ state_add(STATE_GENPC, "GENPC", m_pc).formatstr("0%06O").noshow();
+ state_add(STATE_GENFLAGS, "GENFLAGS", m_ir).noshow();
+
+ m_icountptr = &m_icount;
+}
- /* clean-up */
- cpustate->iface = (const tx0_reset_param_t *)device->static_config();
- cpustate->address_mask = is_64kw ? ADDRESS_MASK_64KW : ADDRESS_MASK_8KW;
- cpustate->ir_mask = is_64kw ? 03 : 037;
+void tx0_device::device_reset()
+{
+ /* reset CPU flip-flops */
+ pulse_reset();
- cpustate->device = device;
- cpustate->program = &device->space(AS_PROGRAM);
+ m_gbl_cm_sel = 1; /* HACK */
}
-static CPU_INIT( tx0_64kw )
-{
- tx0_init_common(device, irqcallback, 1);
-}
-static CPU_INIT( tx0_8kw)
+void tx0_device::call_io_handler(int io_handler)
{
- tx0_init_common(device, irqcallback, 0);
+ /* data will be transferred to AC */
+ switch (io_handler)
+ {
+ case 0: m_cpy_handler(ASSERT_LINE); break;
+ case 1: m_r1l_handler(ASSERT_LINE); break;
+ case 2: m_dis_handler(ASSERT_LINE); break;
+ case 3: m_r3l_handler(ASSERT_LINE); break;
+ case 4: m_prt_handler(ASSERT_LINE); break;
+ case 5: m_rsv_handler(ASSERT_LINE); break;
+ case 6: m_p6h_handler(ASSERT_LINE); break;
+ case 7: m_p7h_handler(ASSERT_LINE); break;
+ }
}
-static CPU_RESET( tx0 )
-{
- tx0_state *cpustate = get_safe_token(device);
-
- /* reset CPU flip-flops */
- pulse_reset(device);
-
- cpustate->gbl_cm_sel = 1; /* HACK */
-}
/* execute instructions on this CPU until icount expires */
-static CPU_EXECUTE( tx0_64kw )
+void tx0_64kw_device::execute_run()
{
- tx0_state *cpustate = get_safe_token(device);
-
do
{
- debugger_instruction_hook(device, PC);
+ debugger_instruction_hook(this, PC);
- if (cpustate->ioh && cpustate->ios)
+ if (m_ioh && m_ios)
{
- cpustate->ioh = 0;
+ m_ioh = 0;
}
- if ((! cpustate->run) && (! cpustate->rim))
- cpustate->icount = 0; /* if processor is stopped, just burn cycles */
- else if (cpustate->rim)
+ if ((! m_run) && (! m_rim))
+ m_icount = 0; /* if processor is stopped, just burn cycles */
+ else if (m_rim)
{
- switch (cpustate->rim_step)
+ switch (m_rim_step)
{
case 0:
/* read first word as instruction */
AC = 0;
- if (cpustate->iface->io_handlers[io_handler_rim])
- (*cpustate->iface->io_handlers[io_handler_rim])(device); /* data will be transferred to AC */
- cpustate->rim_step = 1;
- cpustate->ios = 0;
+ call_io_handler(io_handler_rim);
+ m_rim_step = 1;
+ m_ios = 0;
break;
case 1:
- if (! cpustate->ios)
+ if (! m_ios)
{ /* transfer incomplete: wait some more */
- cpustate->icount = 0;
+ m_icount = 0;
}
else
{ /* data transfer complete */
- cpustate->ios = 0;
+ m_ios = 0;
MBR = AC;
IR = MBR >> 16; /* basic opcode */
if ((IR == 2) || (IR == 1)) /* trn or add instruction? */
{
PC = MBR & ADDRESS_MASK_64KW;
- cpustate->rim = 0; /* exit read-in mode */
- cpustate->run = (IR == 2) ? 1 : 0; /* stop if add instruction */
- cpustate->rim_step = 0;
+ m_rim = 0; /* exit read-in mode */
+ m_run = (IR == 2) ? 1 : 0; /* stop if add instruction */
+ m_rim_step = 0;
}
else if ((IR == 0) || (IR == 3)) /* sto or opr instruction? */
{
MAR = MBR & ADDRESS_MASK_64KW;
- cpustate->rim_step = 2;
+ m_rim_step = 2;
}
}
break;
@@ -218,106 +287,102 @@ static CPU_EXECUTE( tx0_64kw )
case 2:
/* read second word as data */
AC = 0;
- if (cpustate->iface->io_handlers[io_handler_rim])
- (*cpustate->iface->io_handlers[io_handler_rim])(device); /* data will be transferred to AC */
- cpustate->rim_step = 3;
- cpustate->ios = 0;
+ call_io_handler(io_handler_rim);
+ m_rim_step = 3;
+ m_ios = 0;
break;
case 3:
- if (! cpustate->ios)
+ if (! m_ios)
{ /* transfer incomplete: wait some more */
- cpustate->icount = 0;
+ m_icount = 0;
}
else
{ /* data transfer complete */
- cpustate->ios = 0;
+ m_ios = 0;
- tx0_write(cpustate, MAR, MBR = AC);
+ tx0_write(MAR, MBR = AC);
- cpustate->rim_step = 0;
+ m_rim_step = 0;
}
break;
}
}
else
{
- if (cpustate->cycle == 0)
+ if (m_cycle == 0)
{ /* fetch new instruction */
- MBR = tx0_read(cpustate, MAR = PC);
+ MBR = tx0_read(MAR = PC);
INCREMENT_PC_64KW;
IR = MBR >> 16; /* basic opcode */
MAR = MBR & ADDRESS_MASK_64KW;
}
- if (! cpustate->ioh)
+ if (! m_ioh)
{
- if ((cpustate->stop_cyc0 && (cpustate->cycle == 0))
- || (cpustate->stop_cyc1 && (cpustate->cycle == 1)))
- cpustate->run = 0;
+ if ((m_stop_cyc0 && (m_cycle == 0))
+ || (m_stop_cyc1 && (m_cycle == 1)))
+ m_run = 0;
- execute_instruction_64kw(device); /* execute instruction */
+ execute_instruction_64kw();
}
- cpustate->icount --;
+ m_icount --;
}
}
- while (cpustate->icount > 0);
+ while (m_icount > 0);
}
/* execute instructions on this CPU until icount expires */
-static CPU_EXECUTE( tx0_8kw )
+void tx0_8kw_device::execute_run()
{
- tx0_state *cpustate = get_safe_token(device);
-
do
{
- debugger_instruction_hook(device, PC);
+ debugger_instruction_hook(this, PC);
- if (cpustate->ioh && cpustate->ios)
+ if (m_ioh && m_ios)
{
- cpustate->ioh = 0;
+ m_ioh = 0;
}
- if ((! cpustate->run) && (! cpustate->rim))
- cpustate->icount = 0; /* if processor is stopped, just burn cycles */
- else if (cpustate->rim)
+ if ((! m_run) && (! m_rim))
+ m_icount = 0; /* if processor is stopped, just burn cycles */
+ else if (m_rim)
{
- switch (cpustate->rim_step)
+ switch (m_rim_step)
{
case 0:
/* read first word as instruction */
AC = 0;
- if (cpustate->iface->io_handlers[io_handler_rim])
- (*cpustate->iface->io_handlers[io_handler_rim])(device); /* data will be transferred to AC */
- cpustate->rim_step = 1;
- cpustate->ios = 0;
+ call_io_handler(io_handler_rim);
+ m_rim_step = 1;
+ m_ios = 0;
break;
case 1:
- if (! cpustate->ios)
+ if (! m_ios)
{ /* transfer incomplete: wait some more */
- cpustate->icount = 0;
+ m_icount = 0;
}
else
{ /* data transfer complete */
- cpustate->ios = 0;
+ m_ios = 0;
MBR = AC;
IR = MBR >> 13; /* basic opcode */
if ((IR == 16) || (IR == 8)) /* trn or add instruction? */
{
PC = MBR & ADDRESS_MASK_8KW;
- cpustate->rim = 0; /* exit read-in mode */
- cpustate->run = (IR == 16) ? 1 : 0; /* stop if add instruction */
- cpustate->rim_step = 0;
+ m_rim = 0; /* exit read-in mode */
+ m_run = (IR == 16) ? 1 : 0; /* stop if add instruction */
+ m_rim_step = 0;
}
else if ((IR == 0) || (IR == 24)) /* sto or opr instruction? */
{
MAR = MBR & ADDRESS_MASK_8KW;
- cpustate->rim_step = 2;
+ m_rim_step = 2;
}
}
break;
@@ -325,370 +390,59 @@ static CPU_EXECUTE( tx0_8kw )
case 2:
/* read second word as data */
AC = 0;
- if (cpustate->iface->io_handlers[io_handler_rim])
- (*cpustate->iface->io_handlers[io_handler_rim])(device); /* data will be transferred to AC */
- cpustate->rim_step = 3;
- cpustate->ios = 0;
+ call_io_handler(io_handler_rim);
+ m_rim_step = 3;
+ m_ios = 0;
break;
case 3:
- if (! cpustate->ios)
+ if (! m_ios)
{ /* transfer incomplete: wait some more */
- cpustate->icount = 0;
+ m_icount = 0;
}
else
{ /* data transfer complete */
- cpustate->ios = 0;
+ m_ios = 0;
- tx0_write(cpustate, MAR, MBR = AC);
+ tx0_write(MAR, MBR = AC);
- cpustate->rim_step = 0;
+ m_rim_step = 0;
}
break;
}
}
else
{
- if (cpustate->cycle == 0)
+ if (m_cycle == 0)
{ /* fetch new instruction */
- MBR = tx0_read(cpustate, MAR = PC);
+ MBR = tx0_read(MAR = PC);
INCREMENT_PC_8KW;
IR = MBR >> 13; /* basic opcode */
MAR = MBR & ADDRESS_MASK_8KW;
}
- if (! cpustate->ioh)
+ if (! m_ioh)
{
- if ((cpustate->stop_cyc0 && (cpustate->cycle == 0))
- || (cpustate->stop_cyc1 && (cpustate->cycle == 1)))
- cpustate->run = 0;
+ if ((m_stop_cyc0 && (m_cycle == 0))
+ || (m_stop_cyc1 && (m_cycle == 1)))
+ m_run = 0;
- execute_instruction_8kw(device); /* execute instruction */
+ execute_instruction_8kw();
}
- cpustate->icount -= 1;
+ m_icount -= 1;
}
}
- while (cpustate->icount > 0);
-}
-
-
-static CPU_SET_INFO( tx0 )
-{
- tx0_state *cpustate = get_safe_token(device);
-
- switch (state)
- {
- /* --- the following bits of info are set as 64-bit signed integers --- */
- case CPUINFO_INT_SP: (void) info->i; /* no SP */ break;
- case CPUINFO_INT_PC:
- case CPUINFO_INT_REGISTER + TX0_PC: PC = info->i & cpustate->address_mask; break;
- case CPUINFO_INT_REGISTER + TX0_IR: IR = info->i & cpustate->ir_mask; /* weird idea */ break;
- case CPUINFO_INT_REGISTER + TX0_MBR: MBR = info->i & 0777777; break;
- case CPUINFO_INT_REGISTER + TX0_MAR: MAR = info->i & cpustate->address_mask; break;
- case CPUINFO_INT_REGISTER + TX0_AC: AC = info->i & 0777777; break;
- case CPUINFO_INT_REGISTER + TX0_LR: LR = info->i & 0777777; break;
- case CPUINFO_INT_REGISTER + TX0_XR: XR = info->i & 0037777; break;
- case CPUINFO_INT_REGISTER + TX0_PF: PF = info->i & 077; break;
- case CPUINFO_INT_REGISTER + TX0_TBR: cpustate->tbr = info->i & 0777777; break;
- case CPUINFO_INT_REGISTER + TX0_TAC: cpustate->tac = info->i & 0777777; break;
- case CPUINFO_INT_REGISTER + TX0_TSS00:
- case CPUINFO_INT_REGISTER + TX0_TSS01:
- case CPUINFO_INT_REGISTER + TX0_TSS02:
- case CPUINFO_INT_REGISTER + TX0_TSS03:
- case CPUINFO_INT_REGISTER + TX0_TSS04:
- case CPUINFO_INT_REGISTER + TX0_TSS05:
- case CPUINFO_INT_REGISTER + TX0_TSS06:
- case CPUINFO_INT_REGISTER + TX0_TSS07:
- case CPUINFO_INT_REGISTER + TX0_TSS10:
- case CPUINFO_INT_REGISTER + TX0_TSS11:
- case CPUINFO_INT_REGISTER + TX0_TSS12:
- case CPUINFO_INT_REGISTER + TX0_TSS13:
- case CPUINFO_INT_REGISTER + TX0_TSS14:
- case CPUINFO_INT_REGISTER + TX0_TSS15:
- case CPUINFO_INT_REGISTER + TX0_TSS16:
- case CPUINFO_INT_REGISTER + TX0_TSS17: cpustate->tss[state-(CPUINFO_INT_REGISTER + TX0_TSS00)] = info->i & 0777777; break;
- case CPUINFO_INT_REGISTER + TX0_CM_SEL: cpustate->cm_sel = info->i & 0177777; break;
- case CPUINFO_INT_REGISTER + TX0_LR_SEL: cpustate->lr_sel = info->i & 0177777; break;
- case CPUINFO_INT_REGISTER + TX0_GBL_CM_SEL: cpustate->gbl_cm_sel = info->i ? 1 : 0; break;
- case CPUINFO_INT_REGISTER + TX0_STOP_CYC0: cpustate->stop_cyc0 = info->i ? 1 : 0; break;
- case CPUINFO_INT_REGISTER + TX0_STOP_CYC1: cpustate->stop_cyc1 = info->i ? 1 : 0; break;
- case CPUINFO_INT_REGISTER + TX0_RUN: cpustate->run = info->i ? 1 : 0; break;
- case CPUINFO_INT_REGISTER + TX0_RIM: cpustate->rim = info->i ? 1 : 0; break;
- case CPUINFO_INT_REGISTER + TX0_CYCLE: if (LOG) logerror("tx0_set_reg to cycle counter ignored\n");/* no way!*/ break;
- case CPUINFO_INT_REGISTER + TX0_IOH: if (LOG) logerror("tx0_set_reg to ioh flip-flop ignored\n");/* no way!*/ break;
- case CPUINFO_INT_REGISTER + TX0_IOS: cpustate->ios = info->i ? 1 : 0; break;
- case CPUINFO_INT_REGISTER + TX0_RESET: pulse_reset(device); break;
- case CPUINFO_INT_REGISTER + TX0_IO_COMPLETE:cpustate->ios = 1; break;
- }
-}
-
-
-CPU_GET_INFO( tx0_64kw )
-{
- tx0_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(tx0_state); break;
- case CPUINFO_INT_INPUT_LINES: info->i = 0; break;
- case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
- case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; /*don't care*/ 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 = 4; break;
- case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 4; break;
- case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
- case CPUINFO_INT_MAX_CYCLES: info->i = 3; break;
-
- case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 32; break;
- case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 16; break;
- case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = -2; break;
- case CPUINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break;
- case CPUINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break;
-
- case CPUINFO_INT_SP: info->i = 0; /* no SP */ break;
- case CPUINFO_INT_PC: info->i = PC; break;
- case CPUINFO_INT_PREVIOUSPC: info->i = 0; /* TODO??? */ break;
-
- case CPUINFO_INT_REGISTER + TX0_PC: info->i = PC; break;
- case CPUINFO_INT_REGISTER + TX0_IR: info->i = IR; break;
- case CPUINFO_INT_REGISTER + TX0_MBR: info->i = MBR; break;
- case CPUINFO_INT_REGISTER + TX0_MAR: info->i = MAR; break;
- case CPUINFO_INT_REGISTER + TX0_AC: info->i = AC; break;
- case CPUINFO_INT_REGISTER + TX0_LR: info->i = LR; break;
- case CPUINFO_INT_REGISTER + TX0_XR: info->i = XR; break;
- case CPUINFO_INT_REGISTER + TX0_PF: info->i = PF; break;
- case CPUINFO_INT_REGISTER + TX0_TBR: info->i = cpustate->tbr; break;
- case CPUINFO_INT_REGISTER + TX0_TAC: info->i = cpustate->tac; break;
- case CPUINFO_INT_REGISTER + TX0_TSS00:
- case CPUINFO_INT_REGISTER + TX0_TSS01:
- case CPUINFO_INT_REGISTER + TX0_TSS02:
- case CPUINFO_INT_REGISTER + TX0_TSS03:
- case CPUINFO_INT_REGISTER + TX0_TSS04:
- case CPUINFO_INT_REGISTER + TX0_TSS05:
- case CPUINFO_INT_REGISTER + TX0_TSS06:
- case CPUINFO_INT_REGISTER + TX0_TSS07:
- case CPUINFO_INT_REGISTER + TX0_TSS10:
- case CPUINFO_INT_REGISTER + TX0_TSS11:
- case CPUINFO_INT_REGISTER + TX0_TSS12:
- case CPUINFO_INT_REGISTER + TX0_TSS13:
- case CPUINFO_INT_REGISTER + TX0_TSS14:
- case CPUINFO_INT_REGISTER + TX0_TSS15:
- case CPUINFO_INT_REGISTER + TX0_TSS16:
- case CPUINFO_INT_REGISTER + TX0_TSS17: info->i = cpustate->tss[state-(CPUINFO_INT_REGISTER + TX0_TSS00)]; break;
- case CPUINFO_INT_REGISTER + TX0_CM_SEL: info->i = cpustate->cm_sel; break;
- case CPUINFO_INT_REGISTER + TX0_LR_SEL: info->i = cpustate->lr_sel; break;
- case CPUINFO_INT_REGISTER + TX0_GBL_CM_SEL: info->i = cpustate->gbl_cm_sel; break;
- case CPUINFO_INT_REGISTER + TX0_STOP_CYC0: info->i = cpustate->stop_cyc0; break;
- case CPUINFO_INT_REGISTER + TX0_STOP_CYC1: info->i = cpustate->stop_cyc1; break;
- case CPUINFO_INT_REGISTER + TX0_RUN: info->i = cpustate->run; break;
- case CPUINFO_INT_REGISTER + TX0_RIM: info->i = cpustate->rim; break;
- case CPUINFO_INT_REGISTER + TX0_CYCLE: info->i = cpustate->cycle; break;
- case CPUINFO_INT_REGISTER + TX0_IOH: info->i = cpustate->ioh; break;
- case CPUINFO_INT_REGISTER + TX0_IOS: info->i = cpustate->ios; 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(tx0); break;
- case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(tx0_64kw); break;
- case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(tx0); break;
- case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(tx0_64kw); break;
- case CPUINFO_FCT_BURN: info->burn = NULL; break;
- case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(tx0_64kw); break;
- case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case CPUINFO_STR_NAME: strcpy(info->s, "TX-0"); break;
- case CPUINFO_STR_SHORTNAME: strcpy(info->s, "tx0_64kw_cpu"); break;
- case CPUINFO_STR_FAMILY: strcpy(info->s, "TX-0"); break;
- case CPUINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
- case CPUINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
- case CPUINFO_STR_CREDITS: strcpy(info->s, "Raphael Nabet"); break;
-
- case CPUINFO_STR_FLAGS: strcpy(info->s, ""); break;
-
- case CPUINFO_STR_REGISTER + TX0_PC: sprintf(info->s, "PC:0%06o", PC); break;
- case CPUINFO_STR_REGISTER + TX0_IR: sprintf(info->s, "IR:0%02o", IR); break;
- case CPUINFO_STR_REGISTER + TX0_MBR: sprintf(info->s, "MBR:0%06o", MBR); break;
- case CPUINFO_STR_REGISTER + TX0_MAR: sprintf(info->s, "MAR:0%06o", MAR); break;
- case CPUINFO_STR_REGISTER + TX0_AC: sprintf(info->s, "AC:0%06o", AC); break;
- case CPUINFO_STR_REGISTER + TX0_LR: sprintf(info->s, "LR:0%06o", LR); break;
- case CPUINFO_STR_REGISTER + TX0_XR: sprintf(info->s, "XR:0%05o", XR); break;
- case CPUINFO_STR_REGISTER + TX0_PF: sprintf(info->s, "PF:0%02o", PF); break;
- case CPUINFO_STR_REGISTER + TX0_TBR: sprintf(info->s, "TBR:0%06o", cpustate->tbr); break;
- case CPUINFO_STR_REGISTER + TX0_TAC: sprintf(info->s, "TAC:0%06o", cpustate->tac); break;
- case CPUINFO_STR_REGISTER + TX0_TSS00:
- case CPUINFO_STR_REGISTER + TX0_TSS01:
- case CPUINFO_STR_REGISTER + TX0_TSS02:
- case CPUINFO_STR_REGISTER + TX0_TSS03:
- case CPUINFO_STR_REGISTER + TX0_TSS04:
- case CPUINFO_STR_REGISTER + TX0_TSS05:
- case CPUINFO_STR_REGISTER + TX0_TSS06:
- case CPUINFO_STR_REGISTER + TX0_TSS07:
- case CPUINFO_STR_REGISTER + TX0_TSS10:
- case CPUINFO_STR_REGISTER + TX0_TSS11:
- case CPUINFO_STR_REGISTER + TX0_TSS12:
- case CPUINFO_STR_REGISTER + TX0_TSS13:
- case CPUINFO_STR_REGISTER + TX0_TSS14:
- case CPUINFO_STR_REGISTER + TX0_TSS15:
- case CPUINFO_STR_REGISTER + TX0_TSS16:
- case CPUINFO_STR_REGISTER + TX0_TSS17: sprintf(info->s, "TSS%02o:0%06o", state-(CPUINFO_STR_REGISTER + TX0_TSS00), cpustate->tss[state-(CPUINFO_STR_REGISTER + TX0_TSS00)]); break;
- case CPUINFO_STR_REGISTER + TX0_CM_SEL: sprintf(info->s, "CMSEL:0%06o", cpustate->cm_sel); break;
- case CPUINFO_STR_REGISTER + TX0_LR_SEL: sprintf(info->s, "LRSEL:0%06o", cpustate->lr_sel); break;
- case CPUINFO_STR_REGISTER + TX0_GBL_CM_SEL: sprintf(info->s, "GBLCMSEL:%X", cpustate->gbl_cm_sel); break;
- case CPUINFO_STR_REGISTER + TX0_STOP_CYC0: sprintf(info->s, "STOPCYC0:%X", cpustate->stop_cyc0); break;
- case CPUINFO_STR_REGISTER + TX0_STOP_CYC1: sprintf(info->s, "STOPCYC1:%X", cpustate->stop_cyc1); break;
- case CPUINFO_STR_REGISTER + TX0_RUN: sprintf(info->s, "RUN:%X", cpustate->run); break;
- case CPUINFO_STR_REGISTER + TX0_RIM: sprintf(info->s, "RIM:%X", cpustate->rim); break;
- case CPUINFO_STR_REGISTER + TX0_CYCLE: sprintf(info->s, "CYCLE:%X", cpustate->cycle); break;
- case CPUINFO_STR_REGISTER + TX0_IOH: sprintf(info->s, "IOH:%X", cpustate->ioh); break;
- case CPUINFO_STR_REGISTER + TX0_IOS: sprintf(info->s, "IOS:%X", cpustate->ios); break;
- case CPUINFO_IS_OCTAL: info->i = true; break;
- }
-}
-
-CPU_GET_INFO( tx0_8kw )
-{
- tx0_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(tx0_state); break;
- case CPUINFO_INT_INPUT_LINES: info->i = 0; break;
- case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
- case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; /*don't care*/ 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 = 4; break;
- case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 4; break;
- case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
- case CPUINFO_INT_MAX_CYCLES: info->i = 3; break;
-
- case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 32; break;
- case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 13; break;
- case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = -2; break;
- case CPUINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break;
- case CPUINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 0; break;
- case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break;
-
- case CPUINFO_INT_SP: info->i = 0; /* no SP */ break;
- case CPUINFO_INT_PC: info->i = PC; break;
- case CPUINFO_INT_PREVIOUSPC: info->i = 0; /* TODO??? */ break;
-
- case CPUINFO_INT_REGISTER + TX0_PC: info->i = PC; break;
- case CPUINFO_INT_REGISTER + TX0_IR: info->i = IR; break;
- case CPUINFO_INT_REGISTER + TX0_MBR: info->i = MBR; break;
- case CPUINFO_INT_REGISTER + TX0_MAR: info->i = MAR; break;
- case CPUINFO_INT_REGISTER + TX0_AC: info->i = AC; break;
- case CPUINFO_INT_REGISTER + TX0_LR: info->i = LR; break;
- case CPUINFO_INT_REGISTER + TX0_XR: info->i = XR; break;
- case CPUINFO_INT_REGISTER + TX0_PF: info->i = PF; break;
- case CPUINFO_INT_REGISTER + TX0_TBR: info->i = cpustate->tbr; break;
- case CPUINFO_INT_REGISTER + TX0_TAC: info->i = cpustate->tac; break;
- case CPUINFO_INT_REGISTER + TX0_TSS00:
- case CPUINFO_INT_REGISTER + TX0_TSS01:
- case CPUINFO_INT_REGISTER + TX0_TSS02:
- case CPUINFO_INT_REGISTER + TX0_TSS03:
- case CPUINFO_INT_REGISTER + TX0_TSS04:
- case CPUINFO_INT_REGISTER + TX0_TSS05:
- case CPUINFO_INT_REGISTER + TX0_TSS06:
- case CPUINFO_INT_REGISTER + TX0_TSS07:
- case CPUINFO_INT_REGISTER + TX0_TSS10:
- case CPUINFO_INT_REGISTER + TX0_TSS11:
- case CPUINFO_INT_REGISTER + TX0_TSS12:
- case CPUINFO_INT_REGISTER + TX0_TSS13:
- case CPUINFO_INT_REGISTER + TX0_TSS14:
- case CPUINFO_INT_REGISTER + TX0_TSS15:
- case CPUINFO_INT_REGISTER + TX0_TSS16:
- case CPUINFO_INT_REGISTER + TX0_TSS17: info->i = cpustate->tss[state-(CPUINFO_INT_REGISTER + TX0_TSS00)]; break;
- case CPUINFO_INT_REGISTER + TX0_CM_SEL: info->i = cpustate->cm_sel; break;
- case CPUINFO_INT_REGISTER + TX0_LR_SEL: info->i = cpustate->lr_sel; break;
- case CPUINFO_INT_REGISTER + TX0_GBL_CM_SEL: info->i = cpustate->gbl_cm_sel; break;
- case CPUINFO_INT_REGISTER + TX0_STOP_CYC0: info->i = cpustate->stop_cyc0; break;
- case CPUINFO_INT_REGISTER + TX0_STOP_CYC1: info->i = cpustate->stop_cyc1; break;
- case CPUINFO_INT_REGISTER + TX0_RUN: info->i = cpustate->run; break;
- case CPUINFO_INT_REGISTER + TX0_RIM: info->i = cpustate->rim; break;
- case CPUINFO_INT_REGISTER + TX0_CYCLE: info->i = cpustate->cycle; break;
- case CPUINFO_INT_REGISTER + TX0_IOH: info->i = cpustate->ioh; break;
- case CPUINFO_INT_REGISTER + TX0_IOS: info->i = cpustate->ios; 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(tx0); break;
- case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(tx0_8kw); break;
- case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(tx0); break;
- case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(tx0_8kw); break;
- case CPUINFO_FCT_BURN: info->burn = NULL; break;
- case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(tx0_8kw); break;
- case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break;
-
- /* --- the following bits of info are returned as NULL-terminated strings --- */
- case CPUINFO_STR_NAME: strcpy(info->s, "TX-0"); break;
- case CPUINFO_STR_SHORTNAME: strcpy(info->s, "tx0_8kw_cpu"); break;
- case CPUINFO_STR_FAMILY: strcpy(info->s, "TX-0"); break;
- case CPUINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
- case CPUINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
- case CPUINFO_STR_CREDITS: strcpy(info->s, "Raphael Nabet"); break;
-
- case CPUINFO_STR_FLAGS: strcpy(info->s, ""); break;
-
- case CPUINFO_STR_REGISTER + TX0_PC: sprintf(info->s, "PC:0%06o", PC); break;
- case CPUINFO_STR_REGISTER + TX0_IR: sprintf(info->s, "IR:0%02o", IR); break;
- case CPUINFO_STR_REGISTER + TX0_MBR: sprintf(info->s, "MBR:0%06o", MBR); break;
- case CPUINFO_STR_REGISTER + TX0_MAR: sprintf(info->s, "MAR:0%06o", MAR); break;
- case CPUINFO_STR_REGISTER + TX0_AC: sprintf(info->s, "AC:0%06o", AC); break;
- case CPUINFO_STR_REGISTER + TX0_LR: sprintf(info->s, "LR:0%06o", LR); break;
- case CPUINFO_STR_REGISTER + TX0_XR: sprintf(info->s, "XR:0%05o", XR); break;
- case CPUINFO_STR_REGISTER + TX0_PF: sprintf(info->s, "PF:0%02o", PF); break;
- case CPUINFO_STR_REGISTER + TX0_TBR: sprintf(info->s, "TBR:0%06o", cpustate->tbr); break;
- case CPUINFO_STR_REGISTER + TX0_TAC: sprintf(info->s, "TAC:0%06o", cpustate->tac); break;
- case CPUINFO_STR_REGISTER + TX0_TSS00:
- case CPUINFO_STR_REGISTER + TX0_TSS01:
- case CPUINFO_STR_REGISTER + TX0_TSS02:
- case CPUINFO_STR_REGISTER + TX0_TSS03:
- case CPUINFO_STR_REGISTER + TX0_TSS04:
- case CPUINFO_STR_REGISTER + TX0_TSS05:
- case CPUINFO_STR_REGISTER + TX0_TSS06:
- case CPUINFO_STR_REGISTER + TX0_TSS07:
- case CPUINFO_STR_REGISTER + TX0_TSS10:
- case CPUINFO_STR_REGISTER + TX0_TSS11:
- case CPUINFO_STR_REGISTER + TX0_TSS12:
- case CPUINFO_STR_REGISTER + TX0_TSS13:
- case CPUINFO_STR_REGISTER + TX0_TSS14:
- case CPUINFO_STR_REGISTER + TX0_TSS15:
- case CPUINFO_STR_REGISTER + TX0_TSS16:
- case CPUINFO_STR_REGISTER + TX0_TSS17: sprintf(info->s, "TSS%02o:0%06o", state-(CPUINFO_STR_REGISTER + TX0_TSS00), cpustate->tss[state-(CPUINFO_STR_REGISTER + TX0_TSS00)]); break;
- case CPUINFO_STR_REGISTER + TX0_CM_SEL: sprintf(info->s, "CMSEL:0%06o", cpustate->cm_sel); break;
- case CPUINFO_STR_REGISTER + TX0_LR_SEL: sprintf(info->s, "LRSEL:0%06o", cpustate->lr_sel); break;
- case CPUINFO_STR_REGISTER + TX0_GBL_CM_SEL: sprintf(info->s, "GBLCMSEL:%X", cpustate->gbl_cm_sel); break;
- case CPUINFO_STR_REGISTER + TX0_STOP_CYC0: sprintf(info->s, "STOPCYC0:%X", cpustate->stop_cyc0); break;
- case CPUINFO_STR_REGISTER + TX0_STOP_CYC1: sprintf(info->s, "STOPCYC1:%X", cpustate->stop_cyc1); break;
- case CPUINFO_STR_REGISTER + TX0_RUN: sprintf(info->s, "RUN:%X", cpustate->run); break;
- case CPUINFO_STR_REGISTER + TX0_RIM: sprintf(info->s, "RIM:%X", cpustate->rim); break;
- case CPUINFO_STR_REGISTER + TX0_CYCLE: sprintf(info->s, "CYCLE:%X", cpustate->cycle); break;
- case CPUINFO_STR_REGISTER + TX0_IOH: sprintf(info->s, "IOH:%X", cpustate->ioh); break;
- case CPUINFO_STR_REGISTER + TX0_IOS: sprintf(info->s, "IOS:%X", cpustate->ios); break;
- case CPUINFO_IS_OCTAL: info->i = true; break;
- }
+ while (m_icount > 0);
}
/* execute one instruction */
-static void execute_instruction_64kw(device_t *device)
+void tx0_64kw_device::execute_instruction_64kw()
{
- tx0_state *cpustate = get_safe_token(device);
-
- if (! cpustate->cycle)
+ if (! m_cycle)
{
- cpustate->cycle = 1; /* most frequent case */
+ m_cycle = 1; /* most frequent case */
switch (IR)
{
case 0: /* STOre */
@@ -699,7 +453,7 @@ static void execute_instruction_64kw(device_t *device)
if (AC & 0400000)
{
PC = MAR & ADDRESS_MASK_64KW;
- cpustate->cycle = 0; /* instruction only takes one cycle if branch
+ m_cycle = 0; /* instruction only takes one cycle if branch
is taken */
}
break;
@@ -716,7 +470,7 @@ static void execute_instruction_64kw(device_t *device)
if (((MAR & 0030000) >> 12) == 1)
/* (0.8) IOS In-Out Stop = Stop machine so that an In-Out command
(specified by digits 6 7 8 of MAR) may be executed */
- cpustate->ioh = 1;
+ m_ioh = 1;
if (((MAR & 0007000) >> 9) != 0)
{
@@ -750,24 +504,23 @@ static void execute_instruction_64kw(device_t *device)
/* (5 is undefined) */
int index = (MAR & 0007000) >> 9;
- if (cpustate->iface->io_handlers[index])
- (*cpustate->iface->io_handlers[index])(device);
- cpustate->ioh = 1;
+ call_io_handler(index);
+ m_ioh = 1;
}
break;
}
}
else
{
- cpustate->cycle = 0; /* always true */
+ m_cycle = 0; /* always true */
switch (IR)
{
case 0: /* STOre */
- tx0_write(cpustate, MAR, (MBR = AC));
+ tx0_write(MAR, (MBR = AC));
break;
case 1: /* ADD */
- MBR = tx0_read(cpustate, MAR);
+ MBR = tx0_read(MAR);
AC = AC + MBR;
AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
@@ -855,14 +608,14 @@ static void execute_instruction_64kw(device_t *device)
if (((MAR & 0030000) >> 12) == 3)
/* (1.8) Hlt = Halt the computer */
- cpustate->run = 0;
+ m_run = 0;
break;
}
}
}
-static void indexed_address_eval(tx0_state *cpustate)
+void tx0_device::indexed_address_eval()
{
MAR = MAR + XR;
MAR = (MAR + (MAR >> 14)) & 0037777; /* propagate carry around */
@@ -873,13 +626,11 @@ static void indexed_address_eval(tx0_state *cpustate)
}
/* execute one instruction */
-static void execute_instruction_8kw(device_t *device)
+void tx0_8kw_device::execute_instruction_8kw()
{
- tx0_state *cpustate = get_safe_token(device);
-
- if (! cpustate->cycle)
+ if (! m_cycle)
{
- cpustate->cycle = 1; /* most frequent case */
+ m_cycle = 1; /* most frequent case */
switch (IR)
{
case 0: /* STOre */
@@ -903,7 +654,7 @@ static void execute_instruction_8kw(device_t *device)
if (AC & 0400000)
{
PC = MAR & 0017777;
- cpustate->cycle = 0; /* instruction only takes one cycle if branch
+ m_cycle = 0; /* instruction only takes one cycle if branch
is taken */
}
break;
@@ -912,7 +663,7 @@ static void execute_instruction_8kw(device_t *device)
if ((AC == 0000000) || (AC == 0777777))
{
PC = MAR & 0017777;
- cpustate->cycle = 0; /* instruction only takes one cycle if branch
+ m_cycle = 0; /* instruction only takes one cycle if branch
is taken */
}
break;
@@ -920,7 +671,7 @@ static void execute_instruction_8kw(device_t *device)
case 18: /* Transfer and Set indeX */
XR = PC;
PC = MAR & 0017777;
- cpustate->cycle = 0; /* instruction only takes one cycle if branch
+ m_cycle = 0; /* instruction only takes one cycle if branch
is taken */
break;
@@ -932,16 +683,16 @@ static void execute_instruction_8kw(device_t *device)
else
XR--;
PC = MAR & 0017777;
- cpustate->cycle = 0; /* instruction only takes one cycle if branch
+ m_cycle = 0; /* instruction only takes one cycle if branch
is taken */
}
break;
case 21: /* TRansfer indeXed */
- indexed_address_eval(cpustate);
+ indexed_address_eval();
case 20: /* TRAnsfer */
PC = MAR & 0017777;
- cpustate->cycle = 0; /* instruction only takes one cycle if branch
+ m_cycle = 0; /* instruction only takes one cycle if branch
is taken */
break;
@@ -949,7 +700,7 @@ static void execute_instruction_8kw(device_t *device)
/*if (...)
{
PC = MAR & 0017777;
- cpustate->cycle = 0;*/ /* instruction only takes one cycle if branch
+ m_cycle = 0;*/ /* instruction only takes one cycle if branch
is taken */
/*}*/
break;
@@ -969,8 +720,7 @@ static void execute_instruction_8kw(device_t *device)
AC = 0;
/* (IOS???) SEL = SELect */
- if (cpustate->iface->sel_handler)
- (*cpustate->iface->sel_handler)(device);
+ m_sel_handler(ASSERT_LINE);
}
else
{ /* Normal operate class instruction */
@@ -1020,9 +770,8 @@ static void execute_instruction_8kw(device_t *device)
/* (5 is undefined) */
int index = (MAR & 0007000) >> 9;
- if (cpustate->iface->io_handlers[index])
- (*cpustate->iface->io_handlers[index])(device);
- cpustate->ioh = 1;
+ call_io_handler(index);
+ m_ioh = 1;
}
if (((IR & 001) == 00) && ((MAR & 010000) == 010000))
@@ -1038,34 +787,34 @@ static void execute_instruction_8kw(device_t *device)
}
else
{
- if (((IR != 2) && (IR != 3)) || (cpustate->cycle == 2))
- cpustate->cycle = 0;
+ if (((IR != 2) && (IR != 3)) || (m_cycle == 2))
+ m_cycle = 0;
else
- cpustate->cycle = 2; /* SXA and ADO have an extra cycle 2 */
+ m_cycle = 2; /* SXA and ADO have an extra cycle 2 */
switch (IR)
{
case 1: /* STore indeXed */
- indexed_address_eval(cpustate);
+ indexed_address_eval();
case 0: /* STOre */
- tx0_write(cpustate, MAR, (MBR = AC));
+ tx0_write(MAR, (MBR = AC));
break;
case 2: /* Store indeX in Address */
- if (cpustate->cycle)
+ if (m_cycle)
{ /* cycle 1 */
- MBR = tx0_read(cpustate, MAR);
+ MBR = tx0_read(MAR);
MBR = (MBR & 0760000) | (XR & 0017777);
}
else
{ /* cycle 2 */
- tx0_write(cpustate, MAR, MBR);
+ tx0_write(MAR, MBR);
}
break;
case 3: /* ADd One */
- if (cpustate->cycle)
+ if (m_cycle)
{ /* cycle 1 */
- AC = tx0_read(cpustate, MAR) + 1;
+ AC = tx0_read(MAR) + 1;
#if 0
AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
@@ -1078,24 +827,24 @@ static void execute_instruction_8kw(device_t *device)
}
else
{ /* cycle 2 */
- tx0_write(cpustate, MAR, (MBR = AC));
+ tx0_write(MAR, (MBR = AC));
}
break;
case 5: /* Store Lr indeXed */
- indexed_address_eval(cpustate);
+ indexed_address_eval();
case 4: /* Store LR */
- tx0_write(cpustate, MAR, (MBR = LR));
+ tx0_write(MAR, (MBR = LR));
break;
case 6: /* STore Zero */
- tx0_write(cpustate, MAR, (MBR = 0));
+ tx0_write(MAR, (MBR = 0));
break;
case 9: /* ADd indeXed */
- indexed_address_eval(cpustate);
+ indexed_address_eval();
case 8: /* ADD */
- MBR = tx0_read(cpustate, MAR);
+ MBR = tx0_read(MAR);
AC = AC + MBR;
AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */
@@ -1105,12 +854,12 @@ static void execute_instruction_8kw(device_t *device)
break;
case 10: /* LoaD indeX */
- MBR = tx0_read(cpustate, MAR);
+ MBR = tx0_read(MAR);
XR = (MBR & 0017777) | ((MBR >> 4) & 0020000);
break;
case 11: /* AUgment indeX */
- MBR = tx0_read(cpustate, MAR);
+ MBR = tx0_read(MAR);
XR = XR + ((MBR & 0017777) | ((MBR >> 4) & 0020000));
XR = (XR + (XR >> 14)) & 0037777; /* propagate carry around */
@@ -1120,15 +869,15 @@ static void execute_instruction_8kw(device_t *device)
break;
case 13: /* Load Lr indeXed */
- indexed_address_eval(cpustate);
+ indexed_address_eval();
case 12: /* Load LR */
- LR = MBR = tx0_read(cpustate, MAR);
+ LR = MBR = tx0_read(MAR);
break;
case 15: /* Load Ac indeXed */
- indexed_address_eval(cpustate);
+ indexed_address_eval();
case 14: /* LoaD Ac */
- AC = MBR = tx0_read(cpustate, MAR);
+ AC = MBR = tx0_read(MAR);
break;
case 16: /* TRansfer on Negative */
@@ -1163,11 +912,11 @@ static void execute_instruction_8kw(device_t *device)
if (((IR & 001) == 00) && ((MAR & 017000) == 001000))
/* (1.1) TAC = transfer TAC into ac (inclusive or) */
- AC |= cpustate->tac;
+ AC |= m_tac;
if (((IR & 001) == 00) && ((MAR & 017000) == 002000))
/* (1.2) TBR = transfer TBR into mbr (inclusive or) */
- MBR |= cpustate->tbr;
+ MBR |= m_tbr;
if (((IR & 001) == 00) && ((MAR & 017000) == 006000))
/* (1.2) RPF = Read Program Flag register into mbr (inclusive or) */
@@ -1263,7 +1012,7 @@ static void execute_instruction_8kw(device_t *device)
if (((IR & 001) == 01) && ((MAR & 017000) == 010000))
/* (1.8) HLT = HaLT the computer and sound chime */
- cpustate->run = 0;
+ m_run = 0;
}
break;
@@ -1279,10 +1028,8 @@ static void execute_instruction_8kw(device_t *device)
reset most registers and flip-flops, and initialize a few emulator state
variables.
*/
-static void pulse_reset(device_t *device)
+void tx0_device::pulse_reset()
{
- tx0_state *cpustate = get_safe_token(device);
-
/* processor registers */
PC = 0; /* ??? */
IR = 0; /* ??? */
@@ -1292,17 +1039,33 @@ static void pulse_reset(device_t *device)
/*LR = 0;*/ /* ??? */
/* processor state flip-flops */
- cpustate->run = 0; /* ??? */
- cpustate->rim = 0; /* ??? */
- cpustate->ioh = 0; /* ??? */
- cpustate->ios = 0; /* ??? */
+ m_run = 0; /* ??? */
+ m_rim = 0; /* ??? */
+ m_ioh = 0; /* ??? */
+ m_ios = 0; /* ??? */
- cpustate->rim_step = 0;
+ m_rim_step = 0;
/* now, we kindly ask IO devices to reset, too */
- if (cpustate->iface->io_reset_callback)
- (*cpustate->iface->io_reset_callback)(device);
+ m_io_reset_callback(ASSERT_LINE);
+}
+
+void tx0_device::io_complete()
+{
+ m_ios = 1;
+}
+
+
+offs_t tx0_8kw_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ extern CPU_DISASSEMBLE( tx0_8kw );
+ return CPU_DISASSEMBLE_NAME(tx0_8kw)(this, buffer, pc, oprom, opram, options);
+}
+
+
+offs_t tx0_64kw_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ extern CPU_DISASSEMBLE( tx0_64kw );
+ return CPU_DISASSEMBLE_NAME(tx0_64kw)(this, buffer, pc, oprom, opram, options);
}
-DEFINE_LEGACY_CPU_DEVICE(TX0_64KW, tx0_64kw);
-DEFINE_LEGACY_CPU_DEVICE(TX0_8KW, tx0_8kw);
diff --git a/src/emu/cpu/pdp1/tx0.h b/src/emu/cpu/pdp1/tx0.h
index cea455927f0..7c4b4d65a56 100644
--- a/src/emu/cpu/pdp1/tx0.h
+++ b/src/emu/cpu/pdp1/tx0.h
@@ -15,14 +15,103 @@ enum
TX0_CM_SEL, TX0_LR_SEL, TX0_GBL_CM_SEL,
TX0_STOP_CYC0, TX0_STOP_CYC1,
TX0_RUN, TX0_RIM,
- TX0_CYCLE, TX0_IOH, TX0_IOS,
- TX0_RESET, /* hack, do not use directly, use tx0_pulse_reset instead */
- TX0_IO_COMPLETE /* hack, do not use directly, use tx0_pulse_io_complete instead */
+ TX0_CYCLE, TX0_IOH, TX0_IOS
};
-struct tx0_reset_param_t
+#define MCFG_TX0_CONFIG(_cpy_devcb, _r1l_devcb, _dis_devcb, _r3l_devcb, _prt_devcb, _rsv_devcb, _p6h_devcb, _p7h_devcb, _sel_devcb, _res_devcb) \
+ tx0_device::set_cpy_cb(*device, DEVCB2_##_cpy_devcb); \
+ tx0_device::set_r1l_cb(*device, DEVCB2_##_r1l_devcb); \
+ tx0_device::set_dis_cb(*device, DEVCB2_##_dis_devcb); \
+ tx0_device::set_r3l_cb(*device, DEVCB2_##_r3l_devcb); \
+ tx0_device::set_prt_cb(*device, DEVCB2_##_prt_devcb); \
+ tx0_device::set_rsv_cb(*device, DEVCB2_##_rsv_devcb); \
+ tx0_device::set_p6h_cb(*device, DEVCB2_##_p6h_devcb); \
+ tx0_device::set_p7h_cb(*device, DEVCB2_##_p7h_devcb); \
+ tx0_device::set_sel_cb(*device, DEVCB2_##_sel_devcb); \
+ tx0_device::set_res_cb(*device, DEVCB2_##_res_devcb);
+
+
+class tx0_device : public cpu_device
{
+public:
+ // construction/destruction
+ tx0_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 addr_bits, int address_mask, int ir_mask);
+
+ // static configuration helpers
+ template<class _Object> static devcb2_base &set_cpy_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_cpy_handler.set_callback(object); }
+ template<class _Object> static devcb2_base &set_r1l_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_r1l_handler.set_callback(object); }
+ template<class _Object> static devcb2_base &set_dis_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_dis_handler.set_callback(object); }
+ template<class _Object> static devcb2_base &set_r3l_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_r3l_handler.set_callback(object); }
+ template<class _Object> static devcb2_base &set_prt_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_prt_handler.set_callback(object); }
+ template<class _Object> static devcb2_base &set_rsv_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_rsv_handler.set_callback(object); }
+ template<class _Object> static devcb2_base &set_p6h_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_p6h_handler.set_callback(object); }
+ template<class _Object> static devcb2_base &set_p7h_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_p7h_handler.set_callback(object); }
+ template<class _Object> static devcb2_base &set_sel_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_sel_handler.set_callback(object); }
+ template<class _Object> static devcb2_base &set_res_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_io_reset_callback.set_callback(object); }
+
+ void pulse_reset();
+ void io_complete();
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // device_execute_interface overrides
+ virtual UINT32 execute_min_cycles() const { return 1; }
+ virtual UINT32 execute_max_cycles() const { return 3; }
+
+ // device_memory_interface overrides
+ virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : NULL; }
+
+ // device_disasm_interface overrides
+ virtual UINT32 disasm_min_opcode_bytes() const { return 4; }
+ virtual UINT32 disasm_max_opcode_bytes() const { return 4; }
+
+protected:
+ address_space_config m_program_config;
+
+ /* processor registers */
+ int m_mbr; /* memory buffer register (18 bits) */
+ int m_ac; /* accumulator (18 bits) */
+ int m_mar; /* memory address register (16 (64kW) or 13 (8kW) bits) */
+ int m_pc; /* program counter (16 (64kW) or 13 (8kW) bits) */
+ int m_ir; /* instruction register (2 (64kW) or 5 (8kW) bits) */
+ int m_lr; /* live register (18 bits) */
+ int m_xr; /* index register (14 bits) (8kW only) */
+ int m_pf; /* program flags (6 bits expandable to 10) (8kW only) */
+
+ /* operator panel switches */
+ int m_tbr; /* toggle switch buffer register (18 bits) */
+ int m_tac; /* toggle switch accumulator (18 bits) */
+ int m_tss[16]; /* toggle switch storage (18 bits * 16) */
+ UINT16 m_cm_sel; /* individual cm select (1 bit * 16) */
+ UINT16 m_lr_sel; /* individual lr select (1 bit * 16) */
+ unsigned int m_gbl_cm_sel;/* global cm select (1 bit) */
+ unsigned int m_stop_cyc0; /* stop on cycle 0 */
+ unsigned int m_stop_cyc1; /* stop on cycle 1 */
+
+ /* processor state flip-flops */
+ unsigned int m_run; /* processor is running */
+ unsigned int m_rim; /* processor is in read-in mode */
+ unsigned int m_cycle; /* 0 -> fetch */
+ /* 1 -> execute (except for taken branches) */
+ /* 2 -> extra execute cycle for SXA and ADO */
+
+ unsigned int m_ioh; /* i-o halt: processor is executing an Input-Output Transfer wait */
+ unsigned int m_ios; /* i-o synchronizer: set on i-o operation completion */
+
+ /* additional emulator state variables */
+ int m_rim_step; /* current step in rim execution */
+
+ int m_address_mask; /* address mask */
+ int m_ir_mask; /* IR mask */
+
+ int m_icount;
+
+ address_space *m_program;
+
/* 8 standard I/O handlers:
0: cpy (8kW only)
1: r1l
@@ -32,18 +121,57 @@ struct tx0_reset_param_t
5: reserved (for unimplemented typ instruction?)
6: p6h
7: p7h */
- void (*io_handlers[8])(device_t *device);
+ devcb2_write_line m_cpy_handler;
+ devcb2_write_line m_r1l_handler;
+ devcb2_write_line m_dis_handler;
+ devcb2_write_line m_r3l_handler;
+ devcb2_write_line m_prt_handler;
+ devcb2_write_line m_rsv_handler;
+ devcb2_write_line m_p6h_handler;
+ devcb2_write_line m_p7h_handler;
/* select instruction handler */
- void (*sel_handler)(device_t *device);
+ devcb2_write_line m_sel_handler;
/* callback called when reset line is pulsed: IO devices should reset */
- void (*io_reset_callback)(device_t *device);
+ devcb2_write_line m_io_reset_callback;
+
+ int tx0_read(offs_t address);
+ void tx0_write(offs_t address, int data);
+ void call_io_handler(int io_handler);
+ void indexed_address_eval();
+};
+
+
+class tx0_8kw_device : public tx0_device
+{
+public:
+ // construction/destruction
+ tx0_8kw_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
+
+protected:
+ virtual void execute_run();
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
+
+private:
+ void execute_instruction_8kw();
+};
+
+
+class tx0_64kw_device : public tx0_device
+{
+public:
+ // construction/destruction
+ tx0_64kw_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
+
+protected:
+ virtual void execute_run();
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
+
+private:
+ void execute_instruction_64kw();
};
-/* PUBLIC FUNCTIONS */
-DECLARE_LEGACY_CPU_DEVICE(TX0_64KW, tx0_64kw);
-DECLARE_LEGACY_CPU_DEVICE(TX0_8KW, tx0_8kw);
-CPU_DISASSEMBLE( tx0_64kw );
-CPU_DISASSEMBLE( tx0_8kw );
+extern const device_type TX0_64KW;
+extern const device_type TX0_8KW;
#endif /* __TX0_H__ */