From 18ac15ba9e037d37220dc945c1b8d73d7db88b97 Mon Sep 17 00:00:00 2001 From: Dirk Best Date: Sat, 11 Dec 2021 11:50:34 +0100 Subject: [PATCH] hds200: Hook up Z80DMA, initial video work --- src/mame/drivers/hds200.cpp | 103 ++++++++++++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 11 deletions(-) diff --git a/src/mame/drivers/hds200.cpp b/src/mame/drivers/hds200.cpp index 475dc311348..3907e7a02df 100644 --- a/src/mame/drivers/hds200.cpp +++ b/src/mame/drivers/hds200.cpp @@ -20,7 +20,7 @@ - XTAL 22.680 MHz and 35.640 MHz (video) TODO: - - Z80DMA/SCN2674 hookup + - SCN2674 hookup - Keyboard - RS232 ports - Sound? (if supported) @@ -57,9 +57,13 @@ public: m_maincpu(*this, "maincpu"), m_dma(*this, "dma"), m_screen(*this, "screen"), + m_palette(*this, "palette"), m_avdc(*this, "avdc"), m_duart(*this, "duart%u", 0U), - m_rombank(*this, "rombank") + m_chargen(*this, "chargen"), + m_vram(*this, "vram"), + m_rombank(*this, "rombank"), + m_nmi_enabled(false) { } void hds200(machine_config &config); @@ -75,12 +79,26 @@ private: required_device m_maincpu; required_device m_dma; required_device m_screen; + required_device m_palette; required_device m_avdc; required_device_array m_duart; + required_region_ptr m_chargen; + required_shared_ptr m_vram; required_memory_bank m_rombank; + void rowbuffer_map(address_map &map); + SCN2674_DRAW_CHARACTER_MEMBER(draw_character); + uint8_t avdc_videoram_r(offs_t offset); + + uint8_t dma_mreq_r(offs_t offset); + void dma_mreq_w(offs_t offset, uint8_t data); + + void nmi_w(int state); + void duart0_out_w(uint8_t data); void duart1_out_w(uint8_t data); + + bool m_nmi_enabled; }; @@ -93,6 +111,7 @@ void hds200_state::mem_map(address_map &map) map(0x0000, 0x3fff).rom().region("maincpu", 0); map(0x4000, 0x5fff).bankr(m_rombank); map(0x6800, 0x6fff).ram(); // nvram? + map(0x7000, 0x77ff).ram().share("vram"); map(0x8000, 0xbfff).ram(); map(0xc000, 0xffff).noprw(); // expansion ram } @@ -111,6 +130,32 @@ void hds200_state::io_map(address_map &map) // VIDEO EMULATION //************************************************************************** +void hds200_state::rowbuffer_map(address_map &map) +{ + map.global_mask(0xff); + map(0x00, 0xff).ram(); +} + +SCN2674_DRAW_CHARACTER_MEMBER( hds200_state::draw_character ) +{ + uint16_t data = m_chargen[charcode << 4 | linecount]; + const pen_t *const pen = m_palette->pens(); + + // foreground/background colors + rgb_t fg = pen[1]; + rgb_t bg = pen[0]; + + // draw 9 pixels of the character + for (int i = 0; i < 9; i++) + bitmap.pix(y, x + i) = BIT(data, 8 - i) ? fg : bg; +} + +uint8_t hds200_state::avdc_videoram_r(offs_t offset) +{ + logerror("avdc_videoram_r %04x = %02x\n", offset, m_vram[offset & 0x7ff]); + return m_vram[offset & 0x7ff]; +} + static const gfx_layout char_layout = { 8,16, @@ -131,30 +176,59 @@ GFXDECODE_END // MACHINE EMULATION //************************************************************************** +uint8_t hds200_state::dma_mreq_r(offs_t offset) +{ + return m_maincpu->space(AS_PROGRAM).read_byte(offset); +} + +void hds200_state::dma_mreq_w(offs_t offset, uint8_t data) +{ + m_maincpu->space(AS_PROGRAM).write_byte(offset, data); +} + +void hds200_state::nmi_w(int state) +{ + if (state && m_nmi_enabled) + m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); +} + void hds200_state::duart0_out_w(uint8_t data) { + // 765----- unknown + // ---4---- 80/132 column switch (1 = 80) + // ----3210 unknown + logerror("duart0_out_w: %02x\n", data); } void hds200_state::duart1_out_w(uint8_t data) { - // 76543--- unknown + // 765----- unknown + // ---4---- nmi enable + // ----3--- unknown // -----2-- rombank // ------10 unknown logerror("duart1_out_w: %02x\n", data); + m_nmi_enabled = BIT(data, 4); m_rombank->set_entry(!BIT(data, 2)); } void hds200_state::machine_start() { m_rombank->configure_entries(0, 2, memregion("maincpu")->base() + 0x4000, 0x2000); + + // register for save states + save_item(NAME(m_nmi_enabled)); } void hds200_state::machine_reset() { + m_nmi_enabled = false; m_rombank->set_entry(0); + + m_duart[0]->ip4_w(1); } @@ -168,33 +242,40 @@ void hds200_state::hds200(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &hds200_state::mem_map); m_maincpu->set_addrmap(AS_IO, &hds200_state::io_map); - input_merger_device &duart_irq(INPUT_MERGER_ANY_HIGH(config, "duart_irq")); - duart_irq.output_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + input_merger_device &irqs(INPUT_MERGER_ANY_HIGH(config, "irqs")); + irqs.output_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ0); // NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); Z80DMA(config, m_dma, 8_MHz_XTAL / 2); // divider not verified - m_dma->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_NMI); + m_dma->out_busreq_callback().set_inputline(m_maincpu, INPUT_LINE_HALT); + m_dma->in_mreq_callback().set(FUNC(hds200_state::dma_mreq_r)); + m_dma->out_mreq_callback().set(FUNC(hds200_state::dma_mreq_w)); SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_color(rgb_t::amber()); m_screen->set_raw(22.680_MHz_XTAL, 1008, 0, 720, 375, 0, 350); // 80-column mode m_screen->set_screen_update(m_avdc, FUNC(scn2674_device::screen_update)); - PALETTE(config, "palette", palette_device::MONOCHROME); + PALETTE(config, m_palette, palette_device::MONOCHROME); - GFXDECODE(config, "gfxdecode", "palette", chars); + GFXDECODE(config, "gfxdecode", m_palette, chars); SCN2674(config, m_avdc, 22.680_MHz_XTAL / 9); + m_avdc->intr_callback().set("irqs", FUNC(input_merger_device::in_w<0>)); + m_avdc->mbc_callback().set(FUNC(hds200_state::nmi_w)); + m_avdc->set_addrmap(0, &hds200_state::rowbuffer_map); m_avdc->set_character_width(9); m_avdc->set_screen("screen"); + m_avdc->set_display_callback(FUNC(hds200_state::draw_character)); + m_avdc->mbc_char_callback().set(FUNC(hds200_state::avdc_videoram_r)); SCN2681(config, m_duart[0], 3.6864_MHz_XTAL); - m_duart[0]->irq_cb().set("duart_irq", FUNC(input_merger_device::in_w<0>)); + m_duart[0]->irq_cb().set("irqs", FUNC(input_merger_device::in_w<1>)); m_duart[0]->outport_cb().set(FUNC(hds200_state::duart0_out_w)); SCN2681(config, m_duart[1], 3.6864_MHz_XTAL); - m_duart[1]->irq_cb().set("duart_irq", FUNC(input_merger_device::in_w<1>)); + m_duart[1]->irq_cb().set("irqs", FUNC(input_merger_device::in_w<2>)); m_duart[1]->outport_cb().set(FUNC(hds200_state::duart1_out_w)); } @@ -223,4 +304,4 @@ ROM_END //************************************************************************** // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 198?, hds200, 0, 0, hds200, 0, hds200_state, empty_init, "Human Designed Systems", "HDS200", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 198?, hds200, 0, 0, hds200, 0, hds200_state, empty_init, "Human Designed Systems", "HDS200", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE )