summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--.gitattributes2
-rw-r--r--src/mame/drivers/aristmk5.c61
-rw-r--r--src/mame/includes/archimds.h60
-rw-r--r--src/mame/machine/archimds.c689
-rw-r--r--src/mame/mame.mak5
5 files changed, 807 insertions, 10 deletions
diff --git a/.gitattributes b/.gitattributes
index 6806d730fc6..22141a2f04f 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2209,6 +2209,7 @@ src/mame/includes/appoooh.h svneol=native#text/plain
src/mame/includes/aquarium.h svneol=native#text/plain
src/mame/includes/arabian.h svneol=native#text/plain
src/mame/includes/arcadecl.h svneol=native#text/plain
+src/mame/includes/archimds.h svneol=native#text/plain
src/mame/includes/argus.h svneol=native#text/plain
src/mame/includes/arkanoid.h svneol=native#text/plain
src/mame/includes/armedf.h svneol=native#text/plain
@@ -2599,6 +2600,7 @@ src/mame/layout/videopkr.lay svneol=native#text/plain
src/mame/machine/acitya.c svneol=native#text/plain
src/mame/machine/ajax.c svneol=native#text/plain
src/mame/machine/amiga.c svneol=native#text/plain
+src/mame/machine/archimds.c svneol=native#text/plain
src/mame/machine/arkanoid.c svneol=native#text/plain
src/mame/machine/asic65.c svneol=native#text/plain
src/mame/machine/asic65.h svneol=native#text/plain
diff --git a/src/mame/drivers/aristmk5.c b/src/mame/drivers/aristmk5.c
index a6100bc39ca..0267945aa7b 100644
--- a/src/mame/drivers/aristmk5.c
+++ b/src/mame/drivers/aristmk5.c
@@ -4,16 +4,36 @@
possibly 'Acorn Archimedes on a chip' hardware
-- is it missing a bios rom?
-
+
+ Archimedes computer memory map
+ 0000000 - 1FFFFFF - logical RAM (32 meg)
+ 2000000 - 2FFFFFF - physical RAM (supervisor only - max 16MB - requires quad MEMCs)
+ 3000000 - 33FFFFF - IOC (IO controllers - supervisor only)
+ 3270000 - 33FFFFF - external I/O
+ 3350010 - printer (parallel port)
+ 3350018 - latch A
+ 3350040 - latch B
+
+ 3400000 - 37FFFFF - Low ROM (expansion ROM)
+ 3800000 - 3FFFFFF - High ROM (main ROM)
+
+ 3400000 - 35FFFFF - VICD10 (write - supervisor only)
+ 3600000 - 3FFFFFF - MEMC (write - supervisor only)
+
*/
#include "driver.h"
#include "cpu/arm/arm.h"
-
+#include "sound/dac.h"
+#include "includes/archimds.h"
static ADDRESS_MAP_START( aristmk5_map, ADDRESS_SPACE_PROGRAM, 32 )
- AM_RANGE(0x00000000, 0x001fffff) AM_ROM
- AM_RANGE(0x01600000, 0x017fffff) AM_ROM AM_REGION("main", 0) // rom here, or a missing bios here?
+ AM_RANGE(0x00000000, 0x01ffffff) AM_READWRITE(memc_logical_r, memc_logical_w)
+ AM_RANGE(0x02000000, 0x02ffffff) AM_RAM AM_BASE(&memc_physmem) /* physical RAM - 16 MB for now, should be 512k for the A310 */
+ AM_RANGE(0x03000000, 0x033fffff) AM_READWRITE(ioc_r, ioc_w)
+ AM_RANGE(0x03400000, 0x035fffff) AM_READWRITE(vidc_r, vidc_w)
+ AM_RANGE(0x03600000, 0x037fffff) AM_READWRITE(memc_r, memc_w)
+ AM_RANGE(0x03800000, 0x03ffffff) AM_ROM AM_REGION("main", 0) AM_WRITE(memc_page_w)
ADDRESS_MAP_END
@@ -30,10 +50,31 @@ VIDEO_UPDATE(aristmk5)
return 0;
}
+static DRIVER_INIT( aristmk5 )
+{
+ archimedes_driver_init(machine);
+}
+
+static MACHINE_START( aristmk5 )
+{
+ archimedes_init(machine);
+
+ // reset the DAC to centerline
+ dac_signed_data_w(0, 0x80);
+}
+
+static MACHINE_RESET( aristmk5 )
+{
+ archimedes_reset(machine);
+}
+
static MACHINE_DRIVER_START( aristmk5 )
MDRV_CPU_ADD("main", ARM, 10000000) // ?
MDRV_CPU_PROGRAM_MAP(aristmk5_map,0)
+ MDRV_MACHINE_RESET( aristmk5 )
+ MDRV_MACHINE_START( aristmk5 )
+
MDRV_SCREEN_ADD("main", RASTER)
MDRV_SCREEN_REFRESH_RATE(60)
MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
@@ -45,10 +86,14 @@ static MACHINE_DRIVER_START( aristmk5 )
MDRV_VIDEO_START(aristmk5)
MDRV_VIDEO_UPDATE(aristmk5)
+
+ MDRV_SPEAKER_STANDARD_MONO("aristmk5")
+ MDRV_SOUND_ADD("dac", DAC, 0)
+ MDRV_SOUND_ROUTE(0, "aristmk5", 1.00)
MACHINE_DRIVER_END
ROM_START( reelrock )
- ROM_REGION( 0x200000, "main", 0 ) /* ARM Code */
+ ROM_REGION( 0x800000, "main", 0 ) /* ARM Code */
ROM_LOAD16_BYTE( "reelrock.u7", 0x000000, 0x80000, CRC(b60af34f) SHA1(1143380b765db234b3871c0fe04736472fde7de4) )
ROM_LOAD16_BYTE( "reelrock.u11", 0x000001, 0x80000, CRC(57e341d0) SHA1(9b0d50763bb74ca5fe404c9cd526633721cf6677) )
ROM_LOAD16_BYTE( "reelrock.u8", 0x100000, 0x80000, CRC(57eec667) SHA1(5f3888d75f48b6148f451d7ebb7f99e1a0939f3c) )
@@ -56,12 +101,12 @@ ROM_START( reelrock )
ROM_END
ROM_START( indiandr )
- ROM_REGION( 0x200000, "main", 0 ) /* ARM Code */
+ ROM_REGION( 0x800000, "main", 0 ) /* ARM Code */
ROM_LOAD16_BYTE( "indiandr.u7", 0x000000, 0x80000, CRC(0c924a3e) SHA1(499b4ae601e53173e3ba5f400a40e5ae7bbaa043) )
ROM_LOAD16_BYTE( "indiandr.u11", 0x000001, 0x80000, CRC(e371dc0f) SHA1(a01ab7fb63a19c144f2c465ecdfc042695124bdf) )
ROM_LOAD16_BYTE( "indiandr.u8", 0x100000, 0x80000, CRC(1c6bfb47) SHA1(7f751cb499a6185a0ab64eeec511583ceeee6ee8) )
ROM_LOAD16_BYTE( "indiandr.u12", 0x100001, 0x80000, CRC(4bbe67f6) SHA1(928f88387da66697f1de54f086531f600f80a15e) )
ROM_END
-GAME( 1998, reelrock, 0, aristmk5, aristmk5, 0, ROT0, "Aristocrat", "Reelin-n-Rockin (A - 13/07/98)", GAME_NOT_WORKING|GAME_NO_SOUND )
-GAME( 1998, indiandr, 0, aristmk5, aristmk5, 0, ROT0, "Aristocrat", "Indian Dreaming (B - 15/12/98)", GAME_NOT_WORKING|GAME_NO_SOUND )
+GAME( 1998, reelrock, 0, aristmk5, aristmk5, aristmk5, ROT0, "Aristocrat", "Reelin-n-Rockin (A - 13/07/98)", GAME_NOT_WORKING|GAME_NO_SOUND )
+GAME( 1998, indiandr, 0, aristmk5, aristmk5, aristmk5, ROT0, "Aristocrat", "Indian Dreaming (B - 15/12/98)", GAME_NOT_WORKING|GAME_NO_SOUND )
diff --git a/src/mame/includes/archimds.h b/src/mame/includes/archimds.h
new file mode 100644
index 00000000000..d51d505622d
--- /dev/null
+++ b/src/mame/includes/archimds.h
@@ -0,0 +1,60 @@
+/******************************************************************************
+ *
+ * Acorn Archimedes custom chips (IOC, MEMC, VIDC)
+ *
+ *****************************************************************************/
+
+#ifndef _ARCHIMEDES_H_
+#define _ARCHIMEDES_H_
+
+// interrupt definitions. these are for the real Archimedes computer - arcade
+// and gambling knockoffs likely are a bit different.
+
+#define ARCHIMEDES_IRQA_PRINTER_BUSY (0x01)
+#define ARCHIMEDES_IRQA_SERIAL_RING (0x02)
+#define ARCHIMEDES_IRQA_PRINTER_ACK (0x04)
+#define ARCHIMEDES_IRQA_VBL (0x08)
+#define ARCHIMEDES_IRQA_RESET (0x10)
+#define ARCHIMEDES_IRQA_TIMER0 (0x20)
+#define ARCHIMEDES_IRQA_TIMER1 (0x40)
+#define ARCHIMEDES_IRQA_ALWAYS (0x80)
+
+#define ARCHIMEDES_IRQB_PODULE_FIQ (0x01)
+#define ARCHIMEDES_IRQB_SOUND_EMPTY (0x02)
+#define ARCHIMEDES_IRQB_SERIAL (0x04)
+#define ARCHIMEDES_IRQB_HDD (0x08)
+#define ARCHIMEDES_IRQB_DISC_CHANGE (0x10)
+#define ARCHIMEDES_IRQB_PODULE_IRQ (0x20)
+#define ARCHIMEDES_IRQB_KBD_XMIT_EMPTY (0x40)
+#define ARCHIMEDES_IRQB_KBD_RECV_FULL (0x80)
+
+#define ARCHIMEDES_FIQ_FLOPPY_DRQ (0x01)
+#define ARCHIMEDES_FIQ_FLOPPY (0x02)
+#define ARCHIMEDES_FIQ_ECONET (0x04)
+#define ARCHIMEDES_FIQ_PODULE (0x40)
+#define ARCHIMEDES_FIQ_FORCE (0x80)
+
+extern UINT32 *memc_physmem;
+
+void archimedes_init(running_machine *machine); // call at MACHINE_INIT
+void archimedes_reset(running_machine *machine); // call at MACHINE_RESET
+void archimedes_driver_init(running_machine *machine); // call at DRIVER_INIT
+
+void archimedes_request_irq_a(running_machine *machine, int mask);
+void archimedes_request_irq_b(running_machine *machine, int mask);
+void archimedes_request_fiq(running_machine *machine, int mask);
+void archimedes_clear_irq_a(running_machine *machine, int mask);
+void archimedes_clear_irq_b(running_machine *machine, int mask);
+void archimedes_clear_fiq(running_machine *machine, int mask);
+
+extern READ32_HANDLER(memc_logical_r);
+extern WRITE32_HANDLER(memc_logical_w);
+extern READ32_HANDLER(memc_r);
+extern WRITE32_HANDLER(memc_w);
+extern WRITE32_HANDLER(memc_page_w);
+extern READ32_HANDLER(ioc_r);
+extern WRITE32_HANDLER(ioc_w);
+extern READ32_HANDLER(vidc_r);
+extern WRITE32_HANDLER(vidc_w);
+
+#endif // _ARCHIMEDES_H_
diff --git a/src/mame/machine/archimds.c b/src/mame/machine/archimds.c
new file mode 100644
index 00000000000..4fe1fb9b22a
--- /dev/null
+++ b/src/mame/machine/archimds.c
@@ -0,0 +1,689 @@
+/******************************************************************************
+ *
+ * Acorn Archimedes custom chips (IOC, MEMC, VIDC)
+ *
+ * Memory map (from http://b-em.bbcmicro.com/arculator/archdocs.txt)
+ *
+ * 0000000 - 1FFFFFF - logical RAM (32 meg)
+ * 2000000 - 2FFFFFF - physical RAM (supervisor only - max 16MB - requires quad MEMCs)
+ * 3000000 - 33FFFFF - IOC (IO controllers - supervisor only)
+ * 3310000 - FDC - WD1772
+ * 33A0000 - Econet - 6854
+ * 33B0000 - Serial - 6551
+ * 3240000 - 33FFFFF - internal expansion cards
+ * 32D0000 - hard disc controller (not IDE) - HD63463
+ * 3350010 - printer
+ * 3350018 - latch A
+ * 3350040 - latch B
+ * 3270000 - external expansion cards
+ *
+ * 3400000 - 3FFFFFF - ROM (read - 12 meg - Arthur and RiscOS 2 512k, RiscOS 3 2MB)
+ * 3400000 - 37FFFFF - Low ROM (4 meg, I think this is expansion ROMs)
+ * 3800000 - 3FFFFFF - High ROM (main OS ROM)
+ *
+ * 3400000 - 35FFFFF - VICD10 (write - supervisor only)
+ * 3600000 - 3FFFFFF - MEMC (write - supervisor only)
+ *
+ *****************************************************************************/
+
+#include "driver.h"
+#include "cpu/arm/arm.h"
+#include "sound/dac.h"
+#include "includes/archimds.h"
+
+#ifdef MESS
+#include "machine/wd17xx.h"
+#endif
+
+static const int page_sizes[4] = { 4096, 8192, 16384, 32768 };
+
+UINT32 *memc_physmem;
+static UINT32 memc_pagesize;
+static int memc_latchrom;
+static INT16 memc_pages[(32*1024*1024)/(4096)]; // the logical RAM area is 32 megs, and the smallest page size is 4k
+static UINT32 vidc_regs[256];
+static UINT8 ioc_regs[0x80/4];
+static UINT32 ioc_timercnt[4], ioc_timerout[4];
+static UINT32 vidc_sndstart, vidc_sndend, vidc_sndcur;
+
+static emu_timer *vbl_timer, *timer[4], *snd_timer;
+
+void archimedes_request_irq_a(running_machine *machine, int mask)
+{
+ ioc_regs[4] |= mask;
+
+ if (ioc_regs[6] & mask)
+ {
+ cpu_set_input_line(machine->cpu[0], ARM_IRQ_LINE, ASSERT_LINE);
+ }
+}
+
+void archimedes_request_irq_b(running_machine *machine, int mask)
+{
+ ioc_regs[8] |= mask;
+
+ if (ioc_regs[10] & mask)
+ {
+ cpu_set_input_line(machine->cpu[0], ARM_IRQ_LINE, PULSE_LINE);
+ }
+}
+
+void archimedes_request_fiq(running_machine *machine, int mask)
+{
+ ioc_regs[12] |= mask;
+
+ if (ioc_regs[14] & mask)
+ {
+ cpu_set_input_line(machine->cpu[0], ARM_FIRQ_LINE, PULSE_LINE);
+ }
+}
+
+void archimedes_clear_irq_a(running_machine *machine, int mask)
+{
+ ioc_regs[4] &= ~mask;
+}
+
+void archimedes_clear_irq_b(running_machine *machine, int mask)
+{
+ ioc_regs[8] &= ~mask;
+}
+
+void archimedes_clear_fiq(running_machine *machine, int mask)
+{
+ ioc_regs[12] &= ~mask;
+}
+
+static TIMER_CALLBACK( vidc_vblank )
+{
+ archimedes_request_irq_a(machine, ARCHIMEDES_IRQA_VBL);
+
+ // set up for next vbl
+ timer_adjust_oneshot(vbl_timer, video_screen_get_time_until_pos(machine->primary_screen, vidc_regs[0xb4], 0), 0);
+}
+
+static TIMER_CALLBACK( a310_audio_tick )
+{
+ vidc_sndcur++;
+
+ if (vidc_sndcur >= vidc_sndend)
+ {
+ archimedes_request_irq_b(machine, ARCHIMEDES_IRQB_SOUND_EMPTY);
+ }
+}
+
+static void a310_set_timer(int tmr)
+{
+ double freq = 2000000.0 / (double)ioc_timercnt[tmr];
+
+// logerror("IOC: starting timer %d, %d ticks, freq %f Hz\n", tmr, ioc_timercnt[tmr], freq);
+
+ timer_adjust_oneshot(timer[tmr], ATTOTIME_IN_HZ(freq), tmr);
+}
+
+// param
+static TIMER_CALLBACK( ioc_timer )
+{
+ // all timers always run
+ a310_set_timer(param);
+
+ // but only timers 0 and 1 generate IRQs
+ switch (param)
+ {
+ case 0:
+ archimedes_request_irq_a(machine, ARCHIMEDES_IRQA_TIMER0);
+ break;
+
+ case 1:
+ archimedes_request_irq_a(machine, ARCHIMEDES_IRQA_TIMER1);
+ break;
+ }
+}
+
+void archimedes_reset(running_machine *machine)
+{
+ int i;
+
+ memc_latchrom = 1; // map in the boot ROM
+
+ // kill all memc mappings
+ for (i = 0; i < (32*1024*1024)/(4096); i++)
+ {
+ memc_pages[i] = -1; // indicate unmapped
+ }
+}
+
+void archimedes_init(running_machine *machine)
+{
+ memc_pagesize = 0;
+
+ vbl_timer = timer_alloc(machine, vidc_vblank, NULL);
+ timer_adjust_oneshot(vbl_timer, attotime_never, 0);
+
+ timer[0] = timer_alloc(machine, ioc_timer, NULL);
+ timer[1] = timer_alloc(machine, ioc_timer, NULL);
+ timer[2] = timer_alloc(machine, ioc_timer, NULL);
+ timer[3] = timer_alloc(machine, ioc_timer, NULL);
+ timer_adjust_oneshot(timer[0], attotime_never, 0);
+ timer_adjust_oneshot(timer[1], attotime_never, 0);
+ timer_adjust_oneshot(timer[2], attotime_never, 0);
+ timer_adjust_oneshot(timer[3], attotime_never, 0);
+
+ snd_timer = timer_alloc(machine, a310_audio_tick, NULL);
+ timer_adjust_oneshot(snd_timer, attotime_never, 0);
+}
+
+READ32_HANDLER(memc_logical_r)
+{
+ UINT32 page, poffs;
+
+ // are we mapping in the boot ROM?
+ if (memc_latchrom)
+ {
+ UINT32 *rom;
+
+ rom = (UINT32 *)memory_region(space->machine, "main");
+
+ return rom[offset & 0x1fffff];
+ }
+ else
+ {
+ // figure out the page number and offset in the page
+ page = (offset<<2) / page_sizes[memc_pagesize];
+ poffs = (offset<<2) % page_sizes[memc_pagesize];
+
+// printf("Reading offset %x (addr %x): page %x (size %d %d) offset %x ==> %x %x\n", offset, offset<<2, page, memc_pagesize, page_sizes[memc_pagesize], poffs, memc_pages[page], memc_pages[page]*page_sizes[memc_pagesize]);
+
+ if (memc_pages[page] != -1)
+ {
+ return memc_physmem[((memc_pages[page] * page_sizes[memc_pagesize]) + poffs)>>2];
+ }
+ else
+ {
+ printf("ARCHIMEDES_MEMC: Reading unmapped page, what do we do?\n");
+ }
+ }
+
+ return 0;
+}
+
+WRITE32_HANDLER(memc_logical_w)
+{
+ UINT32 page, poffs;
+
+ // if the boot ROM is mapped, ignore writes
+ if (memc_latchrom)
+ {
+ return;
+ }
+ else
+ {
+ // figure out the page number and offset in the page
+ page = (offset<<2) / page_sizes[memc_pagesize];
+ poffs = (offset<<2) % page_sizes[memc_pagesize];
+
+// printf("Writing offset %x (addr %x): page %x (size %d %d) offset %x ==> %x %x\n", offset, offset<<2, page, memc_pagesize, page_sizes[memc_pagesize], poffs, memc_pages[page], memc_pages[page]*page_sizes[memc_pagesize]);
+
+ if (memc_pages[page] != -1)
+ {
+ COMBINE_DATA(&memc_physmem[((memc_pages[page] * page_sizes[memc_pagesize]) + poffs)>>2]);
+ }
+ else
+ {
+ printf("ARCHIMEDES_MEMC: Writing unmapped page, what do we do?\n");
+ }
+ }
+}
+
+static DIRECT_UPDATE_HANDLER( a310_setopbase )
+{
+ // if we're not in logical memory, MAME can do the right thing
+ if (address > 0x1ffffff)
+ {
+ return address;
+ }
+
+ // if the boot ROM is mapped in, do some trickery to make it show up
+ if (memc_latchrom)
+ {
+ direct->bytemask = 0x1fffff;
+ direct->bytestart = 0;
+ direct->byteend = 0x1fffff;
+ direct->raw = direct->decrypted = memory_region(space->machine, "main");
+ }
+ else // executing from logical memory
+ {
+ UINT32 page = address / page_sizes[memc_pagesize];
+
+ direct->bytemask = page_sizes[memc_pagesize]-1;
+ direct->bytestart = page * page_sizes[memc_pagesize];
+ direct->byteend = direct->bytestart + direct->bytemask;
+ direct->raw = direct->decrypted = (UINT8 *)&memc_physmem[(memc_pages[page] * page_sizes[memc_pagesize])>>2];
+ }
+
+ return ~0;
+}
+
+void archimedes_driver_init(running_machine *machine)
+{
+ memory_set_direct_update_handler( cpu_get_address_space( machine->cpu[0], ADDRESS_SPACE_PROGRAM ), a310_setopbase);
+}
+
+static const char *const ioc_regnames[] =
+{
+ "(rw) Control", // 0
+ "(read) Keyboard receive (write) keyboard send", // 1
+ "?",
+ "?",
+ "(read) IRQ status A", // 4
+ "(read) IRQ request A (write) IRQ clear", // 5
+ "(rw) IRQ mask A", // 6
+ "?",
+ "(read) IRQ status B", // 8
+ "(read) IRQ request B", // 9
+ "(rw) IRQ mask B", // 10
+ "?",
+ "(read) FIQ status", // 12
+ "(read) FIQ request", // 13
+ "(rw) FIQ mask", // 14
+ "?",
+ "(read) Timer 0 count low (write) Timer 0 latch low", // 16
+ "(read) Timer 0 count high (write) Timer 0 latch high", // 17
+ "(write) Timer 0 go command", // 18
+ "(write) Timer 0 latch command", // 19
+ "(read) Timer 1 count low (write) Timer 1 latch low", // 20
+ "(read) Timer 1 count high (write) Timer 1 latch high", // 21
+ "(write) Timer 1 go command", // 22
+ "(write) Timer 1 latch command", // 23
+ "(read) Timer 2 count low (write) Timer 2 latch low", // 24
+ "(read) Timer 2 count high (write) Timer 2 latch high", // 25
+ "(write) Timer 2 go command", // 26
+ "(write) Timer 2 latch command", // 27
+ "(read) Timer 3 count low (write) Timer 3 latch low", // 28
+ "(read) Timer 3 count high (write) Timer 3 latch high", // 29
+ "(write) Timer 3 go command", // 30
+ "(write) Timer 3 latch command" // 31
+};
+
+static void latch_timer_cnt(int tmr)
+{
+ double time = attotime_to_double(timer_timeelapsed(timer[tmr]));
+ time *= 2000000.0; // find out how many 2 MHz ticks have gone by
+ ioc_timerout[tmr] = ioc_timercnt[tmr] - (UINT32)time;
+}
+
+READ32_HANDLER(ioc_r)
+{
+ #ifdef MESS
+ device_config *fdc = (device_config*)devtag_get_device(space->machine, WD1772, "wd1772");
+ #endif
+ if (offset >= 0x80000 && offset < 0xc0000)
+ {
+ switch (offset & 0x1f)
+ {
+ case 1: // keyboard read
+ archimedes_request_irq_b(space->machine, ARCHIMEDES_IRQB_KBD_XMIT_EMPTY);
+ break;
+
+ case 16: // timer 0 read
+ return ioc_timerout[0]&0xff;
+ case 17:
+ return (ioc_timerout[0]>>8)&0xff;
+ case 20: // timer 1 read
+ return ioc_timerout[1]&0xff;
+ case 21:
+ return (ioc_timerout[1]>>8)&0xff;
+ case 24: // timer 2 read
+ return ioc_timerout[2]&0xff;
+ case 25:
+ return (ioc_timerout[2]>>8)&0xff;
+ case 28: // timer 3 read
+ return ioc_timerout[3]&0xff;
+ case 29:
+ return (ioc_timerout[3]>>8)&0xff;
+ }
+
+ logerror("IOC: R %s = %02x (PC=%x)\n", ioc_regnames[offset&0x1f], ioc_regs[offset&0x1f], cpu_get_pc( space->cpu ));
+ return ioc_regs[offset&0x1f];
+ }
+ #ifdef MESS
+ else if (offset >= 0xc4000 && offset <= 0xc4010)
+ {
+ logerror("17XX: R @ addr %x mask %08x\n", offset*4, mem_mask);
+ return wd17xx_data_r(fdc, offset&0xf);
+ }
+ #endif
+ else
+ {
+ logerror("IOC: R @ %x (mask %08x)\n", (offset*4)+0x3000000, mem_mask);
+ }
+
+
+ return 0;
+}
+
+WRITE32_HANDLER(ioc_w)
+{
+ #ifdef MESS
+ device_config *fdc = (device_config*)devtag_get_device(space->machine, WD1772, "wd1772");
+ #endif
+ if (offset >= 0x80000 && offset < 0xc0000)
+ {
+// logerror("IOC: W %02x @ reg %s (PC=%x)\n", data&0xff, ioc_regnames[offset&0x1f], cpu_get_pc( space->cpu ));
+
+ switch (offset&0x1f)
+ {
+ case 0: // I2C bus control
+ logerror("IOC I2C: CLK %d DAT %d\n", (data>>1)&1, data&1);
+ break;
+
+ case 5: // IRQ clear A
+ ioc_regs[4] &= ~(data&0xff);
+
+ // if that did it, clear the IRQ
+ if (ioc_regs[4] == 0)
+ {
+ cpu_set_input_line(space->machine->cpu[0], ARM_IRQ_LINE, CLEAR_LINE);
+ }
+ break;
+
+ case 16:
+ case 17:
+ ioc_regs[offset&0x1f] = data & 0xff;
+ break;
+
+ case 20:
+ case 21:
+ ioc_regs[offset&0x1f] = data & 0xff;
+ break;
+
+ case 24:
+ case 25:
+ ioc_regs[offset&0x1f] = data & 0xff;
+ break;
+
+ case 28:
+ case 29:
+ ioc_regs[offset&0x1f] = data & 0xff;
+ break;
+
+ case 19: // Timer 0 latch
+ latch_timer_cnt(0);
+ break;
+
+ case 23: // Timer 1 latch
+ latch_timer_cnt(1);
+ break;
+
+ case 27: // Timer 2 latch
+ latch_timer_cnt(2);
+ break;
+
+ case 31: // Timer 3 latch
+ latch_timer_cnt(3);
+ break;
+
+ case 18: // Timer 0 start
+ ioc_timercnt[0] = ioc_regs[17]<<8 | ioc_regs[16];
+ a310_set_timer(0);
+ break;
+
+ case 22: // Timer 1 start
+ ioc_timercnt[1] = ioc_regs[21]<<8 | ioc_regs[20];
+ a310_set_timer(1);
+ break;
+
+ case 26: // Timer 2 start
+ ioc_timercnt[2] = ioc_regs[25]<<8 | ioc_regs[24];
+ a310_set_timer(2);
+ break;
+
+ case 30: // Timer 3 start
+ ioc_timercnt[3] = ioc_regs[29]<<8 | ioc_regs[28];
+ a310_set_timer(3);
+ break;
+
+ default:
+ ioc_regs[offset&0x1f] = data & 0xff;
+ break;
+ }
+ }
+ #ifdef MESS
+ else if (offset >= 0xc4000 && offset <= 0xc4010)
+ {
+ logerror("17XX: %x to addr %x mask %08x\n", data, offset*4, mem_mask);
+ wd17xx_data_w(fdc, offset&0xf, data&0xff);
+ }
+ else if (offset == 0xd40006)
+ {
+ // latch A
+ if (data & 1)
+ {
+ wd17xx_set_drive(fdc,0);
+ }
+ if (data & 2)
+ {
+ wd17xx_set_drive(fdc,1);
+ }
+ if (data & 4)
+ {
+ wd17xx_set_drive(fdc,2);
+ }
+ if (data & 8)
+ {
+ wd17xx_set_drive(fdc,3);
+ }
+
+ wd17xx_set_side(fdc,(data & 0x10)>>4);
+
+ }
+ else if (offset == 0xd40010)
+ {
+ // latch B
+ wd17xx_set_density(fdc,(data & 2) ? DEN_MFM_LO : DEN_MFM_HI);
+ }
+ #endif
+ else
+ {
+ logerror("I/O: W %x @ %x (mask %08x)\n", data, (offset*4)+0x3000000, mem_mask);
+ }
+}
+
+READ32_HANDLER(vidc_r)
+{
+ return 0;
+}
+
+WRITE32_HANDLER(vidc_w)
+{
+ UINT32 reg = data>>24;
+ UINT32 val = data & 0xffffff;
+ #ifdef DEBUG
+ static const char *const vrnames[] =
+ {
+ "horizontal total",
+ "horizontal sync width",
+ "horizontal border start",
+ "horizontal display start",
+ "horizontal display end",
+ "horizontal border end",
+ "horizontal cursor start",
+ "horizontal interlace",
+ "vertical total",
+ "vertical sync width",
+ "vertical border start",
+ "vertical display start",
+ "vertical display end",
+ "vertical border end",
+ "vertical cursor start",
+ "vertical cursor end",
+ };
+ #endif
+
+ if (reg >= 0x80 && reg <= 0xbc)
+ {
+ #ifdef DEBUG
+ logerror("VIDC: %s = %d\n", vrnames[(reg-0x80)/4], val>>12);
+ #endif
+
+ if ((reg == 0xb0) & ((val>>12) != 0))
+ {
+ rectangle visarea;
+
+ visarea.min_x = 0;
+ visarea.min_y = 0;
+ visarea.max_x = vidc_regs[0x94] - vidc_regs[0x88];
+ visarea.max_y = vidc_regs[0xb4] - vidc_regs[0xa8];
+
+ logerror("Configuring: htotal %d vtotal %d vis %d,%d\n",
+ vidc_regs[0x80], vidc_regs[0xa0],
+ visarea.max_x, visarea.max_y);
+
+ video_screen_configure(space->machine->primary_screen, vidc_regs[0x80], vidc_regs[0xa0], &visarea, video_screen_get_frame_period(space->machine->primary_screen).attoseconds);
+
+ // slightly hacky: fire off a VBL right now. the BIOS doesn't wait long enough otherwise.
+ timer_adjust_oneshot(vbl_timer, attotime_zero, 0);
+ }
+
+ vidc_regs[reg] = val>>12;
+ }
+ else
+ {
+ logerror("VIDC: %x to register %x\n", val, reg);
+ vidc_regs[reg] = val&0xffff;
+ }
+}
+
+READ32_HANDLER(memc_r)
+{
+ return 0;
+}
+
+WRITE32_HANDLER(memc_w)
+{
+ // is it a register?
+ if ((data & 0x0fe00000) == 0x03600000)
+ {
+ switch ((data >> 17) & 7)
+ {
+ case 4: /* sound start */
+ vidc_sndstart = ((data>>2)&0x7fff)*16;
+ break;
+
+ case 5: /* sound end */
+ vidc_sndend = ((data>>2)&0x7fff)*16;
+ break;
+
+ case 7: /* Control */
+ memc_pagesize = ((data>>2) & 3);
+
+ logerror("MEMC: %x to Control (page size %d, %s, %s)\n", data & 0x1ffc, page_sizes[memc_pagesize], ((data>>10)&1) ? "Video DMA on" : "Video DMA off", ((data>>11)&1) ? "Sound DMA on" : "Sound DMA off");
+
+ if ((data>>11)&1)
+ {
+ double sndhz;
+
+ sndhz = 250000.0 / (double)((vidc_regs[0xc0]&0xff)+2);
+
+ logerror("MEMC: Starting audio DMA at %f Hz, buffer from %x to %x\n", sndhz, vidc_sndstart, vidc_sndend);
+
+ vidc_sndcur = vidc_sndstart;
+
+ timer_adjust_periodic(snd_timer, ATTOTIME_IN_HZ(sndhz), 0, ATTOTIME_IN_HZ(sndhz));
+ }
+ else
+ {
+ timer_adjust_oneshot(snd_timer, attotime_never, 0);
+ dac_signed_data_w(0, 0x80);
+ }
+ break;
+
+ default:
+ logerror("MEMC: %x to Unk reg %d\n", data&0x1ffff, (data >> 17) & 7);
+ break;
+ }
+ }
+ else
+ {
+ logerror("MEMC non-reg: W %x @ %x (mask %08x)\n", data, offset, mem_mask);
+ }
+}
+
+/*
+ 22 2222 1111 1111 1100 0000 0000
+ 54 3210 9876 5432 1098 7654 3210
+4k page: 11 1LLL LLLL LLLL LLAA MPPP PPPP
+8k page: 11 1LLL LLLL LLLM LLAA MPPP PPPP
+16k page: 11 1LLL LLLL LLxM LLAA MPPP PPPP
+32k page: 11 1LLL LLLL LxxM LLAA MPPP PPPP
+ 3 8 2 9 0 f f
+
+L - logical page
+P - physical page
+A - access permissions
+M - MEMC number (for machines with multiple MEMCs)
+
+The logical page is encoded with bits 11+10 being the most significant bits
+(in that order), and the rest being bit 22 down.
+
+The physical page is encoded differently depending on the page size :
+
+4k page: bits 6-0 being bits 6-0
+8k page: bits 6-1 being bits 5-0, bit 0 being bit 6
+16k page: bits 6-2 being bits 4-0, bits 1-0 being bits 6-5
+32k page: bits 6-3 being bits 4-0, bit 0 being bit 4, bit 2 being bit 5, bit
+ 1 being bit 6
+*/
+
+WRITE32_HANDLER(memc_page_w)
+{
+ UINT32 log, phys, memc, perms;
+
+ perms = (data & 0x300)>>8;
+ log = phys = memc = 0;
+
+ switch (memc_pagesize)
+ {
+ case 0:
+ phys = data & 0x7f;
+ log = (data & 0xc00)>>10;
+ log <<= 23;
+ log |= (data & 0x7ff000);
+ memc = (data & 0x80) ? 1 : 0;
+ break;
+
+ case 1:
+ phys = ((data & 0x7f) >> 1) | (data & 1) ? 0x40 : 0;
+ log = (data & 0xc00)>>10;
+ log <<= 23;
+ log |= (data & 0x7fe000);
+ memc = ((data & 0x80) ? 1 : 0) | ((data & 0x1000) ? 2 : 0);
+ break;
+
+ case 2:
+ phys = ((data & 0x7f) >> 2) | ((data & 3) << 5);
+ log = (data & 0xc00)>>10;
+ log <<= 23;
+ log |= (data & 0x7fc000);
+ memc = ((data & 0x80) ? 1 : 0) | ((data & 0x1000) ? 2 : 0);
+ break;
+
+ case 3:
+ phys = ((data & 0x7f) >> 3) | (data & 1)<<4 | (data & 2) << 5 | (data & 4)<<3;
+ log = (data & 0xc00)>>10;
+ log <<= 23;
+ log |= (data & 0x7f8000);
+ memc = ((data & 0x80) ? 1 : 0) | ((data & 0x1000) ? 2 : 0);
+ break;
+ }
+
+ log >>= (12 + memc_pagesize);
+
+ // always make sure ROM mode is disconnected when this occurs
+ memc_latchrom = 0;
+
+ // now go ahead and set the mapping in the page table
+ memc_pages[log] = phys * memc;
+
+// printf("MEMC_PAGE(%d): W %08x: log %x to phys %x, MEMC %d, perms %d\n", memc_pagesize, data, log, phys, memc, perms);
+}
+
diff --git a/src/mame/mame.mak b/src/mame/mame.mak
index b60301f5f76..94f23f10181 100644
--- a/src/mame/mame.mak
+++ b/src/mame/mame.mak
@@ -124,8 +124,8 @@ CPUS += ASAP
CPUS += UPD7810
CPUS += UPD7807
CPUS += UPD7801
-CPUS += ARM
-CPUS += ARM7
+CPUS += ARM26
+CPUS += ARM32
CPUS += JAGUAR
CPUS += CUBEQCPU
CPUS += ESRIP
@@ -456,6 +456,7 @@ $(MAMEOBJ)/aristocr.a: \
$(DRIVERS)/86lions.o \
$(DRIVERS)/caswin.o \
$(DRIVERS)/aristmk5.o \
+ $(MACHINE)/archimds.o \
$(MAMEOBJ)/atari.a: \
$(DRIVERS)/atarigx2.o $(VIDEO)/atarigx2.o \