pdp1: Clean up callbacks and start encapsulating peripherals

* pdp1, pdp8: Apply word shift to address spaces
This commit is contained in:
AJR 2020-09-13 21:37:20 -04:00
parent 692ff2c06f
commit f0572bbb8c
9 changed files with 578 additions and 586 deletions

View File

@ -348,8 +348,8 @@
#define LOG_EXTRA 0
#define LOG_IOT_EXTRA 0
#define READ_PDP_18BIT(A) ((signed)m_program->read_dword((A)<<2))
#define WRITE_PDP_18BIT(A,V) (m_program->write_dword((A)<<2,(V)))
#define READ_PDP_18BIT(A) ((signed)m_program->read_dword(A))
#define WRITE_PDP_18BIT(A,V) (m_program->write_dword((A),(V)))
#define PC m_pc
@ -378,12 +378,15 @@
#define PREVIOUS_PC ((PC & ADDRESS_EXTENSION_MASK) | ((PC-1) & BASE_ADDRESS_MASK))
DEFINE_DEVICE_TYPE(PDP1, pdp1_device, "pdp1_cpu", "DEC PDP1")
DEFINE_DEVICE_TYPE(PDP1, pdp1_device, "pdp1_cpu", "DEC PDP-1 Central Processor")
pdp1_device::pdp1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: cpu_device(mconfig, PDP1, tag, owner, clock)
, m_program_config("program", ENDIANNESS_BIG, 32, 18, 0)
, m_program_config("program", ENDIANNESS_BIG, 32, 18, -2) // data is actually 18 bits wide
, m_extern_iot(64, iot_delegate(*this))
, m_read_binary_word(*this)
, m_io_sc_callback(*this)
{
m_program_config.m_is_octal = true;
}
@ -405,16 +408,9 @@ void pdp1_device::device_config_complete()
// or initialize to defaults if none provided
else
{
memset(&read_binary_word, 0, sizeof(read_binary_word));
memset(&io_sc_callback, 0, sizeof(io_sc_callback));
extend_support = 0;
hw_mul_div = 0;
type_20_sbs = 0;
for (auto & elem : extern_iot)
{
memset(&elem, 0, sizeof(elem));
}
}
}
@ -495,34 +491,6 @@ void pdp1_device::execute_set_input(int irqline, int state)
}
static void null_iot(device_t *device, int op2, int nac, int mb, int *io, int ac)
{
pdp1_device *pdp1 = dynamic_cast<pdp1_device*>(device);
pdp1->pdp1_null_iot(op2, nac, mb, io, ac);
}
static void lem_eem_iot(device_t *device, int op2, int nac, int mb, int *io, int ac)
{
pdp1_device *pdp1 = dynamic_cast<pdp1_device*>(device);
pdp1->pdp1_lem_eem_iot(op2, nac, mb, io, ac);
}
static void sbs_iot(device_t *device, int op2, int nac, int mb, int *io, int ac)
{
pdp1_device *pdp1 = dynamic_cast<pdp1_device*>(device);
pdp1->pdp1_sbs_iot(op2, nac, mb, io, ac);
}
static void type_20_sbs_iot(device_t *device, int op2, int nac, int mb, int *io, int ac)
{
pdp1_device *pdp1 = dynamic_cast<pdp1_device*>(device);
pdp1->pdp1_type_20_sbs_iot(op2, nac, mb, io, ac);
}
void pdp1_device::device_start()
{
int i;
@ -569,12 +537,12 @@ void pdp1_device::device_start()
/* set up params and callbacks */
for (i=0; i<64; i++)
{
m_extern_iot[i] = (extern_iot[i])
? extern_iot[i]
: null_iot;
m_extern_iot[i].resolve();
if (m_extern_iot[i].isnull())
m_extern_iot[i] = iot_delegate(*this, FUNC(pdp1_device::null_iot));
}
m_read_binary_word = read_binary_word;
m_io_sc_callback = io_sc_callback;
m_read_binary_word.resolve();
m_io_sc_callback.resolve();
m_extend_support = extend_support;
m_hw_mul_div = hw_mul_div;
m_type_20_sbs = type_20_sbs;
@ -599,13 +567,13 @@ void pdp1_device::device_start()
if (m_extend_support)
{
m_extern_iot[074] = lem_eem_iot;
m_extern_iot[074] = iot_delegate(*this, FUNC(pdp1_device::lem_eem_iot));
}
m_extern_iot[054] = m_extern_iot[055] = m_extern_iot[056] = sbs_iot;
m_extern_iot[054] = m_extern_iot[055] = m_extern_iot[056] = iot_delegate(*this, FUNC(pdp1_device::sbs_iot));
if (m_type_20_sbs)
{
m_extern_iot[050] = m_extern_iot[051] = m_extern_iot[052] = m_extern_iot[053]
= type_20_sbs_iot;
= iot_delegate(*this, FUNC(pdp1_device::type_20_sbs_iot));
}
state_add( PDP1_PC, "PC", m_pc).formatstr("%06O");
@ -796,9 +764,6 @@ void pdp1_device::execute_run()
{
do
{
debugger_instruction_hook(PC);
/* ioh should be cleared at the end of the instruction cycle, and ios at the
start of next instruction cycle, but who cares? */
if (m_ioh && m_ios)
@ -815,8 +780,8 @@ void pdp1_device::execute_run()
{
case 0:
/* read first word as instruction */
if (m_read_binary_word)
(*m_read_binary_word)(this); /* data will be transferred to IO register */
if (!m_read_binary_word.isnull())
m_read_binary_word(); /* data will be transferred to IO register */
m_rim_step = 1;
m_ios = 0;
break;
@ -860,8 +825,8 @@ void pdp1_device::execute_run()
case 2:
/* read second word as data */
if (m_read_binary_word)
(*m_read_binary_word)(this); /* data will be transferred to IO register */
if (!m_read_binary_word.isnull())
m_read_binary_word(); /* data will be transferred to IO register */
m_rim_step = 3;
m_ios = 0;
break;
@ -940,6 +905,7 @@ void pdp1_device::execute_run()
if (! m_cycle)
{ /* no instruction in progress: time to fetch a new instruction, I guess */
debugger_instruction_hook(PC);
MB = READ_PDP_18BIT(MA = PC);
INCREMENT_PC;
IR = MB >> 13; /* basic opcode */
@ -1564,7 +1530,7 @@ void pdp1_device::execute_instruction()
{ /* IOT with IO wait */
if (m_ioc)
{ /* the iot command line is pulsed only if ioc is asserted */
(*m_extern_iot[MB & 0000077])(this, MB & 0000077, (MB & 0004000) == 0, MB, &IO, AC);
m_extern_iot[MB & 0000077](MB & 0000077, (MB & 0004000) == 0, MB, IO, AC);
m_ioh = 1; /* enable io wait */
@ -1587,7 +1553,7 @@ void pdp1_device::execute_instruction()
}
else
{ /* IOT with no IO wait */
(*m_extern_iot[MB & 0000077])(this, MB & 0000077, (MB & 0004000) != 0, MB, &IO, AC);
m_extern_iot[MB & 0000077](MB & 0000077, (MB & 0004000) != 0, MB, IO, AC);
}
break;
case OPR: /* Operate Instruction Group */
@ -1639,7 +1605,7 @@ no_fetch:
/*
Handle unimplemented IOT
*/
void pdp1_device::pdp1_null_iot(int op2, int nac, int mb, int *io, int ac)
void pdp1_device::null_iot(int op2, int nac, int mb, int &io, int ac)
{
/* Note that the dummy IOT 0 is used to wait for the completion pulse
generated by the a pending IOT (IOT with completion pulse but no IO wait) */
@ -1661,7 +1627,7 @@ void pdp1_device::pdp1_null_iot(int op2, int nac, int mb, int *io, int ac)
IOT 74: LEM/EEM
*/
void pdp1_device::pdp1_lem_eem_iot(int op2, int nac, int mb, int *io, int ac)
void pdp1_device::lem_eem_iot(int op2, int nac, int mb, int &io, int ac)
{
if (! m_extend_support) /* extend mode supported? */
{
@ -1684,7 +1650,7 @@ void pdp1_device::pdp1_lem_eem_iot(int op2, int nac, int mb, int *io, int ac)
IOT 55: esm
IOT 56: cbs
*/
void pdp1_device::pdp1_sbs_iot(int op2, int nac, int mb, int *io, int ac)
void pdp1_device::sbs_iot(int op2, int nac, int mb, int &io, int ac)
{
switch (op2)
{
@ -1727,7 +1693,7 @@ void pdp1_device::pdp1_sbs_iot(int op2, int nac, int mb, int *io, int ac)
IOT 52: isb
IOT 53: cac
*/
void pdp1_device::pdp1_type_20_sbs_iot(int op2, int nac, int mb, int *io, int ac)
void pdp1_device::type_20_sbs_iot(int op2, int nac, int mb, int &io, int ac)
{
int channel, mask;
if (! m_type_20_sbs) /* type 20 sequence break system supported? */
@ -1820,6 +1786,6 @@ void pdp1_device::pulse_start_clear()
field_interrupt();
/* now, we kindly ask IO devices to reset, too */
if (m_io_sc_callback)
(*m_io_sc_callback)(this);
if (!m_io_sc_callback.isnull())
m_io_sc_callback();
}

View File

@ -20,20 +20,8 @@ enum
};
typedef void (*pdp1_extern_iot_func)(device_t *device, int op2, int nac, int mb, int *io, int ac);
typedef void (*pdp1_read_binary_word_func)(device_t *device);
typedef void (*pdp1_io_sc_func)(device_t *device);
struct pdp1_reset_param_t
{
/* callbacks for iot instructions (required for any I/O) */
pdp1_extern_iot_func extern_iot[64];
/* read a word from the perforated tape reader (required for read-in mode) */
pdp1_read_binary_word_func read_binary_word;
/* callback called when sc is pulsed: IO devices should reset */
pdp1_io_sc_func io_sc_callback;
/* 0: no extend support, 1: extend with 15-bit address, 2: extend with 16-bit address */
int extend_support;
/* 1 to use hardware multiply/divide (MUL, DIV) instead of MUS, DIS */
@ -49,6 +37,10 @@ class pdp1_device : public cpu_device
, public pdp1_reset_param_t
{
public:
typedef device_delegate<void (int op2, int nac, int mb, int &io, int ac)> iot_delegate;
typedef device_delegate<void ()> read_binary_word_delegate;
typedef device_delegate<void ()> io_sc_delegate;
enum opcode
{
AND = 001,
@ -83,14 +75,17 @@ public:
// construction/destruction
pdp1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template <int I, typename... T> void set_iot_callback(T &&... args) { m_extern_iot[I].set(std::forward<T>(args)...); }
template <typename... T> void set_read_binary_word(T &&... args) { m_read_binary_word.set(std::forward<T>(args)...); }
template <typename... T> void set_io_sc_callback(T &&... args) { m_io_sc_callback.set(std::forward<T>(args)...); }
void set_reset_param(const pdp1_reset_param_t *param) { m_reset_param = param; }
void pulse_start_clear();
void io_complete() { m_ios = 1; }
void pdp1_null_iot(int op2, int nac, int mb, int *io, int ac);
void pdp1_lem_eem_iot(int op2, int nac, int mb, int *io, int ac);
void pdp1_sbs_iot(int op2, int nac, int mb, int *io, int ac);
void pdp1_type_20_sbs_iot(int op2, int nac, int mb, int *io, int ac);
void null_iot(int op2, int nac, int mb, int &io, int ac);
void lem_eem_iot(int op2, int nac, int mb, int &io, int ac);
void sbs_iot(int op2, int nac, int mb, int &io, int ac);
void type_20_sbs_iot(int op2, int nac, int mb, int &io, int ac);
protected:
// device-level overrides
@ -167,11 +162,11 @@ private:
int m_no_sequence_break; /* disable sequence break recognition for one cycle */
/* callbacks for iot instructions (required for any I/O) */
pdp1_extern_iot_func m_extern_iot[64];
std::vector<iot_delegate> m_extern_iot;
/* read a word from the perforated tape reader (required for read-in mode) */
pdp1_read_binary_word_func m_read_binary_word;
read_binary_word_delegate m_read_binary_word;
/* callback called when sc is pulsed: IO devices should reset */
pdp1_io_sc_func m_io_sc_callback;
io_sc_delegate m_io_sc_callback;
/* 0: no extend support, 1: extend with 15-bit address, 2: extend with 16-bit address */
int m_extend_support;

View File

@ -19,7 +19,7 @@ inline void pdp1_disassembler::ea()
u32 pdp1_disassembler::opcode_alignment() const
{
return 4;
return 1;
}
offs_t pdp1_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
@ -290,5 +290,5 @@ offs_t pdp1_disassembler::disassemble(std::ostream &stream, offs_t pc, const dat
//etime = 5;
break;
}
return 4;
return 1;
}

View File

@ -51,7 +51,7 @@ DEFINE_DEVICE_TYPE(PDP8, pdp8_device, "pdp8_cpu", "DEC PDP8")
pdp8_device::pdp8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: cpu_device(mconfig, PDP8, tag, owner, clock),
m_program_config("program", ENDIANNESS_BIG, 12, 12),
m_program_config("program", ENDIANNESS_BIG, 12, 12, -1),
m_pc(0),
m_ac(0),
m_mb(0),

View File

@ -11,7 +11,7 @@
u32 pdp8_disassembler::opcode_alignment() const
{
return 2;
return 1;
}
offs_t pdp8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
@ -164,5 +164,5 @@ offs_t pdp8_disassembler::disassemble(std::ostream &stream, offs_t pc, const dat
}
}
return 2 | SUPPORTED;
return 1 | SUPPORTED | (opcode == 4 ? STEP_OVER : 0);
}

File diff suppressed because it is too large Load Diff

View File

@ -168,59 +168,216 @@ enum
pen_lightpen_pressed = pen_green
};
/* tape reader registers */
struct tape_reader_t
class pdp1_state;
// tape reader device
class pdp1_readtape_image_device : public device_t,
public device_image_interface
{
device_image_interface *fd; /* file descriptor of tape image */
public:
// construction/destruction
pdp1_readtape_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0U);
int motor_on; /* 1-bit reader motor on */
auto st_ptr() { return m_st_ptr.bind(); }
int rb; /* 18-bit reader buffer */
int rcl; /* 1-bit reader clutch */
int rc; /* 2-bit reader counter */
int rby; /* 1-bit reader binary mode flip-flop */
int rcp; /* 1-bit reader "need a completion pulse" flip-flop */
void iot_rpa(int op2, int nac, int mb, int &io, int ac);
void iot_rpb(int op2, int nac, int mb, int &io, int ac);
void iot_rrb(int op2, int nac, int mb, int &io, int ac);
emu_timer *timer; /* timer to simulate reader timing */
void tape_read_binary();
protected:
// device-level overrides
virtual void device_resolve_objects() override;
virtual void device_start() override;
// image-level overrides
virtual iodevice_t image_type() const noexcept override { return IO_PUNCHTAPE; }
virtual bool is_readable() const noexcept override { return true; }
virtual bool is_writeable() const noexcept override { return false; }
virtual bool is_creatable() const noexcept override { return false; }
virtual bool must_be_loaded() const noexcept override { return false; }
virtual bool is_reset_on_load() const noexcept override { return false; }
virtual const char *file_extensions() const noexcept override { return "tap,rim"; }
virtual image_init_result call_load() override;
virtual void call_unload() override;
public:
TIMER_CALLBACK_MEMBER(reader_callback);
int tape_read(uint8_t *reply);
void begin_tape_read(int binary, int nac);
required_device<pdp1_device> m_maincpu;
devcb_write_line m_st_ptr;
int m_motor_on; // 1-bit reader motor on
int m_rb; // 18-bit reader buffer
int m_rcl; // 1-bit reader clutch
int m_rc; // 2-bit reader counter
int m_rby; // 1-bit reader binary mode flip-flop
int m_rcp; // 1-bit reader "need a completion pulse" flip-flop
emu_timer *m_timer; // timer to simulate reader timing
};
/* tape puncher registers */
struct tape_puncher_t
// tape puncher device
class pdp1_punchtape_image_device : public device_t,
public device_image_interface
{
device_image_interface *fd; /* file descriptor of tape image */
public:
// construction/destruction
pdp1_punchtape_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0U);
emu_timer *timer; /* timer to generate completion pulses */
auto st_ptp() { return m_st_ptp.bind(); }
void iot_ppa(int op2, int nac, int mb, int &io, int ac);
void iot_ppb(int op2, int nac, int mb, int &io, int ac);
protected:
// device-level overrides
virtual void device_resolve_objects() override;
virtual void device_start() override;
// image-level overrides
virtual iodevice_t image_type() const noexcept override { return IO_PUNCHTAPE; }
virtual bool is_readable() const noexcept override { return false; }
virtual bool is_writeable() const noexcept override { return true; }
virtual bool is_creatable() const noexcept override { return true; }
virtual bool must_be_loaded() const noexcept override { return false; }
virtual bool is_reset_on_load() const noexcept override { return false; }
virtual const char *file_extensions() const noexcept override { return "tap,rim"; }
virtual image_init_result call_load() override;
virtual void call_unload() override;
public:
TIMER_CALLBACK_MEMBER(puncher_callback);
void tape_write(uint8_t data);
required_device<pdp1_device> m_maincpu;
devcb_write_line m_st_ptp;
emu_timer *m_timer; // timer to generate completion pulses
};
/* typewriter registers */
struct typewriter_t
// typewriter device
class pdp1_typewriter_device : public device_t,
public device_image_interface
{
device_image_interface *fd; /* file descriptor of output image */
public:
// construction/destruction
pdp1_typewriter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0U);
int tb; /* typewriter buffer */
auto st_tyo() { return m_st_tyo.bind(); }
auto st_tyi() { return m_st_tyi.bind(); }
emu_timer *tyo_timer;/* timer to generate completion pulses */
void iot_tyo(int op2, int nac, int mb, int &io, int ac);
void iot_tyi(int op2, int nac, int mb, int &io, int ac);
protected:
// device-level overrides
virtual void device_resolve_objects() override;
virtual void device_start() override;
// image-level overrides
virtual iodevice_t image_type() const noexcept override { return IO_PRINTER; }
virtual bool is_readable() const noexcept override { return false; }
virtual bool is_writeable() const noexcept override { return true; }
virtual bool is_creatable() const noexcept override { return true; }
virtual bool must_be_loaded() const noexcept override { return false; }
virtual bool is_reset_on_load() const noexcept override { return false; }
virtual const char *file_extensions() const noexcept override { return "typ"; }
virtual image_init_result call_load() override;
virtual void call_unload() override;
public:
TIMER_CALLBACK_MEMBER(tyo_callback);
void linefeed();
void drawchar(int character);
void typewriter_out(uint8_t data);
void pdp1_keyboard();
required_device<pdp1_device> m_maincpu;
required_device<pdp1_state> m_driver_state;
required_ioport_array<4> m_twr;
devcb_write_line m_st_tyo;
devcb_write_line m_st_tyi;
int m_tb; // typewriter buffer
emu_timer *m_tyo_timer; // timer to generate completion pulses
int m_old_typewriter_keys[4];
int m_color;
bitmap_ind16 m_bitmap;
int m_pos;
int m_case_shift;
};
/* MIT parallel drum (mostly similar to type 23) */
struct parallel_drum_t
// MIT parallel drum (mostly similar to type 23)
class pdp1_cylinder_image_device : public device_t,
public device_image_interface
{
device_image_interface *fd; /* file descriptor of drum image */
public:
// construction/destruction
pdp1_cylinder_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0U);
int il; /* initial location (12-bit) */
int wc; /* word counter (12-bit) */
int wcl; /* word core location counter (16-bit) */
int rfb; /* read field buffer (5-bit) */
int wfb; /* write field buffer (5-bit) */
void iot_dia(int op2, int nac, int mb, int &io, int ac);
void iot_dba(int op2, int nac, int mb, int &io, int ac);
void iot_dcc(int op2, int nac, int mb, int &io, int ac);
void iot_dra(int op2, int nac, int mb, int &io, int ac);
int dba;
protected:
// device-level overrides
virtual void device_start() override;
emu_timer *rotation_timer; /* timer called each time dc is 0 */
emu_timer *il_timer; /* timer called each time dc is il */
// image-level overrides
virtual iodevice_t image_type() const noexcept override { return IO_CYLINDER; }
virtual bool is_readable() const noexcept override { return true; }
virtual bool is_writeable() const noexcept override { return true; }
virtual bool is_creatable() const noexcept override { return true; }
virtual bool must_be_loaded() const noexcept override { return false; }
virtual bool is_reset_on_load() const noexcept override { return false; }
virtual const char *file_extensions() const noexcept override { return "drm"; }
virtual image_init_result call_load() override;
virtual void call_unload() override;
public:
void set_il(int il);
uint32_t drum_read(int field, int position);
void drum_write(int field, int position, uint32_t data);
required_device<pdp1_device> m_maincpu;
int m_il; // initial location (12-bit)
int m_wc; // word counter (12-bit)
int m_wcl; // word core location counter (16-bit)
int m_rfb; // read field buffer (5-bit)
int m_wfb; // write field buffer (5-bit)
int m_dba;
emu_timer *m_rotation_timer;// timer called each time dc is 0
emu_timer *m_il_timer; // timer called each time dc is il
};
@ -239,6 +396,10 @@ public:
pdp1_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_tape_reader(*this, "readt"),
m_tape_puncher(*this, "punch"),
m_typewriter(*this, "typewriter"),
m_parallel_drum(*this, "drum"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_crt(*this, "crt"),
@ -248,21 +409,20 @@ public:
m_tstadd(*this, "TSTADD"),
m_twdmsb(*this, "TWDMSB"),
m_twdlsb(*this, "TWDLSB"),
m_twr(*this, "TWR.%u", 0),
m_cfg(*this, "CFG"),
m_io_lightpen(*this, "LIGHTPEN"),
m_lightx(*this, "LIGHTX"),
m_lighty(*this, "LIGHTY")
{ }
required_device<pdp1_device> m_maincpu;
required_device<pdp1_readtape_image_device> m_tape_reader;
required_device<pdp1_punchtape_image_device> m_tape_puncher;
required_device<pdp1_typewriter_device> m_typewriter;
required_device<pdp1_cylinder_image_device> m_parallel_drum;
int m_io_status;
tape_reader_t m_tape_reader;
tape_puncher_t m_tape_puncher;
typewriter_t m_typewriter;
emu_timer *m_dpy_timer;
lightpen_t m_lightpen;
parallel_drum_t m_parallel_drum;
required_device<pdp1_device> m_maincpu;
virtual void machine_start() override;
virtual void machine_reset() override;
@ -271,9 +431,6 @@ public:
uint32_t screen_update_pdp1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(screen_vblank_pdp1);
INTERRUPT_GEN_MEMBER(pdp1_interrupt);
TIMER_CALLBACK_MEMBER(reader_callback);
TIMER_CALLBACK_MEMBER(puncher_callback);
TIMER_CALLBACK_MEMBER(tyo_callback);
TIMER_CALLBACK_MEMBER(dpy_callback);
void pdp1_machine_stop();
inline void pdp1_plot_pixel(bitmap_ind16 &bitmap, int x, int y, uint32_t color);
@ -286,39 +443,35 @@ public:
void pdp1_draw_string(bitmap_ind16 &bitmap, const char *buf, int x, int y, int color);
void pdp1_draw_panel_backdrop(bitmap_ind16 &bitmap);
void pdp1_draw_panel(bitmap_ind16 &bitmap);
void pdp1_typewriter_linefeed();
void pdp1_typewriter_drawchar(int character);
void pdp1_update_lightpen_state(const lightpen_t *new_state);
void pdp1_draw_circle(bitmap_ind16 &bitmap, int x, int y, int radius, int color_);
void pdp1_erase_lightpen(bitmap_ind16 &bitmap);
void pdp1_draw_lightpen(bitmap_ind16 &bitmap);
int tape_read(uint8_t *reply);
void begin_tape_read(int binary, int nac);
void tape_write(uint8_t data);
void typewriter_out(uint8_t data);
void parallel_drum_set_il(int il);
uint32_t drum_read(int field, int position);
void drum_write(int field, int position, uint32_t data);
void pdp1_keyboard();
void pdp1_lightpen();
int read_spacewar() { return m_spacewar->read(); }
template <int Mask> DECLARE_WRITE_LINE_MEMBER(io_status_w);
void pdp1(machine_config &config);
void pdp1_map(address_map &map);
private:
void iot_dpy(int op2, int nac, int mb, int &io, int ac);
void iot_011(int op2, int nac, int mb, int &io, int ac);
void iot_cks(int op2, int nac, int mb, int &io, int ac);
void io_state_clear();
pdp1_reset_param_t m_reset_param;
int m_old_typewriter_keys[4];
int m_old_lightpen;
int m_old_control_keys;
int m_old_tw_keys;
int m_old_ta_keys;
int m_typewriter_color;
bitmap_ind16 m_panel_bitmap;
bitmap_ind16 m_typewriter_bitmap;
lightpen_t m_lightpen_state;
lightpen_t m_previous_lightpen_state;
int m_pos;
int m_case_shift;
public:
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<crt_device> m_crt;
@ -328,7 +481,6 @@ private:
required_ioport m_tstadd;
required_ioport m_twdmsb;
required_ioport m_twdlsb;
required_ioport_array<4> m_twr;
required_ioport m_cfg;
required_ioport m_io_lightpen;
required_ioport m_lightx;

View File

@ -37,17 +37,17 @@ inline void pdp1_state::pdp1_plot_pixel(bitmap_ind16 &bitmap, int x, int y, uint
*/
void pdp1_state::video_start()
{
m_typewriter_color = color_typewriter_black;
m_typewriter->m_color = color_typewriter_black;
/* alloc bitmaps for our private fun */
m_panel_bitmap.allocate(panel_window_width, panel_window_height, BITMAP_FORMAT_IND16);
m_typewriter_bitmap.allocate(typewriter_window_width, typewriter_window_height, BITMAP_FORMAT_IND16);
m_typewriter->m_bitmap.allocate(typewriter_window_width, typewriter_window_height, BITMAP_FORMAT_IND16);
/* set up out bitmaps */
pdp1_draw_panel_backdrop(m_panel_bitmap);
const rectangle typewriter_bitmap_bounds(0, typewriter_window_width-1, 0, typewriter_window_height-1);
m_typewriter_bitmap.fill(pen_typewriter_bg, typewriter_bitmap_bounds);
m_typewriter->m_bitmap.fill(pen_typewriter_bg, typewriter_bitmap_bounds);
}
@ -84,7 +84,7 @@ uint32_t pdp1_state::screen_update_pdp1(screen_device &screen, bitmap_ind16 &bit
pdp1_draw_panel(m_panel_bitmap);
copybitmap(bitmap, m_panel_bitmap, 0, 0, panel_window_offset_x, panel_window_offset_y, cliprect);
copybitmap(bitmap, m_typewriter_bitmap, 0, 0, typewriter_window_offset_x, typewriter_window_offset_y, cliprect);
copybitmap(bitmap, m_typewriter->m_bitmap, 0, 0, typewriter_window_offset_x, typewriter_window_offset_y, cliprect);
return 0;
}
@ -353,28 +353,28 @@ enum
};
void pdp1_state::pdp1_typewriter_linefeed()
void pdp1_typewriter_device::linefeed()
{
uint8_t buf[typewriter_window_width];
int y;
assert(typewriter_window_width <= m_typewriter_bitmap.width());
assert(typewriter_window_height <= m_typewriter_bitmap.height());
assert(typewriter_window_width <= m_bitmap.width());
assert(typewriter_window_height <= m_bitmap.height());
for (y=0; y<typewriter_window_height-typewriter_scroll_step; y++)
{
std::copy_n(&m_typewriter_bitmap.pix16(y+typewriter_scroll_step, 0), typewriter_window_width, buf);
draw_scanline8(m_typewriter_bitmap, 0, y, typewriter_window_width, buf, m_palette->pens());
std::copy_n(&m_bitmap.pix16(y+typewriter_scroll_step, 0), typewriter_window_width, buf);
draw_scanline8(m_bitmap, 0, y, typewriter_window_width, buf, m_driver_state->m_palette->pens());
}
const rectangle typewriter_scroll_clear_window(0, typewriter_window_width-1, typewriter_window_height-typewriter_scroll_step, typewriter_window_height-1);
m_typewriter_bitmap.fill(pen_typewriter_bg, typewriter_scroll_clear_window);
m_bitmap.fill(pen_typewriter_bg, typewriter_scroll_clear_window);
}
void pdp1_state::pdp1_typewriter_drawchar(int character)
void pdp1_typewriter_device::drawchar(int character)
{
static const char ascii_table[2][64] =
{ /* n-s = non-spacing */
{ /* lower case */
{ // n-s = non-spacing
{ // lower case
' ', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', '*', '*',
@ -392,7 +392,7 @@ void pdp1_state::pdp1_typewriter_drawchar(int character)
'h', 'i', '*',/*Lower Case*/ '.',
'*',/*Upper Case*/ '*',/*Backspace*/ '*', '*'/*Carriage Return*/
},
{ /* upper case */
{ // upper case
' ', '"', '\'', '~',
'\202',/*implies*/ '\203',/*or*/ '\204',/*and*/ '<',
'>', '\205',/*up arrow*/ '*', '*',
@ -419,58 +419,58 @@ void pdp1_state::pdp1_typewriter_drawchar(int character)
switch (character)
{
case 034:
/* Black */
m_typewriter_color = color_typewriter_black;
// Black
m_color = color_typewriter_black;
break;
case 035:
/* Red */
m_typewriter_color = color_typewriter_red;
// Red
m_color = color_typewriter_red;
break;
case 036:
/* Tab */
// Tab
m_pos = m_pos + tab_step - (m_pos % tab_step);
break;
case 072:
/* Lower case */
// Lower case
m_case_shift = 0;
break;
case 074:
/* Upper case */
// Upper case
m_case_shift = 1;
break;
case 075:
/* Backspace */
// Backspace
if (m_pos)
m_pos--;
break;
case 077:
/* Carriage Return */
// Carriage Return
m_pos = 0;
pdp1_typewriter_linefeed();
linefeed();
break;
default:
/* Any printable character... */
// Any printable character...
if (m_pos >= 80)
{ /* if past right border, wrap around. (Right???) */
pdp1_typewriter_linefeed(); /* next line */
m_pos = 0; /* return to start of line */
{ // if past right border, wrap around. (Right???)
linefeed(); // next line
m_pos = 0; // return to start of line
}
/* print character (lookup ASCII equivalent in table) */
pdp1_draw_char(m_typewriter_bitmap, ascii_table[m_case_shift][character],
// print character (lookup ASCII equivalent in table)
m_driver_state->pdp1_draw_char(m_bitmap, ascii_table[m_case_shift][character],
8*m_pos, typewriter_write_offset_y,
m_typewriter_color); /* print char */
m_color); // print char
if ((character!= 040) && (character!= 056)) /* 040 and 056 are non-spacing characters */
m_pos++; /* step carriage forward */
if ((character!= 040) && (character!= 056)) // 040 and 056 are non-spacing characters
m_pos++; // step carriage forward
break;
}

View File

@ -483,7 +483,7 @@ static const dasm_table_entry dasm_table[] =
{ "nsc8105", be, 0, []() -> util::disasm_interface * { return new m680x_disassembler(8105); } },
{ "pace", le, -1, []() -> util::disasm_interface * { return new pace_disassembler; } },
{ "patinho_feio", le, 0, []() -> util::disasm_interface * { return new patinho_feio_disassembler; } },
{ "pdp1", be, 0, []() -> util::disasm_interface * { return new pdp1_disassembler; } },
{ "pdp1", be, -2, []() -> util::disasm_interface * { return new pdp1_disassembler; } },
{ "pdp8", be, 0, []() -> util::disasm_interface * { return new pdp8_disassembler; } },
{ "pic16", le, -1, []() -> util::disasm_interface * { return new pic16_disassembler; } },
{ "pic16c5x", le, -1, []() -> util::disasm_interface * { return new pic16c5x_disassembler; } },