mirror of
https://github.com/holub/mame
synced 2025-04-22 00:11:58 +03:00
tim100: Fix CRT display by doing DMA the right way; fix serial terminal interface
This commit is contained in:
parent
e0cb1febeb
commit
561cc84b79
@ -9,7 +9,7 @@ Mihajlo Pupin Institute
|
||||
2016/07/14 Fixed display etc [Robbbert]
|
||||
|
||||
Notes:
|
||||
- Serial terminals appear to need 8 bits, 2 stop bits, odd parity @ 9600
|
||||
- Serial keyboard appears to need 8 bits, 2 stop bits, odd parity
|
||||
- Unable to type anything as it seems uarts want BRKDET activated all the time, which we cannot do.
|
||||
- Unable to find any technical info at all, so it's all guesswork.
|
||||
|
||||
@ -30,36 +30,46 @@ public:
|
||||
tim100_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_charmap(*this, "chargen")
|
||||
, m_p_videoram(*this, "videoram")
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_palette(*this, "palette")
|
||||
, m_crtc(*this, "crtc")
|
||||
, m_mem(*this, "maincpu", AS_OPCODES)
|
||||
, m_dma_view(*this, "dma_view")
|
||||
{ }
|
||||
|
||||
void tim100(machine_config &config);
|
||||
|
||||
private:
|
||||
DECLARE_WRITE_LINE_MEMBER(drq_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(irq_w);
|
||||
I8275_DRAW_CHARACTER_MEMBER( crtc_display_pixels );
|
||||
|
||||
void io_map(address_map &map);
|
||||
void mem_map(address_map &map);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
|
||||
uint16_t m_dma_adr;
|
||||
private:
|
||||
u8 dma_r(offs_t offset);
|
||||
DECLARE_WRITE_LINE_MEMBER(sod_w);
|
||||
I8275_DRAW_CHARACTER_MEMBER( crtc_display_pixels );
|
||||
|
||||
void mem_map(address_map &map);
|
||||
void mem_xfer_map(address_map &map);
|
||||
|
||||
required_region_ptr<uint8_t> m_charmap;
|
||||
required_shared_ptr<uint8_t> m_p_videoram;
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<i8085a_cpu_device> m_maincpu;
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<i8276_device> m_crtc;
|
||||
required_address_space m_mem;
|
||||
memory_view m_dma_view;
|
||||
};
|
||||
|
||||
u8 tim100_state::dma_r(offs_t offset)
|
||||
{
|
||||
u8 data = m_mem->read_byte(offset);
|
||||
if (!machine().side_effects_disabled())
|
||||
m_crtc->dack_w(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void tim100_state::mem_map(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x0000, 0x1fff).rom(); // 2764 at U16
|
||||
map(0x0000, 0x1fff).rom().region("maincpu", 0); // 2764 at U16
|
||||
map(0x2000, 0x27ff).ram().share("videoram"); // 2KB static ram CDM6116A at U15
|
||||
map(0x6000, 0x6001).rw("uart_u17", FUNC(i8251_device::read), FUNC(i8251_device::write));
|
||||
map(0x8000, 0x8001).rw("uart_u18", FUNC(i8251_device::read), FUNC(i8251_device::write));
|
||||
@ -67,10 +77,18 @@ void tim100_state::mem_map(address_map &map)
|
||||
map(0xc000, 0xc001).rw(m_crtc, FUNC(i8276_device::read), FUNC(i8276_device::write)); // i8276
|
||||
}
|
||||
|
||||
void tim100_state::io_map(address_map &map)
|
||||
void tim100_state::mem_xfer_map(address_map &map)
|
||||
{
|
||||
// FIXME: this should be a single-entry view layered over mem_map
|
||||
map.unmap_value_high();
|
||||
map.global_mask(0xff);
|
||||
map(0x0000, 0xffff).view(m_dma_view);
|
||||
m_dma_view[0](0x0000, 0xffff).r(FUNC(tim100_state::dma_r));
|
||||
m_dma_view[1](0x0000, 0x1fff).rom().region("maincpu", 0); // 2764 at U16
|
||||
m_dma_view[1](0x2000, 0x27ff).ram().share("videoram"); // 2KB static ram CDM6116A at U15
|
||||
m_dma_view[1](0x6000, 0x6001).rw("uart_u17", FUNC(i8251_device::read), FUNC(i8251_device::write));
|
||||
m_dma_view[1](0x8000, 0x8001).rw("uart_u18", FUNC(i8251_device::read), FUNC(i8251_device::write));
|
||||
m_dma_view[1](0xa000, 0xa000).nopw(); // continuously writes 00 here
|
||||
m_dma_view[1](0xc000, 0xc001).rw(m_crtc, FUNC(i8276_device::read), FUNC(i8276_device::write)); // i8276
|
||||
}
|
||||
|
||||
|
||||
@ -78,7 +96,7 @@ void tim100_state::io_map(address_map &map)
|
||||
static INPUT_PORTS_START( tim100 )
|
||||
INPUT_PORTS_END
|
||||
|
||||
static DEVICE_INPUT_DEFAULTS_START( tim100 )
|
||||
static DEVICE_INPUT_DEFAULTS_START( keyboard )
|
||||
DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_9600 )
|
||||
DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_9600 )
|
||||
DEVICE_INPUT_DEFAULTS( "RS232_STARTBITS", 0xff, RS232_STARTBITS_1 )
|
||||
@ -87,6 +105,15 @@ static DEVICE_INPUT_DEFAULTS_START( tim100 )
|
||||
DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_2 )
|
||||
DEVICE_INPUT_DEFAULTS_END
|
||||
|
||||
static DEVICE_INPUT_DEFAULTS_START( terminal )
|
||||
DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_9600 )
|
||||
DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_9600 )
|
||||
DEVICE_INPUT_DEFAULTS( "RS232_STARTBITS", 0xff, RS232_STARTBITS_1 )
|
||||
DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_7 )
|
||||
DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_EVEN )
|
||||
DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_2 )
|
||||
DEVICE_INPUT_DEFAULTS_END
|
||||
|
||||
static const rgb_t tim100_palette[3] = {
|
||||
rgb_t(0x00, 0x00, 0x00), // black
|
||||
rgb_t(0xa0, 0xa0, 0xa0), // white
|
||||
@ -96,8 +123,6 @@ static const rgb_t tim100_palette[3] = {
|
||||
void tim100_state::machine_start()
|
||||
{
|
||||
m_palette->set_pen_colors(0, tim100_palette);
|
||||
save_item(NAME(m_dma_adr));
|
||||
m_dma_adr = 0;
|
||||
}
|
||||
|
||||
const gfx_layout charlayout =
|
||||
@ -141,24 +166,12 @@ I8275_DRAW_CHARACTER_MEMBER( tim100_state::crtc_display_pixels )
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( tim100_state::drq_w )
|
||||
WRITE_LINE_MEMBER( tim100_state::sod_w )
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
m_crtc->dack_w(m_p_videoram[m_dma_adr++]);
|
||||
m_dma_adr &= 0x7ff;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( tim100_state::irq_w )
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
m_dma_adr = 2;
|
||||
m_maincpu->set_input_line(I8085_RST65_LINE, HOLD_LINE);
|
||||
}
|
||||
m_dma_view.select(0);
|
||||
else
|
||||
m_maincpu->set_input_line(I8085_RST65_LINE, CLEAR_LINE);
|
||||
m_dma_view.select(1);
|
||||
}
|
||||
|
||||
|
||||
@ -166,8 +179,9 @@ void tim100_state::tim100(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
I8085A(config, m_maincpu, XTAL(4'915'200)); // divider unknown
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &tim100_state::mem_map);
|
||||
m_maincpu->set_addrmap(AS_IO, &tim100_state::io_map);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &tim100_state::mem_xfer_map);
|
||||
m_maincpu->set_addrmap(AS_OPCODES, &tim100_state::mem_map);
|
||||
m_maincpu->out_sod_func().set(FUNC(tim100_state::sod_w));
|
||||
|
||||
/* video hardware */
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
@ -179,11 +193,11 @@ void tim100_state::tim100(machine_config &config)
|
||||
|
||||
GFXDECODE(config, "gfxdecode", m_palette, gfx_tim100);
|
||||
|
||||
I8276(config, m_crtc, XTAL(4'915'200));
|
||||
I8276(config, m_crtc, XTAL(4'915'200) / 12);
|
||||
m_crtc->set_character_width(12);
|
||||
m_crtc->set_display_callback(FUNC(tim100_state::crtc_display_pixels));
|
||||
m_crtc->drq_wr_callback().set(FUNC(tim100_state::drq_w));
|
||||
m_crtc->irq_wr_callback().set(FUNC(tim100_state::irq_w));
|
||||
m_crtc->drq_wr_callback().set_inputline(m_maincpu, I8085_RST75_LINE);
|
||||
m_crtc->irq_wr_callback().set_inputline(m_maincpu, I8085_RST65_LINE);
|
||||
m_crtc->set_screen("screen");
|
||||
|
||||
PALETTE(config, m_palette).set_entries(3);
|
||||
@ -192,23 +206,25 @@ void tim100_state::tim100(machine_config &config)
|
||||
uart_u17.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd));
|
||||
uart_u17.dtr_handler().set("rs232", FUNC(rs232_port_device::write_dtr));
|
||||
uart_u17.rts_handler().set("rs232", FUNC(rs232_port_device::write_rts));
|
||||
uart_u17.rxrdy_handler().set_inputline(m_maincpu, I8085_INTR_LINE);
|
||||
|
||||
rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "keyboard"));
|
||||
rs232.rxd_handler().set("uart_u17", FUNC(i8251_device::write_rxd));
|
||||
rs232.dsr_handler().set("uart_u17", FUNC(i8251_device::write_dsr));
|
||||
rs232.cts_handler().set("uart_u17", FUNC(i8251_device::write_cts));
|
||||
rs232.set_option_device_input_defaults("keyboard", DEVICE_INPUT_DEFAULTS_NAME(tim100));
|
||||
rs232.set_option_device_input_defaults("keyboard", DEVICE_INPUT_DEFAULTS_NAME(keyboard));
|
||||
|
||||
i8251_device &uart_u18(I8251(config, "uart_u18", 0));
|
||||
uart_u18.txd_handler().set("rs232a", FUNC(rs232_port_device::write_txd));
|
||||
uart_u18.dtr_handler().set("rs232a", FUNC(rs232_port_device::write_dtr));
|
||||
uart_u18.rts_handler().set("rs232a", FUNC(rs232_port_device::write_rts));
|
||||
uart_u18.rxrdy_handler().set_inputline(m_maincpu, I8085_RST55_LINE);
|
||||
|
||||
rs232_port_device &rs232a(RS232_PORT(config, "rs232a", default_rs232_devices, "terminal")); //"keyboard"));
|
||||
rs232_port_device &rs232a(RS232_PORT(config, "rs232a", default_rs232_devices, "terminal"));
|
||||
rs232a.rxd_handler().set("uart_u18", FUNC(i8251_device::write_rxd));
|
||||
rs232a.dsr_handler().set("uart_u18", FUNC(i8251_device::write_dsr));
|
||||
rs232a.cts_handler().set("uart_u18", FUNC(i8251_device::write_cts));
|
||||
rs232a.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(tim100));
|
||||
rs232a.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal));
|
||||
|
||||
clock_device &uart_clock(CLOCK(config, "uart_clock", 153'600));
|
||||
uart_clock.signal_handler().set("uart_u17", FUNC(i8251_device::write_txc));
|
||||
|
Loading…
Reference in New Issue
Block a user