From 85111661f5d7acb82a805126f59b89a1a45c5f6e Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Thu, 1 Nov 2018 17:00:40 +0700 Subject: rx2030: wip checkpoint (nw) Most hardware is in place now, initial diagnostics pass and it's possible to enter both the boot monitor and load/run the sash (stand-alone shell) from disk. The keyboard no longer works in sash, possibly because it's expecting a MIPS-specific keyboard to be connected. RISC/os loads apparently successfully but dies shortly after, probably due to lack of TLB in r3000.cpp. --- src/mame/drivers/mips.cpp | 411 +++++++++++++++++++++++++++++++++++++--------- src/mame/includes/mips.h | 55 +++++-- 2 files changed, 377 insertions(+), 89 deletions(-) diff --git a/src/mame/drivers/mips.cpp b/src/mame/drivers/mips.cpp index 2a184bf2af6..ed9b67ef0b5 100644 --- a/src/mame/drivers/mips.cpp +++ b/src/mame/drivers/mips.cpp @@ -38,31 +38,82 @@ * http://www.jp.netbsd.org/ports/mipsco/models.html * * TODO - * - everything (skeleton only) + * - implement cpu tlb + * - remaining iop interface + * - figure out the brcond0 signal + * - keyboard controller and keyboard + * - floppy drive + * - buzzer * * Ref Part Function * * System board: * + * MIPS R2000A Main CPU + * PACEMIPS PR2010A Floating point unit + * 33.3330 MHz crystal CPU clock + * DL15CC200 + * DDU7F-25 Delay line (10 taps @ 2.5ns per tap) + * VLSI VL85C30-08PC Serial port controller + * ST Z8038AB1 FIO Parallel port controller + * 1.8432 MHz crystal Serial clock + * NEC D70216L-10 I/O processor + * Adaptec AIC-6250DL SCSI controller + * AMD AM7990DCB/80 Ethernet controller + * 20 MHz crystal + * 2VP5U9 DC/DC converter (Ethernet transceiver power?) + * WDC WD37C65BJW Floppy controller + * Intel P8742AH Keyboard controller + * Dallas DS1287 RTC and NVRAM + * buzzer Connected to keyboard controller? + * + * P4C164-25PC Cache RAM? (8Kx8, total 112KiB) + * U?-U? 14 parts + * + * 27C512 64K EPROM V50 IPL (64Kx8, total 256KiB) + * U139-U142 4 parts + * + * M5M4464 V50 RAM (64Kx4, total 128KiB) + * U164-U167 4 parts + * * Video board: + * Idt75C458 256x24 Color RAMDAC + * Bt438KC Clock generator + * 108.180 MHz crystal * + * D41264V-12 Video RAM (64Kx4, total 1280KiB) + * U?-U? 40 parts */ /* * WIP notes * - * nvram must be prepped with 0x74, 0x61 or 0x31 at offset 0x29 - * - * Currently fails during IOP address path diagnostic. Bypass with: - * bp f7c51; g - * pc=f7c54; aw=0; g + * status: loads RISC/os, but dies probably due to missing R2000A TLB * * V50 internal peripherals: * base = 0xfe00 * serial (sula): fe00 * timer (tula): fe08 * int (iula): fe10 - * dma (dula): fe20 - unimplemented in uPD71037 mode (sctl & 2) + * dma (dula): fe20 + * + * V50 IPL diagnostic routines + * NVRAM f8dc4 + * Ethernet ID f8b58 + * Parallel f8c5c + * Keyboard f4cbc + * SCC ec0fc + * Floppy ee3ea + * SCSI f426e + * LANCE f8f68 * + * V50 interrupts: + * intp1 <- SCU + * intp2 <- CPU interface + * intp3 <- SCC + * intp4 <- FIO + * intp5 <- LANCE + * intp6 <- floppy? + * intp7 <- SCSI */ #include "emu.h" @@ -71,56 +122,80 @@ #include "debugger.h" +#define LOG_GENERAL (1U << 0) +#define LOG_MMU (1U << 1) +#define LOG_IOCB (1U << 2) + #define VERBOSE 0 #include "logmacro.h" void rx2030_state::machine_start() { + save_item(NAME(m_mmu)); + save_item(NAME(m_iop_interface)); } void rx2030_state::machine_reset() { + m_cpu->set_input_line(INPUT_LINE_RESET, 1); } void rx2030_state::rx2030_init() { + m_iop_interface = IOP_NERR | DBG_ABSENT; + // map the configured ram and vram - m_maincpu->space(0).install_ram(0x00000000, 0x00000000 | m_ram->mask(), m_ram->pointer()); + m_cpu->space(0).install_ram(0x00000000, m_ram->mask(), m_ram->pointer()); - if (m_vram) - m_maincpu->space(0).install_ram(0x01000000, 0x01000000 | m_vram->mask(), m_vram->pointer()); + // page zero of prom space is mapped to ram page zero + m_cpu->space(0).install_rom(0x1fc00000, 0x1fc00fff, m_ram->pointer()); + + if (!m_vram) + m_iop_interface |= VID_ABSENT; } -void rx2030_state::iop_program_map(address_map &map) +u16 rx2030_state::mmu_r(offs_t offset, u16 mem_mask) { - map(0x00000, 0x1ffff).ram(); + offs_t const address = (m_mmu[(offset >> 11) & 0x1f] << 12) | ((offset << 1) & 0xfff); - map(0x20000, 0xbffff).lrw16("shared", - [this](offs_t offset, u16 mem_mask) - { - offs_t const address = 0x1000 + (offset << 1); + u16 const data = (m_ram->read(BYTE4_XOR_BE(address + 1)) << 8) | m_ram->read(BYTE4_XOR_BE(address + 0)); - u16 const data = (m_ram->read(address + 1) << 8) | m_ram->read(address + 0); - //logerror("shared_r 0x%04x data 0x%04x mask 0x%04x\n", address, data, mem_mask); - return data; - }, - [this](offs_t offset, u16 data, u16 mem_mask) - { - offs_t const address = 0x1000 + (offset << 1); + LOGMASKED(LOG_MMU, "mmu_r offset 0x%06x reg %d page 0x%04x mapped 0x%06x data 0x%04x\n", + (offset << 1), (offset >> 11) & 0x1f, m_mmu[(offset >> 11) & 0x1f], address, data); - //logerror("shared_w 0x%04x data 0x%04x mask 0x%04x\n", address, data, mem_mask); - m_ram->write(address + 0, data); - m_ram->write(address + 1, data >> 8); - }); - map(0xc0000, 0xfffff).rom().region("eprom", 0); + return data; +} + +void rx2030_state::mmu_w(offs_t offset, u16 data, u16 mem_mask) +{ + offs_t const address = (m_mmu[(offset >> 11) & 0x1f] << 12) | ((offset << 1) & 0xfff); + + LOGMASKED(LOG_MMU, "mmu_w offset 0x%06x reg %d page 0x%04x mapped 0x%06x data 0x%04x\n", + (offset << 1), (offset >> 11) & 0x1f, m_mmu[(offset >> 11) & 0x1f], address, data); + + if (ACCESSING_BITS_0_7) + m_ram->write(BYTE4_XOR_BE(address + 0), data); + + if (ACCESSING_BITS_8_15) + m_ram->write(BYTE4_XOR_BE(address + 1), data >> 8); +} + +void rx2030_state::iop_program_map(address_map &map) +{ + // 00000:1ffff 128k ram (64kx4, 4 parts) + // 20000:3ffff 128k shared (32x4k mapped pages, bits 0-11 offset, bits 12-16 mmu register) + // 80000:fffff 512k eprom (256k x 2 copies) + + map(0x00000, 0x1ffff).ram(); + map(0x20000, 0x3ffff).rw(FUNC(rx2030_state::mmu_r), FUNC(rx2030_state::mmu_w)); + + map(0x80000, 0xbffff).rom().region("v50_ipl", 0).mirror(0x40000); } void rx2030_state::iop_io_map(address_map &map) { // 0x180-18a ? .umask16(0xff) - // 0x1c0 ? - // 0x044 - // 0x2c0 + // 0x040, 0x044 map(0x0000, 0x003f).lrw16("mmu", [this](offs_t offset, u16 mem_mask) @@ -129,49 +204,162 @@ void rx2030_state::iop_io_map(address_map &map) }, [this](offs_t offset, u16 data, u16 mem_mask) { - //logerror("mmu_w %d data 0x%04x\n", offset, data); - m_mmu[offset] = data; }); + //map(0x0040, 0x0041).r(m_fdc, FUNC(wd37c65c_device::msr_r)).umask16(0xff); + //map(0x0044, 0x0045).w(m_fdc, FUNC(wd37c65c_device::dor_w)).umask16(0xff); + + map(0x0080, 0x0083).rw(m_scsi, FUNC(aic6250_device::read), FUNC(aic6250_device::write)).umask16(0xff); + map(0x00c0, 0x00c1).rw(m_kbdc, FUNC(at_keyboard_controller_device::data_r), FUNC(at_keyboard_controller_device::data_w)).umask16(0xff); map(0x00c4, 0x00c5).rw(m_kbdc, FUNC(at_keyboard_controller_device::status_r), FUNC(at_keyboard_controller_device::command_w)).umask16(0xff); - map(0x0080, 0x0083).rw(m_scsi, FUNC(wd33c93_device::read), FUNC(wd33c93_device::write)).umask16(0xff); - map(0x0100, 0x0107).rw(m_scc, FUNC(z80scc_device::ba_cd_inv_r), FUNC(z80scc_device::ba_cd_inv_w)).umask16(0xff); + map(0x0140, 0x0143).rw(m_net, FUNC(am7990_device::regs_r), FUNC(am7990_device::regs_w)); - //map(0x0200, 0x0203).rw(m_lpt, FUNC(::read), FUNC(::write)); + + // iop tests bits 0x04, 0x10 and 0x20 + map(0x01c0, 0x01c1).lr8("?", [this]() { return m_iop_interface; }); // maybe? + + map(0x0200, 0x0201).rw(m_fio, FUNC(z8038_device::fifo_r<1>), FUNC(z8038_device::fifo_w<1>)).umask16(0xff); + map(0x0202, 0x0203).rw(m_fio, FUNC(z8038_device::reg_r<1>), FUNC(z8038_device::reg_w<1>)).umask16(0xff); map(0x0240, 0x0241).lw8("rtc", [this](address_space &space, offs_t offset, u8 data) { m_rtc->write(space, 0, data); }).umask16(0xff00); map(0x0280, 0x0281).lrw8("rtc", [this](address_space &space, offs_t offset) { return m_rtc->read(space, 1); }, [this](address_space &space, offs_t offset, u8 data) { m_rtc->write(space, 1, data); }).umask16(0xff00); + map(0x02c0, 0x2c1).lw8("cpu_interface", [this](u8 data) + { + switch (data) + { + case 0: LOG("cpu interrupt 0 asserted\n"); m_cpu->set_input_line(R3000_IRQ0, ASSERT_LINE); break; + case 1: LOG("cpu interrupt 1 asserted\n"); m_cpu->set_input_line(R3000_IRQ1, ASSERT_LINE); break; + case 2: LOG("cpu interrupt 2 asserted\n"); m_cpu->set_input_line(R3000_IRQ2, ASSERT_LINE); break; + case 3: LOG("cpu interrupt 4 asserted\n"); m_cpu->set_input_line(R3000_IRQ4, ASSERT_LINE); break; + + case 4: + if (m_cpu->suspended()) + { + LOG("cpu reset released\n"); + m_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); + } + else + m_iop->set_input_line(INPUT_LINE_IRQ2, CLEAR_LINE); + m_iop_interface |= IOP_IACK; + m_iop_interface &= ~IOP_IRQ; // maybe? + break; + + default: + LOG("cpu interface command 0x%02x\n", data); + break; + + //case 5: break; // unknown + //case 6: + //case 7: + // something to do with shared memory access? + //break; + } + }).umask16(0xff); + map(0x0380, 0x0381).lw8("led", [this](u8 data) { logerror("led_w 0x%02x\n", data); }).umask16(0xff00); } -void rx2030_state::cpu_map(address_map &map) +void rx2030_state::rx2030_map(address_map &map) { - //map(0x01ff0000, 0x01ffffff).m() // ramdac - //map(0x1fc00000, 0x1fc3ffff).rom().region("eprom", 0); + map(0x02000000, 0x02000003).lrw8("iop_interface", + [this]() { return m_iop_interface; }, + [this](u8 data) + { + switch (data) + { + case 0: LOG("cpu interrupt 0 cleared\n"); m_cpu->set_input_line(R3000_IRQ0, CLEAR_LINE); break; + case 1: LOG("cpu interrupt 1 cleared\n"); m_cpu->set_input_line(R3000_IRQ1, CLEAR_LINE); break; + case 2: LOG("cpu interrupt 2 cleared\n"); m_cpu->set_input_line(R3000_IRQ2, CLEAR_LINE); break; + case 3: LOG("cpu interrupt 4 cleared\n"); m_cpu->set_input_line(R3000_IRQ4, CLEAR_LINE); break; + break; + + case 4: + if (VERBOSE & LOG_IOCB) + { + static char const *const iop_commands[] = + { + "IOP", "UART0", "UART1", "NVRAM", "LED", "CLOCK", "TOD", "SCSI0", + "SCSI1", "SCSI2", "SCSI3", "SCSI4", "SCSI5", "SCSI6", "SCSI7", "FLOPPY0", + "FLOPPY1", "LANCE", "PP", "KYBD", "MOUSE", "BUZZER", "UNK22", "UNK23" + }; + + for (int iocb = 0; iocb < 24; iocb++) + { + // check if command semaphore set + if (m_ram->read(0x1000 + iocb * 16 + 10) || m_ram->read(0x1000 + iocb * 16 + 11)) + { + u32 const iocb_cmdparam = m_ram->read(0x1000 + iocb * 16 + 0) + | (m_ram->read(0x1000 + iocb * 16 + 1) << 8) + | (m_ram->read(0x1000 + iocb * 16 + 2) << 16) + | (m_ram->read(0x1000 + iocb * 16 + 3) << 24); + + u16 const iop_cmd = m_ram->read(0x1000 + iocb_cmdparam + 2) | (m_ram->read(0x1000 + iocb_cmdparam + 3) << 8); + + LOGMASKED(LOG_IOCB, "iocb %s command 0x%04x (%s)\n", + iop_commands[iocb], iop_cmd, machine().describe_context()); + } + } + } + + // interrupt the iop + m_iop_interface &= ~IOP_IACK; + m_iop_interface |= IOP_IRQ; // maybe? + m_iop->set_input_line(INPUT_LINE_IRQ2, ASSERT_LINE); + break; + + case 6: LOG("led on\n"); break; + case 7: LOG("led off\n"); break; + + default: + LOG("iop interface command 0x%02x (%s)\n", data, machine().describe_context()); + break; + } + } + ).umask32(0xff); +} + +void rx2030_state::rs2030_map(address_map &map) +{ + rx2030_map(map); - //map(0x10003000, 0x1003ffff).rom().region("eprom", 0); // mirror? + // video hardware + map(0x01000000, 0x011fffff).ram().share("vram"); + map(0x01ffff00, 0x01ffffff).m(m_ramdac, FUNC(bt458_device::map)).umask32(0xff); +} + +static void rx2030_scsi_devices(device_slot_interface &device) +{ + device.option_add("harddisk", NSCSI_HARDDISK); + device.option_add("cdrom", NSCSI_CDROM); } void rx2030_state::rx2030(machine_config &config) { - // FIXME: main cpu disabled for now - R2000(config, m_maincpu, 16.6698_MHz_XTAL); - m_maincpu->set_addrmap(AS_PROGRAM, &rx2030_state::cpu_map); - m_maincpu->in_brcond0().set([]() { return ASSERT_LINE; }); - m_maincpu->set_disable(); - - // TODO: mouse connects to v50 serial? - V53(config, m_iop, 20_MHz_XTAL / 2); + R2000A(config, m_cpu, 33.333_MHz_XTAL / 2, 32768, 32768); + m_cpu->set_fpurev(0x0315); // 0x0315 == R2010A v1.5 + m_cpu->in_brcond0().set([this]() { logerror("brcond0 sampled (%s)\n", machine().describe_context()); return ASSERT_LINE; }); + + V50(config, m_iop, 20_MHz_XTAL / 2); m_iop->set_addrmap(AS_PROGRAM, &rx2030_state::iop_program_map); m_iop->set_addrmap(AS_IO, &rx2030_state::iop_io_map); + // general dma configuration + m_iop->out_hreq_cb().set(m_iop, FUNC(v50_device::hack_w)); + m_iop->in_mem16r_cb().set(FUNC(rx2030_state::mmu_r)); + m_iop->out_mem16w_cb().set(FUNC(rx2030_state::mmu_w)); + + // dma channel 1: scsi + m_iop->in_io16r_cb<1>().set(m_scsi, FUNC(aic6250_device::dma16_r)); + m_iop->out_io16w_cb<1>().set(m_scsi, FUNC(aic6250_device::dma16_w)); + m_iop->out_dack_cb<1>().set(m_scsi, FUNC(aic6250_device::back_w)); + RAM(config, m_ram); m_ram->set_default_size("16M"); m_ram->set_extra_options("4M,8M,12M"); @@ -180,8 +368,9 @@ void rx2030_state::rx2030(machine_config &config) // rtc and nvram MC146818(config, m_rtc, 32.768_kHz_XTAL); - // TODO: ethernet id prom - // TODO: parallel port + // parallel port + Z8038(config, m_fio, 0); + m_fio->out_int_cb<1>().set_inputline(m_iop, INPUT_LINE_IRQ4); // keyboard pc_kbdc_device &kbdc(PC_KBDC(config, "pc_kbdc", 0)); @@ -197,10 +386,9 @@ void rx2030_state::rx2030(machine_config &config) m_kbdc->kbd_clk().set(kbdc, FUNC(pc_kbdc_device::clock_write_from_mb)); m_kbdc->kbd_data().set(kbdc, FUNC(pc_kbdc_device::data_write_from_mb)); - // TODO: verify scc device and clock - SCC85C30(config, m_scc, 4.9152_MHz_XTAL); - m_scc->configure_channels(1'843'200, 1'843'200, 1'843'200, 1'843'200); - //m_scc->out_int_callback().set(m_iop, FUNC(v53_device::intp1_w)); + SCC85C30(config, m_scc, 1.8432_MHz_XTAL); + m_scc->configure_channels(m_scc->clock(), m_scc->clock(), m_scc->clock(), m_scc->clock()); + m_scc->out_int_callback().set_inputline(m_iop, INPUT_LINE_IRQ3); // scc channel A (tty0) RS232_PORT(config, m_tty[0], default_rs232_devices, nullptr); @@ -209,7 +397,6 @@ void rx2030_state::rx2030(machine_config &config) m_tty[0]->rxd_handler().set(m_scc, FUNC(z80scc_device::rxa_w)); m_scc->out_rtsa_callback().set(m_tty[0], FUNC(rs232_port_device::write_rts)); m_scc->out_txda_callback().set(m_tty[0], FUNC(rs232_port_device::write_txd)); - //m_scc->out_wreqa_callback().set(m_ioga, FUNC(interpro_ioga_device::drq_serial1)).invert(); // scc channel B (tty1) RS232_PORT(config, m_tty[1], default_rs232_devices, nullptr); @@ -218,32 +405,60 @@ void rx2030_state::rx2030(machine_config &config) m_tty[1]->rxd_handler().set(m_scc, FUNC(z80scc_device::rxb_w)); m_scc->out_rtsb_callback().set(m_tty[1], FUNC(rs232_port_device::write_rts)); m_scc->out_txdb_callback().set(m_tty[1], FUNC(rs232_port_device::write_txd)); - //m_scc->out_wreqb_callback().set(m_ioga, FUNC(interpro_ioga_device::drq_serial2)).invert(); // floppy controller and drive WD37C65C(config, m_fdc, 16_MHz_XTAL); - //m_fdc->intrq_wr_callback().set(m_mct_adr, FUNC(jazz_mct_adr_device::irq<1>)); - //m_fdc->drq_wr_callback().set(m_mct_adr, FUNC(jazz_mct_adr_device::drq<1>)); + //m_fdc->intrq_wr_callback().set_inputline(m_iop, INPUT_LINE_IRQ6); + //m_fdc->drq_wr_callback().set(); FLOPPY_CONNECTOR(config, "fdc:0", "35hd", FLOPPY_35_HD, true, &FLOPPY_PC_FORMAT).enable_sound(false); - //m_mct_adr->dma_r_cb<1>().set(m_fdc, FUNC(n82077aa_device::dma_r)); - //m_mct_adr->dma_w_cb<1>().set(m_fdc, FUNC(n82077aa_device::dma_w)); - // scsi controller and port - scsi_port_device &scsi_port(SCSI_PORT(config, "scsi_port")); - WD33C93(config, m_scsi); - m_scsi->set_scsi_port(scsi_port); - //m_scsi->irq_cb().set_inputline() + // scsi bus and devices + NSCSI_BUS(config, m_scsibus, 0); + + nscsi_connector &harddisk(NSCSI_CONNECTOR(config, "scsi:0", 0)); + rx2030_scsi_devices(harddisk); + harddisk.set_default_option("harddisk"); + + rx2030_scsi_devices(NSCSI_CONNECTOR(config, "scsi:1", 0)); + rx2030_scsi_devices(NSCSI_CONNECTOR(config, "scsi:2", 0)); + rx2030_scsi_devices(NSCSI_CONNECTOR(config, "scsi:3", 0)); + rx2030_scsi_devices(NSCSI_CONNECTOR(config, "scsi:4", 0)); + rx2030_scsi_devices(NSCSI_CONNECTOR(config, "scsi:5", 0)); + rx2030_scsi_devices(NSCSI_CONNECTOR(config, "scsi:6", 0)); + + // scsi host adapter + nscsi_connector &adapter(NSCSI_CONNECTOR(config, "scsi:7", 0)); + adapter.option_add_internal("aic6250", AIC6250); + adapter.set_default_option("aic6250"); + adapter.set_fixed(true); + adapter.set_option_machine_config("aic6250", [this](device_t *device) + { + aic6250_device &adapter = downcast(*device); + + adapter.set_clock(10_MHz_XTAL); // clock assumed + + adapter.int_cb().set_inputline(m_iop, INPUT_LINE_IRQ7).invert(); + adapter.breq_cb().set(m_iop, FUNC(v50_device::dreq_w<1>)); + }); // ethernet AM7990(config, m_net); - //m_net->dma_in().set(FUNC(rx2030_state::lance_dma_r)); - //m_net->dma_out().set(FUNC(rx2030_state::lance_dma_w)); + m_net->irq_out().set_inputline(m_iop, INPUT_LINE_IRQ5); + //m_net->dma_in().set(FUNC(rx2030_state::mmu_r)); + //m_net->dma_out().set(FUNC(rx2030_state::mmu_w)); + + // buzzer + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_buzzer); + m_buzzer->add_route(ALL_OUTPUTS, "mono", 0.50); } void rx2030_state::rc2030(machine_config &config) { rx2030(config); + m_cpu->set_addrmap(AS_PROGRAM, &rx2030_state::rx2030_map); + // no keyboard m_kbd->set_default_option(nullptr); @@ -254,6 +469,8 @@ void rx2030_state::rs2030(machine_config &config) { rx2030(config); + m_cpu->set_addrmap(AS_PROGRAM, &rx2030_state::rs2030_map); + m_kbd->set_default_option(STR_KBD_MICROSOFT_NATURAL); // video hardware (1280x1024x8bpp @ 60Hz), 40 parts vram @@ -263,26 +480,41 @@ void rx2030_state::rs2030(machine_config &config) SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_raw(pixclock, 1688, 248, 1528, 1066, 38, 1062); m_screen->set_screen_update(FUNC(rx2030_state::screen_update)); - m_screen->screen_vblank().set([](int state) {}); + m_screen->screen_vblank().set_inputline(m_cpu, R3000_IRQ5); BT458(config, m_ramdac, pixclock); - RAM(config, m_vram, 0).set_default_size("2M"); } u32 rx2030_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - u8 *pixel_data = m_vram->pointer(); + /* + * The graphics board has 1280KiB of video ram fitted, which is organised + * such that each 1280 pixel line occupies 2048 bytes of the address space; + * the remaining 768 addresses are presumably not mapped to anything. + */ + u32 *pixel_pointer = m_vram; for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) - for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x++) - bitmap.pix(y, x) = m_ramdac->pen_color(*pixel_data++); + { + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 4) + { + u32 const pixel_data = *pixel_pointer++; + + bitmap.pix(y, x + 0) = m_ramdac->pen_color((pixel_data >> 24) & 0xff); + bitmap.pix(y, x + 1) = m_ramdac->pen_color((pixel_data >> 16) & 0xff); + bitmap.pix(y, x + 2) = m_ramdac->pen_color((pixel_data >> 8) & 0xff); + bitmap.pix(y, x + 3) = m_ramdac->pen_color((pixel_data >> 0) & 0xff); + } + + // compensate by 2048 - 1280 pixels per line + pixel_pointer += 0xc0; + } return 0; } ROM_START(rx2030) - ROM_REGION(0x40000, "eprom", 0) - + ROM_REGION16_LE(0x40000, "v50_ipl", 0) ROM_SYSTEM_BIOS(0, "v4.32", "Rx2030 v4.32, Jan 1991") ROMX_LOAD("50-00121__005.u139", 0x00000, 0x10000, CRC(b2f42665) SHA1(81c83aa6b8865338fda5c03733ede91749997648), ROM_BIOS(0) | ROM_SKIP(1)) ROMX_LOAD("50-00120__005.u140", 0x00001, 0x10000, CRC(0ffa485e) SHA1(7cdfb81d1a547c5ccc88e1e0ef73d447cd03e9e2), ROM_BIOS(0) | ROM_SKIP(1)) @@ -294,10 +526,37 @@ ROM_START(rx2030) ROMX_LOAD("50-00120__003.u140", 0x00001, 0x10000, CRC(e1991721) SHA1(028d33be271c95f198473b650f7800f9ca4a60b2), ROM_BIOS(1) | ROM_SKIP(1)) ROMX_LOAD("50-00119__003.u141", 0x20001, 0x10000, CRC(c8469906) SHA1(69bbf4b5c415b2e2156a4467bf9cb30e79f586ef), ROM_BIOS(1) | ROM_SKIP(1)) ROMX_LOAD("50-00118__003.u142", 0x20000, 0x10000, CRC(18cc001a) SHA1(198023e92e1e3ba2fc8637f5dd6f370e7e023fdd), ROM_BIOS(1) | ROM_SKIP(1)) + + ROM_REGION(0x800, "i8742_eprom", 0) + ROM_LOAD("keyboard_1.5.bin", 0x000, 0x800, CRC(f86ba0f7) SHA1(1ad475451db35a76d929824c035d582279fbe3a3)) + + /* + * The following isn't a real dump, but a hand-made nvram image that allows + * entry to the boot monitor. Variables can be adjusted via the monitor, + * and are laid out as follows: + * + * Offset Length Variable + * 0x0e 4 netaddr + * 0x12 1 lbaud + * 0x13 1 rbaud + * 0x14 20 bootfile + * 0x28 1 bootmode + * 0x29 1 console + * 0x2a 1 ponmask? or something similar + * 0x2b 3 unused? + * 0x2e 4 resetepc + * 0x32 4 resetra + * 0x36 1 keyswtch + * 0x37 1 flag + * 0x38 8 unused? + * + */ + ROM_REGION(0x40, "rtc", 0) + ROM_LOAD("ds1287.bin", 0x00, 0x40, CRC(28369bf3) SHA1(64f24e1d8fb7103ab0bd3023c66490447bdcbf89)) ROM_END #define rom_rc2030 rom_rx2030 #define rom_rs2030 rom_rx2030 /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ -COMP(1989, rc2030, 0, 0, rc2030, 0, rx2030_state, rx2030_init, "MIPS", "RC2030", MACHINE_IS_SKELETON ) -COMP(1989, rs2030, 0, 0, rs2030, 0, rx2030_state, rx2030_init, "MIPS", "RS2030", MACHINE_IS_SKELETON ) +COMP(1989, rc2030, 0, 0, rc2030, 0, rx2030_state, rx2030_init, "MIPS", "RC2030", MACHINE_NOT_WORKING) +COMP(1989, rs2030, 0, 0, rs2030, 0, rx2030_state, rx2030_init, "MIPS", "RS2030", MACHINE_NOT_WORKING) diff --git a/src/mame/includes/mips.h b/src/mame/includes/mips.h index 8fc51841f48..d7df4116618 100644 --- a/src/mame/includes/mips.h +++ b/src/mame/includes/mips.h @@ -12,22 +12,28 @@ #include "machine/ram.h" // i/o devices -#include "machine/am79c90.h" -#include "machine/at_keybc.h" #include "machine/mc146818.h" -#include "machine/ncr5390.h" -#include "machine/upd765.h" -#include "machine/wd33c93.h" +#include "machine/z8038.h" +#include "machine/at_keybc.h" #include "machine/z80scc.h" +#include "machine/upd765.h" +#include "machine/aic6250.h" +#include "machine/am79c90.h" // busses and connectors +#include "machine/nscsi_bus.h" +#include "machine/nscsi_cd.h" +#include "machine/nscsi_hd.h" + #include "bus/pc_kbd/pc_kbdc.h" #include "bus/pc_kbd/keyboards.h" #include "bus/rs232/rs232.h" -// video +// video and audio #include "screen.h" #include "video/bt45x.h" +#include "sound/spkrdev.h" +#include "speaker.h" #include "formats/pc_dsk.h" @@ -36,17 +42,20 @@ class rx2030_state : public driver_device public: rx2030_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) - , m_maincpu(*this, "cpu") + , m_cpu(*this, "cpu") , m_iop(*this, "iop") , m_ram(*this, "ram") , m_rtc(*this, "rtc") + , m_fio(*this, "fio") , m_kbdc(*this, "kbdc") , m_kbd(*this, "kbd") , m_scc(*this, "scc") , m_tty(*this, "tty%u", 0U) , m_fdc(*this, "fdc") - , m_scsi(*this, "scsi") + , m_scsibus(*this, "scsi") + , m_scsi(*this, "scsi:7:aic6250") , m_net(*this, "net") + , m_buzzer(*this, "buzzer") , m_screen(*this, "screen") , m_ramdac(*this, "ramdac") , m_vram(*this, "vram") @@ -66,35 +75,55 @@ protected: virtual void machine_reset() override; // address maps - void cpu_map(address_map &map); + void rx2030_map(address_map &map); + void rs2030_map(address_map &map); + void iop_program_map(address_map &map); void iop_io_map(address_map &map); + u16 mmu_r(offs_t offset, u16 mem_mask = 0xffff); + void mmu_w(offs_t offset, u16 data, u16 mem_mask = 0xffff); + u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); private: + enum iop_interface_status_mask : u8 + { + FPU_ABSENT = 0x01, // clear if FPU installed + DBG_ABSENT = 0x02, // clear if debug board installed + IOP_IRQ = 0x04, // set when CPU interrupts IOP + VID_ABSENT = 0x10, // clear if video board installed + IOP_IACK = 0x40, // set when IOP acknowledges CPU interrupt + IOP_NERR = 0x80, // clear when IOP receives parity error + }; + // processors and memory - required_device m_maincpu; - required_device m_iop; + required_device m_cpu; + required_device m_iop; required_device m_ram; // i/o devices required_device m_rtc; + required_device m_fio; required_device m_kbdc; required_device m_kbd; required_device m_scc; required_device_array m_tty; required_device m_fdc; - required_device m_scsi; + required_device m_scsibus; + required_device m_scsi; required_device m_net; + required_device m_buzzer; // optional video board optional_device m_screen; optional_device m_ramdac; - optional_device m_vram; + optional_shared_ptr m_vram; // machine state u16 m_mmu[32]; + + u8 m_iop_interface; }; #endif // MAME_INCLUDES_MIPS_H -- cgit v1.2.3