From 7ce0c0fbc750acd9db54f5a1f1b135852ba905ac Mon Sep 17 00:00:00 2001 From: Dirk Best Date: Thu, 15 Apr 2021 11:46:54 +0200 Subject: basf7100: CPU executes loaded code, initial video - Add shared RAM - Implement bootrom disable and main CPU NMI - Initial video output using the charrom of another system --- src/mame/drivers/basf7100.cpp | 161 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 146 insertions(+), 15 deletions(-) diff --git a/src/mame/drivers/basf7100.cpp b/src/mame/drivers/basf7100.cpp index ac98f5d9ea9..dc1c8938a5b 100644 --- a/src/mame/drivers/basf7100.cpp +++ b/src/mame/drivers/basf7100.cpp @@ -51,6 +51,8 @@ #include "machine/i8255.h" #include "machine/wd_fdc.h" #include "imagedev/floppy.h" +#include "emupal.h" +#include "screen.h" namespace { @@ -70,6 +72,11 @@ public: m_fdccpu(*this, "fdccpu"), m_fdc(*this, "fdc"), m_floppy(*this, "fdc:%u", 0), + m_screen(*this, "screen"), + m_palette(*this, "palette"), + m_chargen(*this, "chargen"), + m_bootview(*this, "bootview"), + m_fdc_intrq_vector(0), m_fdc_drq(false) { } @@ -85,6 +92,10 @@ private: required_device m_fdccpu; required_device m_fdc; required_device_array m_floppy; + required_device m_screen; + required_device m_palette; + required_region_ptr m_chargen; + memory_view m_bootview; void mem_map(address_map &map); void io_map(address_map &map); @@ -95,12 +106,21 @@ private: uint8_t mmio_r(offs_t offset); void mmio_w(offs_t offset, uint8_t data); - IRQ_CALLBACK_MEMBER(fdccpu_irq_callback); + void sod_high_w(uint8_t data); + void sod_low_w(uint8_t data); + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); void fdc_drq_w(int state); uint8_t fdc_ctrl_r(); void fdc_ctrl_w(uint8_t data); + void fdc_intrq_vector_w(uint8_t data); + void unk_cc_w(uint8_t data); + + IRQ_CALLBACK_MEMBER(fdccpu_irq_callback); + uint8_t int_flags_r(); + uint16_t m_sod; + uint8_t m_fdc_intrq_vector; bool m_fdc_drq; }; @@ -111,9 +131,11 @@ private: void basf7100_state::mem_map(address_map &map) { - map(0x0000, 0x001f).rom().region("maincpu", 0); - map(0x0020, 0x0020).nopr(); // stop log spam + map(0x0000, 0x7fff).ram().share("shared_ram"); + map(0x8000, 0xffff).ram(); map(0xff00, 0xffff).rw(FUNC(basf7100_state::mmio_r), FUNC(basf7100_state::mmio_w)); + map(0x0000, 0xffff).view(m_bootview); + m_bootview[0](0x0000, 0x001f).mirror(0xffe0).rom().region("maincpu", 0); } void basf7100_state::io_map(address_map &map) @@ -128,7 +150,7 @@ void basf7100_state::io_map(address_map &map) // map(0x14, 0x15) 8251 (secondary) // map(0x16, 0x16) baud rate // map(0x17, 0x17) rs232 flags/control -// map(0x18, 0x18) interrupt flags + map(0x18, 0x18).r(FUNC(basf7100_state::int_flags_r)); // map(0x1c, 0x1f) switches // map(0xb0, 0xb3) display hardware clear map(0xb8, 0xbb).rw(m_ppi[3], FUNC(i8255_device::read), FUNC(i8255_device::write)); @@ -136,12 +158,14 @@ void basf7100_state::io_map(address_map &map) map(0xbc, 0xbf).lw8(NAME([this] (offs_t offset, uint8_t data) { m_ppi[4]->write(offset ^ 3, data); })); map(0xc0, 0xc3).rw(m_fdc, FUNC(fd1791_device::read), FUNC(fd1791_device::write)); map(0xc4, 0xc4).rw(FUNC(basf7100_state::fdc_ctrl_r), FUNC(basf7100_state::fdc_ctrl_w)); + map(0xca, 0xca).w(FUNC(basf7100_state::fdc_intrq_vector_w)); + map(0xcc, 0xcc).w(FUNC(basf7100_state::unk_cc_w)); } void basf7100_state::fdc_mem_map(address_map &map) { - map(0x0000, 0xcfff).ram(); - map(0xd000, 0xefff).ram(); + map(0x0000, 0x7fff).ram().share("shared_ram"); + map(0x8000, 0xefff).ram(); map(0xf000, 0xfbff).ram(); map(0xfc00, 0xffff).rom().region("fdccpu", 0); map(0xff00, 0xffff).rw(FUNC(basf7100_state::mmio_r), FUNC(basf7100_state::mmio_w)); @@ -166,6 +190,67 @@ INPUT_PORTS_END // VIDEO EMULATION //************************************************************************** +static const gfx_layout crt8002_charlayout = +{ + 8, 12, + 128, + 1, + { 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7 }, + { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8 }, + 8*16 +}; + +static GFXDECODE_START( gfx_crt8002 ) + GFXDECODE_ENTRY( "chargen", 0, crt8002_charlayout, 0, 1 ) +GFXDECODE_END + +void basf7100_state::sod_high_w(uint8_t data) +{ + m_sod = (data << 8) | (m_sod & 0x00ff); +} + +void basf7100_state::sod_low_w(uint8_t data) +{ + // 7654---- sod low byte + // ----3210 set to input (clear in progress flag?) + + m_sod = (m_sod & 0xff00) | ((data & 0xf0) << 0); +} + +uint32_t basf7100_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + for (int y = 0; y < 26; y++) + { + for (int x = 0; x < 80; x++) + { + uint16_t addr = m_sod + y * 80 + x; + uint8_t code = m_maincpu->space(AS_PROGRAM).read_byte(addr); + + // draw 12 lines + for (int i = 0; i < 12; i++) + { + uint8_t data = m_chargen[(((code & 0x7f) << 4) + i)]; + + if (BIT(code, 7)) + data ^= 0xff; + + // 8 pixels of the character + bitmap.pix(y * 12 + i, x * 8 + 0) = BIT(data, 7) ? rgb_t::white() : rgb_t::black(); + bitmap.pix(y * 12 + i, x * 8 + 1) = BIT(data, 6) ? rgb_t::white() : rgb_t::black(); + bitmap.pix(y * 12 + i, x * 8 + 2) = BIT(data, 5) ? rgb_t::white() : rgb_t::black(); + bitmap.pix(y * 12 + i, x * 8 + 3) = BIT(data, 4) ? rgb_t::white() : rgb_t::black(); + bitmap.pix(y * 12 + i, x * 8 + 4) = BIT(data, 3) ? rgb_t::white() : rgb_t::black(); + bitmap.pix(y * 12 + i, x * 8 + 5) = BIT(data, 2) ? rgb_t::white() : rgb_t::black(); + bitmap.pix(y * 12 + i, x * 8 + 6) = BIT(data, 1) ? rgb_t::white() : rgb_t::black(); + bitmap.pix(y * 12 + i, x * 8 + 7) = BIT(data, 0) ? rgb_t::white() : rgb_t::black(); + } + } + } + + return 0; +} + //************************************************************************** // FLOPPY @@ -198,15 +283,18 @@ uint8_t basf7100_state::fdc_ctrl_r() void basf7100_state::fdc_ctrl_w(uint8_t data) { // 7654---- unknown - // ----3--- select drive 0 or motor on? - // -----210 unknown + // ----3--- motor on? + // -----2-- unknown + // ------10 drive select - logerror("fdc_ctrl_w: %04x\n", data); + if (data != 0x08) + logerror("fdc_ctrl_w: %04x\n", data); floppy_image_device *floppy = nullptr; - // hardcoded to drive 0 for now - floppy = m_floppy[0]->get_device(); + if ((data & 0x03) < 3) + floppy = m_floppy[data & 0x03]->get_device(); + m_fdc->set_floppy(floppy); // motor runs all the time for now @@ -217,6 +305,20 @@ void basf7100_state::fdc_ctrl_w(uint8_t data) m_fdc->dden_w(0); } +void basf7100_state::fdc_intrq_vector_w(uint8_t data) +{ + m_fdc_intrq_vector = data; +} + +void basf7100_state::unk_cc_w(uint8_t data) +{ + logerror("unk_cc_w: %02x\n", data); + + m_bootview.disable(); + m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); + m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE); +} + //************************************************************************** // MACHINE EMULATION @@ -234,17 +336,30 @@ void basf7100_state::mmio_w(offs_t offset, uint8_t data) IRQ_CALLBACK_MEMBER( basf7100_state::fdccpu_irq_callback ) { - return 0x60; + return m_fdc_intrq_vector; +} + +uint8_t basf7100_state::int_flags_r() +{ + // 765----- unknown + // ---4---- unknown (used, needs to be set at least 2 times to continue booting) + // ----3--- unknown (used) + // -----210 unknown + + return m_screen->vblank() ? 0x10 : 0x00; } void basf7100_state::machine_start() { // register for save states + save_item(NAME(m_sod)); + save_item(NAME(m_fdc_intrq_vector)); save_item(NAME(m_fdc_drq)); } void basf7100_state::machine_reset() { + m_bootview.select(0); m_fdccpu->set_pc(0xfc00); } @@ -286,11 +401,24 @@ void basf7100_state::basf7100(machine_config &config) I8255(config, m_ppi[4]); // port a: output (roll offset) - // port b: output (start of display high byte) - // port c: input (start of display low byte, clear in progress flag), output (sod low byte) + m_ppi[4]->out_pb_callback().set(FUNC(basf7100_state::sod_high_w)); + m_ppi[4]->out_pc_callback().set(FUNC(basf7100_state::sod_low_w)); + + // video + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_color(rgb_t::green()); + m_screen->set_size(640, 288); // wrong because of wrong charrom + m_screen->set_visarea_full(); + m_screen->set_refresh_hz(60); + m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate + m_screen->set_screen_update(FUNC(basf7100_state::screen_update)); + + GFXDECODE(config, "gfxdecode", "palette", gfx_crt8002); + + PALETTE(config, m_palette, palette_device::MONOCHROME); // floppy - FD1791(config, m_fdc, 2000000); + FD1791(config, m_fdc, 1000000); m_fdc->intrq_wr_callback().set_inputline(m_fdccpu, INPUT_LINE_IRQ0); m_fdc->drq_wr_callback().set(FUNC(basf7100_state::fdc_drq_w)); FLOPPY_CONNECTOR(config, "fdc:0", basf7100_floppies, "basf6106", floppy_image_device::default_mfm_floppy_formats); @@ -319,6 +447,9 @@ ROM_START( basf7120 ) ROM_REGION(0x100, "prom", 0) ROM_LOAD("video.30", 0x000, 0x100, CRC(89175ac9) SHA1(69b2055bee87e11cc74c70cef2f2bebcbd0004c9)) // N82S129N (label missing) + + ROM_REGION(0x800, "chargen", 0) + ROM_LOAD("8002.bin", 0x000, 0x800, CRC(fdd6eb13) SHA1(a094d416e66bdab916e72238112a6265a75ca690)) // placeholder, wrong ROM_END -- cgit v1.2.3