mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
mips: you're not hunting him... he's hunting you (nw)
* added rambo dma/timer asic device * rx3230 boots to monitor * rx3230 monochrome video working * rx3230 networking is alive
This commit is contained in:
parent
c6ec55d1d3
commit
b80631d2dd
@ -2503,6 +2503,8 @@ createMESSProjects(_target, _subtarget, "mips")
|
||||
files {
|
||||
MAME_DIR .. "src/mame/drivers/mips.cpp",
|
||||
MAME_DIR .. "src/mame/includes/mips.h",
|
||||
MAME_DIR .. "src/mame/machine/mips_rambo.h",
|
||||
MAME_DIR .. "src/mame/machine/mips_rambo.cpp",
|
||||
}
|
||||
|
||||
createMESSProjects(_target, _subtarget, "mit")
|
||||
|
@ -12,16 +12,17 @@
|
||||
* M/500 R2300 R2000 5MHz VME ESDI
|
||||
* M/800 R2600 R2000 8MHz VME ESDI
|
||||
* M/1000 R2800 R2000 10MHz VME ESDI
|
||||
* M/120-3 R2400? R2000 12MHz PC-AT SCSI Deskside aka Intrepid?
|
||||
* M/120-5 R2400? R2000 16MHz PC-AT SCSI Deskside
|
||||
* M/120-3 R2400 R2000 12.5MHz PC-AT SCSI Deskside aka Intrepid
|
||||
* M/120-5 R2400 R2000 16MHz PC-AT SCSI Deskside
|
||||
* M/180 R2400
|
||||
* M/2000-6 R3200 R3000 20MHz VMEx13 SMD Rack Cabinet
|
||||
* M/2000-8 R3200 R3000 25MHz VMEx13 SMD Rack Cabinet
|
||||
* M/2000-? RB3125 R3000 33MHz
|
||||
* RC2030 I2000 R2000 16MHz SCSI Desktop aka M/12, Jupiter
|
||||
* RS2030 I2000 R2000 16MHz SCSI Desktop aka M/12, Jupiter
|
||||
* RC3230 R3030 R3000 25MHz PC-ATx1 SCSI Desktop
|
||||
* RS3230 R3030 R3000 25MHz PC-ATx1 SCSI Desktop aka M/20, Magnum 3000, Pizazz
|
||||
* RC3240 R3000 20MHz PC-ATx4 SCSI Deskside M/120 with CPU-board upgrade
|
||||
* RC3230 R3030 R3000 25MHz PC-ATx1 SCSI Desktop aka M/20, Pizazz
|
||||
* RS3230 R3030 R3000 25MHz PC-ATx1 SCSI Desktop aka M/20, Pizazz, Magnum 3000
|
||||
* RC3240 R3000 25MHz PC-ATx4 SCSI Deskside M/120 with CPU-board upgrade
|
||||
* RC3330 R3000 33MHz PC-AT SCSI Desktop
|
||||
* RS3330 R3000 33MHz PC-AT SCSI Desktop
|
||||
* RC3260 R3000 25MHz VMEx7 SCSI Pedestal
|
||||
@ -29,9 +30,9 @@
|
||||
* RC3370 RB3133
|
||||
* RC6260 R6300 R6000 66MHz VME SCSI Pedestal
|
||||
* RC6280 R6300 R6000 66MHz VMEx6 SMD Data Center
|
||||
* RC6380-100 R6000x1 66MHz VME SMD Data Center
|
||||
* RC6380-200 R6000x2 66MHz VME SMD Data Center
|
||||
* RC6380-400 R6000x4 66MHz VME SMD Data Center
|
||||
* RC6380-100 R6000x1 66MHz VME SMD Data Center
|
||||
* RC6380-200 R6000x2 66MHz VME SMD Data Center
|
||||
* RC6380-400 R6000x4 66MHz VME SMD Data Center
|
||||
*
|
||||
* Sources:
|
||||
*
|
||||
@ -48,11 +49,10 @@
|
||||
* TODO (rx3230)
|
||||
* - verify/complete address maps
|
||||
* - idprom
|
||||
* - rambo device
|
||||
*
|
||||
* Ref Part Function
|
||||
*
|
||||
* System board:
|
||||
* I2000 system board:
|
||||
*
|
||||
* MIPS R2000A Main CPU
|
||||
* PACEMIPS PR2010A Floating point unit
|
||||
@ -81,18 +81,57 @@
|
||||
* M5M4464 V50 RAM (64Kx4, total 128KiB)
|
||||
* U164-U167 4 parts
|
||||
*
|
||||
* Video board:
|
||||
*
|
||||
* Jupiter video board:
|
||||
*
|
||||
* Idt75C458 256x24 Color RAMDAC
|
||||
* Bt438KC Clock generator
|
||||
* 108.180 MHz crystal
|
||||
*
|
||||
* D41264V-12 Video RAM (64Kx4, total 1280KiB)
|
||||
* U?-U? 40 parts
|
||||
*
|
||||
*
|
||||
* R3030 system board (Assy. No. 03-00082- rev J):
|
||||
*
|
||||
* N2B1 IDT 79R3000-25G CPU
|
||||
* L6B1 IDT 79R3010L-25OJ FPU
|
||||
* C3A2 50.0000 MHz crystal
|
||||
* G2B8 MIPS 32-00039-000 RAMBO DMA/timer ASIC?
|
||||
* H8B8 MIPS 32-00038-000 Cache control/write buffer ASIC?
|
||||
* H8A3 MIPS 32-00038-000 Cache control/write buffer ASIC?
|
||||
* E3H7 NCR 53C94 SCSI controller
|
||||
* C410 Intel N82072 Floppy controller
|
||||
* B510 Z85C3010VSC Serial controller
|
||||
* C232 AMD AM7990JC/80 Ethernet controller
|
||||
* AMD AM7992BDC Ethernet serial interface
|
||||
* M48T02 RTC and NVRAM (labelled B6B93)
|
||||
* MCS-48? Keyboard controller
|
||||
* A7A7 DP8530V Clock generator
|
||||
* AM27C1024 IPL EPROM (128KiB, MSW)
|
||||
* 50-314-003
|
||||
* 3230 RIGHT
|
||||
* CKSM / B098BB9
|
||||
* TMS27C210 IPL EPROM (128KiB, LSW)
|
||||
* 50-314-003
|
||||
* 3230 LEFT
|
||||
* CKSM / 045A
|
||||
*
|
||||
*
|
||||
* Colour graphics board (assy. no. 03-00087- rev D):
|
||||
*
|
||||
* UF4 Bt459KG110 256x24 Color RAMDAC
|
||||
* UC4 Bt435KPJ Clock generator?
|
||||
* OSC3 108.1800 MHz crystal Pixel clock
|
||||
*
|
||||
* ? Video RAM (total 1280KiB?)
|
||||
* UJ11-UM11 8 parts
|
||||
* UJ13-UM13 8 parts
|
||||
*/
|
||||
/*
|
||||
* WIP notes
|
||||
* Rx2030 WIP
|
||||
*
|
||||
* status: loads RISC/os, but dies probably due to missing R2000A TLB
|
||||
* status: loads RISC/os, but panics
|
||||
*
|
||||
* V50 internal peripherals:
|
||||
* base = 0xfe00
|
||||
@ -127,6 +166,19 @@
|
||||
* int4 <- iop clock
|
||||
* int5 <- vblank
|
||||
*/
|
||||
/*
|
||||
* Rx3230 WIP
|
||||
*
|
||||
* status: boots to monitor
|
||||
*
|
||||
* R3000 interrupts
|
||||
* 0 <- lance, scc, slot, keyboard
|
||||
* 1 <- scsi
|
||||
* 2 <- timer
|
||||
* 3 <- fpu
|
||||
* 4 <- fdc
|
||||
* 5 <- parity error
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
@ -594,42 +646,82 @@ void rx3230_state::rx3230_map(address_map &map)
|
||||
{
|
||||
map(0x00000000, 0x07ffffff).noprw(); // silence ram
|
||||
|
||||
map(0x16080004, 0x16080007).nopr(); // silence graphics register
|
||||
|
||||
map(0x18000000, 0x1800003f).m(m_scsi, FUNC(ncr53c94_device::map)).umask32(0xff);
|
||||
map(0x19000000, 0x19000003).rw(m_kbdc, FUNC(at_keyboard_controller_device::data_r), FUNC(at_keyboard_controller_device::data_w)).umask32(0xff);
|
||||
map(0x19000004, 0x19000007).rw(m_kbdc, FUNC(at_keyboard_controller_device::status_r), FUNC(at_keyboard_controller_device::command_w)).umask32(0xff);
|
||||
map(0x19800000, 0x19800003).lr8("int_reg", [this]() { return m_int_reg; }).umask32(0xff);
|
||||
map(0x1a000000, 0x1a000007).rw(m_net, FUNC(am7990_device::regs_r), FUNC(am7990_device::regs_w)).umask32(0xffff);
|
||||
map(0x1b000000, 0x1b00001f).rw(m_scc, FUNC(z80scc_device::ba_cd_inv_r), FUNC(z80scc_device::ba_cd_inv_w)).umask32(0xff); // TODO: order?
|
||||
|
||||
map(0x1c000000, 0x1c000fff).ram(); // MIPS RAMBO DMA engine
|
||||
map(0x1c000000, 0x1c000fff).m(m_rambo, FUNC(mips_rambo_device::map));
|
||||
|
||||
map(0x1d000000, 0x1d001fff).rw(m_rtc, FUNC(m48t02_device::read), FUNC(m48t02_device::write)).umask32(0xff);
|
||||
map(0x1e000000, 0x1e000007).m(m_fdc, FUNC(i82072_device::map)).umask32(0xff);
|
||||
//map(0x1e800000, 0x1e800003).umask32(0xff); // fdc tc
|
||||
|
||||
map(0x1fc00000, 0x1fc3ffff).rom().region("rx3230", 0);
|
||||
|
||||
map(0x1ff00000, 0x1ff00003).lr8("boardtype", []() { return 0xa; }).umask32(0xff); // r? idprom boardtype?
|
||||
//map(0x1ff00018, 0x1ff0001b).umask32(0x0000ff00); // r? idprom?
|
||||
|
||||
map(0x1fc00000, 0x1fc3ffff).rom().region("rx3230", 0);
|
||||
}
|
||||
|
||||
void rx3230_state::rs3230_map(address_map &map)
|
||||
{
|
||||
rx3230_map(map);
|
||||
|
||||
map(0x10000000, 0x103fffff); // frame buffer, 4M?
|
||||
map(0x10000000, 0x12ffffff).lrw32("vram",
|
||||
[this](offs_t offset)
|
||||
{
|
||||
u32 const ram_offset = ((offset >> 13) * 0x500) + ((offset & 0x1ff) << 2);
|
||||
|
||||
u32 const data =
|
||||
u32(m_vram->read(ram_offset | 0)) << 24 |
|
||||
u32(m_vram->read(ram_offset | 1)) << 16 |
|
||||
u32(m_vram->read(ram_offset | 2)) << 8 |
|
||||
u32(m_vram->read(ram_offset | 3)) << 0;
|
||||
|
||||
return data;
|
||||
},
|
||||
[this](offs_t offset, u32 data)
|
||||
{
|
||||
u32 const ram_offset = ((offset >> 13) * 0x500) + ((offset & 0x1ff) << 2);
|
||||
|
||||
m_vram->write(ram_offset | 0, data >> 24);
|
||||
m_vram->write(ram_offset | 1, data >> 16);
|
||||
m_vram->write(ram_offset | 2, data >> 8);
|
||||
m_vram->write(ram_offset | 3, data >> 0);
|
||||
});
|
||||
|
||||
map(0x14000000, 0x14000003).rw(m_ramdac, FUNC(bt459_device::address_lo_r), FUNC(bt459_device::address_lo_w)).umask32(0xff);
|
||||
map(0x14080000, 0x14080003).rw(m_ramdac, FUNC(bt459_device::address_hi_r), FUNC(bt459_device::address_hi_w)).umask32(0xff);
|
||||
map(0x14100000, 0x14100003).rw(m_ramdac, FUNC(bt459_device::register_r), FUNC(bt459_device::register_w)).umask32(0xff);
|
||||
map(0x14180000, 0x14180003).rw(m_ramdac, FUNC(bt459_device::palette_r), FUNC(bt459_device::palette_w)).umask32(0xff);
|
||||
|
||||
map(0x16080004, 0x16080007).lr8("gfx_reg", [this]()
|
||||
{
|
||||
u8 const data = (m_screen->vblank() ? GFX_V_BLANK : 0) | (m_screen->hblank() ? GFX_H_BLANK : 0);
|
||||
|
||||
return data;
|
||||
}).umask32(0xff); // also write 0
|
||||
|
||||
//map(0x16000004, 0x16000007).w(); // write 0x00000001
|
||||
//map(0x16100000, 0x16100003).w(); // write 0xffffffff
|
||||
}
|
||||
|
||||
void rx3230_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_int_reg));
|
||||
save_item(NAME(m_int0_state));
|
||||
save_item(NAME(m_int1_state));
|
||||
}
|
||||
|
||||
void rx3230_state::machine_reset()
|
||||
{
|
||||
m_int_reg = INT_CLR;
|
||||
m_int0_state = 1;
|
||||
m_int1_state = 1;
|
||||
}
|
||||
|
||||
void rx3230_state::rx3230_init()
|
||||
@ -641,15 +733,22 @@ void rx3230_state::rx3230_init()
|
||||
void rx3230_state::rx3230(machine_config &config)
|
||||
{
|
||||
R3000A(config, m_cpu, 50_MHz_XTAL / 2, 32768, 32768);
|
||||
m_cpu->set_addrmap(AS_PROGRAM, &rx3230_state::rx3230_map);
|
||||
m_cpu->set_fpurev(0x0340); // 0x0340 == R3010A v4.0?
|
||||
m_cpu->in_brcond<0>().set([]() { return 1; });
|
||||
m_cpu->in_brcond<0>().set([]() { return 1; }); // bus grant?
|
||||
|
||||
// 32 SIMM slots, 8-128MB memory, banks of 8 1MB or 4MB SIMMs
|
||||
RAM(config, m_ram);
|
||||
m_ram->set_default_size("16M");
|
||||
m_ram->set_extra_options("32M,64M,128M");
|
||||
m_ram->set_default_size("32M");
|
||||
m_ram->set_extra_options("16M,64M,128M");
|
||||
m_ram->set_default_value(0);
|
||||
|
||||
MIPS_RAMBO(config, m_rambo, 25_MHz_XTAL / 4);
|
||||
m_rambo->timer_out().set_inputline(m_cpu, INPUT_LINE_IRQ2);
|
||||
m_rambo->parity_out().set_inputline(m_cpu, INPUT_LINE_IRQ5);
|
||||
//m_rambo->buzzer_out().set(m_buzzer, FUNC(speaker_sound_device::level_w));
|
||||
m_rambo->set_ram(m_ram);
|
||||
|
||||
// scsi bus and devices
|
||||
NSCSI_BUS(config, m_scsibus, 0);
|
||||
|
||||
@ -675,19 +774,18 @@ void rx3230_state::rx3230(machine_config &config)
|
||||
|
||||
adapter.set_clock(24_MHz_XTAL);
|
||||
|
||||
adapter.irq_handler_cb().set_inputline(m_cpu, INPUT_LINE_IRQ1);
|
||||
//adapter.breq_cb().set(m_iop, FUNC(v50_device::dreq_w<1>));
|
||||
adapter.irq_handler_cb().set(*this, FUNC(rx3230_state::irq_w<INT_SCSI>)).invert();
|
||||
adapter.drq_handler_cb().set(m_rambo, FUNC(mips_rambo_device::drq_w<0>));
|
||||
});
|
||||
|
||||
// ethernet
|
||||
AM7990(config, m_net);
|
||||
//m_net->intr_out().set_inputline(m_iop, INPUT_LINE_IRQ5).invert(); // -> rambo
|
||||
//m_net->dma_in().set(FUNC(rx3230_state::lance_r));
|
||||
//m_net->dma_out().set(FUNC(rx3230_state::lance_w));
|
||||
m_net->intr_out().set(FUNC(rx3230_state::irq_w<INT_NET>));
|
||||
m_net->dma_in().set(FUNC(rx3230_state::lance_r));
|
||||
m_net->dma_out().set(FUNC(rx3230_state::lance_w));
|
||||
|
||||
SCC85C30(config, m_scc, 1.8432_MHz_XTAL); // TODO: clock
|
||||
//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); // -> rambo
|
||||
SCC85C30(config, m_scc, 9.8304_MHz_XTAL); // TODO: clock working but unverified
|
||||
m_scc->out_int_callback().set(FUNC(rx3230_state::irq_w<INT_SCC>)).invert();
|
||||
|
||||
// scc channel A (tty0)
|
||||
RS232_PORT(config, m_tty[0], default_rs232_devices, nullptr);
|
||||
@ -723,10 +821,24 @@ void rx3230_state::rx3230(machine_config &config)
|
||||
m_kbd->set_pc_kbdc_slot(&kbdc);
|
||||
|
||||
AT_KEYBOARD_CONTROLLER(config, m_kbdc, 12_MHz_XTAL); // TODO: confirm
|
||||
//m_kbdc->hot_res().set_inputline(m_maincpu, INPUT_LINE_RESET);
|
||||
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));
|
||||
//m_kbdc->kbd_irq().set(); // -> rambo
|
||||
m_kbdc->kbd_irq().set(FUNC(rx3230_state::irq_w<INT_KBD>)).invert();
|
||||
|
||||
// buzzer
|
||||
SPEAKER(config, "mono").front_center();
|
||||
SPEAKER_SOUND(config, m_buzzer);
|
||||
m_buzzer->add_route(ALL_OUTPUTS, "mono", 0.50);
|
||||
|
||||
// motherboard monochrome video (1152x900 @ 60Hz?)
|
||||
u32 const pixclock = 62'208'000;
|
||||
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_raw(pixclock, 1152, 0, 1152, 900, 0, 900);
|
||||
m_screen->set_screen_update(m_rambo.finder_tag(), FUNC(mips_rambo_device::screen_update));
|
||||
|
||||
// TODO: slot - motherboard can accept either the colour graphics board, or
|
||||
// a riser which presents an ISA 16-bit slot.
|
||||
}
|
||||
|
||||
void rx3230_state::rc3230(machine_config &config)
|
||||
@ -735,31 +847,65 @@ void rx3230_state::rc3230(machine_config &config)
|
||||
|
||||
m_cpu->set_addrmap(AS_PROGRAM, &rx3230_state::rx3230_map);
|
||||
|
||||
m_tty[1]->set_default_option("terminal");
|
||||
m_kbd->set_default_option(STR_KBD_MICROSOFT_NATURAL);
|
||||
//m_tty[1]->set_default_option("terminal");
|
||||
}
|
||||
|
||||
void rx3230_state::rs3230(machine_config &config)
|
||||
{
|
||||
rx3230(config);
|
||||
|
||||
m_cpu->set_addrmap(AS_PROGRAM, &rx3230_state::rs3230_map);
|
||||
|
||||
m_kbd->set_default_option(STR_KBD_MICROSOFT_NATURAL);
|
||||
|
||||
// video hardware (1280x1024x8bpp @ 60Hz), 16 parts vram
|
||||
u32 const pixclock = 108'180'000;
|
||||
// FIXME: colour video board disabled for now
|
||||
if (false)
|
||||
{
|
||||
m_cpu->set_addrmap(AS_PROGRAM, &rx3230_state::rs3230_map);
|
||||
|
||||
// timing from VESA 1280x1024 @ 60Hz
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_raw(pixclock, 1688, 248, 1528, 1066, 38, 1062);
|
||||
m_screen->set_screen_update(FUNC(rx3230_state::screen_update));
|
||||
//m_screen->screen_vblank().set_inputline(m_cpu, INPUT_LINE_IRQ5);
|
||||
// video hardware (1280x1024x8bpp @ 60Hz), 16 parts vram
|
||||
u32 const pixclock = 108'180'000;
|
||||
|
||||
BT459(config, m_ramdac, pixclock);
|
||||
// timing from VESA 1280x1024 @ 60Hz
|
||||
m_screen->set_raw(pixclock, 1688, 248, 1528, 1066, 38, 1062);
|
||||
m_screen->set_screen_update(FUNC(rx3230_state::screen_update));
|
||||
//m_screen->screen_vblank().set_inputline(m_cpu, INPUT_LINE_IRQ5);
|
||||
|
||||
RAM(config, m_vram);
|
||||
m_vram->set_default_size("2M");
|
||||
m_vram->set_default_value(0);
|
||||
BT459(config, m_ramdac, pixclock);
|
||||
|
||||
RAM(config, m_vram);
|
||||
m_vram->set_default_size("2M");
|
||||
m_vram->set_default_value(0);
|
||||
}
|
||||
}
|
||||
|
||||
template <u8 Source> WRITE_LINE_MEMBER(rx3230_state::irq_w)
|
||||
{
|
||||
if (state)
|
||||
m_int_reg |= Source;
|
||||
else
|
||||
m_int_reg &= ~Source;
|
||||
|
||||
switch (Source)
|
||||
{
|
||||
case INT_SLOT:
|
||||
case INT_KBD:
|
||||
case INT_SCC:
|
||||
case INT_NET:
|
||||
if (m_int0_state != state)
|
||||
{
|
||||
m_int0_state = state;
|
||||
m_cpu->set_input_line(INPUT_LINE_IRQ0, !state);
|
||||
}
|
||||
break;
|
||||
|
||||
case INT_SCSI:
|
||||
if (m_int1_state != state)
|
||||
{
|
||||
m_int1_state = state;
|
||||
m_cpu->set_input_line(INPUT_LINE_IRQ1, !state);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u32 rx3230_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect)
|
||||
@ -769,6 +915,24 @@ u32 rx3230_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rec
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 rx3230_state::lance_r(offs_t offset, u16 mem_mask)
|
||||
{
|
||||
u16 const data =
|
||||
(m_ram->read(WORD_XOR_BE(offset + 1)) << 8) |
|
||||
m_ram->read(WORD_XOR_BE(offset + 0));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void rx3230_state::lance_w(offs_t offset, u16 data, u16 mem_mask)
|
||||
{
|
||||
if (ACCESSING_BITS_0_7)
|
||||
m_ram->write(WORD_XOR_BE(offset + 0), data);
|
||||
|
||||
if (ACCESSING_BITS_8_15)
|
||||
m_ram->write(WORD_XOR_BE(offset + 1), data >> 8);
|
||||
}
|
||||
|
||||
ROM_START(rx2030)
|
||||
ROM_REGION16_LE(0x40000, "v50_ipl", 0)
|
||||
ROM_SYSTEM_BIOS(0, "v4.32", "Rx2030 v4.32, Jan 1991")
|
||||
@ -832,8 +996,8 @@ ROM_END
|
||||
#define rom_rc3230 rom_rx3230
|
||||
#define rom_rs3230 rom_rx3230
|
||||
|
||||
/* 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_NOT_WORKING)
|
||||
COMP(1989, rs2030, 0, 0, rs2030, 0, rx2030_state, rx2030_init, "MIPS", "RS2030", MACHINE_NOT_WORKING)
|
||||
COMP(1990, rc3230, 0, 0, rc3230, 0, rx3230_state, rx3230_init, "MIPS", "RC3230", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
|
||||
COMP(1990, rs3230, 0, 0, rs3230, 0, rx3230_state, rx3230_init, "MIPS", "RS3230", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
|
||||
/* 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_NOT_WORKING)
|
||||
COMP(1989, rs2030, 0, 0, rs2030, 0, rx2030_state, rx2030_init, "MIPS", "RS2030", MACHINE_NOT_WORKING)
|
||||
COMP(1990, rc3230, 0, 0, rc3230, 0, rx3230_state, rx3230_init, "MIPS", "RC3230", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
|
||||
COMP(1990, rs3230, 0, 0, rs3230, 0, rx3230_state, rx3230_init, "MIPS", "Magnum 3000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
|
||||
|
@ -25,6 +25,7 @@
|
||||
// i/o devices (rx3230)
|
||||
#include "machine/timekpr.h"
|
||||
#include "machine/ncr5390.h"
|
||||
#include "machine/mips_rambo.h"
|
||||
|
||||
// busses and connectors
|
||||
#include "machine/nscsi_bus.h"
|
||||
@ -143,6 +144,7 @@ public:
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_cpu(*this, "cpu")
|
||||
, m_ram(*this, "ram")
|
||||
, m_rambo(*this, "rambo")
|
||||
, m_scsibus(*this, "scsi")
|
||||
, m_scsi(*this, "scsi:7:ncr53c94")
|
||||
, m_net(*this, "net")
|
||||
@ -152,6 +154,7 @@ public:
|
||||
, m_fdc(*this, "fdc")
|
||||
, m_kbdc(*this, "kbdc")
|
||||
, m_kbd(*this, "kbd")
|
||||
, m_buzzer(*this, "buzzer")
|
||||
, m_screen(*this, "screen")
|
||||
, m_ramdac(*this, "ramdac")
|
||||
, m_vram(*this, "vram")
|
||||
@ -176,12 +179,18 @@ protected:
|
||||
|
||||
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect);
|
||||
|
||||
u16 lance_r(offs_t offset, u16 mem_mask = 0xffff);
|
||||
void lance_w(offs_t offset, u16 data, u16 mem_mask = 0xffff);
|
||||
|
||||
template <u8 Source> WRITE_LINE_MEMBER(irq_w);
|
||||
|
||||
private:
|
||||
// processors and memory
|
||||
required_device<r3000a_device> m_cpu;
|
||||
required_device<ram_device> m_ram;
|
||||
|
||||
// i/o devices
|
||||
required_device<mips_rambo_device> m_rambo;
|
||||
required_device<nscsi_bus_device> m_scsibus;
|
||||
required_device<ncr53c94_device> m_scsi;
|
||||
required_device<am7990_device> m_net;
|
||||
@ -191,11 +200,37 @@ private:
|
||||
required_device<i82072_device> m_fdc;
|
||||
required_device<at_keyboard_controller_device> m_kbdc;
|
||||
required_device<pc_kbdc_slot_device> m_kbd;
|
||||
required_device<speaker_sound_device> m_buzzer;
|
||||
|
||||
// optional colour video board
|
||||
optional_device<screen_device> m_screen;
|
||||
optional_device<bt459_device> m_ramdac;
|
||||
optional_device<ram_device> m_vram;
|
||||
|
||||
enum int_reg_mask : u8
|
||||
{
|
||||
INT_SLOT = 0x01, // expansion slot
|
||||
INT_KBD = 0x02, // keyboard controller
|
||||
INT_SCC = 0x04, // serial controller
|
||||
INT_SCSI = 0x08, // scsi controller
|
||||
INT_NET = 0x10, // ethernet controller
|
||||
INT_DRS = 0x20, // data rate select
|
||||
INT_DSR = 0x40, // data set ready
|
||||
INT_CEB = 0x80, // modem call indicator
|
||||
|
||||
INT_CLR = 0xff,
|
||||
};
|
||||
|
||||
enum gfx_reg_mask : u8
|
||||
{
|
||||
GFX_H_BLANK = 0x10,
|
||||
GFX_V_BLANK = 0x20,
|
||||
GFX_COLOR_RSV = 0xce, // reserved
|
||||
};
|
||||
|
||||
u8 m_int_reg;
|
||||
int m_int0_state;
|
||||
int m_int1_state;
|
||||
};
|
||||
|
||||
#endif // MAME_INCLUDES_MIPS_H
|
||||
|
174
src/mame/machine/mips_rambo.cpp
Normal file
174
src/mame/machine/mips_rambo.cpp
Normal file
@ -0,0 +1,174 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
/*
|
||||
* DMA/timer ASIC used in MIPS Pizazz architecture systems.
|
||||
*
|
||||
* Sources:
|
||||
*
|
||||
* https://github.com/NetBSD/src/blob/trunk/sys/arch/mipsco/obio/rambo.h
|
||||
*
|
||||
* TODO
|
||||
* - interrupts
|
||||
* - dma
|
||||
* - timer
|
||||
* - buzzer
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "mips_rambo.h"
|
||||
|
||||
#define LOG_GENERAL (1U << 0)
|
||||
#define LOG_REG (1U << 1)
|
||||
|
||||
//#define VERBOSE (LOG_GENERAL|LOG_REG)
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(MIPS_RAMBO, mips_rambo_device, "mips_rambo", "MIPS RAMBO")
|
||||
|
||||
mips_rambo_device::mips_rambo_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, MIPS_RAMBO, tag, owner, clock)
|
||||
, m_ram(*this, finder_base::DUMMY_TAG)
|
||||
, m_irq_out_cb(*this)
|
||||
, m_parity_out_cb(*this)
|
||||
, m_timer_out_cb(*this)
|
||||
, m_buzzer_out_cb(*this)
|
||||
, m_irq_out_state(0)
|
||||
, m_buzzer_out_state(0)
|
||||
{
|
||||
}
|
||||
|
||||
void mips_rambo_device::map(address_map &map)
|
||||
{
|
||||
map(0x000, 0x003).rw(FUNC(mips_rambo_device::load_address_r<0>), FUNC(mips_rambo_device::load_address_w<0>));
|
||||
map(0x100, 0x103).r(FUNC(mips_rambo_device::diag_r<0>));
|
||||
map(0x202, 0x203).rw(FUNC(mips_rambo_device::fifo_r<0>), FUNC(mips_rambo_device::fifo_w<0>));
|
||||
map(0x300, 0x303).rw(FUNC(mips_rambo_device::mode_r<0>), FUNC(mips_rambo_device::mode_w<0>));
|
||||
map(0x402, 0x403).rw(FUNC(mips_rambo_device::block_count_r<0>), FUNC(mips_rambo_device::block_count_w<0>));
|
||||
map(0x500, 0x503).r(FUNC(mips_rambo_device::current_address_r<0>));
|
||||
|
||||
map(0x600, 0x603).rw(FUNC(mips_rambo_device::load_address_r<1>), FUNC(mips_rambo_device::load_address_w<1>));
|
||||
map(0x700, 0x703).r(FUNC(mips_rambo_device::diag_r<1>));
|
||||
map(0x802, 0x803).rw(FUNC(mips_rambo_device::fifo_r<1>), FUNC(mips_rambo_device::fifo_w<1>));
|
||||
map(0x900, 0x903).rw(FUNC(mips_rambo_device::mode_r<1>), FUNC(mips_rambo_device::mode_w<1>));
|
||||
map(0xa02, 0xa03).rw(FUNC(mips_rambo_device::block_count_r<1>), FUNC(mips_rambo_device::block_count_w<1>));
|
||||
map(0xb00, 0xb03).r(FUNC(mips_rambo_device::current_address_r<1>));
|
||||
|
||||
map(0xc00, 0xc03).rw(FUNC(mips_rambo_device::tcount_r), FUNC(mips_rambo_device::tcount_w));
|
||||
map(0xd00, 0xd03).rw(FUNC(mips_rambo_device::tbreak_r), FUNC(mips_rambo_device::tbreak_w));
|
||||
map(0xe00, 0xe03).r(FUNC(mips_rambo_device::error_r));
|
||||
map(0xf00, 0xf03).rw(FUNC(mips_rambo_device::control_r), FUNC(mips_rambo_device::control_w));
|
||||
}
|
||||
|
||||
void mips_rambo_device::device_start()
|
||||
{
|
||||
m_irq_out_cb.resolve_safe();
|
||||
m_parity_out_cb.resolve_safe();
|
||||
m_timer_out_cb.resolve_safe();
|
||||
m_buzzer_out_cb.resolve_safe();
|
||||
|
||||
m_buzzer_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mips_rambo_device::buzzer_toggle), this));
|
||||
|
||||
}
|
||||
|
||||
void mips_rambo_device::device_reset()
|
||||
{
|
||||
// TODO: update interrupts
|
||||
|
||||
m_tcount = machine().time();
|
||||
}
|
||||
|
||||
READ32_MEMBER(mips_rambo_device::tcount_r)
|
||||
{
|
||||
return attotime_to_clocks(machine().time() - m_tcount);
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(mips_rambo_device::tcount_w)
|
||||
{
|
||||
LOGMASKED(LOG_REG, "tcount_w 0x%08x (%s)\n", data, machine().describe_context());
|
||||
|
||||
m_tcount = machine().time();
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(mips_rambo_device::tbreak_w)
|
||||
{
|
||||
LOGMASKED(LOG_REG, "tbreak_w 0x%08x (%s)\n", data, machine().describe_context());
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(mips_rambo_device::control_w)
|
||||
{
|
||||
LOGMASKED(LOG_REG, "control_w 0x%08x (%s)\n", data, machine().describe_context());
|
||||
|
||||
// stop the buzzer
|
||||
m_buzzer_timer->enable(false);
|
||||
m_buzzer_out_state = 0;
|
||||
m_buzzer_out_cb(m_buzzer_out_state);
|
||||
|
||||
// start the buzzer if requested
|
||||
if (data & CONTROL_BUZZON)
|
||||
{
|
||||
attotime const period = attotime::from_ticks(1 << ((data & CONTROL_BUZZMASK) >> 4), 1524_Hz_XTAL);
|
||||
|
||||
m_buzzer_timer->adjust(period, 0, period);
|
||||
}
|
||||
}
|
||||
|
||||
template <unsigned Channel> WRITE32_MEMBER(mips_rambo_device::load_address_w)
|
||||
{
|
||||
LOGMASKED(LOG_REG, "load_address_w<%d> 0x%08x (%s)\n", Channel, data, machine().describe_context());
|
||||
|
||||
COMBINE_DATA(&m_channel[Channel].load_address);
|
||||
}
|
||||
|
||||
template <unsigned Channel> WRITE16_MEMBER(mips_rambo_device::fifo_w)
|
||||
{
|
||||
LOGMASKED(LOG_REG, "fifo_w<%d> 0x%04x (%s)\n", Channel, data, machine().describe_context());
|
||||
}
|
||||
|
||||
template <unsigned Channel> WRITE32_MEMBER(mips_rambo_device::mode_w)
|
||||
{
|
||||
LOGMASKED(LOG_REG, "mode_w<%d> 0x%08x (%s)\n", Channel, data, machine().describe_context());
|
||||
|
||||
COMBINE_DATA(&m_channel[Channel].mode);
|
||||
}
|
||||
|
||||
template <unsigned Channel> WRITE16_MEMBER(mips_rambo_device::block_count_w)
|
||||
{
|
||||
LOGMASKED(LOG_REG, "block_count_w<%d> 0x%04x (%s)\n", Channel, data, machine().describe_context());
|
||||
|
||||
COMBINE_DATA(&m_channel[Channel].block_count);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(mips_rambo_device::buzzer_toggle)
|
||||
{
|
||||
m_buzzer_out_state = !m_buzzer_out_state;
|
||||
m_buzzer_out_cb(m_buzzer_out_state);
|
||||
}
|
||||
|
||||
u32 mips_rambo_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
// check if dma channel is configured
|
||||
u32 const blocks_required = (screen.visible_area().height() * screen.visible_area().width()) >> 9;
|
||||
if (!(m_channel[1].mode & MODE_CHANNEL_EN) || !(m_channel[1].mode & MODE_AUTO_RELOAD) || (m_channel[1].block_count != blocks_required))
|
||||
return 1;
|
||||
|
||||
u32 address = m_channel[1].load_address;
|
||||
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 += 8)
|
||||
{
|
||||
u8 pixel_data = m_ram->read(BYTE4_XOR_BE(address));
|
||||
|
||||
bitmap.pix(y, x + 0) = BIT(pixel_data, 7) ? rgb_t::white() : rgb_t::black();
|
||||
bitmap.pix(y, x + 1) = BIT(pixel_data, 6) ? rgb_t::white() : rgb_t::black();
|
||||
bitmap.pix(y, x + 2) = BIT(pixel_data, 5) ? rgb_t::white() : rgb_t::black();
|
||||
bitmap.pix(y, x + 3) = BIT(pixel_data, 4) ? rgb_t::white() : rgb_t::black();
|
||||
bitmap.pix(y, x + 4) = BIT(pixel_data, 3) ? rgb_t::white() : rgb_t::black();
|
||||
bitmap.pix(y, x + 5) = BIT(pixel_data, 2) ? rgb_t::white() : rgb_t::black();
|
||||
bitmap.pix(y, x + 6) = BIT(pixel_data, 1) ? rgb_t::white() : rgb_t::black();
|
||||
bitmap.pix(y, x + 7) = BIT(pixel_data, 0) ? rgb_t::white() : rgb_t::black();
|
||||
|
||||
address++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
114
src/mame/machine/mips_rambo.h
Normal file
114
src/mame/machine/mips_rambo.h
Normal file
@ -0,0 +1,114 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
#ifndef MAME_MACHINE_MIPS_RAMBO_H
|
||||
#define MAME_MACHINE_MIPS_RAMBO_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/ram.h"
|
||||
#include "screen.h"
|
||||
|
||||
class mips_rambo_device : public device_t
|
||||
{
|
||||
public:
|
||||
mips_rambo_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
// configuration
|
||||
auto irq_out() { return m_irq_out_cb.bind(); }
|
||||
auto parity_out() { return m_parity_out_cb.bind(); }
|
||||
auto timer_out() { return m_timer_out_cb.bind(); }
|
||||
auto buzzer_out() { return m_buzzer_out_cb.bind(); }
|
||||
template <typename T> void set_ram(T &&tag) { m_ram.set_tag(std::forward<T>(tag)); }
|
||||
|
||||
// input lines
|
||||
template <unsigned Interrupt> DECLARE_WRITE_LINE_MEMBER(irq_w) {}
|
||||
template <unsigned Channel> DECLARE_WRITE_LINE_MEMBER(drq_w) {}
|
||||
|
||||
void map(address_map &map);
|
||||
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
protected:
|
||||
// device_t overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
template <unsigned Channel> DECLARE_READ32_MEMBER(load_address_r) { return m_channel[Channel].load_address; }
|
||||
template <unsigned Channel> DECLARE_READ32_MEMBER(diag_r) { return 0; }
|
||||
template <unsigned Channel> DECLARE_READ16_MEMBER(fifo_r) { return 0; }
|
||||
template <unsigned Channel> DECLARE_READ32_MEMBER(mode_r) { return m_channel[Channel].mode; }
|
||||
template <unsigned Channel> DECLARE_READ16_MEMBER(block_count_r) { return m_channel[Channel].block_count; }
|
||||
template <unsigned Channel> DECLARE_READ32_MEMBER(current_address_r) { return 0; }
|
||||
|
||||
DECLARE_READ32_MEMBER(tcount_r);
|
||||
DECLARE_READ32_MEMBER(tbreak_r) { return 0; }
|
||||
DECLARE_READ32_MEMBER(error_r) { return 0; }
|
||||
DECLARE_READ32_MEMBER(control_r) { return 0; }
|
||||
|
||||
template <unsigned Channel> DECLARE_WRITE32_MEMBER(load_address_w);
|
||||
template <unsigned Channel> DECLARE_WRITE16_MEMBER(fifo_w);
|
||||
template <unsigned Channel> DECLARE_WRITE32_MEMBER(mode_w);
|
||||
template <unsigned Channel> DECLARE_WRITE16_MEMBER(block_count_w);
|
||||
|
||||
DECLARE_WRITE32_MEMBER(tcount_w);
|
||||
DECLARE_WRITE32_MEMBER(tbreak_w);
|
||||
DECLARE_WRITE32_MEMBER(control_w);
|
||||
|
||||
TIMER_CALLBACK_MEMBER(buzzer_toggle);
|
||||
|
||||
private:
|
||||
enum mode_mask : u32
|
||||
{
|
||||
// these bits are read/write
|
||||
MODE_FLUSH_FIFO = 0x80000000, // clears fifo
|
||||
MODE_CHANNEL_EN = 0x40000000, // enable dma channel
|
||||
MODE_AUTO_RELOAD = 0x20000000, // reload src/dst address
|
||||
MODE_INTR_EN = 0x10000000, // enable dma interrupt
|
||||
MODE_TO_MEMORY = 0x08000000, // direction (0=>scsi write)
|
||||
MODE_CLR_DMA_ERR = 0x04000000, // clear dma error
|
||||
|
||||
// these bits are read only
|
||||
MODE_FIFO_FULL = 0x00000800, // fifo full state
|
||||
MODE_FIFO_EMPTY = 0x00000400, // fifo empty state
|
||||
MODE_DMA_ERROR = 0x00000200, // parity error during transfer
|
||||
MODE_DMA_INTR = 0x00000100, // channel interrupt pending
|
||||
MODE_COUNT_MASK = 0x000000ff, // halfword count bits
|
||||
};
|
||||
|
||||
enum control_mask : u32
|
||||
{
|
||||
CONTROL_CLRERRINT = 0x01, // clear error interrupt
|
||||
CONTROL_RESETERROR = 0x02, // reset error latch of EReg
|
||||
CONTROL_ENABLEPARITY = 0x04, // enable parity checking
|
||||
CONTROL_BUZZON = 0x08, // buzzer enable
|
||||
CONTROL_BUZZMASK = 0x70, // buzzer divider (1 == 1524 Hz)
|
||||
};
|
||||
|
||||
required_device<ram_device> m_ram;
|
||||
|
||||
devcb_write_line m_irq_out_cb;
|
||||
devcb_write_line m_parity_out_cb;
|
||||
devcb_write_line m_timer_out_cb;
|
||||
devcb_write_line m_buzzer_out_cb;
|
||||
|
||||
struct dma_t
|
||||
{
|
||||
u32 load_address;
|
||||
u32 diag;
|
||||
u32 mode;
|
||||
u16 block_count;
|
||||
u32 current_address;
|
||||
}
|
||||
m_channel[2];
|
||||
|
||||
emu_timer *m_buzzer_timer;
|
||||
|
||||
int m_irq_out_state;
|
||||
int m_buzzer_out_state;
|
||||
|
||||
attotime m_tcount;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(MIPS_RAMBO, mips_rambo_device)
|
||||
|
||||
#endif // MAME_MACHINE_MIPS_RAMBO_H
|
Loading…
Reference in New Issue
Block a user