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,80 +15,21 @@ #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); - -/* 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 */ - - /* additional emulator state variables */ - int rim_step; /* current step in rim execution */ - - int address_mask; /* address mask */ - int ir_mask; /* IR mask */ - - int icount; - - legacy_cpu_device *device; - address_space *program; -}; - -INLINE tx0_state *get_safe_token(device_t *device) -{ - assert(device != NULL); - assert(device->type() == TX0_64KW || - device->type() == TX0_8KW); - return (tx0_state *)downcast(device)->token(); -} - -#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 READ_TX0_18BIT(A) ((signed)m_program->read_dword((A)<<2)) +#define WRITE_TX0_18BIT(A,V) (m_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 +#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 #define ADDRESS_MASK_64KW 0177777 #define ADDRESS_MASK_8KW 0017777 @@ -97,25 +38,60 @@ INLINE tx0_state *get_safe_token(device_t *device) #define INCREMENT_PC_8KW (PC = (PC+1) & ADDRESS_MASK_8KW) -static int tx0_read(tx0_state *cpustate, offs_t address) +const device_type TX0_8KW = &device_creator; +const device_type TX0_64KW = &device_creator; + + +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) { - if ((address >= 16) || (cpustate->gbl_cm_sel) || ((cpustate->cm_sel >> address) & 1)) + m_is_octal = true; +} + +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) +{ +} + + +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) +{ +} + + +int tx0_device::tx0_read(offs_t address) +{ + 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; - /* clean-up */ - cpustate->iface = (const tx0_reset_param_t *)device->static_config(); + // 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(); - cpustate->address_mask = is_64kw ? ADDRESS_MASK_64KW : ADDRESS_MASK_8KW; - cpustate->ir_mask = is_64kw ? 03 : 037; + m_program = &space(AS_PROGRAM); - cpustate->device = device; - cpustate->program = &device->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; } -static CPU_INIT( tx0_64kw ) -{ - tx0_init_common(device, irqcallback, 1); -} -static CPU_INIT( tx0_8kw) +void tx0_device::device_reset() { - tx0_init_common(device, irqcallback, 0); -} - -static CPU_RESET( tx0 ) -{ - tx0_state *cpustate = get_safe_token(device); - /* reset CPU flip-flops */ - pulse_reset(device); + pulse_reset(); - cpustate->gbl_cm_sel = 1; /* HACK */ + m_gbl_cm_sel = 1; /* HACK */ } + +void tx0_device::call_io_handler(int io_handler) +{ + /* 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; + } +} + + /* 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 static devcb2_base &set_cpy_cb(device_t &device, _Object object) { return downcast(device).m_cpy_handler.set_callback(object); } + template static devcb2_base &set_r1l_cb(device_t &device, _Object object) { return downcast(device).m_r1l_handler.set_callback(object); } + template static devcb2_base &set_dis_cb(device_t &device, _Object object) { return downcast(device).m_dis_handler.set_callback(object); } + template static devcb2_base &set_r3l_cb(device_t &device, _Object object) { return downcast(device).m_r3l_handler.set_callback(object); } + template static devcb2_base &set_prt_cb(device_t &device, _Object object) { return downcast(device).m_prt_handler.set_callback(object); } + template static devcb2_base &set_rsv_cb(device_t &device, _Object object) { return downcast(device).m_rsv_handler.set_callback(object); } + template static devcb2_base &set_p6h_cb(device_t &device, _Object object) { return downcast(device).m_p6h_handler.set_callback(object); } + template static devcb2_base &set_p7h_cb(device_t &device, _Object object) { return downcast(device).m_p7h_handler.set_callback(object); } + template static devcb2_base &set_sel_cb(device_t &device, _Object object) { return downcast(device).m_sel_handler.set_callback(object); } + template static devcb2_base &set_res_cb(device_t &device, _Object object) { return downcast(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(); }; -/* 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 ); +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(); +}; + + +extern const device_type TX0_64KW; +extern const device_type TX0_8KW; #endif /* __TX0_H__ */ diff --git a/src/emu/distate.c b/src/emu/distate.c index 991b76a3a96..15f834b0ecb 100644 --- a/src/emu/distate.c +++ b/src/emu/distate.c @@ -248,6 +248,31 @@ astring &device_state_entry::format(astring &dest, const char *string, bool maxo reset = true; break; + // O outputs as octal + case 'O': + if (width == 0) + throw emu_fatalerror("Width required for %%O formats\n"); + hitnonzero = false; + while (leadzero && width > 22) + { + dest.cat(" "); + width--; + } + for (int digitnum = 21; digitnum >= 0; digitnum--) + { + int digit = (result >> (3 * digitnum)) & 07; + if (digit != 0) + { + static const char octchars[] = "01234567"; + dest.cat(&octchars[digit], 1); + hitnonzero = true; + } + else if (hitnonzero || (leadzero && digitnum < width) || digitnum == 0) + dest.cat("0"); + } + reset = true; + break; + // d outputs as signed decimal case 'd': if (width == 0) diff --git a/src/mess/drivers/tx0.c b/src/mess/drivers/tx0.c index 214d2079fab..4cdd01b1b64 100644 --- a/src/mess/drivers/tx0.c +++ b/src/mess/drivers/tx0.c @@ -301,31 +301,6 @@ void tx0_state::palette_init() colortable_entry_set_value(machine().colortable, total_colors_needed + i, tx0_palette[i]); } -static void tx0_io_cpy(device_t *device); -static void tx0_io_r1l(device_t *device); -static void tx0_io_r3l(device_t *device); -static void tx0_io_p6h(device_t *device); -static void tx0_io_p7h(device_t *device); -static void tx0_io_prt(device_t *device); -static void tx0_io_dis(device_t *device); -static void tx0_sel(device_t *device); -static void tx0_io_reset_callback(device_t *device); - -static const tx0_reset_param_t tx0_reset_param = -{ - { - tx0_io_cpy, - tx0_io_r1l, - tx0_io_dis, - tx0_io_r3l, - tx0_io_prt, - /*tx0_io_typ*/NULL, - tx0_io_p6h, - tx0_io_p7h - }, - tx0_sel, - tx0_io_reset_callback -}; static const crt_interface tx0_crt_interface = { @@ -705,51 +680,47 @@ TIMER_CALLBACK_MEMBER(tx0_state::puncher_callback) /* Initiate read of a 6-bit word from tape */ -static void tx0_io_r1l(device_t *device) +WRITE_LINE_MEMBER( tx0_state::tx0_io_r1l ) { - tx0_state *state = device->machine().driver_data(); - state->begin_tape_read( 0); + begin_tape_read( 0); } /* Initiate read of a 18-bit word from tape (used in read-in mode) */ -static void tx0_io_r3l(device_t *device) +WRITE_LINE_MEMBER( tx0_state::tx0_io_r3l ) { - tx0_state *state = device->machine().driver_data(); - state->begin_tape_read(1); + begin_tape_read(1); } /* Write a 7-bit word to tape (7th bit clear) */ -static void tx0_io_p6h(device_t *device) +WRITE_LINE_MEMBER( tx0_state::tx0_io_p6h ) { - tx0_state *state = device->machine().driver_data(); int ac; /* read current AC */ - ac = device->state().state_int(TX0_AC); + ac = m_maincpu->state_int(TX0_AC); /* shuffle and punch 6-bit word */ - state->tape_write(((ac & 0100000) >> 15) | ((ac & 0010000) >> 11) | ((ac & 0001000) >> 7) | ((ac & 0000100) >> 3) | ((ac & 0000010) << 1) | ((ac & 0000001) << 5)); + tape_write(((ac & 0100000) >> 15) | ((ac & 0010000) >> 11) | ((ac & 0001000) >> 7) | ((ac & 0000100) >> 3) | ((ac & 0000010) << 1) | ((ac & 0000001) << 5)); - state->m_tape_puncher.timer->adjust(attotime::from_usec(15800)); + m_tape_puncher.timer->adjust(attotime::from_usec(15800)); } /* Write a 7-bit word to tape (7th bit set) */ -static void tx0_io_p7h(device_t *device) +WRITE_LINE_MEMBER( tx0_state::tx0_io_p7h ) { - tx0_state *state = device->machine().driver_data(); int ac; /* read current AC */ - ac = device->state().state_int(TX0_AC); + ac = m_maincpu->state_int(TX0_AC); /* shuffle and punch 6-bit word */ - state->tape_write(((ac & 0100000) >> 15) | ((ac & 0010000) >> 11) | ((ac & 0001000) >> 7) | ((ac & 0000100) >> 3) | ((ac & 0000010) << 1) | ((ac & 0000001) << 5) | 0100); + tape_write(((ac & 0100000) >> 15) | ((ac & 0010000) >> 11) | ((ac & 0001000) >> 7) | ((ac & 0000100) >> 3) | ((ac & 0000010) << 1) | ((ac & 0000001) << 5) | 0100); - state->m_tape_puncher.timer->adjust(attotime::from_usec(15800)); + m_tape_puncher.timer->adjust(attotime::from_usec(15800)); } @@ -793,25 +764,24 @@ void tx0_state::typewriter_out(UINT8 data) */ TIMER_CALLBACK_MEMBER(tx0_state::prt_callback) { - m_maincpu->set_state_int(TX0_IOS,1); + m_maincpu->io_complete(); } /* prt io callback */ -static void tx0_io_prt(device_t *device) +WRITE_LINE_MEMBER( tx0_state::tx0_io_prt ) { - tx0_state *state = device->machine().driver_data(); int ac; int ch; /* read current AC */ - ac = device->state().state_int(TX0_AC); + ac = m_maincpu->state_int(TX0_AC); /* shuffle and print 6-bit word */ ch = ((ac & 0100000) >> 15) | ((ac & 0010000) >> 11) | ((ac & 0001000) >> 7) | ((ac & 0000100) >> 3) | ((ac & 0000010) << 1) | ((ac & 0000001) << 5); - state->typewriter_out(ch); + typewriter_out(ch); - state->m_typewriter.prt_timer->adjust(attotime::from_msec(100)); + m_typewriter.prt_timer->adjust(attotime::from_msec(100)); } @@ -820,25 +790,24 @@ static void tx0_io_prt(device_t *device) */ TIMER_CALLBACK_MEMBER(tx0_state::dis_callback) { - m_maincpu->set_state_int(TX0_IOS,1); + m_maincpu->io_complete(); } /* Plot one point on crt */ -static void tx0_io_dis(device_t *device) +WRITE_LINE_MEMBER( tx0_state::tx0_io_dis ) { - tx0_state *state = device->machine().driver_data(); int ac; int x; int y; - ac = device->state().state_int(TX0_AC); + ac = m_maincpu->state_int(TX0_AC); x = ac >> 9; y = ac & 0777; - state->tx0_plot(x, y); + tx0_plot(x, y); - state->m_dis_timer->adjust(attotime::from_usec(50)); + m_dis_timer->adjust(attotime::from_usec(50)); } @@ -944,143 +913,142 @@ void tx0_magtape_image_device::call_unload() } } -static void magtape_callback(device_t *device) +void tx0_state::magtape_callback() { - tx0_state *state = device->machine().driver_data(); UINT8 buf = 0; int lr; - switch (state->m_magtape.state) + switch (m_magtape.state) { case MTS_UNSELECTING: - state->m_magtape.state = MTS_UNSELECTED; + m_magtape.state = MTS_UNSELECTED; case MTS_UNSELECTED: - if (state->m_magtape.sel_pending) + if (m_magtape.sel_pending) { int mar; - mar = device->state().state_int(TX0_MAR); + mar = m_maincpu->state_int(TX0_MAR); if ((mar & 03) != 1) { /* unimplemented device: remain in unselected state and set rwc flag? */ - device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_RWC); + m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_RWC); } else { - state->m_magtape.state = MTS_SELECTING; + m_magtape.state = MTS_SELECTING; - state->m_magtape.command = (mar & 014 >> 2); + m_magtape.command = (mar & 014 >> 2); - state->m_magtape.binary_flag = (mar & 020 >> 4); + m_magtape.binary_flag = (mar & 020 >> 4); - if (state->m_magtape.img) - state->schedule_select(); + if (m_magtape.img) + schedule_select(); } - state->m_magtape.sel_pending = FALSE; - device->state().set_state_int(TX0_IOS,1); + m_magtape.sel_pending = FALSE; + m_maincpu->io_complete(); } break; case MTS_SELECTING: - state->m_magtape.state = MTS_SELECTED; - switch (state->m_magtape.command) + m_magtape.state = MTS_SELECTED; + switch (m_magtape.command) { case 0: /* backspace */ - state->m_magtape.long_parity = 0177; - state->m_magtape.u.backspace_state = MTBSS_STATE0; + m_magtape.long_parity = 0177; + m_magtape.u.backspace_state = MTBSS_STATE0; break; case 1: /* read */ - state->m_magtape.long_parity = 0177; - state->m_magtape.u.read.state = MTRDS_STATE0; + m_magtape.long_parity = 0177; + m_magtape.u.read.state = MTRDS_STATE0; break; case 2: /* rewind */ break; case 3: /* write */ - state->m_magtape.long_parity = 0177; - state->m_magtape.u.write.state = MTWTS_STATE0; - switch (state->m_magtape.irg_pos) + m_magtape.long_parity = 0177; + m_magtape.u.write.state = MTWTS_STATE0; + switch (m_magtape.irg_pos) { case MTIRGP_START: - state->m_magtape.u.write.counter = 150; + m_magtape.u.write.counter = 150; break; case MTIRGP_ENDMINUS1: - state->m_magtape.u.write.counter = 1; + m_magtape.u.write.counter = 1; break; case MTIRGP_END: - state->m_magtape.u.write.counter = 0; + m_magtape.u.write.counter = 0; break; } break; } case MTS_SELECTED: - switch (state->m_magtape.command) + switch (m_magtape.command) { case 0: /* backspace */ - if (state->m_magtape.img->ftell() == 0) + if (m_magtape.img->ftell() == 0) { /* tape at ldp */ - state->m_magtape.state = MTS_UNSELECTING; - device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_RWC); - state->schedule_unselect(); + m_magtape.state = MTS_UNSELECTING; + m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_RWC); + schedule_unselect(); } - else if (state->m_magtape.img->fseek( -1, SEEK_CUR)) + else if (m_magtape.img->fseek( -1, SEEK_CUR)) { /* eject tape */ - state->m_magtape.img->unload(); + m_magtape.img->unload(); } - else if (state->m_magtape.img->fread(&buf, 1) != 1) + else if (m_magtape.img->fread(&buf, 1) != 1) { /* eject tape */ - state->m_magtape.img->unload(); + m_magtape.img->unload(); } - else if (state->m_magtape.img->fseek( -1, SEEK_CUR)) + else if (m_magtape.img->fseek( -1, SEEK_CUR)) { /* eject tape */ - state->m_magtape.img->unload(); + m_magtape.img->unload(); } else { buf &= 0x7f; /* 7-bit tape, ignore 8th bit */ - state->m_magtape.long_parity ^= buf; - switch (state->m_magtape.u.backspace_state) + m_magtape.long_parity ^= buf; + switch (m_magtape.u.backspace_state) { case MTBSS_STATE0: /* STATE0 -> initial interrecord gap, longitudinal parity; if longitudinal parity was all 0s, gap between longitudinal parity and data, first byte of data */ if (buf != 0) - state->m_magtape.u.backspace_state = MTBSS_STATE1; + m_magtape.u.backspace_state = MTBSS_STATE1; break; case MTBSS_STATE1: /* STATE1 -> first byte of gap between longitudinal parity and data, second byte of data */ if (buf == 0) - state->m_magtape.u.backspace_state = MTBSS_STATE2; + m_magtape.u.backspace_state = MTBSS_STATE2; else - state->m_magtape.u.backspace_state = MTBSS_STATE5; + m_magtape.u.backspace_state = MTBSS_STATE5; break; case MTBSS_STATE2: /* STATE2 -> second byte of gap between longitudinal parity and data */ if (buf == 0) - state->m_magtape.u.backspace_state = MTBSS_STATE3; + m_magtape.u.backspace_state = MTBSS_STATE3; else { logerror("tape seems to be corrupt\n"); /* eject tape */ - state->m_magtape.img->unload(); + m_magtape.img->unload(); } break; case MTBSS_STATE3: /* STATE3 -> third byte of gap between longitudinal parity and data */ if (buf == 0) - state->m_magtape.u.backspace_state = MTBSS_STATE4; + m_magtape.u.backspace_state = MTBSS_STATE4; else { logerror("tape seems to be corrupt\n"); /* eject tape */ - state->m_magtape.img->unload(); + m_magtape.img->unload(); } break; case MTBSS_STATE4: @@ -1088,16 +1056,16 @@ static void magtape_callback(device_t *device) interrecord gap after data */ if (buf == 0) { - if (state->m_magtape.long_parity) + if (m_magtape.long_parity) logerror("invalid longitudinal parity\n"); /* set EOR and unselect... */ - state->m_magtape.state = MTS_UNSELECTING; - device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_EOR); - state->schedule_unselect(); - state->m_magtape.irg_pos = MTIRGP_ENDMINUS1; + m_magtape.state = MTS_UNSELECTING; + m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_EOR); + schedule_unselect(); + m_magtape.irg_pos = MTIRGP_ENDMINUS1; } else - state->m_magtape.u.backspace_state = MTBSS_STATE5; + m_magtape.u.backspace_state = MTBSS_STATE5; break; case MTBSS_STATE5: /* STATE5 -> second byte of data word */ @@ -1105,10 +1073,10 @@ static void magtape_callback(device_t *device) { logerror("tape seems to be corrupt\n"); /* eject tape */ - state->m_magtape.img->unload(); + m_magtape.img->unload(); } else - state->m_magtape.u.backspace_state = MTBSS_STATE6; + m_magtape.u.backspace_state = MTBSS_STATE6; break; case MTBSS_STATE6: /* STATE6 -> third byte of data word */ @@ -1116,67 +1084,67 @@ static void magtape_callback(device_t *device) { logerror("tape seems to be corrupt\n"); /* eject tape */ - state->m_magtape.img->unload(); + m_magtape.img->unload(); } else - state->m_magtape.u.backspace_state = MTBSS_STATE6; + m_magtape.u.backspace_state = MTBSS_STATE6; break; } - if (state->m_magtape.state != MTS_UNSELECTING) - state->m_magtape.timer->adjust(attotime::from_usec(66)); + if (m_magtape.state != MTS_UNSELECTING) + m_magtape.timer->adjust(attotime::from_usec(66)); } break; case 1: /* read */ - if (state->m_magtape.img->fread(&buf, 1) != 1) + if (m_magtape.img->fread(&buf, 1) != 1) { /* I/O error or EOF? */ /* The MAME fileio layer makes it very hard to make the difference... MAME seems to assume that I/O errors never happen, whereas it is really easy to cause one by deconnecting an external drive the image is located on!!! */ UINT64 offs; - offs = state->m_magtape.img->ftell(); - if (state->m_magtape.img->fseek( 0, SEEK_END) || (offs != state->m_magtape.img->ftell())) + offs = m_magtape.img->ftell(); + if (m_magtape.img->fseek( 0, SEEK_END) || (offs != m_magtape.img->ftell())) { /* I/O error */ /* eject tape */ - state->m_magtape.img->unload(); + m_magtape.img->unload(); } else { /* end of tape -> ??? */ /* maybe we run past end of tape, so that tape is ejected from upper reel and unit becomes unavailable??? */ - /*state->m_magtape.img->unload();*/ + /*m_magtape.img->unload();*/ /* Or do we stop at EOT mark??? */ - state->m_magtape.state = MTS_UNSELECTING; - device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_EOT); - state->schedule_unselect(); + m_magtape.state = MTS_UNSELECTING; + m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_EOT); + schedule_unselect(); } } else { buf &= 0x7f; /* 7-bit tape, ignore 8th bit */ - state->m_magtape.long_parity ^= buf; - switch (state->m_magtape.u.read.state) + m_magtape.long_parity ^= buf; + switch (m_magtape.u.read.state) { case MTRDS_STATE0: /* STATE0 -> interrecord blank or first byte of data */ if (buf != 0) { - if (state->m_magtape.cpy_pending) + if (m_magtape.cpy_pending) { /* read command */ - state->m_magtape.u.read.space_flag = FALSE; - device->state().set_state_int(TX0_IOS,1); - device->state().set_state_int(TX0_LR, ((device->state().state_int(TX0_LR) >> 1) & 0333333) + m_magtape.u.read.space_flag = FALSE; + m_maincpu->set_state_int(TX0_IOS,1); + m_maincpu->set_state_int(TX0_LR, ((m_maincpu->state_int(TX0_LR) >> 1) & 0333333) | ((buf & 040) << 12) | ((buf & 020) << 10) | ((buf & 010) << 8) | ((buf & 004) << 6) | ((buf & 002) << 4) | ((buf & 001) << 2)); /* check parity */ - if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ state->m_magtape.binary_flag)) - device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_PC); + if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ m_magtape.binary_flag)) + m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_PC); } else { /* space command */ - state->m_magtape.u.read.space_flag = TRUE; + m_magtape.u.read.space_flag = TRUE; } - state->m_magtape.u.read.state = MTRDS_STATE1; + m_magtape.u.read.state = MTRDS_STATE1; } break; case MTRDS_STATE1: @@ -1185,17 +1153,17 @@ static void magtape_callback(device_t *device) { logerror("tape seems to be corrupt\n"); /* eject tape */ - state->m_magtape.img->unload(); + m_magtape.img->unload(); } - if (!state->m_magtape.u.read.space_flag) + if (!m_magtape.u.read.space_flag) { - device->state().set_state_int(TX0_LR, ((device->state().state_int(TX0_LR) >> 1) & 0333333) + m_maincpu->set_state_int(TX0_LR, ((m_maincpu->state_int(TX0_LR) >> 1) & 0333333) | ((buf & 040) << 12) | ((buf & 020) << 10) | ((buf & 010) << 8) | ((buf & 004) << 6) | ((buf & 002) << 4) | ((buf & 001) << 2)); /* check parity */ - if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ state->m_magtape.binary_flag)) - device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_PC); + if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ m_magtape.binary_flag)) + m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_PC); } - state->m_magtape.u.read.state = MTRDS_STATE2; + m_magtape.u.read.state = MTRDS_STATE2; break; case MTRDS_STATE2: /* STATE2 -> third byte of data word */ @@ -1203,40 +1171,40 @@ static void magtape_callback(device_t *device) { logerror("tape seems to be corrupt\n"); /* eject tape */ - state->m_magtape.img->unload(); + m_magtape.img->unload(); } - if (!state->m_magtape.u.read.space_flag) + if (!m_magtape.u.read.space_flag) { - device->state().set_state_int(TX0_LR, ((device->state().state_int(TX0_LR) >> 1) & 0333333) + m_maincpu->set_state_int(TX0_LR, ((m_maincpu->state_int(TX0_LR) >> 1) & 0333333) | ((buf & 040) << 12) | ((buf & 020) << 10) | ((buf & 010) << 8) | ((buf & 004) << 6) | ((buf & 002) << 4) | ((buf & 001) << 2)); /* check parity */ - if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ state->m_magtape.binary_flag)) - device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_PC); + if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ m_magtape.binary_flag)) + m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_PC); /* synchronize with cpy instruction */ - if (state->m_magtape.cpy_pending) - device->state().set_state_int(TX0_IOS,1); + if (m_magtape.cpy_pending) + m_maincpu->set_state_int(TX0_IOS,1); else - device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_RWC); + m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_RWC); } - state->m_magtape.u.read.state = MTRDS_STATE3; + m_magtape.u.read.state = MTRDS_STATE3; break; case MTRDS_STATE3: /* STATE3 -> first byte of new word of data, or first byte of gap between data and longitudinal parity */ if (buf != 0) { - state->m_magtape.u.read.state = MTRDS_STATE1; - if (!state->m_magtape.u.read.space_flag) + m_magtape.u.read.state = MTRDS_STATE1; + if (!m_magtape.u.read.space_flag) { - device->state().set_state_int(TX0_LR, ((device->state().state_int(TX0_LR) >> 1) & 0333333) + m_maincpu->set_state_int(TX0_LR, ((m_maincpu->state_int(TX0_LR) >> 1) & 0333333) | ((buf & 040) << 12) | ((buf & 020) << 10) | ((buf & 010) << 8) | ((buf & 004) << 6) | ((buf & 002) << 4) | ((buf & 001) << 2)); /* check parity */ - if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ state->m_magtape.binary_flag)) - device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_PC); + if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ m_magtape.binary_flag)) + m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_PC); } } else - state->m_magtape.u.read.state = MTRDS_STATE4; + m_magtape.u.read.state = MTRDS_STATE4; break; case MTRDS_STATE4: /* STATE4 -> second byte of gap between data and @@ -1245,10 +1213,10 @@ static void magtape_callback(device_t *device) { logerror("tape seems to be corrupt\n"); /* eject tape */ - state->m_magtape.img->unload(); + m_magtape.img->unload(); } else - state->m_magtape.u.read.state = MTRDS_STATE5; + m_magtape.u.read.state = MTRDS_STATE5; break; case MTRDS_STATE5: @@ -1258,126 +1226,126 @@ static void magtape_callback(device_t *device) { logerror("tape seems to be corrupt\n"); /* eject tape */ - state->m_magtape.img->unload(); + m_magtape.img->unload(); } else - state->m_magtape.u.read.state = MTRDS_STATE6; + m_magtape.u.read.state = MTRDS_STATE6; break; case MTRDS_STATE6: /* STATE6 -> longitudinal parity */ /* check parity */ - if (state->m_magtape.long_parity) + if (m_magtape.long_parity) { logerror("invalid longitudinal parity\n"); /* no idea if the original tx-0 magtape controller checks parity, but can't harm if we do */ - device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_PC); + m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_PC); } /* set EOR and unselect... */ - state->m_magtape.state = MTS_UNSELECTING; - device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_EOR); - state->schedule_unselect(); - state->m_magtape.irg_pos = MTIRGP_START; + m_magtape.state = MTS_UNSELECTING; + m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_EOR); + schedule_unselect(); + m_magtape.irg_pos = MTIRGP_START; break; } - if (state->m_magtape.state != MTS_UNSELECTING) - state->m_magtape.timer->adjust(attotime::from_usec(66)); + if (m_magtape.state != MTS_UNSELECTING) + m_magtape.timer->adjust(attotime::from_usec(66)); } break; case 2: /* rewind */ - state->m_magtape.state = MTS_UNSELECTING; + m_magtape.state = MTS_UNSELECTING; /* we rewind at 10*read speed (I don't know the real value) */ - state->m_magtape.timer->adjust((attotime::from_nsec(6600) * state->m_magtape.img->ftell())); + m_magtape.timer->adjust((attotime::from_nsec(6600) * m_magtape.img->ftell())); //schedule_unselect(state); - state->m_magtape.img->fseek( 0, SEEK_END); - state->m_magtape.irg_pos = MTIRGP_END; + m_magtape.img->fseek( 0, SEEK_END); + m_magtape.irg_pos = MTIRGP_END; break; case 3: /* write */ - switch (state->m_magtape.u.write.state) + switch (m_magtape.u.write.state) { case MTWTS_STATE0: - if (state->m_magtape.u.write.counter != 0) + if (m_magtape.u.write.counter != 0) { - state->m_magtape.u.write.counter--; + m_magtape.u.write.counter--; buf = 0; break; } else { - state->m_magtape.u.write.state = MTWTS_STATE1; + m_magtape.u.write.state = MTWTS_STATE1; } case MTWTS_STATE1: - if (state->m_magtape.u.write.counter) + if (m_magtape.u.write.counter) { - state->m_magtape.u.write.counter--; - lr = device->state().state_int(TX0_LR); + m_magtape.u.write.counter--; + lr = m_maincpu->state_int(TX0_LR); buf = ((lr >> 10) & 040) | ((lr >> 8) & 020) | ((lr >> 6) & 010) | ((lr >> 4) & 004) | ((lr >> 2) & 002) | (lr & 001); - buf |= ((buf << 1) ^ (buf << 2) ^ (buf << 3) ^ (buf << 4) ^ (buf << 5) ^ (buf << 6) ^ ((!state->m_magtape.binary_flag) << 6)) & 0100; - device->state().set_state_int(TX0_LR, lr >> 1); + buf |= ((buf << 1) ^ (buf << 2) ^ (buf << 3) ^ (buf << 4) ^ (buf << 5) ^ (buf << 6) ^ ((!m_magtape.binary_flag) << 6)) & 0100; + m_maincpu->set_state_int(TX0_LR, lr >> 1); } else { - if (state->m_magtape.cpy_pending) + if (m_magtape.cpy_pending) { - device->state().set_state_int(TX0_IOS,1); - lr = device->state().state_int(TX0_LR); + m_maincpu->set_state_int(TX0_IOS,1); + lr = m_maincpu->state_int(TX0_LR); buf = ((lr >> 10) & 040) | ((lr >> 8) & 020) | ((lr >> 6) & 010) | ((lr >> 4) & 004) | ((lr >> 2) & 002) | (lr & 001); - buf |= ((buf << 1) ^ (buf << 2) ^ (buf << 3) ^ (buf << 4) ^ (buf << 5) ^ (buf << 6) ^ ((!state->m_magtape.binary_flag) << 6)) & 0100; - device->state().set_state_int(TX0_LR, lr >> 1); - state->m_magtape.u.write.counter = 2; + buf |= ((buf << 1) ^ (buf << 2) ^ (buf << 3) ^ (buf << 4) ^ (buf << 5) ^ (buf << 6) ^ ((!m_magtape.binary_flag) << 6)) & 0100; + m_maincpu->set_state_int(TX0_LR, lr >> 1); + m_magtape.u.write.counter = 2; break; } else { - state->m_magtape.u.write.state = MTWTS_STATE2; - state->m_magtape.u.write.counter = 3; + m_magtape.u.write.state = MTWTS_STATE2; + m_magtape.u.write.counter = 3; } } case MTWTS_STATE2: - if (state->m_magtape.u.write.counter != 0) + if (m_magtape.u.write.counter != 0) { - state->m_magtape.u.write.counter--; + m_magtape.u.write.counter--; buf = 0; break; } else { - buf = state->m_magtape.long_parity; - state->m_magtape.state = (state_t)MTWTS_STATE3; - state->m_magtape.u.write.counter = 150; + buf = m_magtape.long_parity; + m_magtape.state = (state_t)MTWTS_STATE3; + m_magtape.u.write.counter = 150; } break; case MTWTS_STATE3: - if (state->m_magtape.u.write.counter != 0) + if (m_magtape.u.write.counter != 0) { - state->m_magtape.u.write.counter--; + m_magtape.u.write.counter--; buf = 0; break; } else { - state->m_magtape.state = MTS_UNSELECTING; - state->schedule_unselect(); - state->m_magtape.irg_pos = MTIRGP_END; + m_magtape.state = MTS_UNSELECTING; + schedule_unselect(); + m_magtape.irg_pos = MTIRGP_END; } break; } - if (state->m_magtape.state != MTS_UNSELECTING) + if (m_magtape.state != MTS_UNSELECTING) { /* write data word */ - state->m_magtape.long_parity ^= buf; - if (state->m_magtape.img->fwrite(&buf, 1) != 1) + m_magtape.long_parity ^= buf; + if (m_magtape.img->fwrite(&buf, 1) != 1) { /* I/O error */ /* eject tape */ - state->m_magtape.img->unload(); + m_magtape.img->unload(); } else - state->m_magtape.timer->adjust(attotime::from_usec(66)); + m_magtape.timer->adjust(attotime::from_usec(66)); } break; } @@ -1385,42 +1353,40 @@ static void magtape_callback(device_t *device) } } -static void tx0_sel(device_t *device) +WRITE_LINE_MEMBER( tx0_state::tx0_sel ) { - tx0_state *state = device->machine().driver_data(); - state->m_magtape.sel_pending = TRUE; + m_magtape.sel_pending = TRUE; - if (state->m_magtape.state == MTS_UNSELECTED) + if (m_magtape.state == MTS_UNSELECTED) { if (0) - magtape_callback(device); - state->m_magtape.timer->adjust(attotime::zero); + magtape_callback(); + m_magtape.timer->adjust(attotime::zero); } } -static void tx0_io_cpy(device_t *device) +WRITE_LINE_MEMBER( tx0_state::tx0_io_cpy ) { - tx0_state *state = device->machine().driver_data(); - switch (state->m_magtape.state) + switch (m_magtape.state) { case MTS_UNSELECTED: case MTS_UNSELECTING: /* ignore instruction and set rwc flag? */ - device->state().set_state_int(TX0_IOS,1); + m_maincpu->io_complete(); break; case MTS_SELECTING: case MTS_SELECTED: - switch (state->m_magtape.command) + switch (m_magtape.command) { case 0: /* backspace */ case 2: /* rewind */ /* ignore instruction and set rwc flag? */ - device->state().set_state_int(TX0_IOS,1); + m_maincpu->io_complete(); break; case 1: /* read */ case 3: /* write */ - state->m_magtape.cpy_pending = TRUE; + m_magtape.cpy_pending = TRUE; break; } break; @@ -1433,21 +1399,20 @@ static void tx0_io_cpy(device_t *device) IO devices should reset */ -static void tx0_io_reset_callback(device_t *device) +WRITE_LINE_MEMBER( tx0_state::tx0_io_reset_callback ) { - tx0_state *state = device->machine().driver_data(); - state->m_tape_reader.rcl = state->m_tape_reader.rc = 0; - if (state->m_tape_reader.timer) - state->m_tape_reader.timer->enable(0); + m_tape_reader.rcl = m_tape_reader.rc = 0; + if (m_tape_reader.timer) + m_tape_reader.timer->enable(0); - if (state->m_tape_puncher.timer) - state->m_tape_puncher.timer->enable(0); + if (m_tape_puncher.timer) + m_tape_puncher.timer->enable(0); - if (state->m_typewriter.prt_timer) - state->m_typewriter.prt_timer->enable(0); + if (m_typewriter.prt_timer) + m_typewriter.prt_timer->enable(0); - if (state->m_dis_timer) - state->m_dis_timer->enable(0); + if (m_dis_timer) + m_dis_timer->enable(0); } @@ -1537,7 +1502,7 @@ INTERRUPT_GEN_MEMBER(tx0_state::tx0_interrupt) } if (control_transitions & tx0_read_in) { /* set cpu to read instructions from perforated tape */ - m_maincpu->set_state_int(TX0_RESET, (UINT64)0); + m_maincpu->pulse_reset(); m_maincpu->set_state_int(TX0_RUN, (UINT64)0); m_maincpu->set_state_int(TX0_RIM, 1); } @@ -1600,7 +1565,18 @@ static MACHINE_CONFIG_START( tx0_64kw, tx0_state ) /* basic machine hardware */ /* TX0 CPU @ approx. 167 kHz (no master clock, but the memory cycle time is approximately 6usec) */ MCFG_CPU_ADD("maincpu", TX0_64KW, 166667) - MCFG_CPU_CONFIG(tx0_reset_param) + MCFG_TX0_CONFIG( + WRITELINE( tx0_state, tx0_io_cpy ), + WRITELINE( tx0_state, tx0_io_r1l ), + WRITELINE( tx0_state, tx0_io_dis ), + WRITELINE( tx0_state, tx0_io_r3l ), + WRITELINE( tx0_state, tx0_io_prt ), + NULL, + WRITELINE( tx0_state, tx0_io_p6h ), + WRITELINE( tx0_state, tx0_io_p7h ), + WRITELINE( tx0_state, tx0_sel ), + WRITELINE( tx0_state, tx0_io_reset_callback ) + ) MCFG_CPU_PROGRAM_MAP(tx0_64kw_map) /* dummy interrupt: handles input */ MCFG_CPU_VBLANK_INT_DRIVER("screen", tx0_state, tx0_interrupt) @@ -1632,7 +1608,6 @@ static MACHINE_CONFIG_DERIVED( tx0_8kw, tx0_64kw ) /* TX0 CPU @ approx. 167 kHz (no master clock, but the memory cycle time is approximately 6usec) */ MCFG_CPU_MODIFY("maincpu") - MCFG_CPU_CONFIG(tx0_reset_param) MCFG_CPU_PROGRAM_MAP(tx0_8kw_map) /*MCFG_CPU_PORTS(readport, writeport)*/ MACHINE_CONFIG_END diff --git a/src/mess/includes/tx0.h b/src/mess/includes/tx0.h index b3f7e3d0c68..7c2d678d61e 100644 --- a/src/mess/includes/tx0.h +++ b/src/mess/includes/tx0.h @@ -8,6 +8,7 @@ #define TX0_H_ #include "video/crt.h" +#include "cpu/pdp1/tx0.h" enum state_t { @@ -161,7 +162,7 @@ public: TIMER_CALLBACK_MEMBER(prt_callback); TIMER_CALLBACK_MEMBER(dis_callback); void tx0_machine_stop(); - required_device m_maincpu; + required_device m_maincpu; inline void tx0_plot_pixel(bitmap_ind16 &bitmap, int x, int y, UINT32 color); void tx0_plot(int x, int y); void tx0_draw_led(bitmap_ind16 &bitmap, int x, int y, int state); @@ -183,6 +184,16 @@ public: void schedule_select(); void schedule_unselect(); void tx0_keyboard(); + DECLARE_WRITE_LINE_MEMBER(tx0_io_cpy); + DECLARE_WRITE_LINE_MEMBER(tx0_io_r1l); + DECLARE_WRITE_LINE_MEMBER(tx0_io_r3l); + DECLARE_WRITE_LINE_MEMBER(tx0_io_p6h); + DECLARE_WRITE_LINE_MEMBER(tx0_io_p7h); + DECLARE_WRITE_LINE_MEMBER(tx0_io_prt); + DECLARE_WRITE_LINE_MEMBER(tx0_io_dis); + DECLARE_WRITE_LINE_MEMBER(tx0_sel); + DECLARE_WRITE_LINE_MEMBER(tx0_io_reset_callback); + void magtape_callback(); }; /* defines for each bit and mask in input port "CSW" */