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 \