Modernized archimedes (no whatsnew)

This commit is contained in:
Miodrag Milanovic 2012-09-20 08:36:19 +00:00
parent 13ad383bf4
commit cde37d5026
6 changed files with 357 additions and 366 deletions

View File

@ -64,11 +64,11 @@
//#include "machine/i2cmem.h" //#include "machine/i2cmem.h"
class aristmk5_state : public driver_device class aristmk5_state : public archimedes_state
{ {
public: public:
aristmk5_state(const machine_config &mconfig, device_type type, const char *tag) aristmk5_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) { } : archimedes_state(mconfig, type, tag) { }
emu_timer *m_mk5_2KHz_timer; emu_timer *m_mk5_2KHz_timer;
emu_timer *m_mk5_VSYNC_timer; emu_timer *m_mk5_VSYNC_timer;
@ -89,7 +89,7 @@ public:
static TIMER_CALLBACK( mk5_VSYNC_callback ) static TIMER_CALLBACK( mk5_VSYNC_callback )
{ {
aristmk5_state *state = machine.driver_data<aristmk5_state>(); aristmk5_state *state = machine.driver_data<aristmk5_state>();
ioc_regs[IRQ_STATUS_A] |= 0x08; //turn vsync bit on state->m_ioc_regs[IRQ_STATUS_A] |= 0x08; //turn vsync bit on
state->m_mk5_VSYNC_timer->adjust(attotime::never); state->m_mk5_VSYNC_timer->adjust(attotime::never);
} }
@ -131,7 +131,7 @@ WRITE32_MEMBER(aristmk5_state::Ns5w48)
*/ */
ioc_regs[IRQ_STATUS_A] &= ~0x08; m_ioc_regs[IRQ_STATUS_A] &= ~0x08;
/* bit 1 bit 0 */ /* bit 1 bit 0 */
if((data &~(0x02)) && (data & (0x01))) // external video crystal is enabled. 25 mhz if((data &~(0x02)) && (data & (0x01))) // external video crystal is enabled. 25 mhz
@ -155,7 +155,7 @@ WRITE32_MEMBER(aristmk5_state::Ns5w48)
static TIMER_CALLBACK( mk5_2KHz_callback ) static TIMER_CALLBACK( mk5_2KHz_callback )
{ {
aristmk5_state *state = machine.driver_data<aristmk5_state>(); aristmk5_state *state = machine.driver_data<aristmk5_state>();
ioc_regs[IRQ_STATUS_A] |= 0x01; state->m_ioc_regs[IRQ_STATUS_A] |= 0x01;
state->m_mk5_2KHz_timer->adjust(attotime::never); state->m_mk5_2KHz_timer->adjust(attotime::never);
} }
@ -183,7 +183,7 @@ READ32_MEMBER(aristmk5_state::Ns5x58)
// reset 2KHz timer // reset 2KHz timer
m_mk5_2KHz_timer->adjust(attotime::from_hz(1953.125)); m_mk5_2KHz_timer->adjust(attotime::from_hz(1953.125));
ioc_regs[IRQ_STATUS_A] &= ~0x01; m_ioc_regs[IRQ_STATUS_A] &= ~0x01;
machine().device("maincpu")->execute().set_input_line(ARM_IRQ_LINE, CLEAR_LINE); machine().device("maincpu")->execute().set_input_line(ARM_IRQ_LINE, CLEAR_LINE);
return 0xffffffff; return 0xffffffff;
} }
@ -202,11 +202,11 @@ READ32_MEMBER(aristmk5_state::mk5_ioc_r)
int vert_pos; int vert_pos;
vert_pos = machine().primary_screen->vpos(); vert_pos = machine().primary_screen->vpos();
m_flyback = (vert_pos <= vidc_regs[VIDC_VDSR] || vert_pos >= vidc_regs[VIDC_VDER]) ? 0x80 : 0x00; m_flyback = (vert_pos <= m_vidc_regs[VIDC_VDSR] || vert_pos >= m_vidc_regs[VIDC_VDER]) ? 0x80 : 0x00;
//i2c_data = (i2cmem_sda_read(machine().device("i2cmem")) & 1); //i2c_data = (i2cmem_sda_read(machine().device("i2cmem")) & 1);
return (m_flyback) | (ioc_regs[CONTROL] & 0x7c) | (1<<1) | 1; return (m_flyback) | (m_ioc_regs[CONTROL] & 0x7c) | (1<<1) | 1;
} }
return archimedes_ioc_r(space,offset,mem_mask); return archimedes_ioc_r(space,offset,mem_mask);
@ -224,7 +224,7 @@ WRITE32_MEMBER(aristmk5_state::mk5_ioc_w)
{ {
if(((ioc_addr == 0x20) || (ioc_addr == 0x30)) && (offset & 0x1f) == 0) if(((ioc_addr == 0x20) || (ioc_addr == 0x30)) && (offset & 0x1f) == 0)
{ {
ioc_regs[CONTROL] = data & 0x7c; m_ioc_regs[CONTROL] = data & 0x7c;
return; return;
} }
else else
@ -298,7 +298,7 @@ WRITE32_MEMBER(aristmk5_state::sram_banksel_w)
/* U.S games have no dram emulator enabled */ /* U.S games have no dram emulator enabled */
static ADDRESS_MAP_START( aristmk5_map, AS_PROGRAM, 32, aristmk5_state ) static ADDRESS_MAP_START( aristmk5_map, AS_PROGRAM, 32, aristmk5_state )
AM_RANGE(0x00000000, 0x01ffffff) AM_READWRITE_LEGACY(archimedes_memc_logical_r, archimedes_memc_logical_w) AM_RANGE(0x00000000, 0x01ffffff) AM_READWRITE(archimedes_memc_logical_r, archimedes_memc_logical_w)
AM_RANGE(0x02000000, 0x02ffffff) AM_RAM AM_SHARE("physicalram") /* physical RAM - 16 MB for now, should be 512k for the A310 */ AM_RANGE(0x02000000, 0x02ffffff) AM_RAM AM_SHARE("physicalram") /* physical RAM - 16 MB for now, should be 512k for the A310 */
/* MK-5 overrides */ /* MK-5 overrides */
@ -317,14 +317,14 @@ static ADDRESS_MAP_START( aristmk5_map, AS_PROGRAM, 32, aristmk5_state )
AM_RANGE(0x03000000, 0x0331ffff) AM_READWRITE(mk5_ioc_r, mk5_ioc_w) AM_RANGE(0x03000000, 0x0331ffff) AM_READWRITE(mk5_ioc_r, mk5_ioc_w)
AM_RANGE(0x03320000, 0x0333ffff) AM_RAMBANK("sram_bank_nz") // AM_BASE_SIZE_GENERIC(nvram) // nvram 32kbytes x 3 NZ AM_RANGE(0x03320000, 0x0333ffff) AM_RAMBANK("sram_bank_nz") // AM_BASE_SIZE_GENERIC(nvram) // nvram 32kbytes x 3 NZ
AM_RANGE(0x03400000, 0x035fffff) AM_ROM AM_REGION("maincpu", 0) AM_WRITE_LEGACY(archimedes_vidc_w) AM_RANGE(0x03400000, 0x035fffff) AM_ROM AM_REGION("maincpu", 0) AM_WRITE(archimedes_vidc_w)
AM_RANGE(0x03600000, 0x037fffff) AM_READWRITE_LEGACY(archimedes_memc_r, archimedes_memc_w) AM_RANGE(0x03600000, 0x037fffff) AM_READWRITE(archimedes_memc_r, archimedes_memc_w)
AM_RANGE(0x03800000, 0x039fffff) AM_WRITE_LEGACY(archimedes_memc_page_w) AM_RANGE(0x03800000, 0x039fffff) AM_WRITE(archimedes_memc_page_w)
ADDRESS_MAP_END ADDRESS_MAP_END
/* with dram emulator enabled */ /* with dram emulator enabled */
static ADDRESS_MAP_START( aristmk5_drame_map, AS_PROGRAM, 32, aristmk5_state ) static ADDRESS_MAP_START( aristmk5_drame_map, AS_PROGRAM, 32, aristmk5_state )
AM_RANGE(0x00000000, 0x01ffffff) AM_READWRITE_LEGACY(aristmk5_drame_memc_logical_r, archimedes_memc_logical_w) AM_RANGE(0x00000000, 0x01ffffff) AM_READWRITE(aristmk5_drame_memc_logical_r, archimedes_memc_logical_w)
AM_RANGE(0x02000000, 0x02ffffff) AM_RAM AM_SHARE("physicalram") /* physical RAM - 16 MB for now, should be 512k for the A310 */ AM_RANGE(0x02000000, 0x02ffffff) AM_RAM AM_SHARE("physicalram") /* physical RAM - 16 MB for now, should be 512k for the A310 */
/* MK-5 overrides */ /* MK-5 overrides */
@ -344,9 +344,9 @@ static ADDRESS_MAP_START( aristmk5_drame_map, AS_PROGRAM, 32, aristmk5_state )
AM_RANGE(0x03000000, 0x0331ffff) AM_READWRITE(mk5_ioc_r, mk5_ioc_w) AM_RANGE(0x03000000, 0x0331ffff) AM_READWRITE(mk5_ioc_r, mk5_ioc_w)
AM_RANGE(0x03320000, 0x0333ffff) AM_RAMBANK("sram_bank_nz") // AM_BASE_SIZE_GENERIC(nvram) // nvram 32kbytes x 3 NZ AM_RANGE(0x03320000, 0x0333ffff) AM_RAMBANK("sram_bank_nz") // AM_BASE_SIZE_GENERIC(nvram) // nvram 32kbytes x 3 NZ
AM_RANGE(0x03400000, 0x035fffff) AM_ROM AM_REGION("maincpu", 0) AM_WRITE_LEGACY(archimedes_vidc_w) AM_RANGE(0x03400000, 0x035fffff) AM_ROM AM_REGION("maincpu", 0) AM_WRITE(archimedes_vidc_w)
AM_RANGE(0x03600000, 0x037fffff) AM_READWRITE_LEGACY(archimedes_memc_r, archimedes_memc_w) AM_RANGE(0x03600000, 0x037fffff) AM_READWRITE(archimedes_memc_r, archimedes_memc_w)
AM_RANGE(0x03800000, 0x039fffff) AM_WRITE_LEGACY(archimedes_memc_page_w) AM_RANGE(0x03800000, 0x039fffff) AM_WRITE(archimedes_memc_page_w)
ADDRESS_MAP_END ADDRESS_MAP_END
@ -365,7 +365,7 @@ DRIVER_INIT_MEMBER(aristmk5_state,aristmk5)
UINT8 *SRAM = machine().root_device().memregion("sram")->base(); UINT8 *SRAM = machine().root_device().memregion("sram")->base();
UINT8 *SRAM_NZ = machine().root_device().memregion("sram")->base(); UINT8 *SRAM_NZ = machine().root_device().memregion("sram")->base();
archimedes_driver_init(machine()); archimedes_driver_init();
machine().root_device().membank("sram_bank")->configure_entries(0, 4, &SRAM[0], 0x20000); machine().root_device().membank("sram_bank")->configure_entries(0, 4, &SRAM[0], 0x20000);
machine().root_device().membank("sram_bank_nz")->configure_entries(0, 4, &SRAM_NZ[0], 0x20000); machine().root_device().membank("sram_bank_nz")->configure_entries(0, 4, &SRAM_NZ[0], 0x20000);
@ -374,7 +374,7 @@ DRIVER_INIT_MEMBER(aristmk5_state,aristmk5)
void aristmk5_state::machine_start() void aristmk5_state::machine_start()
{ {
archimedes_init(machine()); archimedes_init();
// reset the DAC to centerline // reset the DAC to centerline
//machine().device<dac_device>("dac")->write_signed8(0x80); //machine().device<dac_device>("dac")->write_signed8(0x80);
@ -385,11 +385,11 @@ void aristmk5_state::machine_start()
void aristmk5_state::machine_reset() void aristmk5_state::machine_reset()
{ {
archimedes_reset(machine()); archimedes_reset();
m_mk5_2KHz_timer->adjust(attotime::from_hz(1953.125)); // 8MHz / 4096 m_mk5_2KHz_timer->adjust(attotime::from_hz(1953.125)); // 8MHz / 4096
m_mk5_VSYNC_timer->adjust(attotime::from_hz(50000)); // default bit 1 & bit 2 == 0 m_mk5_VSYNC_timer->adjust(attotime::from_hz(50000)); // default bit 1 & bit 2 == 0
ioc_regs[IRQ_STATUS_B] |= 0x40; //hack, set keyboard irq empty to be ON m_ioc_regs[IRQ_STATUS_B] |= 0x40; //hack, set keyboard irq empty to be ON
/* load the roms according to what the operator wants */ /* load the roms according to what the operator wants */
{ {
@ -435,7 +435,7 @@ static MACHINE_CONFIG_START( aristmk5, aristmk5_state )
MCFG_PALETTE_LENGTH(0x200) MCFG_PALETTE_LENGTH(0x200)
MCFG_SCREEN_UPDATE_STATIC(archimds_vidc) MCFG_SCREEN_UPDATE_DRIVER(archimedes_state, screen_update)
MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_DAC_ADD("dac0") MCFG_DAC_ADD("dac0")
@ -478,8 +478,7 @@ static MACHINE_CONFIG_START( aristmk5_usa, aristmk5_state )
MCFG_PALETTE_LENGTH(0x200) MCFG_PALETTE_LENGTH(0x200)
MCFG_VIDEO_START(archimds_vidc) MCFG_SCREEN_UPDATE_DRIVER(archimedes_state, screen_update)
MCFG_SCREEN_UPDATE_STATIC(archimds_vidc)
MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_DAC_ADD("dac0") MCFG_DAC_ADD("dac0")

View File

@ -28,11 +28,11 @@ PCB has a single OSC at 24MHz
#include "machine/i2cmem.h" #include "machine/i2cmem.h"
class ertictac_state : public driver_device class ertictac_state : public archimedes_state
{ {
public: public:
ertictac_state(const machine_config &mconfig, device_type type, const char *tag) ertictac_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) { } : archimedes_state(mconfig, type, tag) { }
DECLARE_READ32_MEMBER(ertictac_podule_r); DECLARE_READ32_MEMBER(ertictac_podule_r);
DECLARE_DRIVER_INIT(ertictac); DECLARE_DRIVER_INIT(ertictac);
@ -44,7 +44,7 @@ public:
READ32_MEMBER(ertictac_state::ertictac_podule_r) READ32_MEMBER(ertictac_state::ertictac_podule_r)
{ {
ioc_regs[IRQ_STATUS_B] &= ~ARCHIMEDES_IRQB_PODULE_IRQ; m_ioc_regs[IRQ_STATUS_B] &= ~ARCHIMEDES_IRQB_PODULE_IRQ;
switch(offset) switch(offset)
{ {
@ -59,16 +59,16 @@ READ32_MEMBER(ertictac_state::ertictac_podule_r)
} }
static ADDRESS_MAP_START( ertictac_map, AS_PROGRAM, 32, ertictac_state ) static ADDRESS_MAP_START( ertictac_map, AS_PROGRAM, 32, ertictac_state )
AM_RANGE(0x00000000, 0x01ffffff) AM_READWRITE_LEGACY(archimedes_memc_logical_r, archimedes_memc_logical_w) AM_RANGE(0x00000000, 0x01ffffff) AM_READWRITE(archimedes_memc_logical_r, archimedes_memc_logical_w)
AM_RANGE(0x02000000, 0x02ffffff) AM_RAM AM_SHARE("physicalram") /* physical RAM - 16 MB for now, should be 512k for the A310 */ AM_RANGE(0x02000000, 0x02ffffff) AM_RAM AM_SHARE("physicalram") /* physical RAM - 16 MB for now, should be 512k for the A310 */
AM_RANGE(0x03340000, 0x0334001f) AM_READ(ertictac_podule_r) AM_RANGE(0x03340000, 0x0334001f) AM_READ(ertictac_podule_r)
AM_RANGE(0x033c0000, 0x033c001f) AM_READ(ertictac_podule_r) AM_RANGE(0x033c0000, 0x033c001f) AM_READ(ertictac_podule_r)
AM_RANGE(0x03000000, 0x033fffff) AM_READWRITE_LEGACY(archimedes_ioc_r, archimedes_ioc_w) AM_RANGE(0x03000000, 0x033fffff) AM_READWRITE(archimedes_ioc_r, archimedes_ioc_w)
AM_RANGE(0x03400000, 0x035fffff) AM_READWRITE_LEGACY(archimedes_vidc_r, archimedes_vidc_w) AM_RANGE(0x03400000, 0x035fffff) AM_READWRITE(archimedes_vidc_r, archimedes_vidc_w)
AM_RANGE(0x03600000, 0x037fffff) AM_READWRITE_LEGACY(archimedes_memc_r, archimedes_memc_w) AM_RANGE(0x03600000, 0x037fffff) AM_READWRITE(archimedes_memc_r, archimedes_memc_w)
AM_RANGE(0x03800000, 0x03ffffff) AM_ROM AM_REGION("maincpu", 0) AM_WRITE_LEGACY(archimedes_memc_page_w) AM_RANGE(0x03800000, 0x03ffffff) AM_ROM AM_REGION("maincpu", 0) AM_WRITE(archimedes_memc_page_w)
ADDRESS_MAP_END ADDRESS_MAP_END
static INPUT_PORTS_START( ertictac ) static INPUT_PORTS_START( ertictac )
@ -193,12 +193,12 @@ INPUT_PORTS_END
DRIVER_INIT_MEMBER(ertictac_state,ertictac) DRIVER_INIT_MEMBER(ertictac_state,ertictac)
{ {
archimedes_driver_init(machine()); archimedes_driver_init();
} }
void ertictac_state::machine_start() void ertictac_state::machine_start()
{ {
archimedes_init(machine()); archimedes_init();
// reset the DAC to centerline // reset the DAC to centerline
//machine().device<dac_device>("dac")->write_signed8(0x80); //machine().device<dac_device>("dac")->write_signed8(0x80);
@ -206,12 +206,12 @@ void ertictac_state::machine_start()
void ertictac_state::machine_reset() void ertictac_state::machine_reset()
{ {
archimedes_reset(machine()); archimedes_reset();
} }
INTERRUPT_GEN_MEMBER(ertictac_state::ertictac_podule_irq) INTERRUPT_GEN_MEMBER(ertictac_state::ertictac_podule_irq)
{ {
archimedes_request_irq_b(machine(), ARCHIMEDES_IRQB_PODULE_IRQ); archimedes_request_irq_b(ARCHIMEDES_IRQB_PODULE_IRQ);
} }
/* TODO: Are we sure that this HW have I2C device? */ /* TODO: Are we sure that this HW have I2C device? */
@ -237,12 +237,10 @@ static MACHINE_CONFIG_START( ertictac, ertictac_state )
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_SCREEN_SIZE(1280, 1024) MCFG_SCREEN_SIZE(1280, 1024)
MCFG_SCREEN_VISIBLE_AREA(0, 1280-1, 0, 1024-1) MCFG_SCREEN_VISIBLE_AREA(0, 1280-1, 0, 1024-1)
MCFG_SCREEN_UPDATE_STATIC(archimds_vidc) MCFG_SCREEN_UPDATE_DRIVER(archimedes_state, screen_update)
MCFG_PALETTE_LENGTH(0x200) MCFG_PALETTE_LENGTH(0x200)
MCFG_VIDEO_START(archimds_vidc)
MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_DAC_ADD("dac0") MCFG_DAC_ADD("dac0")
MCFG_SOUND_ROUTE(0, "mono", 0.05) MCFG_SOUND_ROUTE(0, "mono", 0.05)

View File

@ -34,36 +34,73 @@
#define ARCHIMEDES_FIQ_PODULE (0x40) #define ARCHIMEDES_FIQ_PODULE (0x40)
#define ARCHIMEDES_FIQ_FORCE (0x80) #define ARCHIMEDES_FIQ_FORCE (0x80)
/*----------- defined in machine/archimds.c -----------*/ class archimedes_state : public driver_device
{
public:
archimedes_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) { }
void archimedes_init(running_machine &machine); // call at MACHINE_INIT void archimedes_init();
void archimedes_reset(running_machine &machine); // call at MACHINE_RESET void archimedes_reset();
void archimedes_driver_init(running_machine &machine); // call at DRIVER_INIT void archimedes_driver_init();
void archimedes_request_irq_a(running_machine &machine, int mask); void archimedes_request_irq_a(int mask);
void archimedes_request_irq_b(running_machine &machine, int mask); void archimedes_request_irq_b(int mask);
void archimedes_request_fiq(running_machine &machine, int mask); void archimedes_request_fiq(int mask);
void archimedes_clear_irq_a(running_machine &machine, int mask); void archimedes_clear_irq_a(int mask);
void archimedes_clear_irq_b(running_machine &machine, int mask); void archimedes_clear_irq_b(int mask);
void archimedes_clear_fiq(running_machine &machine, int mask); void archimedes_clear_fiq(int mask);
extern DECLARE_READ32_HANDLER(aristmk5_drame_memc_logical_r); DECLARE_READ32_MEMBER(aristmk5_drame_memc_logical_r);
extern DECLARE_READ32_HANDLER(archimedes_memc_logical_r); DECLARE_READ32_MEMBER(archimedes_memc_logical_r);
extern DECLARE_WRITE32_HANDLER(archimedes_memc_logical_w); DECLARE_WRITE32_MEMBER(archimedes_memc_logical_w);
extern DECLARE_READ32_HANDLER(archimedes_memc_r); DECLARE_READ32_MEMBER(archimedes_memc_r);
extern DECLARE_WRITE32_HANDLER(archimedes_memc_w); DECLARE_WRITE32_MEMBER(archimedes_memc_w);
extern DECLARE_WRITE32_HANDLER(archimedes_memc_page_w); DECLARE_WRITE32_MEMBER(archimedes_memc_page_w);
extern DECLARE_READ32_HANDLER(archimedes_ioc_r); DECLARE_READ32_MEMBER(archimedes_ioc_r);
extern DECLARE_WRITE32_HANDLER(archimedes_ioc_w); DECLARE_WRITE32_MEMBER(archimedes_ioc_w);
extern DECLARE_READ32_HANDLER(archimedes_vidc_r); DECLARE_READ32_MEMBER(archimedes_vidc_r);
extern DECLARE_WRITE32_HANDLER(archimedes_vidc_w); DECLARE_WRITE32_MEMBER(archimedes_vidc_w);
extern UINT8 i2c_clk; UINT8 m_i2c_clk;
extern INT16 memc_pages[0x2000]; // the logical RAM area is 32 megs, and the smallest page size is 4k INT16 m_memc_pages[0x2000]; // the logical RAM area is 32 megs, and the smallest page size is 4k
extern UINT32 vidc_regs[256]; UINT32 m_vidc_regs[256];
extern UINT8 ioc_regs[0x80/4]; UINT8 m_ioc_regs[0x80/4];
extern UINT8 vidc_bpp_mode; UINT8 m_vidc_bpp_mode;
extern UINT8 vidc_interlace; UINT8 m_vidc_interlace;
UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
private:
static const device_timer_id TIMER_VBLANK = 0;
static const device_timer_id TIMER_VIDEO = 1;
static const device_timer_id TIMER_AUDIO = 2;
static const device_timer_id TIMER_IOC = 3;
void vidc_vblank();
void vidc_video_tick();
void vidc_audio_tick();
void ioc_timer(int param);
void vidc_dynamic_res_change();
void latch_timer_cnt(int tmr);
void a310_set_timer(int tmr);
READ32_MEMBER(ioc_ctrl_r);
WRITE32_MEMBER(ioc_ctrl_w);
UINT32 *m_archimedes_memc_physmem;
UINT32 m_memc_pagesize;
int m_memc_latchrom;
UINT32 m_ioc_timercnt[4], m_ioc_timerout[4];
UINT32 m_vidc_vidstart, m_vidc_vidend, m_vidc_vidinit, m_vidc_vidcur;
UINT32 m_vidc_sndstart, m_vidc_sndend, m_vidc_sndcur;
UINT8 m_video_dma_on,m_audio_dma_on;
UINT8 m_vidc_pixel_clk;
UINT8 m_vidc_stereo_reg[8];
emu_timer *m_timer[4], *m_snd_timer, *m_vid_timer;
emu_timer *m_vbl_timer;
};
/* IOC registers */ /* IOC registers */
@ -101,12 +138,6 @@ extern UINT8 vidc_interlace;
#define T3_GO 0x78/4 #define T3_GO 0x78/4
#define T3_LATCH 0x7c/4 #define T3_LATCH 0x7c/4
/*----------- defined in video/archimds.c -----------*/
extern VIDEO_START( archimds_vidc );
extern SCREEN_UPDATE_RGB32( archimds_vidc );
#define VIDC_HCR 0x80 #define VIDC_HCR 0x80
#define VIDC_HSWR 0x84 #define VIDC_HSWR 0x84
#define VIDC_HBSR 0x88 #define VIDC_HBSR 0x88

View File

@ -35,105 +35,98 @@
#include "machine/wd17xx.h" #include "machine/wd17xx.h"
static const int page_sizes[4] = { 4096, 8192, 16384, 32768 }; static const int page_sizes[4] = { 4096, 8192, 16384, 32768 };
static const UINT32 pixel_rate[4] = { 8000000, 12000000, 16000000, 24000000};
#define IOC_LOG 0 #define IOC_LOG 0
static UINT32 *archimedes_memc_physmem; void archimedes_state::archimedes_request_irq_a(int mask)
static UINT32 memc_pagesize;
static int memc_latchrom;
static UINT32 ioc_timercnt[4], ioc_timerout[4];
static UINT32 vidc_vidstart, vidc_vidend, vidc_vidinit,vidc_vidcur;
static UINT32 vidc_sndstart, vidc_sndend, vidc_sndcur;
static UINT8 video_dma_on,audio_dma_on;
UINT8 i2c_clk;
INT16 memc_pages[0x2000]; // the logical RAM area is 32 megs, and the smallest page size is 4k
UINT32 vidc_regs[256];
UINT8 ioc_regs[0x80/4];
UINT8 vidc_bpp_mode;
UINT8 vidc_interlace;
static UINT8 vidc_pixel_clk;
static const UINT32 pixel_rate[4] = { 8000000, 12000000, 16000000, 24000000};
static UINT8 vidc_stereo_reg[8];
static emu_timer *timer[4], *snd_timer, *vid_timer;
static emu_timer *vbl_timer;
void archimedes_request_irq_a(running_machine &machine, int mask)
{ {
ioc_regs[IRQ_STATUS_A] |= mask; m_ioc_regs[IRQ_STATUS_A] |= mask;
if (ioc_regs[IRQ_MASK_A] & mask) if (m_ioc_regs[IRQ_MASK_A] & mask)
{ {
machine.device("maincpu")->execute().set_input_line(ARM_IRQ_LINE, ASSERT_LINE); machine().device("maincpu")->execute().set_input_line(ARM_IRQ_LINE, ASSERT_LINE);
} }
} }
void archimedes_request_irq_b(running_machine &machine, int mask) void archimedes_state::archimedes_request_irq_b(int mask)
{ {
ioc_regs[IRQ_STATUS_B] |= mask; m_ioc_regs[IRQ_STATUS_B] |= mask;
if (ioc_regs[IRQ_MASK_B] & mask) if (m_ioc_regs[IRQ_MASK_B] & mask)
{ {
generic_pulse_irq_line(machine.device("maincpu"), ARM_IRQ_LINE, 1); generic_pulse_irq_line(machine().device("maincpu")->execute(), ARM_IRQ_LINE, 1);
} }
} }
void archimedes_request_fiq(running_machine &machine, int mask) void archimedes_state::archimedes_request_fiq(int mask)
{ {
ioc_regs[FIQ_STATUS] |= mask; m_ioc_regs[FIQ_STATUS] |= mask;
if (ioc_regs[FIQ_MASK] & mask) if (m_ioc_regs[FIQ_MASK] & mask)
{ {
generic_pulse_irq_line(machine.device("maincpu"), ARM_FIRQ_LINE, 1); generic_pulse_irq_line(machine().device("maincpu")->execute(), ARM_FIRQ_LINE, 1);
} }
} }
void archimedes_clear_irq_a(running_machine &machine, int mask) void archimedes_state::archimedes_clear_irq_a(int mask)
{ {
ioc_regs[IRQ_STATUS_A] &= ~mask; m_ioc_regs[IRQ_STATUS_A] &= ~mask;
} }
void archimedes_clear_irq_b(running_machine &machine, int mask) void archimedes_state::archimedes_clear_irq_b(int mask)
{ {
ioc_regs[IRQ_STATUS_B] &= ~mask; m_ioc_regs[IRQ_STATUS_B] &= ~mask;
} }
void archimedes_clear_fiq(running_machine &machine, int mask) void archimedes_state::archimedes_clear_fiq(int mask)
{ {
ioc_regs[FIQ_STATUS] &= ~mask; m_ioc_regs[FIQ_STATUS] &= ~mask;
} }
static TIMER_CALLBACK( vidc_vblank ) void archimedes_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{ {
archimedes_request_irq_a(machine, ARCHIMEDES_IRQA_VBL); switch (id)
{
case TIMER_VBLANK: vidc_vblank();break;
case TIMER_VIDEO: vidc_video_tick(); break;
case TIMER_AUDIO: vidc_audio_tick(); break;
case TIMER_IOC: ioc_timer(param); break;
}
}
void archimedes_state::vidc_vblank()
{
archimedes_request_irq_a(ARCHIMEDES_IRQA_VBL);
// set up for next vbl // set up for next vbl
vbl_timer->adjust(machine.primary_screen->time_until_pos(vidc_regs[0xb4])); m_vbl_timer->adjust(machine().primary_screen->time_until_pos(m_vidc_regs[0xb4]));
} }
/* video DMA */ /* video DMA */
/* TODO: what type of DMA this is, burst or cycle steal? Docs doesn't explain it (4 usec is the DRAM refresh). */ /* TODO: what type of DMA this is, burst or cycle steal? Docs doesn't explain it (4 usec is the DRAM refresh). */
static TIMER_CALLBACK( vidc_video_tick ) void archimedes_state::vidc_video_tick()
{ {
address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM); address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM);
static UINT8 *vram = machine.root_device().memregion("vram")->base(); static UINT8 *vram = machine().root_device().memregion("vram")->base();
UINT32 size; UINT32 size;
size = vidc_vidend-vidc_vidstart+0x10; size = m_vidc_vidend-m_vidc_vidstart+0x10;
for(vidc_vidcur = 0;vidc_vidcur < size;vidc_vidcur++) for(m_vidc_vidcur = 0;m_vidc_vidcur < size;m_vidc_vidcur++)
vram[vidc_vidcur] = (space.read_byte(vidc_vidstart+vidc_vidcur)); vram[m_vidc_vidcur] = (space.read_byte(m_vidc_vidstart+m_vidc_vidcur));
if(video_dma_on) if(m_video_dma_on)
vid_timer->adjust(space.machine().primary_screen->time_until_pos(vidc_regs[0xb4])); m_vid_timer->adjust(machine().primary_screen->time_until_pos(m_vidc_regs[0xb4]));
else else
vid_timer->adjust(attotime::never); m_vid_timer->adjust(attotime::never);
} }
/* audio DMA */ /* audio DMA */
static TIMER_CALLBACK( vidc_audio_tick ) void archimedes_state::vidc_audio_tick()
{ {
address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM); address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM);
UINT8 ulaw_comp; UINT8 ulaw_comp;
INT16 res; INT16 res;
UINT8 ch; UINT8 ch;
@ -176,32 +169,32 @@ static TIMER_CALLBACK( vidc_audio_tick )
for(ch=0;ch<8;ch++) for(ch=0;ch<8;ch++)
{ {
UINT8 ulaw_temp = (space.read_byte(vidc_sndstart+vidc_sndcur + ch)) ^ 0xff; UINT8 ulaw_temp = (space.read_byte(m_vidc_sndstart+m_vidc_sndcur + ch)) ^ 0xff;
ulaw_comp = (ulaw_temp>>1) | ((ulaw_temp&1)<<7); ulaw_comp = (ulaw_temp>>1) | ((ulaw_temp&1)<<7);
res = mulawTable[ulaw_comp]; res = mulawTable[ulaw_comp];
space.machine().device<dac_device>(dac_port[ch & 7])->write_signed16(res^0x8000); machine().device<dac_device>(dac_port[ch & 7])->write_signed16(res^0x8000);
} }
vidc_sndcur+=8; m_vidc_sndcur+=8;
if (vidc_sndcur >= (vidc_sndend-vidc_sndstart)+0x10) if (m_vidc_sndcur >= (m_vidc_sndend-m_vidc_sndstart)+0x10)
{ {
vidc_sndcur = 0; m_vidc_sndcur = 0;
archimedes_request_irq_b(machine, ARCHIMEDES_IRQB_SOUND_EMPTY); archimedes_request_irq_b(ARCHIMEDES_IRQB_SOUND_EMPTY);
if(!audio_dma_on) if(!m_audio_dma_on)
{ {
snd_timer->adjust(attotime::never); m_snd_timer->adjust(attotime::never);
for(ch=0;ch<8;ch++) for(ch=0;ch<8;ch++)
space.machine().device<dac_device>(dac_port[ch & 7])->write_signed16(0x8000); machine().device<dac_device>(dac_port[ch & 7])->write_signed16(0x8000);
} }
} }
} }
static void a310_set_timer(int tmr) void archimedes_state::a310_set_timer(int tmr)
{ {
double freq; double freq;
@ -209,21 +202,21 @@ static void a310_set_timer(int tmr)
{ {
case 0: case 0:
case 1: case 1:
timer[tmr]->adjust(attotime::from_usec(ioc_timercnt[tmr]/8), tmr); // TODO: ARM timings are quite off there, it should be latch and not latch/8 m_timer[tmr]->adjust(attotime::from_usec(m_ioc_timercnt[tmr]/8), tmr); // TODO: ARM timings are quite off there, it should be latch and not latch/8
break; break;
case 2: case 2:
freq = 1000000.0 / (double)(ioc_timercnt[tmr]+1); freq = 1000000.0 / (double)(m_ioc_timercnt[tmr]+1);
timer[tmr]->adjust(attotime::from_hz(freq), tmr); m_timer[tmr]->adjust(attotime::from_hz(freq), tmr);
break; break;
case 3: case 3:
freq = 1000000.0 / (double)((ioc_timercnt[tmr]+1)*16); freq = 1000000.0 / (double)((m_ioc_timercnt[tmr]+1)*16);
timer[tmr]->adjust(attotime::from_hz(freq), tmr); m_timer[tmr]->adjust(attotime::from_hz(freq), tmr);
break; break;
} }
} }
// param // param
static TIMER_CALLBACK( ioc_timer ) void archimedes_state::ioc_timer(int param)
{ {
// all timers always run // all timers always run
a310_set_timer(param); a310_set_timer(param);
@ -232,78 +225,78 @@ static TIMER_CALLBACK( ioc_timer )
switch (param) switch (param)
{ {
case 0: case 0:
archimedes_request_irq_a(machine, ARCHIMEDES_IRQA_TIMER0); archimedes_request_irq_a(ARCHIMEDES_IRQA_TIMER0);
break; break;
case 1: case 1:
archimedes_request_irq_a(machine, ARCHIMEDES_IRQA_TIMER1); archimedes_request_irq_a(ARCHIMEDES_IRQA_TIMER1);
break; break;
} }
} }
void archimedes_reset(running_machine &machine) void archimedes_state::archimedes_reset()
{ {
int i; int i;
memc_latchrom = 1; // map in the boot ROM m_memc_latchrom = 1; // map in the boot ROM
// kill all memc mappings // kill all memc mappings
for (i = 0; i < (32*1024*1024)/(4096); i++) for (i = 0; i < (32*1024*1024)/(4096); i++)
{ {
memc_pages[i] = -1; // indicate unmapped m_memc_pages[i] = -1; // indicate unmapped
} }
ioc_regs[IRQ_STATUS_A] = 0x10 | 0x80; //set up POR (Power On Reset) and Force IRQ at start-up m_ioc_regs[IRQ_STATUS_A] = 0x10 | 0x80; //set up POR (Power On Reset) and Force IRQ at start-up
ioc_regs[IRQ_STATUS_B] = 0x02; //set up IL[1] On m_ioc_regs[IRQ_STATUS_B] = 0x02; //set up IL[1] On
ioc_regs[FIQ_STATUS] = 0x80; //set up Force FIQ m_ioc_regs[FIQ_STATUS] = 0x80; //set up Force FIQ
ioc_regs[CONTROL] = 0xff; m_ioc_regs[CONTROL] = 0xff;
} }
void archimedes_init(running_machine &machine) void archimedes_state::archimedes_init()
{ {
memc_pagesize = 0; m_memc_pagesize = 0;
vbl_timer = machine.scheduler().timer_alloc(FUNC(vidc_vblank)); m_vbl_timer = timer_alloc(TIMER_VBLANK);
vbl_timer->adjust(attotime::never); m_vbl_timer->adjust(attotime::never);
timer[0] = machine.scheduler().timer_alloc(FUNC(ioc_timer)); m_timer[0] = timer_alloc(TIMER_IOC);
timer[1] = machine.scheduler().timer_alloc(FUNC(ioc_timer)); m_timer[1] = timer_alloc(TIMER_IOC);
timer[2] = machine.scheduler().timer_alloc(FUNC(ioc_timer)); m_timer[2] = timer_alloc(TIMER_IOC);
timer[3] = machine.scheduler().timer_alloc(FUNC(ioc_timer)); m_timer[3] = timer_alloc(TIMER_IOC);
timer[0]->adjust(attotime::never); m_timer[0]->adjust(attotime::never);
timer[1]->adjust(attotime::never); m_timer[1]->adjust(attotime::never);
timer[2]->adjust(attotime::never); m_timer[2]->adjust(attotime::never);
timer[3]->adjust(attotime::never); m_timer[3]->adjust(attotime::never);
vid_timer = machine.scheduler().timer_alloc(FUNC(vidc_video_tick)); m_vid_timer = timer_alloc(TIMER_VIDEO);
snd_timer = machine.scheduler().timer_alloc(FUNC(vidc_audio_tick)); m_snd_timer = timer_alloc(TIMER_AUDIO);
snd_timer->adjust(attotime::never); m_snd_timer->adjust(attotime::never);
} }
READ32_HANDLER(archimedes_memc_logical_r) READ32_MEMBER(archimedes_state::archimedes_memc_logical_r)
{ {
UINT32 page, poffs; UINT32 page, poffs;
// are we mapping in the boot ROM? // are we mapping in the boot ROM?
if (memc_latchrom) if (m_memc_latchrom)
{ {
UINT32 *rom; UINT32 *rom;
rom = (UINT32 *)space.machine().root_device().memregion("maincpu")->base(); rom = (UINT32 *)machine().root_device().memregion("maincpu")->base();
return rom[offset & 0x1fffff]; return rom[offset & 0x1fffff];
} }
else else
{ {
// figure out the page number and offset in the page // figure out the page number and offset in the page
page = (offset<<2) / page_sizes[memc_pagesize]; page = (offset<<2) / page_sizes[m_memc_pagesize];
poffs = (offset<<2) % page_sizes[memc_pagesize]; poffs = (offset<<2) % page_sizes[m_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]); // 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) if (m_memc_pages[page] != -1)
{ {
return archimedes_memc_physmem[((memc_pages[page] * page_sizes[memc_pagesize]) + poffs)>>2]; return m_archimedes_memc_physmem[((m_memc_pages[page] * page_sizes[m_memc_pagesize]) + poffs)>>2];
} }
else else
{ {
@ -317,26 +310,26 @@ READ32_HANDLER(archimedes_memc_logical_r)
WRITE32_HANDLER(archimedes_memc_logical_w) WRITE32_MEMBER(archimedes_state::archimedes_memc_logical_w)
{ {
UINT32 page, poffs; UINT32 page, poffs;
// if the boot ROM is mapped, ignore writes // if the boot ROM is mapped, ignore writes
if (memc_latchrom) if (m_memc_latchrom)
{ {
return; return;
} }
else else
{ {
// figure out the page number and offset in the page // figure out the page number and offset in the page
page = (offset<<2) / page_sizes[memc_pagesize]; page = (offset<<2) / page_sizes[m_memc_pagesize];
poffs = (offset<<2) % page_sizes[memc_pagesize]; poffs = (offset<<2) % page_sizes[m_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]); // 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) if (m_memc_pages[page] != -1)
{ {
COMBINE_DATA(&archimedes_memc_physmem[((memc_pages[page] * page_sizes[memc_pagesize]) + poffs)>>2]); COMBINE_DATA(&m_archimedes_memc_physmem[((m_memc_pages[page] * page_sizes[m_memc_pagesize]) + poffs)>>2]);
} }
else else
{ {
@ -346,28 +339,28 @@ WRITE32_HANDLER(archimedes_memc_logical_w)
} }
/* Aristocrat Mark 5 - same as normal AA except with Dram emulator */ /* Aristocrat Mark 5 - same as normal AA except with Dram emulator */
READ32_HANDLER(aristmk5_drame_memc_logical_r) READ32_MEMBER(archimedes_state::aristmk5_drame_memc_logical_r)
{ {
UINT32 page, poffs; UINT32 page, poffs;
// are we mapping in the boot ROM? // are we mapping in the boot ROM?
if (memc_latchrom) if (m_memc_latchrom)
{ {
UINT32 *rom; UINT32 *rom;
rom = (UINT32 *)space.machine().root_device().memregion("maincpu")->base(); rom = (UINT32 *)machine().root_device().memregion("maincpu")->base();
return rom[offset & 0x1fffff]; return rom[offset & 0x1fffff];
} }
else else
{ {
// figure out the page number and offset in the page // figure out the page number and offset in the page
page = (offset<<2) / page_sizes[memc_pagesize]; page = (offset<<2) / page_sizes[m_memc_pagesize];
poffs = (offset<<2) % page_sizes[memc_pagesize]; poffs = (offset<<2) % page_sizes[m_memc_pagesize];
if (memc_pages[page] != -1) if (m_memc_pages[page] != -1)
{ {
/******************* DRAM Emulator - gal20v - Aristocrat Mark 5 ************************ /******************* DRAM Emulator - gal20v - Aristocrat Mark 5 ************************
A Dynamic RAM emulator is provided which avoids the need to execute code A Dynamic RAM emulator is provided which avoids the need to execute code
@ -380,9 +373,9 @@ READ32_HANDLER(aristmk5_drame_memc_logical_r)
In this state, DRAM memory space is disabled. In this state, DRAM memory space is disabled.
****************************************************************************************/ ****************************************************************************************/
if(!(memc_pages[page] & 0x10) && (offset <= 0x3ff)) if(!(m_memc_pages[page] & 0x10) && (offset <= 0x3ff))
return 0xEAD0000A; return 0xEAD0000A;
return archimedes_memc_physmem[((memc_pages[page] * page_sizes[memc_pagesize]) + poffs)>>2]; return m_archimedes_memc_physmem[((m_memc_pages[page] * page_sizes[m_memc_pagesize]) + poffs)>>2];
} }
else else
{ {
@ -394,35 +387,9 @@ READ32_HANDLER(aristmk5_drame_memc_logical_r)
return 0; return 0;
} }
#if 0 void archimedes_state::archimedes_driver_init()
DIRECT_UPDATE_HANDLER( a310_setopbase )
{ {
// if we're not in logical memory, MAME can do the right thing m_archimedes_memc_physmem = reinterpret_cast<UINT32 *>(machine().root_device().memshare("physicalram")->ptr());
if (address > 0x1ffffff)
{
return address;
}
// if the boot ROM is mapped in, do some trickery to make it show up
if (memc_latchrom)
{
direct.explicit_configure(0x000000, 0x1fffff, 0x1fffff, *direct.space().machine().root_device().memregion("maincpu"));
}
else // executing from logical memory
{
offs_t pagesize = page_sizes[memc_pagesize];
UINT32 page = address / pagesize;
direct.explicit_configure(page * pagesize, page * pagesize - 1, pagesize - 1, &archimedes_memc_physmem[(memc_pages[page] * pagesize)>>2]);
}
return ~0;
}
#endif
void archimedes_driver_init(running_machine &machine)
{
archimedes_memc_physmem = reinterpret_cast<UINT32 *>(machine.root_device().memshare("physicalram")->ptr());
// address_space &space = machine.device<arm_device>("maincpu")->space(AS_PROGRAM); // address_space &space = machine.device<arm_device>("maincpu")->space(AS_PROGRAM);
// space.set_direct_update_handler(direct_update_delegate(FUNC(a310_setopbase), &machine)); // space.set_direct_update_handler(direct_update_delegate(FUNC(a310_setopbase), &machine));
} }
@ -463,18 +430,18 @@ static const char *const ioc_regnames[] =
"(write) Timer 3 latch command" // 31 "(write) Timer 3 latch command" // 31
}; };
static void latch_timer_cnt(int tmr) void archimedes_state::latch_timer_cnt(int tmr)
{ {
double time = timer[tmr]->elapsed().as_double(); double time = m_timer[tmr]->elapsed().as_double();
time *= 2000000.0; // find out how many 2 MHz ticks have gone by time *= 2000000.0; // find out how many 2 MHz ticks have gone by
ioc_timerout[tmr] = ioc_timercnt[tmr] - (UINT32)time; m_ioc_timerout[tmr] = m_ioc_timercnt[tmr] - (UINT32)time;
} }
/* TODO: should be a 8-bit handler */ /* TODO: should be a 8-bit handler */
static READ32_HANDLER( ioc_ctrl_r ) READ32_MEMBER( archimedes_state::ioc_ctrl_r )
{ {
if(IOC_LOG) if(IOC_LOG)
logerror("IOC: R %s = %02x (PC=%x) %02x\n", ioc_regnames[offset&0x1f], ioc_regs[offset&0x1f], space.device() .safe_pc( ),offset & 0x1f); logerror("IOC: R %s = %02x (PC=%x) %02x\n", ioc_regnames[offset&0x1f], m_ioc_regs[offset&0x1f], space.device() .safe_pc( ),offset & 0x1f);
switch (offset & 0x1f) switch (offset & 0x1f)
{ {
@ -484,67 +451,67 @@ static READ32_HANDLER( ioc_ctrl_r )
static UINT8 flyback; //internal name for vblank here static UINT8 flyback; //internal name for vblank here
int vert_pos; int vert_pos;
vert_pos = space.machine().primary_screen->vpos(); vert_pos = machine().primary_screen->vpos();
flyback = (vert_pos <= vidc_regs[VIDC_VDSR] || vert_pos >= vidc_regs[VIDC_VDER]) ? 0x80 : 0x00; flyback = (vert_pos <= m_vidc_regs[VIDC_VDSR] || vert_pos >= m_vidc_regs[VIDC_VDER]) ? 0x80 : 0x00;
i2c_data = (i2cmem_sda_read(space.machine().device("i2cmem")) & 1); i2c_data = (i2cmem_sda_read(space.machine().device("i2cmem")) & 1);
return (flyback) | (ioc_regs[CONTROL] & 0x7c) | (i2c_clk<<1) | i2c_data; return (flyback) | (m_ioc_regs[CONTROL] & 0x7c) | (m_i2c_clk<<1) | i2c_data;
} }
case KART: // keyboard read case KART: // keyboard read
archimedes_request_irq_b(space.machine(), ARCHIMEDES_IRQB_KBD_XMIT_EMPTY); archimedes_request_irq_b(ARCHIMEDES_IRQB_KBD_XMIT_EMPTY);
break; break;
case IRQ_STATUS_A: case IRQ_STATUS_A:
return (ioc_regs[IRQ_STATUS_A] & 0x7f) | 0x80; // Force IRQ is always '1' return (m_ioc_regs[IRQ_STATUS_A] & 0x7f) | 0x80; // Force IRQ is always '1'
case IRQ_REQUEST_A: case IRQ_REQUEST_A:
return (ioc_regs[IRQ_STATUS_A] & ioc_regs[IRQ_MASK_A]); return (m_ioc_regs[IRQ_STATUS_A] & m_ioc_regs[IRQ_MASK_A]);
case IRQ_MASK_A: case IRQ_MASK_A:
return (ioc_regs[IRQ_MASK_A]); return (m_ioc_regs[IRQ_MASK_A]);
case IRQ_STATUS_B: case IRQ_STATUS_B:
return (ioc_regs[IRQ_STATUS_B]); return (m_ioc_regs[IRQ_STATUS_B]);
case IRQ_REQUEST_B: case IRQ_REQUEST_B:
return (ioc_regs[IRQ_STATUS_B] & ioc_regs[IRQ_MASK_B]); return (m_ioc_regs[IRQ_STATUS_B] & m_ioc_regs[IRQ_MASK_B]);
case IRQ_MASK_B: case IRQ_MASK_B:
return (ioc_regs[IRQ_MASK_B]); return (m_ioc_regs[IRQ_MASK_B]);
case FIQ_STATUS: case FIQ_STATUS:
return (ioc_regs[FIQ_STATUS] & 0x7f) | 0x80; // Force FIQ is always '1' return (m_ioc_regs[FIQ_STATUS] & 0x7f) | 0x80; // Force FIQ is always '1'
case FIQ_REQUEST: case FIQ_REQUEST:
return (ioc_regs[FIQ_STATUS] & ioc_regs[FIQ_MASK]); return (m_ioc_regs[FIQ_STATUS] & m_ioc_regs[FIQ_MASK]);
case FIQ_MASK: case FIQ_MASK:
return (ioc_regs[FIQ_MASK]); return (m_ioc_regs[FIQ_MASK]);
case T0_LATCH_LO: return ioc_timerout[0]&0xff; case T0_LATCH_LO: return m_ioc_timerout[0]&0xff;
case T0_LATCH_HI: return (ioc_timerout[0]>>8)&0xff; case T0_LATCH_HI: return (m_ioc_timerout[0]>>8)&0xff;
case T1_LATCH_LO: return ioc_timerout[1]&0xff; case T1_LATCH_LO: return m_ioc_timerout[1]&0xff;
case T1_LATCH_HI: return (ioc_timerout[1]>>8)&0xff; case T1_LATCH_HI: return (m_ioc_timerout[1]>>8)&0xff;
case T2_LATCH_LO: return ioc_timerout[2]&0xff; case T2_LATCH_LO: return m_ioc_timerout[2]&0xff;
case T2_LATCH_HI: return (ioc_timerout[2]>>8)&0xff; case T2_LATCH_HI: return (m_ioc_timerout[2]>>8)&0xff;
case T3_LATCH_LO: return ioc_timerout[3]&0xff; case T3_LATCH_LO: return m_ioc_timerout[3]&0xff;
case T3_LATCH_HI: return (ioc_timerout[3]>>8)&0xff; case T3_LATCH_HI: return (m_ioc_timerout[3]>>8)&0xff;
default: default:
if(!IOC_LOG) if(!IOC_LOG)
logerror("IOC: R %s = %02x (PC=%x) %02x\n", ioc_regnames[offset&0x1f], ioc_regs[offset&0x1f], space.device() .safe_pc( ),offset & 0x1f); logerror("IOC: R %s = %02x (PC=%x) %02x\n", ioc_regnames[offset&0x1f], m_ioc_regs[offset&0x1f], space.device() .safe_pc( ),offset & 0x1f);
break; break;
} }
return ioc_regs[offset&0x1f]; return m_ioc_regs[offset&0x1f];
} }
/* TODO: should be a 8-bit handler */ /* TODO: should be a 8-bit handler */
static WRITE32_HANDLER( ioc_ctrl_w ) WRITE32_MEMBER( archimedes_state::ioc_ctrl_w )
{ {
if(IOC_LOG) if(IOC_LOG)
logerror("IOC: W %02x @ reg %s (PC=%x)\n", data&0xff, ioc_regnames[offset&0x1f], space.device() .safe_pc( )); logerror("IOC: W %02x @ reg %s (PC=%x)\n", data&0xff, ioc_regnames[offset&0x1f], space.device() .safe_pc( ));
@ -553,9 +520,9 @@ static WRITE32_HANDLER( ioc_ctrl_w )
{ {
case CONTROL: // I2C bus control case CONTROL: // I2C bus control
//logerror("IOC I2C: CLK %d DAT %d\n", (data>>1)&1, data&1); //logerror("IOC I2C: CLK %d DAT %d\n", (data>>1)&1, data&1);
i2cmem_sda_write(space.machine().device("i2cmem"), data & 0x01); i2cmem_sda_write(machine().device("i2cmem"), data & 0x01);
i2cmem_scl_write(space.machine().device("i2cmem"), (data & 0x02) >> 1); i2cmem_scl_write(machine().device("i2cmem"), (data & 0x02) >> 1);
i2c_clk = (data & 2) >> 1; m_i2c_clk = (data & 2) >> 1;
break; break;
case KART: case KART:
@ -568,53 +535,53 @@ static WRITE32_HANDLER( ioc_ctrl_w )
break; break;
case IRQ_MASK_A: case IRQ_MASK_A:
ioc_regs[IRQ_MASK_A] = data & 0xff; m_ioc_regs[IRQ_MASK_A] = data & 0xff;
if(data & 0x80) //force an IRQ if(data & 0x80) //force an IRQ
archimedes_request_irq_a(space.machine(),ARCHIMEDES_IRQA_FORCE); archimedes_request_irq_a(ARCHIMEDES_IRQA_FORCE);
if(data & 0x08) //set up the VBLANK timer if(data & 0x08) //set up the VBLANK timer
vbl_timer->adjust(space.machine().primary_screen->time_until_pos(vidc_regs[0xb4])); m_vbl_timer->adjust(machine().primary_screen->time_until_pos(m_vidc_regs[0xb4]));
break; break;
case FIQ_MASK: case FIQ_MASK:
ioc_regs[FIQ_MASK] = data & 0xff; m_ioc_regs[FIQ_MASK] = data & 0xff;
if(data & 0x80) //force a FIRQ if(data & 0x80) //force a FIRQ
archimedes_request_fiq(space.machine(),ARCHIMEDES_FIQ_FORCE); archimedes_request_fiq(ARCHIMEDES_FIQ_FORCE);
break; break;
case IRQ_REQUEST_A: // IRQ clear A case IRQ_REQUEST_A: // IRQ clear A
ioc_regs[IRQ_STATUS_A] &= ~(data&0xff); m_ioc_regs[IRQ_STATUS_A] &= ~(data&0xff);
// if that did it, clear the IRQ // if that did it, clear the IRQ
//if (ioc_regs[IRQ_STATUS_A] == 0) //if (ioc_regs[IRQ_STATUS_A] == 0)
{ {
//printf("IRQ clear A\n"); //printf("IRQ clear A\n");
space.machine().device("maincpu")->execute().set_input_line(ARM_IRQ_LINE, CLEAR_LINE); machine().device("maincpu")->execute().set_input_line(ARM_IRQ_LINE, CLEAR_LINE);
} }
break; break;
case T0_LATCH_LO: case T0_LATCH_LO:
case T0_LATCH_HI: case T0_LATCH_HI:
ioc_regs[offset&0x1f] = data & 0xff; m_ioc_regs[offset&0x1f] = data & 0xff;
break; break;
case T1_LATCH_LO: case T1_LATCH_LO:
case T1_LATCH_HI: case T1_LATCH_HI:
ioc_regs[offset&0x1f] = data & 0xff; m_ioc_regs[offset&0x1f] = data & 0xff;
break; break;
case T2_LATCH_LO: case T2_LATCH_LO:
case T2_LATCH_HI: case T2_LATCH_HI:
ioc_regs[offset&0x1f] = data & 0xff; m_ioc_regs[offset&0x1f] = data & 0xff;
break; break;
case T3_LATCH_LO: case T3_LATCH_LO:
case T3_LATCH_HI: case T3_LATCH_HI:
ioc_regs[offset&0x1f] = data & 0xff; m_ioc_regs[offset&0x1f] = data & 0xff;
break; break;
case T0_LATCH: // Timer 0 latch case T0_LATCH: // Timer 0 latch
@ -634,22 +601,22 @@ static WRITE32_HANDLER( ioc_ctrl_w )
break; break;
case T0_GO: // Timer 0 start case T0_GO: // Timer 0 start
ioc_timercnt[0] = ioc_regs[T0_LATCH_HI]<<8 | ioc_regs[T0_LATCH_LO]; m_ioc_timercnt[0] = m_ioc_regs[T0_LATCH_HI]<<8 | m_ioc_regs[T0_LATCH_LO];
a310_set_timer(0); a310_set_timer(0);
break; break;
case T1_GO: // Timer 1 start case T1_GO: // Timer 1 start
ioc_timercnt[1] = ioc_regs[T1_LATCH_HI]<<8 | ioc_regs[T1_LATCH_LO]; m_ioc_timercnt[1] = m_ioc_regs[T1_LATCH_HI]<<8 | m_ioc_regs[T1_LATCH_LO];
a310_set_timer(1); a310_set_timer(1);
break; break;
case T2_GO: // Timer 2 start case T2_GO: // Timer 2 start
ioc_timercnt[2] = ioc_regs[T2_LATCH_HI]<<8 | ioc_regs[T2_LATCH_LO]; m_ioc_timercnt[2] = m_ioc_regs[T2_LATCH_HI]<<8 | m_ioc_regs[T2_LATCH_LO];
a310_set_timer(2); a310_set_timer(2);
break; break;
case T3_GO: // Timer 3 start case T3_GO: // Timer 3 start
ioc_timercnt[3] = ioc_regs[T3_LATCH_HI]<<8 | ioc_regs[T3_LATCH_LO]; m_ioc_timercnt[3] = m_ioc_regs[T3_LATCH_HI]<<8 | m_ioc_regs[T3_LATCH_LO];
a310_set_timer(3); a310_set_timer(3);
break; break;
@ -657,12 +624,12 @@ static WRITE32_HANDLER( ioc_ctrl_w )
if(!IOC_LOG) if(!IOC_LOG)
logerror("IOC: W %02x @ reg %s (PC=%x)\n", data&0xff, ioc_regnames[offset&0x1f], space.device() .safe_pc( )); logerror("IOC: W %02x @ reg %s (PC=%x)\n", data&0xff, ioc_regnames[offset&0x1f], space.device() .safe_pc( ));
ioc_regs[offset&0x1f] = data & 0xff; m_ioc_regs[offset&0x1f] = data & 0xff;
break; break;
} }
} }
READ32_HANDLER(archimedes_ioc_r) READ32_MEMBER(archimedes_state::archimedes_ioc_r)
{ {
UINT32 ioc_addr; UINT32 ioc_addr;
device_t *fdc = (device_t *)space.machine().device("wd1772"); device_t *fdc = (device_t *)space.machine().device("wd1772");
@ -718,7 +685,7 @@ READ32_HANDLER(archimedes_ioc_r)
return 0; return 0;
} }
WRITE32_HANDLER(archimedes_ioc_w) WRITE32_MEMBER(archimedes_state::archimedes_ioc_w)
{ {
UINT32 ioc_addr; UINT32 ioc_addr;
device_t *fdc = (device_t *)space.machine().device("wd1772"); device_t *fdc = (device_t *)space.machine().device("wd1772");
@ -782,51 +749,51 @@ WRITE32_HANDLER(archimedes_ioc_w)
logerror("(PC=%08x) I/O: W %x @ %x (mask %08x)\n", space.device().safe_pc(), data, (offset*4)+0x3000000, mem_mask); logerror("(PC=%08x) I/O: W %x @ %x (mask %08x)\n", space.device().safe_pc(), data, (offset*4)+0x3000000, mem_mask);
} }
READ32_HANDLER(archimedes_vidc_r) READ32_MEMBER(archimedes_state::archimedes_vidc_r)
{ {
return 0; return 0;
} }
static void vidc_dynamic_res_change(running_machine &machine) void archimedes_state::vidc_dynamic_res_change()
{ {
/* sanity checks - first pass */ /* sanity checks - first pass */
/* /*
total cycles + border end total cycles + border end
*/ */
if(vidc_regs[VIDC_HCR] && vidc_regs[VIDC_HBER] && if(m_vidc_regs[VIDC_HCR] && m_vidc_regs[VIDC_HBER] &&
vidc_regs[VIDC_VCR] && vidc_regs[VIDC_VBER]) m_vidc_regs[VIDC_VCR] && m_vidc_regs[VIDC_VBER])
{ {
/* sanity checks - second pass */ /* sanity checks - second pass */
/* /*
total cycles >= border end >= border start total cycles >= border end >= border start
*/ */
if((vidc_regs[VIDC_HCR] >= vidc_regs[VIDC_HBER]) && if((m_vidc_regs[VIDC_HCR] >= m_vidc_regs[VIDC_HBER]) &&
(vidc_regs[VIDC_HBER] >= vidc_regs[VIDC_HBSR]) && (m_vidc_regs[VIDC_HBER] >= m_vidc_regs[VIDC_HBSR]) &&
(vidc_regs[VIDC_VCR] >= vidc_regs[VIDC_VBER]) && (m_vidc_regs[VIDC_VCR] >= m_vidc_regs[VIDC_VBER]) &&
(vidc_regs[VIDC_VBER] >= vidc_regs[VIDC_VBSR])) (m_vidc_regs[VIDC_VBER] >= m_vidc_regs[VIDC_VBSR]))
{ {
rectangle visarea; rectangle visarea;
attoseconds_t refresh; attoseconds_t refresh;
visarea.min_x = 0; visarea.min_x = 0;
visarea.min_y = 0; visarea.min_y = 0;
visarea.max_x = vidc_regs[VIDC_HBER] - vidc_regs[VIDC_HBSR] - 1; visarea.max_x = m_vidc_regs[VIDC_HBER] - m_vidc_regs[VIDC_HBSR] - 1;
visarea.max_y = vidc_regs[VIDC_VBER] - vidc_regs[VIDC_VBSR]; visarea.max_y = m_vidc_regs[VIDC_VBER] - m_vidc_regs[VIDC_VBSR];
logerror("Configuring: htotal %d vtotal %d border %d x %d display %d x %d\n", logerror("Configuring: htotal %d vtotal %d border %d x %d display %d x %d\n",
vidc_regs[VIDC_HCR], vidc_regs[VIDC_VCR], m_vidc_regs[VIDC_HCR], m_vidc_regs[VIDC_VCR],
visarea.max_x, visarea.max_y, visarea.max_x, visarea.max_y,
vidc_regs[VIDC_HDER]-vidc_regs[VIDC_HDSR],vidc_regs[VIDC_VDER]-vidc_regs[VIDC_VDSR]+1); m_vidc_regs[VIDC_HDER]-m_vidc_regs[VIDC_HDSR],m_vidc_regs[VIDC_VDER]-m_vidc_regs[VIDC_VDSR]+1);
/* FIXME: pixel clock */ /* FIXME: pixel clock */
refresh = HZ_TO_ATTOSECONDS(pixel_rate[vidc_pixel_clk]*2) * vidc_regs[VIDC_HCR] * vidc_regs[VIDC_VCR]; refresh = HZ_TO_ATTOSECONDS(pixel_rate[m_vidc_pixel_clk]*2) * m_vidc_regs[VIDC_HCR] * m_vidc_regs[VIDC_VCR];
machine.primary_screen->configure(vidc_regs[VIDC_HCR], vidc_regs[VIDC_VCR], visarea, refresh); machine().primary_screen->configure(m_vidc_regs[VIDC_HCR], m_vidc_regs[VIDC_VCR], visarea, refresh);
} }
} }
} }
WRITE32_HANDLER(archimedes_vidc_w) WRITE32_MEMBER(archimedes_state::archimedes_vidc_w)
{ {
UINT32 reg = data>>24; UINT32 reg = data>>24;
UINT32 val = data & 0xffffff; UINT32 val = data & 0xffffff;
@ -868,7 +835,7 @@ WRITE32_HANDLER(archimedes_vidc_w)
if(reg == 0x40 && val & 0xfff) if(reg == 0x40 && val & 0xfff)
logerror("WARNING: border color write here (PC=%08x)!\n",space.device().safe_pc()); logerror("WARNING: border color write here (PC=%08x)!\n",space.device().safe_pc());
palette_set_color_rgb(space.machine(), reg >> 2, pal4bit(r), pal4bit(g), pal4bit(b) ); palette_set_color_rgb(machine(), reg >> 2, pal4bit(r), pal4bit(g), pal4bit(b) );
/* handle 8bpp colors here */ /* handle 8bpp colors here */
if(reg <= 0x3c) if(reg <= 0x3c)
@ -881,14 +848,14 @@ WRITE32_HANDLER(archimedes_vidc_w)
g = ((val & 0x030) >> 4) | ((i & 0x20) >> 3) | ((i & 0x40) >> 3); g = ((val & 0x030) >> 4) | ((i & 0x20) >> 3) | ((i & 0x40) >> 3);
r = ((val & 0x007) >> 0) | ((i & 0x10) >> 1); r = ((val & 0x007) >> 0) | ((i & 0x10) >> 1);
palette_set_color_rgb(space.machine(), (reg >> 2) + 0x100 + i, pal4bit(r), pal4bit(g), pal4bit(b) ); palette_set_color_rgb(machine(), (reg >> 2) + 0x100 + i, pal4bit(r), pal4bit(g), pal4bit(b) );
} }
} }
} }
else if (reg >= 0x60 && reg <= 0x7c) else if (reg >= 0x60 && reg <= 0x7c)
{ {
vidc_stereo_reg[(reg >> 2) & 7] = val & 0x07; m_vidc_stereo_reg[(reg >> 2) & 7] = val & 0x07;
// popmessage("%02x %02x %02x %02x %02x %02x %02x %02x",vidc_stereo_reg[0],vidc_stereo_reg[1],vidc_stereo_reg[2],vidc_stereo_reg[3] // popmessage("%02x %02x %02x %02x %02x %02x %02x %02x",vidc_stereo_reg[0],vidc_stereo_reg[1],vidc_stereo_reg[2],vidc_stereo_reg[3]
// ,vidc_stereo_reg[4],vidc_stereo_reg[5],vidc_stereo_reg[6],vidc_stereo_reg[7]); // ,vidc_stereo_reg[4],vidc_stereo_reg[5],vidc_stereo_reg[6],vidc_stereo_reg[7]);
@ -897,52 +864,52 @@ WRITE32_HANDLER(archimedes_vidc_w)
{ {
switch(reg) switch(reg)
{ {
case VIDC_HCR: vidc_regs[VIDC_HCR] = ((val >> 14)<<1)+1; break; case VIDC_HCR: m_vidc_regs[VIDC_HCR] = ((val >> 14)<<1)+1; break;
// case VIDC_HSWR: vidc_regs[VIDC_HSWR] = (val >> 14)+1; break; // case VIDC_HSWR: m_vidc_regs[VIDC_HSWR] = (val >> 14)+1; break;
case VIDC_HBSR: vidc_regs[VIDC_HBSR] = ((val >> 14)<<1)+1; break; case VIDC_HBSR: m_vidc_regs[VIDC_HBSR] = ((val >> 14)<<1)+1; break;
case VIDC_HDSR: vidc_regs[VIDC_HDSR] = (val >> 14); break; case VIDC_HDSR: m_vidc_regs[VIDC_HDSR] = (val >> 14); break;
case VIDC_HDER: vidc_regs[VIDC_HDER] = (val >> 14); break; case VIDC_HDER: m_vidc_regs[VIDC_HDER] = (val >> 14); break;
case VIDC_HBER: vidc_regs[VIDC_HBER] = ((val >> 14)<<1)+1; break; case VIDC_HBER: m_vidc_regs[VIDC_HBER] = ((val >> 14)<<1)+1; break;
// #define VIDC_HCSR 0x98 // #define VIDC_HCSR 0x98
// #define VIDC_HIR 0x9c // #define VIDC_HIR 0x9c
case VIDC_VCR: vidc_regs[VIDC_VCR] = ((val >> 14)<<1)+1; break; case VIDC_VCR: m_vidc_regs[VIDC_VCR] = ((val >> 14)<<1)+1; break;
// #define VIDC_VSWR 0xa4 // #define VIDC_VSWR 0xa4
case VIDC_VBSR: vidc_regs[VIDC_VBSR] = (val >> 14)+1; break; case VIDC_VBSR: m_vidc_regs[VIDC_VBSR] = (val >> 14)+1; break;
case VIDC_VDSR: vidc_regs[VIDC_VDSR] = (val >> 14)+1; break; case VIDC_VDSR: m_vidc_regs[VIDC_VDSR] = (val >> 14)+1; break;
case VIDC_VDER: vidc_regs[VIDC_VDER] = (val >> 14)+1; break; case VIDC_VDER: m_vidc_regs[VIDC_VDER] = (val >> 14)+1; break;
case VIDC_VBER: vidc_regs[VIDC_VBER] = (val >> 14)+1; break; case VIDC_VBER: m_vidc_regs[VIDC_VBER] = (val >> 14)+1; break;
// #define VIDC_VCSR 0xb8 // #define VIDC_VCSR 0xb8
// #define VIDC_VCER 0xbc // #define VIDC_VCER 0xbc
} }
//#ifdef DEBUG //#ifdef DEBUG
logerror("VIDC: %s = %d\n", vrnames[(reg-0x80)/4], vidc_regs[reg]); logerror("VIDC: %s = %d\n", vrnames[(reg-0x80)/4], m_vidc_regs[reg]);
//#endif //#endif
vidc_dynamic_res_change(space.machine()); vidc_dynamic_res_change();
} }
else if(reg == 0xe0) else if(reg == 0xe0)
{ {
vidc_bpp_mode = ((val & 0x0c) >> 2); m_vidc_bpp_mode = ((val & 0x0c) >> 2);
vidc_interlace = ((val & 0x40) >> 6); m_vidc_interlace = ((val & 0x40) >> 6);
vidc_pixel_clk = (val & 0x03); m_vidc_pixel_clk = (val & 0x03);
vidc_dynamic_res_change(space.machine()); vidc_dynamic_res_change();
} }
else else
{ {
logerror("VIDC: %x to register %x\n", val, reg); logerror("VIDC: %x to register %x\n", val, reg);
vidc_regs[reg] = val&0xffff; m_vidc_regs[reg] = val&0xffff;
} }
} }
READ32_HANDLER(archimedes_memc_r) READ32_MEMBER(archimedes_state::archimedes_memc_r)
{ {
return 0; return 0;
} }
WRITE32_HANDLER(archimedes_memc_w) WRITE32_MEMBER(archimedes_state::archimedes_memc_w)
{ {
// is it a register? // is it a register?
if ((data & 0x0fe00000) == 0x03600000) if ((data & 0x0fe00000) == 0x03600000)
@ -950,48 +917,48 @@ WRITE32_HANDLER(archimedes_memc_w)
switch ((data >> 17) & 7) switch ((data >> 17) & 7)
{ {
case 0: /* video init */ case 0: /* video init */
vidc_vidinit = ((data>>2)&0x7fff)*16; m_vidc_vidinit = ((data>>2)&0x7fff)*16;
//logerror("MEMC: VIDINIT %08x\n",vidc_vidinit); //logerror("MEMC: VIDINIT %08x\n",vidc_vidinit);
break; break;
case 1: /* video start */ case 1: /* video start */
vidc_vidstart = 0x2000000 | (((data>>2)&0x7fff)*16); m_vidc_vidstart = 0x2000000 | (((data>>2)&0x7fff)*16);
//logerror("MEMC: VIDSTART %08x\n",vidc_vidstart); //logerror("MEMC: VIDSTART %08x\n",vidc_vidstart);
break; break;
case 2: /* video end */ case 2: /* video end */
vidc_vidend = 0x2000000 | (((data>>2)&0x7fff)*16); m_vidc_vidend = 0x2000000 | (((data>>2)&0x7fff)*16);
//logerror("MEMC: VIDEND %08x\n",vidc_vidend); //logerror("MEMC: VIDEND %08x\n",vidc_vidend);
break; break;
case 4: /* sound start */ case 4: /* sound start */
//logerror("MEMC: SNDSTART %08x\n",data); //logerror("MEMC: SNDSTART %08x\n",data);
vidc_sndstart = 0x2000000 | ((data>>2)&0x7fff)*16; m_vidc_sndstart = 0x2000000 | ((data>>2)&0x7fff)*16;
ioc_regs[IRQ_STATUS_B] &= ~ARCHIMEDES_IRQB_SOUND_EMPTY; m_ioc_regs[IRQ_STATUS_B] &= ~ARCHIMEDES_IRQB_SOUND_EMPTY;
break; break;
case 5: /* sound end */ case 5: /* sound end */
//logerror("MEMC: SNDEND %08x\n",data); //logerror("MEMC: SNDEND %08x\n",data);
vidc_sndend = 0x2000000 | ((data>>2)&0x7fff)*16; m_vidc_sndend = 0x2000000 | ((data>>2)&0x7fff)*16;
break; break;
case 6: case 6:
vidc_sndcur = 0; m_vidc_sndcur = 0;
archimedes_request_irq_b(space.machine(), ARCHIMEDES_IRQB_SOUND_EMPTY); archimedes_request_irq_b(ARCHIMEDES_IRQB_SOUND_EMPTY);
break; break;
case 7: /* Control */ case 7: /* Control */
memc_pagesize = ((data>>2) & 3); m_memc_pagesize = ((data>>2) & 3);
logerror("(PC = %08x) MEMC: %x to Control (page size %d, %s, %s)\n", space.device().safe_pc(), data & 0x1ffc, page_sizes[memc_pagesize], ((data>>10)&1) ? "Video DMA on" : "Video DMA off", ((data>>11)&1) ? "Sound DMA on" : "Sound DMA off"); logerror("(PC = %08x) MEMC: %x to Control (page size %d, %s, %s)\n", space.device().safe_pc(), data & 0x1ffc, page_sizes[m_memc_pagesize], ((data>>10)&1) ? "Video DMA on" : "Video DMA off", ((data>>11)&1) ? "Sound DMA on" : "Sound DMA off");
video_dma_on = ((data>>10)&1); m_video_dma_on = ((data>>10)&1);
audio_dma_on = ((data>>11)&1); m_audio_dma_on = ((data>>11)&1);
if ((data>>10)&1) if ((data>>10)&1)
{ {
vidc_vidcur = 0; m_vidc_vidcur = 0;
vid_timer->adjust(space.machine().primary_screen->time_until_pos(vidc_regs[0xb4])); m_vid_timer->adjust(machine().primary_screen->time_until_pos(m_vidc_regs[0xb4]));
} }
if ((data>>11)&1) if ((data>>11)&1)
@ -999,11 +966,11 @@ WRITE32_HANDLER(archimedes_memc_w)
double sndhz; double sndhz;
/* FIXME: is the frequency correct? */ /* FIXME: is the frequency correct? */
sndhz = (250000.0 / 2) / (double)((vidc_regs[0xc0]&0xff)+2); sndhz = (250000.0 / 2) / (double)((m_vidc_regs[0xc0]&0xff)+2);
printf("MEMC: Starting audio DMA at %f Hz, buffer from %x to %x\n", sndhz, vidc_sndstart, vidc_sndend); printf("MEMC: Starting audio DMA at %f Hz, buffer from %x to %x\n", sndhz, m_vidc_sndstart, m_vidc_sndend);
snd_timer->adjust(attotime::zero, 0, attotime::from_hz(sndhz)); m_snd_timer->adjust(attotime::zero, 0, attotime::from_hz(sndhz));
} }
break; break;
@ -1045,14 +1012,14 @@ The physical page is encoded differently depending on the page size :
1 being bit 6 1 being bit 6
*/ */
WRITE32_HANDLER(archimedes_memc_page_w) WRITE32_MEMBER(archimedes_state::archimedes_memc_page_w)
{ {
UINT32 log, phys, memc; UINT32 log, phys, memc;
// perms = (data & 0x300)>>8; // perms = (data & 0x300)>>8;
log = phys = memc = 0; log = phys = memc = 0;
switch (memc_pagesize) switch (m_memc_pagesize)
{ {
case 0: case 0:
phys = data & 0x7f; phys = data & 0x7f;
@ -1083,10 +1050,10 @@ WRITE32_HANDLER(archimedes_memc_page_w)
// log >>= (12 + memc_pagesize); // log >>= (12 + memc_pagesize);
// always make sure ROM mode is disconnected when this occurs // always make sure ROM mode is disconnected when this occurs
memc_latchrom = 0; m_memc_latchrom = 0;
// now go ahead and set the mapping in the page table // now go ahead and set the mapping in the page table
memc_pages[log] = phys + (memc*0x80); m_memc_pages[log] = phys + (memc*0x80);
// printf("PC=%08x = MEMC_PAGE(%d): W %08x: log %x to phys %x, MEMC %d, perms %d\n", space.device().safe_pc(),memc_pagesize, data, log, phys, memc, perms); // printf("PC=%08x = MEMC_PAGE(%d): W %08x: log %x to phys %x, MEMC %d, perms %d\n", space.device().safe_pc(),memc_pagesize, data, log, phys, memc, perms);
} }

View File

@ -7,11 +7,7 @@
#include "emu.h" #include "emu.h"
#include "includes/archimds.h" #include "includes/archimds.h"
VIDEO_START( archimds_vidc ) UINT32 archimedes_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
}
SCREEN_UPDATE_RGB32( archimds_vidc )
{ {
int xstart,ystart,xend,yend; int xstart,ystart,xend,yend;
int res_x,res_y; int res_x,res_y;
@ -20,34 +16,34 @@ SCREEN_UPDATE_RGB32( archimds_vidc )
const UINT8 x_step[4] = { 5, 7, 11, 19 }; const UINT8 x_step[4] = { 5, 7, 11, 19 };
/* border color */ /* border color */
bitmap.fill(screen.machine().pens[0x10], cliprect); bitmap.fill(machine().pens[0x10], cliprect);
/* define X display area through BPP mode register */ /* define X display area through BPP mode register */
calc_dxs = (vidc_regs[VIDC_HDSR]*2)+x_step[vidc_bpp_mode & 3]; calc_dxs = (m_vidc_regs[VIDC_HDSR]*2)+x_step[m_vidc_bpp_mode & 3];
calc_dxe = (vidc_regs[VIDC_HDER]*2)+x_step[vidc_bpp_mode & 3]; calc_dxe = (m_vidc_regs[VIDC_HDER]*2)+x_step[m_vidc_bpp_mode & 3];
/* now calculate display clip rectangle start/end areas */ /* now calculate display clip rectangle start/end areas */
xstart = (calc_dxs)-vidc_regs[VIDC_HBSR]; xstart = (calc_dxs)-m_vidc_regs[VIDC_HBSR];
ystart = (vidc_regs[VIDC_VDSR])-vidc_regs[VIDC_VBSR]; ystart = (m_vidc_regs[VIDC_VDSR])-m_vidc_regs[VIDC_VBSR];
xend = (calc_dxe)+xstart; xend = (calc_dxe)+xstart;
yend = vidc_regs[VIDC_VDER]+ystart; yend = m_vidc_regs[VIDC_VDER]+ystart;
/* disable the screen if display params are invalid */ /* disable the screen if display params are invalid */
if(xstart > xend || ystart > yend) if(xstart > xend || ystart > yend)
return 0; return 0;
xsize = calc_dxe-calc_dxs; xsize = calc_dxe-calc_dxs;
ysize = vidc_regs[VIDC_VDER]-vidc_regs[VIDC_VDSR]; ysize = m_vidc_regs[VIDC_VDER]-m_vidc_regs[VIDC_VDSR];
{ {
int count; int count;
int x,y,xi; int x,y,xi;
UINT8 pen; UINT8 pen;
static UINT8 *vram = screen.machine().root_device().memregion("vram")->base(); static UINT8 *vram = machine().root_device().memregion("vram")->base();
count = (0); count = (0);
switch(vidc_bpp_mode) switch(m_vidc_bpp_mode)
{ {
case 0: //1 bpp case 0: //1 bpp
{ {
@ -60,19 +56,19 @@ SCREEN_UPDATE_RGB32( archimds_vidc )
for(xi=0;xi<8;xi++) for(xi=0;xi<8;xi++)
{ {
res_x = x+xi+xstart; res_x = x+xi+xstart;
res_y = (y+ystart)*(vidc_interlace+1); res_y = (y+ystart)*(m_vidc_interlace+1);
if(vidc_interlace) if(m_vidc_interlace)
{ {
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend) if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend)
bitmap.pix32(res_y, res_x) = screen.machine().pens[(pen>>(xi))&0x1]; bitmap.pix32(res_y, res_x) = machine().pens[(pen>>(xi))&0x1];
if (cliprect.contains(res_x, res_y+1) && (res_x) <= xend && (res_y+1) <= yend) if (cliprect.contains(res_x, res_y+1) && (res_x) <= xend && (res_y+1) <= yend)
bitmap.pix32(res_y+1, res_x) = screen.machine().pens[(pen>>(xi))&0x1]; bitmap.pix32(res_y+1, res_x) = machine().pens[(pen>>(xi))&0x1];
} }
else else
{ {
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend) if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend)
bitmap.pix32(res_y, res_x) = screen.machine().pens[(pen>>(xi))&0x1]; bitmap.pix32(res_y, res_x) = machine().pens[(pen>>(xi))&0x1];
} }
} }
@ -90,19 +86,19 @@ SCREEN_UPDATE_RGB32( archimds_vidc )
pen = vram[count]; pen = vram[count];
res_x = x+xstart; res_x = x+xstart;
res_y = (y+ystart)*(vidc_interlace+1); res_y = (y+ystart)*(m_vidc_interlace+1);
if(vidc_interlace) if(m_vidc_interlace)
{ {
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend) if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend)
bitmap.pix32(res_y, res_x) = screen.machine().pens[(pen&0xff)+0x100]; bitmap.pix32(res_y, res_x) = machine().pens[(pen&0xff)+0x100];
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y+1) <= yend) if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y+1) <= yend)
bitmap.pix32(res_y+1, res_x) = screen.machine().pens[(pen&0xff)+0x100]; bitmap.pix32(res_y+1, res_x) = machine().pens[(pen&0xff)+0x100];
} }
else else
{ {
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend) if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend)
bitmap.pix32(res_y, res_x) = screen.machine().pens[(pen&0xff)+0x100]; bitmap.pix32(res_y, res_x) = machine().pens[(pen&0xff)+0x100];
} }
count++; count++;

View File

@ -65,37 +65,39 @@
#include "machine/ram.h" #include "machine/ram.h"
class a310_state : public driver_device class a310_state : public archimedes_state
{ {
public: public:
a310_state(const machine_config &mconfig, device_type type, const char *tag) a310_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag), : archimedes_state(mconfig, type, tag),
m_physram(*this, "physicalram") { } m_physram(*this, "physicalram") { }
required_shared_ptr<UINT32> m_physram; required_shared_ptr<UINT32> m_physram;
DECLARE_READ32_MEMBER(a310_psy_wram_r); DECLARE_READ32_MEMBER(a310_psy_wram_r);
DECLARE_WRITE32_MEMBER(a310_psy_wram_w); DECLARE_WRITE32_MEMBER(a310_psy_wram_w);
DECLARE_WRITE_LINE_MEMBER(a310_wd177x_intrq_w);
DECLARE_WRITE_LINE_MEMBER(a310_wd177x_drq_w);
DECLARE_DRIVER_INIT(a310); DECLARE_DRIVER_INIT(a310);
virtual void machine_start(); virtual void machine_start();
virtual void machine_reset(); virtual void machine_reset();
}; };
static WRITE_LINE_DEVICE_HANDLER( a310_wd177x_intrq_w ) WRITE_LINE_MEMBER(a310_state::a310_wd177x_intrq_w)
{ {
if (state) if (state)
archimedes_request_fiq(device->machine(), ARCHIMEDES_FIQ_FLOPPY); archimedes_request_fiq(ARCHIMEDES_FIQ_FLOPPY);
else else
archimedes_clear_fiq(device->machine(), ARCHIMEDES_FIQ_FLOPPY); archimedes_clear_fiq(ARCHIMEDES_FIQ_FLOPPY);
} }
static WRITE_LINE_DEVICE_HANDLER( a310_wd177x_drq_w ) WRITE_LINE_MEMBER(a310_state::a310_wd177x_drq_w)
{ {
if (state) if (state)
archimedes_request_fiq(device->machine(), ARCHIMEDES_FIQ_FLOPPY_DRQ); archimedes_request_fiq(ARCHIMEDES_FIQ_FLOPPY_DRQ);
else else
archimedes_clear_fiq(device->machine(), ARCHIMEDES_FIQ_FLOPPY_DRQ); archimedes_clear_fiq(ARCHIMEDES_FIQ_FLOPPY_DRQ);
} }
READ32_MEMBER(a310_state::a310_psy_wram_r) READ32_MEMBER(a310_state::a310_psy_wram_r)
@ -115,12 +117,12 @@ DRIVER_INIT_MEMBER(a310_state,a310)
machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler( 0x02000000, 0x02000000+(ram_size-1), read32_delegate(FUNC(a310_state::a310_psy_wram_r), this), write32_delegate(FUNC(a310_state::a310_psy_wram_w), this)); machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler( 0x02000000, 0x02000000+(ram_size-1), read32_delegate(FUNC(a310_state::a310_psy_wram_r), this), write32_delegate(FUNC(a310_state::a310_psy_wram_w), this));
archimedes_driver_init(machine()); archimedes_driver_init();
} }
void a310_state::machine_start() void a310_state::machine_start()
{ {
archimedes_init(machine()); archimedes_init();
// reset the DAC to centerline // reset the DAC to centerline
//machine().device<dac_device>("dac")->write_signed8(0x80); //machine().device<dac_device>("dac")->write_signed8(0x80);
@ -128,16 +130,16 @@ void a310_state::machine_start()
void a310_state::machine_reset() void a310_state::machine_reset()
{ {
archimedes_reset(machine()); archimedes_reset();
} }
static ADDRESS_MAP_START( a310_mem, AS_PROGRAM, 32, a310_state ) static ADDRESS_MAP_START( a310_mem, AS_PROGRAM, 32, a310_state )
AM_RANGE(0x00000000, 0x01ffffff) AM_READWRITE_LEGACY(archimedes_memc_logical_r, archimedes_memc_logical_w) AM_RANGE(0x00000000, 0x01ffffff) AM_READWRITE(archimedes_memc_logical_r, archimedes_memc_logical_w)
AM_RANGE(0x02000000, 0x02ffffff) AM_RAM AM_SHARE("physicalram") /* physical RAM - 16 MB for now, should be 512k for the A310 */ AM_RANGE(0x02000000, 0x02ffffff) AM_RAM AM_SHARE("physicalram") /* physical RAM - 16 MB for now, should be 512k for the A310 */
AM_RANGE(0x03000000, 0x033fffff) AM_READWRITE_LEGACY(archimedes_ioc_r, archimedes_ioc_w) AM_RANGE(0x03000000, 0x033fffff) AM_READWRITE(archimedes_ioc_r, archimedes_ioc_w)
AM_RANGE(0x03400000, 0x035fffff) AM_READWRITE_LEGACY(archimedes_vidc_r, archimedes_vidc_w) AM_RANGE(0x03400000, 0x035fffff) AM_READWRITE(archimedes_vidc_r, archimedes_vidc_w)
AM_RANGE(0x03600000, 0x037fffff) AM_READWRITE_LEGACY(archimedes_memc_r, archimedes_memc_w) AM_RANGE(0x03600000, 0x037fffff) AM_READWRITE(archimedes_memc_r, archimedes_memc_w)
AM_RANGE(0x03800000, 0x03ffffff) AM_ROM AM_REGION("maincpu", 0) AM_WRITE_LEGACY(archimedes_memc_page_w) AM_RANGE(0x03800000, 0x03ffffff) AM_ROM AM_REGION("maincpu", 0) AM_WRITE(archimedes_memc_page_w)
ADDRESS_MAP_END ADDRESS_MAP_END
@ -255,8 +257,8 @@ INPUT_PORTS_END
static const wd17xx_interface a310_wd17xx_interface = static const wd17xx_interface a310_wd17xx_interface =
{ {
DEVCB_NULL, DEVCB_NULL,
DEVCB_LINE(a310_wd177x_intrq_w), DEVCB_DRIVER_LINE_MEMBER(a310_state, a310_wd177x_intrq_w),
DEVCB_LINE(a310_wd177x_drq_w), DEVCB_DRIVER_LINE_MEMBER(a310_state, a310_wd177x_drq_w),
{FLOPPY_0, FLOPPY_1, FLOPPY_2, FLOPPY_3} {FLOPPY_0, FLOPPY_1, FLOPPY_2, FLOPPY_3}
}; };
@ -279,12 +281,10 @@ static MACHINE_CONFIG_START( a310, a310_state )
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MCFG_SCREEN_SIZE(1280, 1024) //TODO: default screen size MCFG_SCREEN_SIZE(1280, 1024) //TODO: default screen size
MCFG_SCREEN_VISIBLE_AREA(0*8, 1280 - 1, 0*16, 1024 - 1) MCFG_SCREEN_VISIBLE_AREA(0*8, 1280 - 1, 0*16, 1024 - 1)
MCFG_SCREEN_UPDATE_STATIC(archimds_vidc) MCFG_SCREEN_UPDATE_DRIVER(archimedes_state, screen_update)
MCFG_PALETTE_LENGTH(32768) MCFG_PALETTE_LENGTH(32768)
MCFG_VIDEO_START(archimds_vidc)
MCFG_RAM_ADD(RAM_TAG) MCFG_RAM_ADD(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("2M") MCFG_RAM_DEFAULT_SIZE("2M")
MCFG_RAM_EXTRA_OPTIONS("512K, 1M, 4M, 8M, 16M") MCFG_RAM_EXTRA_OPTIONS("512K, 1M, 4M, 8M, 16M")