summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/riscpc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/riscpc.cpp')
-rw-r--r--src/mame/drivers/riscpc.cpp933
1 files changed, 93 insertions, 840 deletions
diff --git a/src/mame/drivers/riscpc.cpp b/src/mame/drivers/riscpc.cpp
index a5fb926105d..5208fec8e41 100644
--- a/src/mame/drivers/riscpc.cpp
+++ b/src/mame/drivers/riscpc.cpp
@@ -2,28 +2,25 @@
// copyright-holders:Angelo Salese
/***************************************************************************
- Acorn Archimedes 7000/7000+
+ Acorn RiscPC line of computers
- very preliminary driver by Angelo Salese,
+ preliminary driver by Angelo Salese,
based on work by Tomasz Slanina and Sarah Walker
TODO:
- - 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
+ - IOMD currently hardwired with ARM7500FE flavour for all machines, needs information about
+ which uses what;
+ - PS/2 keyboard doesn't work properly;
+ - Fix pendingUnd fatalerror from ARM7 core;
+ - Fix pendingAbtD fatalerror for RiscOS 4.xx;
****************************************************************************/
#include "emu.h"
#include "cpu/arm7/arm7.h"
#include "cpu/arm7/arm7core.h"
+#include "machine/acorn_vidc.h"
+#include "machine/arm_iomd.h"
#include "machine/i2cmem.h"
#include "machine/at_keybc.h"
#include "bus/pc_kbd/pc_kbdc.h"
@@ -37,12 +34,13 @@ class riscpc_state : public driver_device
{
public:
riscpc_state(const machine_config &mconfig, device_type type, const char *tag)
- : driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu"),
- m_screen(*this, "screen"),
- m_palette(*this, "palette"),
- m_i2cmem(*this, "i2cmem"),
- m_kbdc(*this, "kbdc")
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ , m_vidc(*this, "vidc")
+ , m_iomd(*this, "iomd")
+ , m_screen(*this, "screen")
+ , m_i2cmem(*this, "i2cmem")
+ , m_kbdc(*this, "kbdc")
{ }
void rpc700(machine_config &config);
@@ -56,791 +54,47 @@ private:
void base_config(machine_config &config);
required_device<cpu_device> m_maincpu;
+ required_device<arm_vidc20_device> m_vidc;
+ required_device<arm7500fe_iomd_device> m_iomd;
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];
- uint16_t m_vidc20_vert_reg[0x10];
- uint8_t m_vidc20_bpp_mode;
- emu_timer *m_flyback_timer;
- uint16_t m_timer_in[2];
- uint16_t m_timer_out[2];
- int m_timer_counter[2];
- emu_timer *m_IOMD_timer[2];
- 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;
- uint8_t m_viddma_status;
- uint32_t m_viddma_addr_init;
- uint32_t m_viddma_addr_start;
- 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();
- virtual void video_start() override;
+
virtual void machine_reset() override;
virtual void machine_start() override;
- uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
- TIMER_CALLBACK_MEMBER(IOMD_timer0_callback);
- TIMER_CALLBACK_MEMBER(IOMD_timer1_callback);
- TIMER_CALLBACK_MEMBER(flyback_timer_callback);
- TIMER_CALLBACK_MEMBER(videodma_timer_callback);
-
void a7000_map(address_map &map);
void riscpc_map(address_map &map);
- void update_irq();
-};
-
-
-/*
- *
- * VIDC20 chip emulation
- *
- */
-
-void riscpc_state::video_start()
-{
- const uint32_t vram_size = 0x1000000/4;
- m_vram = std::make_unique<uint32_t[]>(vram_size);
- save_pointer(NAME(m_vram), vram_size);
-}
-
-
-static const char *const vidc20_regnames[] =
-{
- "Video Palette", // 0
- "Video Palette Address", // 1
- "RESERVED", // 2
- "LCD offset", // 3
- "Border Colour", // 4
- "Cursor Palette Logical Colour 1", // 5
- "Cursor Palette Logical Colour 2", // 6
- "Cursor Palette Logical Colour 3", // 7
- "Horizontal", // 8
- "Vertical", // 9
- "Stereo Image", // A
- "Sound", // B
- "External", // C
- "Frequency Synthesis", // D
- "Control", // E
- "Data Control" // F
-};
-
-#if 0
-static const char *const vidc20_horz_regnames[] =
-{
- "Horizontal Cycle", // 0x80 HCR
- "Horizontal Sync Width", // 0x81 HSWR
- "Horizontal Border Start", // 0x82 HBSR
- "Horizontal Display Start", // 0x83 HDSR
- "Horizontal Display End", // 0x84 HDER
- "Horizontal Border End", // 0x85 HBER
- "Horizontal Cursor Start", // 0x86 HCSR
- "Horizontal Interlace", // 0x87 HIR
- "Horizontal Counter TEST", // 0x88
- "Horizontal <UNDEFINED>", // 0x89
- "Horizontal <UNDEFINED>", // 0x8a
- "Horizontal <UNDEFINED>", // 0x8b
- "Horizontal All TEST", // 0x8c
- "Horizontal <UNDEFINED>", // 0x8d
- "Horizontal <UNDEFINED>", // 0x8e
- "Horizontal <UNDEFINED>" // 0x8f
-};
-#endif
-
-#define HCR 0
-#define HSWR 1
-#define HBSR 2
-#define HDSR 3
-#define HDER 4
-#define HBER 5
-#define HCSR 6
-#define HIR 7
-
-#if 0
-static const char *const vidc20_vert_regnames[] =
-{
- "Vertical Cycle", // 0x90 VCR
- "Vertical Sync Width", // 0x91 VSWR
- "Vertical Border Start", // 0x92 VBSR
- "Vertical Display Start", // 0x93 VDSR
- "Vertical Display End", // 0x94 VDER
- "Vertical Border End", // 0x95 VBER
- "Vertical Cursor Start", // 0x96 VCSR
- "Vertical Cursor End", // 0x97 VCER
- "Vertical Counter TEST", // 0x98
- "Horizontal <UNDEFINED>", // 0x99
- "Vertical Counter Increment TEST", // 0x9a
- "Horizontal <UNDEFINED>", // 0x9b
- "Vertical All TEST", // 0x9c
- "Horizontal <UNDEFINED>", // 0x9d
- "Horizontal <UNDEFINED>", // 0x9e
- "Horizontal <UNDEFINED>" // 0x9f
-};
-#endif
-
-#define VCR 0
-#define VSWR 1
-#define VBSR 2
-#define VDSR 3
-#define VDER 4
-#define VBER 5
-#define VCSR 6
-#define VCER 7
-
-void riscpc_state::vidc20_dynamic_screen_change()
-{
- /* sanity checks - first pass */
- /*
- total cycles + border start/end
- */
- if(m_vidc20_horz_reg[HCR] && m_vidc20_horz_reg[HBSR] && m_vidc20_horz_reg[HBER] &&
- m_vidc20_vert_reg[VCR] && m_vidc20_vert_reg[VBSR] && m_vidc20_vert_reg[VBER])
- {
- /* sanity checks - second pass */
- /*
- total cycles > border end > border start
- */
- if((m_vidc20_horz_reg[HCR] > m_vidc20_horz_reg[HBER]) &&
- (m_vidc20_horz_reg[HBER] > m_vidc20_horz_reg[HBSR]) &&
- (m_vidc20_vert_reg[VCR] > m_vidc20_vert_reg[VBER]) &&
- (m_vidc20_vert_reg[VBER] > m_vidc20_vert_reg[VBSR]))
- {
- /* finally ready to change the resolution */
- int hblank_period,vblank_period;
- rectangle visarea = m_screen->visible_area();
- hblank_period = (m_vidc20_horz_reg[HCR] & 0x3ffc);
- vblank_period = (m_vidc20_vert_reg[VCR] & 0x3fff);
- /* note that we use the border registers as the visible area */
- visarea.set(
- (m_vidc20_horz_reg[HBSR] & 0x3ffe),
- (m_vidc20_horz_reg[HBER] & 0x3ffe) - 1,
- (m_vidc20_vert_reg[VBSR] & 0x1fff),
- (m_vidc20_vert_reg[VBER] & 0x1fff) - 1);
-
- m_screen->configure(hblank_period, vblank_period, visarea, m_screen->frame_period().attoseconds() );
- logerror("VIDC20: successfully changed the screen to:\n Display Size = %d x %d\n Border Size %d x %d\n Cycle Period %d x %d\n",
- (m_vidc20_horz_reg[HDER]-m_vidc20_horz_reg[HDSR]),(m_vidc20_vert_reg[VDER]-m_vidc20_vert_reg[VDSR]),
- (m_vidc20_horz_reg[HBER]-m_vidc20_horz_reg[HBSR]),(m_vidc20_vert_reg[VBER]-m_vidc20_vert_reg[VBSR]),
- hblank_period,vblank_period);
- }
- }
-}
-
-WRITE32_MEMBER( riscpc_state::a7000_vidc20_w )
-{
- int r,g,b,cursor_index,horz_reg,vert_reg,reg = data >> 28;
-
- switch(reg)
- {
- case 0: // Video Palette
- r = (data & 0x0000ff) >> 0;
- g = (data & 0x00ff00) >> 8;
- b = (data & 0xff0000) >> 16;
-
- m_palette->set_pen_color(m_vidc20_pal_index & 0xff,r,g,b);
-
- /* auto-increment & wrap-around */
- m_vidc20_pal_index++;
- m_vidc20_pal_index &= 0xff;
- break;
-
- case 1: // Video Palette Address
-
- // according to RPCEmu, these mustn't be set
- if (data & 0x0fffff00)
- return;
-
- m_vidc20_pal_index = data & 0xff;
- break;
-
- case 4: // Border Color
- r = (data & 0x0000ff) >> 0;
- g = (data & 0x00ff00) >> 8;
- b = (data & 0xff0000) >> 16;
-
- m_palette->set_pen_color(0x100,r,g,b);
- break;
- case 5: // Cursor Palette Logical Colour n
- case 6:
- case 7:
- cursor_index = 0x100 + reg - 4; // 0x101,0x102 and 0x103 (plus 0x100 of above, 2bpp)
-
- r = (data & 0x0000ff) >> 0;
- g = (data & 0x00ff00) >> 8;
- b = (data & 0xff0000) >> 16;
-
- m_palette->set_pen_color(cursor_index,r,g,b);
- break;
- case 8: // Horizontal
- horz_reg = (data >> 24) & 0xf;
- m_vidc20_horz_reg[horz_reg] = data & 0x3fff;
- if(horz_reg == 0 || horz_reg == 2 || horz_reg == 5)
- vidc20_dynamic_screen_change();
-
- // logerror("VIDC20: %s Register write = %08x (%d)\n",vidc20_horz_regnames[horz_reg],val,val);
- break;
- case 9: // Vertical
- vert_reg = (data >> 24) & 0xf;
- m_vidc20_vert_reg[vert_reg] = data & 0x1fff;
- if(vert_reg == 0 || vert_reg == 2 || vert_reg == 5)
- vidc20_dynamic_screen_change();
-
- if(vert_reg == 4)
- {
- if(m_vidc20_vert_reg[VDER] != 0)
- m_flyback_timer->adjust(m_screen->time_until_pos(m_vidc20_vert_reg[VDER]));
- else
- m_flyback_timer->adjust(attotime::never);
- }
-
- // logerror("VIDC20: %s Register write = %08x (%d)\n",vidc20_vert_regnames[vert_reg],val,val);
-
- break;
- case 0x0e: // Control
- m_vidc20_bpp_mode = (data & 0xe0) >> 5;
- break;
- default: logerror("VIDC20: %s Register write = %08x\n",vidc20_regnames[reg],data & 0xfffffff);
- }
-}
-
-uint32_t riscpc_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
-{
- int x_size,y_size,x_start,y_start;
- int x,y,xi;
- uint32_t count;
-
- bitmap.fill(m_palette->pen(0x100), cliprect);
-
- x_size = (m_vidc20_horz_reg[HDER]-m_vidc20_horz_reg[HDSR]);
- y_size = (m_vidc20_vert_reg[VDER]-m_vidc20_vert_reg[VDSR]);
- x_start = m_vidc20_horz_reg[HDSR];
- y_start = m_vidc20_vert_reg[VDSR];
-
- /* check if display is enabled */
- if(x_size <= 0 || y_size <= 0)
- return 0;
-
-// popmessage("%d",m_vidc20_bpp_mode);
-
- count = 0;
-
- switch(m_vidc20_bpp_mode)
- {
- case 0: /* 1 bpp */
- {
- for(y=0;y<y_size;y++)
- {
- for(x=0;x<x_size;x+=32)
- {
- for(xi=0;xi<32;xi++)
- bitmap.pix32(y+y_start, x+xi+x_start) = m_palette->pen((m_vram[count]>>(xi))&1);
-
- count++;
- }
- }
- break;
- }
- case 2: /* 4 bpp */
- {
- for(y=0;y<y_size;y++)
- {
- for(x=0;x<x_size;x+=8)
- {
- for(xi=0;xi<8;xi++)
- bitmap.pix32(y+y_start, x+xi+x_start) = m_palette->pen((m_vram[count]>>(xi*4))&0xf);
-
- count++;
- }
- }
- break;
- }
- #if 0
- case 1: /* 2 bpp */
- {
- for(y=0;y<y_size;y++)
- {
- for(x=0;x<x_size;x+=4)
- {
- for(xi=0;xi<4;xi++)
- bitmap.pix32(y+y_start, x+xi+x_start) = m_palette->pen((vram[count]>>(xi*2))&3);
-
- count++;
- }
- }
- }
- break;
-
- case 3: /* 8 bpp */
- {
- for(y=0;y<y_size;y++)
- {
- for(x=0;x<x_size;x++)
- {
- bitmap.pix32(y+y_start, x+x_start) = m_palette->pen((vram[count])&0xff);
-
- count++;
- }
- }
- }
- break;
- case 4: /* 16 bpp */
- {
- for(y=0;y<y_size;y++)
- {
- for(x=0;x<x_size;x++)
- {
- int r,g,b,pen;
-
- pen = ((vram[count]<<8)|(vram[count+1]))&0xffff;
- r = (pen & 0x000f);
- g = (pen & 0x00f0) >> 4;
- b = (pen & 0x0f00) >> 8;
- r = (r << 4) | (r & 0xf);
- g = (g << 4) | (g & 0xf);
- b = (b << 4) | (b & 0xf);
-
- bitmap.pix32(y+y_start, x+x_start) = b | g << 8 | r << 16;
-
- count+=2;
- }
- }
- }
- break;
- case 6: /* 32 bpp */
- {
- for(y=0;y<y_size;y++)
- {
- for(x=0;x<x_size;x++)
- {
- int r,g,b,pen;
-
- pen = ((vram[count]<<24)|(vram[count+1]<<16)|(vram[count+2]<<8)|(vram[count+3]<<0));
- r = (pen & 0x0000ff);
- g = (pen & 0x00ff00) >> 8;
- b = (pen & 0xff0000) >> 16;
-
- bitmap.pix32(y+y_start, x+x_start) = b | g << 8 | r << 16;
-
- count+=4;
- }
- }
- }
- break;
- #endif
- default:
- fatalerror("VIDC20 %08x BPP mode not supported\n",m_vidc20_bpp_mode);
- break;
- }
-
- return 0;
-}
-
-/*
-*
-* IOMD / ARM7500 / ARM7500FE chip emulation
-*
-*/
-
-/* TODO: some of these registers are actually ARM7500 specific */
-static const char *const iomd_regnames[] =
-{
- "I/O Control", // 0x000 IOCR
- "Keyboard Data", // 0x004 KBDDAT
- "Keyboard Control", // 0x008 KBDCR
- "General Purpose I/O Lines", // 0x00c IOLINES
- "IRQA Status", // 0x010 IRQSTA
- "IRQA Request/clear", // 0x014 IRQRQA
- "IRQA Mask", // 0x018 IRQMSKA
- "Enter SUSPEND Mode", // 0x01c SUSMODE
- "IRQB Status", // 0x020 IRQSTB
- "IRQB Request/clear", // 0x024 IRQRQB
- "IRQB Mask", // 0x028 IRQMSKB
- "Enter STOP Mode", // 0x02c STOPMODE
- "FIQ Status", // 0x030 FIQST
- "FIQ Request/clear", // 0x034 FIQRQ
- "FIQ Mask", // 0x038 FIQMSK
- "Clock divider control", // 0x03c CLKCTL
- "Timer 0 Low Bits", // 0x040 T0LOW
- "Timer 0 High Bits", // 0x044 T0HIGH
- "Timer 0 Go Command", // 0x048 T0GO
- "Timer 0 Latch Command", // 0x04c T0LATCH
- "Timer 1 Low Bits", // 0x050 T1LOW
- "Timer 1 High Bits", // 0x054 T1HIGH
- "Timer 1 Go Command", // 0x058 T1GO
- "Timer 1 Latch Command", // 0x05c T1LATCH
- "IRQC Status", // 0x060 IRQSTC
- "IRQC Request/clear", // 0x064 IRQRQC
- "IRQC Mask", // 0x068 IRQMSKC
- "LCD and IIS Control Bits", // 0x06c VIDIMUX
- "IRQD Status", // 0x070 IRQSTD
- "IRQD Request/clear", // 0x074 IRQRQD
- "IRQD Mask", // 0x078 IRQMSKD
- "<RESERVED>", // 0x07c
- "ROM Control Bank 0", // 0x080 ROMCR0
- "ROM Control Bank 1", // 0x084 ROMCR1
- "DRAM Control (IOMD)", // 0x088 DRAMCR
- "VRAM and Refresh Control", // 0x08c VREFCR
- "Flyback Line Size", // 0x090 FSIZE
- "Chip ID no. Low Byte", // 0x094 ID0
- "Chip ID no. High Byte", // 0x098 ID1
- "Chip Version Number", // 0x09c VERSION
- "Mouse X Position", // 0x0a0 MOUSEX
- "Mouse Y Position", // 0x0a4 MOUSEY
- "Mouse Data", // 0x0a8 MSEDAT
- "Mouse Control", // 0x0ac MSECR
- "<RESERVED>", // 0x0b0
- "<RESERVED>", // 0x0b4
- "<RESERVED>", // 0x0b8
- "<RESERVED>", // 0x0bc
- "DACK Timing Control", // 0x0c0 DMATCR
- "I/O Timing Control", // 0x0c4 IOTCR
- "Expansion Card Timing", // 0x0c8 ECTCR
- "DMA External Control", // 0x0cc DMAEXT (IOMD) / ASTCR (ARM7500)
- "DRAM Width Control", // 0x0d0 DRAMWID
- "Force CAS/RAS Lines Low", // 0x0d4 SELFREF
- "<RESERVED>", // 0x0d8
- "<RESERVED>", // 0x0dc
- "A to D IRQ Control", // 0x0e0 ATODICR
- "A to D IRQ Status", // 0x0e4 ATODCC
- "A to D IRQ Converter Control", // 0x0e8 ATODICR
- "A to D IRQ Counter 1", // 0x0ec ATODCNT1
- "A to D IRQ Counter 2", // 0x0f0 ATODCNT2
- "A to D IRQ Counter 3", // 0x0f4 ATODCNT3
- "A to D IRQ Counter 4", // 0x0f8 ATODCNT4
- "<RESERVED>", // 0x0fc
- "I/O DMA 0 CurA", // 0x100 IO0CURA
- "I/O DMA 0 EndA", // 0x104 IO0ENDA
- "I/O DMA 0 CurB", // 0x108 IO0CURB
- "I/O DMA 0 EndB", // 0x10c IO0ENDB
- "I/O DMA 0 Control", // 0x110 IO0CR
- "I/O DMA 0 Status", // 0x114 IO0ST
- "<RESERVED>", // 0x118
- "<RESERVED>", // 0x11c
- "I/O DMA 1 CurA", // 0x120 IO1CURA
- "I/O DMA 1 EndA", // 0x124 IO1ENDA
- "I/O DMA 1 CurB", // 0x128 IO1CURB
- "I/O DMA 1 EndB", // 0x12c IO1ENDB
- "I/O DMA 1 Control", // 0x130 IO1CR
- "I/O DMA 1 Status", // 0x134 IO1ST
- "<RESERVED>", // 0x138
- "<RESERVED>", // 0x13c
- "I/O DMA 2 CurA", // 0x140 IO2CURA
- "I/O DMA 2 EndA", // 0x144 IO2ENDA
- "I/O DMA 2 CurB", // 0x148 IO2CURB
- "I/O DMA 2 EndB", // 0x14c IO2ENDB
- "I/O DMA 2 Control", // 0x150 IO2CR
- "I/O DMA 2 Status", // 0x154 IO2ST
- "<RESERVED>", // 0x158
- "<RESERVED>", // 0x15c
- "I/O DMA 3 CurA", // 0x160 IO3CURA
- "I/O DMA 3 EndA", // 0x164 IO3ENDA
- "I/O DMA 3 CurB", // 0x168 IO3CURB
- "I/O DMA 3 EndB", // 0x16c IO3ENDB
- "I/O DMA 3 Control", // 0x170 IO3CR
- "I/O DMA 3 Status", // 0x174 IO3ST
- "<RESERVED>", // 0x178
- "<RESERVED>", // 0x17c
- "Sound DMA 0 CurA", // 0x180 SD0CURA
- "Sound DMA 0 EndA", // 0x184 SD0ENDA
- "Sound DMA 0 CurB", // 0x188 SD0CURB
- "Sound DMA 0 EndB", // 0x18c SD0ENDB
- "Sound DMA 0 Control", // 0x190 SD0CR
- "Sound DMA 0 Status", // 0x194 SD0ST
- "<RESERVED>", // 0x198
- "<RESERVED>", // 0x19c
- "Sound DMA 1 CurA", // 0x1a0 SD1CURA
- "Sound DMA 1 EndA", // 0x1a4 SD1ENDA
- "Sound DMA 1 CurB", // 0x1a8 SD1CURB
- "Sound DMA 1 EndB", // 0x1ac SD1ENDB
- "Sound DMA 1 Control", // 0x1b0 SD1CR
- "Sound DMA 1 Status", // 0x1b4 SD1ST
- "<RESERVED>", // 0x1b8
- "<RESERVED>", // 0x1bc
- "Cursor DMA Current", // 0x1c0 CURSCUR
- "Cursor DMA Init", // 0x1c4 CURSINIT
- "Duplex LCD Current B", // 0x1c8 VIDCURB
- "<RESERVED>", // 0x1cc
- "Video DMA Current", // 0x1d0 VIDCUR
- "Video DMA End", // 0x1d4 VIDEND
- "Video DMA Start", // 0x1d8 VIDSTART
- "Video DMA Init", // 0x1dc VIDINIT
- "Video DMA Control", // 0x1e0 VIDCR
- "<RESERVED>", // 0x1e4
- "Duplex LCD Init B", // 0x1e8 VIDINITB
- "<RESERVED>", // 0x1ec
- "DMA IRQ Status", // 0x1f0 DMAST
- "DMA IRQ Request", // 0x1f4 DMARQ
- "DMA IRQ Mask", // 0x1f8 DMAMSK
- "<RESERVED>" // 0x1fc
+
+ bool m_i2cmem_clock;
+ DECLARE_READ_LINE_MEMBER(iocr_od0_r);
+ DECLARE_READ_LINE_MEMBER(iocr_od1_r);
+ DECLARE_WRITE_LINE_MEMBER(iocr_od0_w);
+ DECLARE_WRITE_LINE_MEMBER(iocr_od1_w);
};
-#define IOMD_IOCR 0x000/4
-#define IOMD_KBDDAT 0x004/4
-#define IOMD_KBDCR 0x008/4
-
-#define IOMD_IRQSTA 0x010/4
-#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
-#define IOMD_T0LATCH 0x04c/4
-
-#define IOMD_T1LOW 0x050/4
-#define IOMD_T1HIGH 0x054/4
-#define IOMD_T1GO 0x058/4
-#define IOMD_T1LATCH 0x05c/4
-
-#define IOMD_ID0 0x094/4
-#define IOMD_ID1 0x098/4
-#define IOMD_VERSION 0x09c/4
-
-#define IOMD_VIDCUR 0x1d0/4
-#define IOMD_VIDEND 0x1d4/4
-#define IOMD_VIDSTART 0x1d8/4
-#define IOMD_VIDINIT 0x1dc/4
-#define IOMD_VIDCR 0x1e0/4
-
-#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)
+READ_LINE_MEMBER(riscpc_state::iocr_od1_r)
{
- int timer_count = m_timer_counter[timer];
- int val = timer_count / 2; // correct?
-
- if(val==0)
- m_IOMD_timer[timer]->adjust(attotime::never);
- else
- m_IOMD_timer[timer]->adjust(attotime::from_usec(val), 0, attotime::from_usec(val));
+ // TODO: presuming same as Acorn Archimedes, where i2c clock can be readback
+ return (m_i2cmem_clock == true) ? 1 : 0;
}
-TIMER_CALLBACK_MEMBER(riscpc_state::IOMD_timer0_callback)
+READ_LINE_MEMBER(riscpc_state::iocr_od0_r)
{
- m_IRQ_status_A|=0x20;
- update_irq();
-}
-
-TIMER_CALLBACK_MEMBER(riscpc_state::IOMD_timer1_callback)
-{
- m_IRQ_status_A|=0x40;
- update_irq();
-}
-
-TIMER_CALLBACK_MEMBER(riscpc_state::flyback_timer_callback)
-{
- m_IRQ_status_A|=0x08;
- update_irq();
-
- // for convenience lets just implement the video DMA transfer here
- // the actual transfer probably works per scanline once enabled.
- if(m_viddma_status & 0x20)
- viddma_transfer_start();
-
- m_flyback_timer->adjust(m_screen->time_until_pos(m_vidc20_vert_reg[VDER]));
+ return (m_i2cmem->read_sda() ? 1 : 0); //eeprom read
}
-void riscpc_state::viddma_transfer_start()
+WRITE_LINE_MEMBER(riscpc_state::iocr_od0_w)
{
- address_space &mem = m_maincpu->space(AS_PROGRAM);
- uint32_t src = m_viddma_addr_init;
- uint32_t dst = 0;
- uint32_t size = m_viddma_addr_end;
- uint32_t dma_index;
-
- /* TODO: this should actually be a qword transfer */
- for(dma_index = 0;dma_index < size;dma_index+=4)
- {
- m_vram[dst] = mem.read_dword(src);
-
- src+=4;
- // TODO: honor boundary
- dst++;
- }
-}
-
-READ32_MEMBER( riscpc_state::a7000_iomd_r )
-{
-// if(offset != IOMD_KBDCR)
-// logerror("IOMD: %s Register (%04x) read\n",iomd_regnames[offset & (0x1ff >> 2)],offset*4);
-
-
- switch(offset)
- {
- case IOMD_IOCR:
- {
- uint8_t flyback;
- int vert_pos;
-
- vert_pos = m_screen->vpos();
- flyback = (vert_pos <= m_vidc20_vert_reg[VDSR] || vert_pos >= m_vidc20_vert_reg[VDER]) ? 0x80 : 0x00;
-
- return flyback | (m_IOMD_IO_ctrl & 0x7c) | 0x34 | (m_i2c_clk << 1) | (m_i2cmem->read_sda() ? 1 : 0);
- }
- case IOMD_KBDDAT: return m_kbdc->data_r();
- case IOMD_KBDCR: return m_kbdc->status_r();
-
- /*
- 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 & 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;
-
- case IOMD_T1LOW: return m_timer_out[1] & 0xff;
- case IOMD_T1HIGH: return (m_timer_out[1] >> 8) & 0xff;
-
- case IOMD_ID0: return m_io_id & 0xff; // IOMD ID low
- case IOMD_ID1: return (m_io_id >> 8) & 0xff; // IOMD ID high
- case IOMD_VERSION: return 0;
-
- 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 & 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;
- }
-
- return 0;
+ m_i2cmem->write_sda(state == true ? 1 : 0);
}
-WRITE32_MEMBER( riscpc_state::a7000_iomd_w )
+WRITE_LINE_MEMBER(riscpc_state::iocr_od1_w)
{
-// logerror("IOMD: %s Register (%04x) write = %08x\n",iomd_regnames[offset & (0x1ff >> 2)],offset*4,data);
-
- switch(offset)
- {
- 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_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;
- 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;
- case IOMD_T0GO:
- m_timer_counter[0] = m_timer_in[0];
- fire_iomd_timer(0);
- break;
- case IOMD_T0LATCH:
- {
- m_t0readinc^=1;
- m_timer_out[0] = m_timer_counter[0];
- if(m_t0readinc)
- {
- m_timer_counter[0]--;
- if(m_timer_counter[0] < 0)
- m_timer_counter[0]+= m_timer_in[0];
- }
- }
- break;
-
- case IOMD_T1LOW: m_timer_in[1] = (m_timer_in[1] & 0xff00) | (data & 0xff); break;
- case IOMD_T1HIGH: m_timer_in[1] = (m_timer_in[1] & 0x00ff) | ((data & 0xff) << 8); break;
- case IOMD_T1GO:
- m_timer_counter[1] = m_timer_in[1];
- fire_iomd_timer(1);
- break;
- case IOMD_T1LATCH:
- {
- m_t1readinc^=1;
- m_timer_out[1] = m_timer_counter[1];
- if(m_t1readinc)
- {
- m_timer_counter[1]--;
- if(m_timer_counter[1] < 0)
- m_timer_counter[1]+= m_timer_in[1];
- }
- }
- break;
-
- case IOMD_VIDEND: m_viddma_addr_end = data & 0x00fffff8; //bits 31:24 unused
- break;
- case IOMD_VIDSTART: m_viddma_addr_start = data & 0x1ffffff8; //bits 31, 30, 29 unused
- break;
- case IOMD_VIDINIT: m_viddma_addr_init = data & 0x1ffffff8;
- break;
- case IOMD_VIDCR:
- m_viddma_status = data & 0xa0; if(data & 0x20) { viddma_transfer_start(); }
- break;
-
-
- default: logerror("IOMD: %s Register (%04x) write = %08x\n",iomd_regnames[offset & (0x1ff >> 2)],offset*4,data);
- }
+ m_i2cmem_clock = state;
+ m_i2cmem->write_scl(state == true ? 1 : 0);
}
void riscpc_state::a7000_map(address_map &map)
@@ -850,16 +104,17 @@ void riscpc_state::a7000_map(address_map &map)
//
// map(0x02000000, 0x027fffff).mirror(0x00800000).ram(); // VRAM, not installed on A7000 models
// I/O 03000000 - 033fffff
-// map(0x03010000, 0x03011fff) //Super IO
-// map(0x03012000, 0x03029fff) //FDC
-// map(0x0302b000, 0x0302bfff) //Network podule
-// map(0x03040000, 0x0304ffff) //podule space 0,1,2,3
-// map(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(0x03010000, 0x03011fff) //Super IO
+// AM_RANGE(0x03012000, 0x03029fff) //FDC
+// AM_RANGE(0x0302b000, 0x0302bfff) //Network podule
+// AM_RANGE(0x03040000, 0x0304ffff) //podule space 0,1,2,3
+// AM_RANGE(0x03070000, 0x0307ffff) //podule space 4,5,6,7
+ map(0x03200000, 0x032001ff).m(m_iomd, FUNC(arm7500fe_iomd_device::map));
map(0x03310000, 0x03310003).portr("MOUSE");
- map(0x03400000, 0x037fffff).w(FUNC(riscpc_state::a7000_vidc20_w));
-// map(0x08000000, 0x08ffffff).mirror(0x07000000); //EASI space
+ map(0x03400000, 0x037fffff).w(m_vidc, FUNC(arm_vidc20_device::write));
+// AM_RANGE(0x08000000, 0x08ffffff) AM_MIRROR(0x07000000) //EASI space
+
map(0x10000000, 0x13ffffff).ram(); //SIMM 0 bank 0
map(0x14000000, 0x17ffffff).ram(); //SIMM 0 bank 1
// map(0x18000000, 0x18ffffff).mirror(0x03000000).ram(); //SIMM 1 bank 0
@@ -898,44 +153,14 @@ INPUT_PORTS_END
void riscpc_state::machine_start()
{
- m_IOMD_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(riscpc_state::IOMD_timer0_callback),this));
- m_IOMD_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(riscpc_state::IOMD_timer1_callback),this));
- m_flyback_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(riscpc_state::flyback_timer_callback),this));
-
- m_io_id = 0xd4e7;
+ // ...
}
void riscpc_state::machine_reset()
{
- 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);
}
-WRITE_LINE_MEMBER(riscpc_state::keyboard_reset)
-{
- 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);
@@ -958,67 +183,95 @@ void riscpc_state::base_config(machine_config &config)
// 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->hot_res().set(m_iomd, FUNC(arm_iomd_device::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->kbd_irq().set(m_iomd, FUNC(arm_iomd_device::keyboard_irq));
// 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);
- 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);
+
+ ARM_VIDC20(config, m_vidc, 24_MHz_XTAL);
+ m_vidc->set_screen("screen");
+ m_vidc->vblank().set(m_iomd, FUNC(arm_iomd_device::vblank_irq));
+ m_vidc->sound_drq().set(m_iomd, FUNC(arm_iomd_device::sound_drq));
+
+ m_iomd->set_host_cpu_tag(m_maincpu);
+ m_iomd->set_vidc_tag(m_vidc);
+ m_iomd->set_kbdc_tag(m_kbdc);
+ m_iomd->iocr_read_od<0>().set(FUNC(riscpc_state::iocr_od0_r));
+ m_iomd->iocr_read_od<1>().set(FUNC(riscpc_state::iocr_od1_r));
+ m_iomd->iocr_write_od<0>().set(FUNC(riscpc_state::iocr_od0_w));
+ m_iomd->iocr_write_od<1>().set(FUNC(riscpc_state::iocr_od1_w));
}
void riscpc_state::rpc600(machine_config &config)
{
- /* Basic machine hardware */
- ARM7(config, m_maincpu, 60_MHz_XTAL/2); // ARM610
+ constexpr XTAL cpuxtal(60_MHz_XTAL/2);
+
+ ARM7(config, m_maincpu, cpuxtal); // really ARM610
m_maincpu->set_addrmap(AS_PROGRAM, &riscpc_state::riscpc_map);
+
+ ARM7500FE_IOMD(config, m_iomd, cpuxtal);
base_config(config);
}
void riscpc_state::rpc700(machine_config &config)
{
- /* Basic machine hardware */
- ARM710A(config, m_maincpu, 80_MHz_XTAL/2); // ARM710
+ constexpr XTAL cpuxtal(80_MHz_XTAL/2);
+ ARM710A(config, m_maincpu, cpuxtal);
m_maincpu->set_addrmap(AS_PROGRAM, &riscpc_state::riscpc_map);
+
+ ARM7500FE_IOMD(config, m_iomd, cpuxtal);
base_config(config);
}
void riscpc_state::a7000(machine_config &config)
{
- /* Basic machine hardware */
- ARM7(config, m_maincpu, XTAL(32'000'000)); // ARM7500
+ constexpr XTAL cpuxtal(32'000'000);
+
+ ARM7500(config, m_maincpu, cpuxtal);
m_maincpu->set_addrmap(AS_PROGRAM, &riscpc_state::a7000_map);
+
+ ARM7500FE_IOMD(config, m_iomd, cpuxtal);
base_config(config);
}
void riscpc_state::a7000p(machine_config &config)
{
- a7000(config);
- m_maincpu->set_clock(XTAL(48'000'000)); // ARM7500FE
+ constexpr XTAL cpuxtal(48'000'000);
+
+ ARM7500(config, m_maincpu, cpuxtal); // really ARM7500FE
+ m_maincpu->set_addrmap(AS_PROGRAM, &riscpc_state::a7000_map);
+
+ ARM7500FE_IOMD(config, m_iomd, cpuxtal);
+ base_config(config);
}
void riscpc_state::sarpc(machine_config &config)
{
- /* Basic machine hardware */
- SA1110(config, m_maincpu, 202000000); // StrongARM
+ // TODO: ranges from 160 to 233 MHz
+ constexpr XTAL cpuxtal(200'000'000);
+
+ SA1110(config, m_maincpu, cpuxtal); // StrongARM
m_maincpu->set_addrmap(AS_PROGRAM, &riscpc_state::riscpc_map);
+
+ ARM7500FE_IOMD(config, m_iomd, cpuxtal);
base_config(config);
}
void riscpc_state::sarpc_j233(machine_config &config)
{
- /* Basic machine hardware */
- SA1110(config, m_maincpu, 233000000); // StrongARM
+ // TODO: 233 MHz, unsupported by xtal module
+ constexpr XTAL cpuxtal(200'000'000);
+
+ SA1110(config, m_maincpu, cpuxtal); // StrongARM
m_maincpu->set_addrmap(AS_PROGRAM, &riscpc_state::riscpc_map);
+
+ ARM7500FE_IOMD(config, m_iomd, cpuxtal);
base_config(config);
}