hds200: Hook up Z80DMA, initial video work

This commit is contained in:
Dirk Best 2021-12-11 11:50:34 +01:00
parent ad264cac3e
commit 18ac15ba9e

View File

@ -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<z80_device> m_maincpu;
required_device<z80dma_device> m_dma;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_device<scn2674_device> m_avdc;
required_device_array<scn2681_device, 2> m_duart;
required_region_ptr<uint8_t> m_chargen;
required_shared_ptr<uint8_t> 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 )