mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
tx0.c: Modernized cpu core. [Wilbert Pol]
Out of whatsnew: Also copied over the support for octal in debugger state from the alto2 branch.
This commit is contained in:
parent
9c03593b09
commit
cc74ef9ade
File diff suppressed because it is too large
Load Diff
@ -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();
|
||||
};
|
||||
|
||||
/* 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__ */
|
||||
|
@ -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)
|
||||
|
@ -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<tx0_state>();
|
||||
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<tx0_state>();
|
||||
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<tx0_state>();
|
||||
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<tx0_state>();
|
||||
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<tx0_state>();
|
||||
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<tx0_state>();
|
||||
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<tx0_state>();
|
||||
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<tx0_state>();
|
||||
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<tx0_state>();
|
||||
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<tx0_state>();
|
||||
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
|
||||
|
@ -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<cpu_device> m_maincpu;
|
||||
required_device<tx0_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" */
|
||||
|
Loading…
Reference in New Issue
Block a user