diff options
Diffstat (limited to 'src/mame/drivers/riscpc.cpp')
-rw-r--r-- | src/mame/drivers/riscpc.cpp | 258 |
1 files changed, 173 insertions, 85 deletions
diff --git a/src/mame/drivers/riscpc.cpp b/src/mame/drivers/riscpc.cpp index eebe3bb2846..3ecf5eb42bf 100644 --- a/src/mame/drivers/riscpc.cpp +++ b/src/mame/drivers/riscpc.cpp @@ -8,8 +8,13 @@ based on work by Tomasz Slanina and Tom Walker TODO: - - probably needs a full rewrite & merge with ssfindo.c - + - Move device implementations into specific files; + - PS/2 keyboard doesn't work properly; + - i2c device should actually be a pcf8583 RTC with i2c as slave + (and indeed CMOS settings doesn't work); + - Fix pendingUnd fatalerror from ARM7 core + - Fix per-machine configurations; + ??? bp (0382827C) (second trigger) do R13 = SR13 @@ -19,10 +24,14 @@ #include "emu.h" #include "cpu/arm7/arm7.h" #include "cpu/arm7/arm7core.h" +#include "machine/i2cmem.h" +#include "machine/at_keybc.h" +#include "bus/pc_kbd/pc_kbdc.h" +#include "bus/pc_kbd/keyboards.h" #include "emupal.h" #include "screen.h" #include "speaker.h" - +#include "debugger.h" class riscpc_state : public driver_device { @@ -31,7 +40,9 @@ public: : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_screen(*this, "screen"), - m_palette(*this, "palette") + m_palette(*this, "palette"), + m_i2cmem(*this, "i2cmem"), + m_kbdc(*this, "kbdc") { } void rpc700(machine_config &config); @@ -42,15 +53,21 @@ public: void a7000p(machine_config &config); private: + void base_config(machine_config &config); + required_device<cpu_device> m_maincpu; required_device<screen_device> m_screen; required_device<palette_device> m_palette; + required_device<i2cmem_device> m_i2cmem; + required_device<ps2_keyboard_controller_device> m_kbdc; std::unique_ptr<uint32_t[]> m_vram; DECLARE_READ32_MEMBER(a7000_iomd_r); DECLARE_WRITE32_MEMBER(a7000_iomd_w); DECLARE_WRITE32_MEMBER(a7000_vidc20_w); + DECLARE_WRITE_LINE_MEMBER(keyboard_reset); + DECLARE_WRITE_LINE_MEMBER(keyboard_interrupt); uint8_t m_vidc20_pal_index; uint16_t m_vidc20_horz_reg[0x10]; @@ -61,8 +78,8 @@ private: uint16_t m_timer_out[2]; int m_timer_counter[2]; emu_timer *m_IOMD_timer[2]; - uint8_t m_IRQ_status_A; - uint8_t m_IRQ_mask_A; + uint8_t m_IRQ_status_A, m_IRQ_status_B; + uint8_t m_IRQ_mask_A, m_IRQ_mask_B; uint8_t m_IOMD_IO_ctrl; uint8_t m_IOMD_keyb_ctrl; uint16_t m_io_id; @@ -72,6 +89,7 @@ private: uint32_t m_viddma_addr_end; uint8_t m_t0readinc; uint8_t m_t1readinc; + uint8_t m_i2c_clk; void fire_iomd_timer(int timer); void viddma_transfer_start(); void vidc20_dynamic_screen_change(); @@ -87,7 +105,7 @@ private: void a7000_map(address_map &map); void riscpc_map(address_map &map); - + void update_irq(); }; @@ -582,6 +600,10 @@ static const char *const iomd_regnames[] = #define IOMD_IRQRQA 0x014/4 #define IOMD_IRQMSKA 0x018/4 +#define IOMD_IRQSTB 0x020/4 +#define IOMD_IRQRQB 0x024/4 +#define IOMD_IRQMSKB 0x028/4 + #define IOMD_T0LOW 0x040/4 #define IOMD_T0HIGH 0x044/4 #define IOMD_T0GO 0x048/4 @@ -604,6 +626,14 @@ static const char *const iomd_regnames[] = #define IOMD_DMARQ 0x1f4/4 +void riscpc_state::update_irq() +{ + if (m_IRQ_status_A & m_IRQ_mask_A) + m_maincpu->pulse_input_line(ARM7_IRQ_LINE, m_maincpu->minimum_quantum_time()); + if (m_IRQ_status_B & m_IRQ_mask_B) + m_maincpu->pulse_input_line(ARM7_IRQ_LINE, m_maincpu->minimum_quantum_time()); +} + void riscpc_state::fire_iomd_timer(int timer) { int timer_count = m_timer_counter[timer]; @@ -618,28 +648,19 @@ void riscpc_state::fire_iomd_timer(int timer) TIMER_CALLBACK_MEMBER(riscpc_state::IOMD_timer0_callback) { m_IRQ_status_A|=0x20; - if(m_IRQ_mask_A&0x20) - { - m_maincpu->pulse_input_line(ARM7_IRQ_LINE, m_maincpu->minimum_quantum_time()); - } + update_irq(); } TIMER_CALLBACK_MEMBER(riscpc_state::IOMD_timer1_callback) { m_IRQ_status_A|=0x40; - if(m_IRQ_mask_A&0x40) - { - m_maincpu->pulse_input_line(ARM7_IRQ_LINE, m_maincpu->minimum_quantum_time()); - } + update_irq(); } TIMER_CALLBACK_MEMBER(riscpc_state::flyback_timer_callback) { m_IRQ_status_A|=0x08; - if(m_IRQ_mask_A&0x08) - { - m_maincpu->pulse_input_line(ARM7_IRQ_LINE, m_maincpu->minimum_quantum_time()); - } + update_irq(); // for convenience lets just implement the video DMA transfer here // the actual transfer probably works per scanline once enabled. @@ -652,7 +673,7 @@ TIMER_CALLBACK_MEMBER(riscpc_state::flyback_timer_callback) void riscpc_state::viddma_transfer_start() { address_space &mem = m_maincpu->space(AS_PROGRAM); - uint32_t src = m_viddma_addr_start; + uint32_t src = m_viddma_addr_init; uint32_t dst = 0; uint32_t size = m_viddma_addr_end; uint32_t dma_index; @@ -663,6 +684,7 @@ void riscpc_state::viddma_transfer_start() m_vram[dst] = mem.read_dword(src); src+=4; + // TODO: honor boundary dst++; } } @@ -683,24 +705,29 @@ READ32_MEMBER( riscpc_state::a7000_iomd_r ) vert_pos = m_screen->vpos(); flyback = (vert_pos <= m_vidc20_vert_reg[VDSR] || vert_pos >= m_vidc20_vert_reg[VDER]) ? 0x80 : 0x00; - return m_IOMD_IO_ctrl | 0x34 | flyback; + return flyback | (m_IOMD_IO_ctrl & 0x7c) | 0x34 | (m_i2c_clk << 1) | (m_i2cmem->read_sda() ? 1 : 0); } - case IOMD_KBDCR: return m_IOMD_keyb_ctrl | 0x80; //IOMD Keyb status + case IOMD_KBDDAT: return m_kbdc->data_r(); + case IOMD_KBDCR: return m_kbdc->status_r(); /* - 1--- ---- always high - -x-- ---- Timer 1 - --x- ---- Timer 0 - ---x ---- Power On Reset - ---- x--- Flyback - ---- -x-- nINT1 - ---- --0- always low - ---- ---x INT2 + 1--- ---- always high (force) + -x-- ---- Timer 1 + --x- ---- Timer 0 + ---x ---- Power On Reset + ---- x--- Flyback + ---- -x-- nINT1 + ---- --0- always low + ---- ---x INT2 */ - case IOMD_IRQSTA: return (m_IRQ_status_A & ~2) | 0x80; - case IOMD_IRQRQA: return (m_IRQ_status_A & m_IRQ_mask_A) | 0x80; + case IOMD_IRQSTA: return (m_IRQ_status_A & 0x7d) | 0x80; + case IOMD_IRQRQA: return (m_IRQ_status_A & m_IRQ_mask_A); case IOMD_IRQMSKA: return m_IRQ_mask_A; + case IOMD_IRQSTB: return m_IRQ_status_B; + case IOMD_IRQRQB: return (m_IRQ_status_B & m_IRQ_mask_B); + case IOMD_IRQMSKB: return m_IRQ_mask_B; + case IOMD_T0LOW: return m_timer_out[0] & 0xff; case IOMD_T0HIGH: return (m_timer_out[0] >> 8) & 0xff; @@ -713,7 +740,7 @@ READ32_MEMBER( riscpc_state::a7000_iomd_r ) case IOMD_VIDEND: return m_viddma_addr_end & 0x00fffff8; //bits 31:24 undefined case IOMD_VIDSTART: return m_viddma_addr_start & 0x1ffffff8; //bits 31, 30, 29 undefined - case IOMD_VIDINIT: return m_viddma_addr_init & 0xfffffff8; + case IOMD_VIDINIT: return m_viddma_addr_init & 0x1ffffff8; case IOMD_VIDCR: return (m_viddma_status & 0xa0) | 0x50; //bit 6 = DRAM mode, bit 4 = QWORD transfer default: logerror("IOMD: %s Register (%04x) read\n",iomd_regnames[offset & (0x1ff >> 2)],offset*4); break; @@ -728,15 +755,40 @@ WRITE32_MEMBER( riscpc_state::a7000_iomd_w ) switch(offset) { - case IOMD_IOCR: m_IOMD_IO_ctrl = data & ~0xf4; break; + case IOMD_IOCR: + m_IOMD_IO_ctrl = data & 0x7c; + m_i2cmem->write_sda(data & 0x01); + m_i2c_clk = (data & 2) >> 1; + m_i2cmem->write_scl(m_i2c_clk); + break; - case IOMD_KBDCR: - m_IOMD_keyb_ctrl = data & ~0xf4; - //keyboard_ctrl_write(data & 0x08); + case IOMD_KBDDAT: m_kbdc->data_w(data); break; + case IOMD_KBDCR: m_kbdc->command_w(data); + //m_IRQ_status_B |= 0x40; + //machine().debug_break(); + //update_irq(); break; - case IOMD_IRQRQA: m_IRQ_status_A &= ~data; break; - case IOMD_IRQMSKA: m_IRQ_mask_A = (data & ~2) | 0x80; break; + case IOMD_IRQRQA: + m_IRQ_status_A &= ~data; + m_IRQ_status_A |= 0x80; + update_irq(); + break; + + case IOMD_IRQMSKA: + m_IRQ_mask_A = data; + update_irq(); + break; + + case IOMD_IRQRQB: + m_IRQ_status_B &= ~data; + update_irq(); + break; + + case IOMD_IRQMSKB: + m_IRQ_mask_B = data; + update_irq(); + break; case IOMD_T0LOW: m_timer_in[0] = (m_timer_in[0] & 0xff00) | (data & 0xff); break; case IOMD_T0HIGH: m_timer_in[0] = (m_timer_in[0] & 0x00ff) | ((data & 0xff) << 8); break; @@ -780,7 +832,7 @@ WRITE32_MEMBER( riscpc_state::a7000_iomd_w ) break; case IOMD_VIDSTART: m_viddma_addr_start = data & 0x1ffffff8; //bits 31, 30, 29 unused break; - case IOMD_VIDINIT: m_viddma_addr_init = data & 0xfffffff0; + case IOMD_VIDINIT: m_viddma_addr_init = data & 0x1ffffff8; break; case IOMD_VIDCR: m_viddma_status = data & 0xa0; if(data & 0x20) { viddma_transfer_start(); } @@ -804,7 +856,7 @@ void riscpc_state::a7000_map(address_map &map) // AM_RANGE(0x03040000, 0x0304ffff) //podule space 0,1,2,3 // AM_RANGE(0x03070000, 0x0307ffff) //podule space 4,5,6,7 map(0x03200000, 0x032001ff).rw(FUNC(riscpc_state::a7000_iomd_r), FUNC(riscpc_state::a7000_iomd_w)); //IOMD Registers //mirrored at 0x03000000-0x1ff? -// AM_RANGE(0x03310000, 0x03310003) //Mouse Buttons + map(0x03310000, 0x03310003).portr("MOUSE"); map(0x03400000, 0x037fffff).w(FUNC(riscpc_state::a7000_vidc20_w)); // AM_RANGE(0x08000000, 0x08ffffff) AM_MIRROR(0x07000000) //EASI space @@ -823,6 +875,25 @@ void riscpc_state::riscpc_map(address_map &map) /* Input ports */ static INPUT_PORTS_START( a7000 ) +// PORT_INCLUDE( at_keyboard ) + + PORT_START("MOUSE") + // for debugging we leave video and sound HWs as options, eventually slotify them + PORT_CONFNAME( 0x01, 0x00, "Monitor Type" ) + PORT_CONFSETTING( 0x00, "VGA" ) + PORT_CONFSETTING( 0x01, "TV Screen" ) + PORT_BIT( 0x0e, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Mouse Right") PORT_CODE(MOUSECODE_BUTTON3) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Mouse Center") PORT_CODE(MOUSECODE_BUTTON2) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Mouse Left") PORT_CODE(MOUSECODE_BUTTON1) + // TODO: understand condition where this occurs + PORT_CONFNAME( 0x80, 0x00, "CMOS Reset bit" ) + PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) + PORT_CONFSETTING( 0x80, DEF_STR( On ) ) + PORT_CONFNAME( 0x100, 0x000, "Sound HW" ) + PORT_CONFSETTING( 0x000, "16-bit" ) + PORT_CONFSETTING( 0x100, "8-bit" ) + PORT_BIT(0xfffffe00, IP_ACTIVE_LOW, IPT_UNUSED ) INPUT_PORTS_END void riscpc_state::machine_start() @@ -836,23 +907,64 @@ void riscpc_state::machine_start() void riscpc_state::machine_reset() { - m_IOMD_IO_ctrl = 0x0b | 0x34; //bit 0,1 and 3 set high on reset plus 2,4,5 always high + m_IOMD_IO_ctrl = 0x08 | 0x34; //bit 0,1 and 3 set high on reset plus 2,4,5 always high // TODO: jumps to EASI space at $0c0016xx with this on!? // m_IRQ_status_A = 0x10; // set POR bit ON m_IRQ_mask_A = 0x00; m_IOMD_keyb_ctrl = 0x00; - m_IOMD_timer[0]->adjust( attotime::never); - m_IOMD_timer[1]->adjust( attotime::never); - m_flyback_timer->adjust( attotime::never); + m_IOMD_timer[0]->adjust(attotime::never); + m_IOMD_timer[1]->adjust(attotime::never); + m_flyback_timer->adjust(attotime::never); } -void riscpc_state::rpc600(machine_config &config) +WRITE_LINE_MEMBER(riscpc_state::keyboard_reset) { - /* Basic machine hardware */ - ARM7(config, m_maincpu, 60_MHz_XTAL/2); // ARM610 - m_maincpu->set_addrmap(AS_PROGRAM, &riscpc_state::riscpc_map); + printf("RST %d\n",state); +} + +WRITE_LINE_MEMBER(riscpc_state::keyboard_interrupt) +{ + printf("IRQ %d\n",state); + if (!state) + return; + +// machine().debug_break(); + m_IRQ_status_B|=0x80; + update_irq(); +} + + +void riscpc_state::base_config(machine_config &config) +{ + I2C_24C02(config, m_i2cmem); + + pc_kbdc_device &kbd_con(PC_KBDC(config, "kbd_con", 0)); + kbd_con.out_clock_cb().set(m_kbdc, FUNC(ps2_keyboard_controller_device::kbd_clk_w)); + kbd_con.out_data_cb().set(m_kbdc, FUNC(ps2_keyboard_controller_device::kbd_data_w)); + + // TODO: verify type + pc_kbdc_slot_device &kbd(PC_KBDC_SLOT(config, "kbd", pc_at_keyboards, STR_KBD_IBM_PC_AT_101)); + kbd.set_pc_kbdc_slot(&kbd_con); + + // auxiliary connector +// pc_kbdc_device &aux_con(PC_KBDC(config, "aux_con", 0)); +// aux_con.out_clock_cb().set(m_kbdc, FUNC(ps2_keyboard_controller_device::aux_clk_w)); +// aux_con.out_data_cb().set(m_kbdc, FUNC(ps2_keyboard_controller_device::aux_data_w)); + + // auxiliary port +// pc_kbdc_slot_device &aux(PC_KBDC_SLOT(config, "aux", ps2_mice, STR_HLE_PS2_MOUSE)); +// aux.set_pc_kbdc_slot(&aux_con); + + PS2_KEYBOARD_CONTROLLER(config, m_kbdc, 12_MHz_XTAL); + m_kbdc->hot_res().set(FUNC(riscpc_state::keyboard_reset)); + m_kbdc->kbd_clk().set(kbd_con, FUNC(pc_kbdc_device::clock_write_from_mb)); + m_kbdc->kbd_data().set(kbd_con, FUNC(pc_kbdc_device::data_write_from_mb)); + m_kbdc->kbd_irq().set(FUNC(riscpc_state::keyboard_interrupt)); +// m_kbdc->aux_clk().set(aux_con, FUNC(pc_kbdc_device::clock_write_from_mb)); +// m_kbdc->aux_data().set(aux_con, FUNC(pc_kbdc_device::data_write_from_mb)); +// m_kbdc->aux_irq().set(FUNC(riscpc_state::keyboard_interrupt)); /* video hardware */ SCREEN(config, m_screen, SCREEN_TYPE_RASTER); @@ -864,20 +976,20 @@ void riscpc_state::rpc600(machine_config &config) PALETTE(config, m_palette).set_entries(0x200); } +void riscpc_state::rpc600(machine_config &config) +{ + /* Basic machine hardware */ + ARM7(config, m_maincpu, 60_MHz_XTAL/2); // ARM610 + m_maincpu->set_addrmap(AS_PROGRAM, &riscpc_state::riscpc_map); + base_config(config); +} + void riscpc_state::rpc700(machine_config &config) { /* Basic machine hardware */ ARM710A(config, m_maincpu, 80_MHz_XTAL/2); // ARM710 m_maincpu->set_addrmap(AS_PROGRAM, &riscpc_state::riscpc_map); - - /* video hardware */ - SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_refresh_hz(60); - m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ - m_screen->set_size(1900, 1080); //max available size - m_screen->set_visarea(0, 1900-1, 0, 1080-1); - m_screen->set_screen_update(FUNC(riscpc_state::screen_update)); - PALETTE(config, m_palette).set_entries(0x200); + base_config(config); } void riscpc_state::a7000(machine_config &config) @@ -885,15 +997,7 @@ void riscpc_state::a7000(machine_config &config) /* Basic machine hardware */ ARM7(config, m_maincpu, XTAL(32'000'000)); // ARM7500 m_maincpu->set_addrmap(AS_PROGRAM, &riscpc_state::a7000_map); - - /* video hardware */ - SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_refresh_hz(60); - m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ - m_screen->set_size(1900, 1080); //max available size - m_screen->set_visarea(0, 1900-1, 0, 1080-1); - m_screen->set_screen_update(FUNC(riscpc_state::screen_update)); - PALETTE(config, m_palette).set_entries(0x200); + base_config(config); } void riscpc_state::a7000p(machine_config &config) @@ -907,15 +1011,7 @@ void riscpc_state::sarpc(machine_config &config) /* Basic machine hardware */ ARM7(config, m_maincpu, 202000000); // StrongARM m_maincpu->set_addrmap(AS_PROGRAM, &riscpc_state::riscpc_map); - - /* video hardware */ - SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_refresh_hz(60); - m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ - m_screen->set_size(1900, 1080); //max available size - m_screen->set_visarea(0, 1900-1, 0, 1080-1); - m_screen->set_screen_update(FUNC(riscpc_state::screen_update)); - PALETTE(config, m_palette).set_entries(0x200); + base_config(config); } void riscpc_state::sarpc_j233(machine_config &config) @@ -923,15 +1019,7 @@ void riscpc_state::sarpc_j233(machine_config &config) /* Basic machine hardware */ ARM7(config, m_maincpu, 233000000); // StrongARM m_maincpu->set_addrmap(AS_PROGRAM, &riscpc_state::riscpc_map); - - /* video hardware */ - SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_refresh_hz(60); - m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ - m_screen->set_size(1900, 1080); //max available size - m_screen->set_visarea(0, 1900-1, 0, 1080-1); - m_screen->set_screen_update(FUNC(riscpc_state::screen_update)); - PALETTE(config, m_palette).set_entries(0x200); + base_config(config); } ROM_START(rpc600) |