mirror of
https://github.com/holub/mame
synced 2025-05-19 12:18:56 +03:00
Adding first-cut shared Archimedes code and hooked it up to MK5.
This commit is contained in:
parent
355d1124c4
commit
adf3ac320d
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -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
|
||||
|
@ -5,15 +5,35 @@
|
||||
|
||||
-- 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 )
|
||||
|
60
src/mame/includes/archimds.h
Normal file
60
src/mame/includes/archimds.h
Normal file
@ -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_
|
689
src/mame/machine/archimds.c
Normal file
689
src/mame/machine/archimds.c
Normal file
@ -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);
|
||||
}
|
||||
|
@ -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 \
|
||||
|
Loading…
Reference in New Issue
Block a user