From 800a422e42da5e3bdd5e75d91a5ceb7e2d3b536f Mon Sep 17 00:00:00 2001 From: Sandro Ronco Date: Sat, 1 May 2021 23:07:51 +0200 Subject: [PATCH] ertictac.cpp: convert to use IOC and MEMC devices. --- scripts/src/machine.lua | 12 - scripts/target/mame/arcade.lua | 3 - scripts/target/mame/mess.lua | 2 - src/devices/machine/aakart.cpp | 209 ------- src/devices/machine/aakart.h | 81 --- src/mame/drivers/aa310.cpp | 18 + src/mame/drivers/ertictac.cpp | 74 ++- src/mame/includes/archimds.h | 168 ------ src/mame/machine/archimds.cpp | 1018 -------------------------------- 9 files changed, 68 insertions(+), 1517 deletions(-) delete mode 100644 src/devices/machine/aakart.cpp delete mode 100644 src/devices/machine/aakart.h delete mode 100644 src/mame/includes/archimds.h delete mode 100644 src/mame/machine/archimds.cpp diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index b6bb6d7aec8..25d518e5065 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -632,18 +632,6 @@ if (MACHINES["8530SCC"]~=null) then } end ---------------------------------------------------- --- ---@src/devices/machine/aakart.h,MACHINES["AAKARTDEV"] = true ---------------------------------------------------- - -if (MACHINES["AAKARTDEV"]~=null) then - files { - MAME_DIR .. "src/devices/machine/aakart.cpp", - MAME_DIR .. "src/devices/machine/aakart.h", - } -end - --------------------------------------------------- -- --@src/devices/machine/adc0804.h,MACHINES["ADC0804"] = true diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 4565f6472e7..c383b647fcd 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -441,7 +441,6 @@ MACHINES["TTL74259"] = true MACHINES["TTL7474"] = true MACHINES["KBDC8042"] = true MACHINES["I8257"] = true -MACHINES["AAKARTDEV"] = true --MACHINES["ACIA6850"] = true MACHINES["ADC0804"] = true MACHINES["ADC0808"] = true @@ -1045,8 +1044,6 @@ files { MAME_DIR .. "src/mame/drivers/ertictac.cpp", MAME_DIR .. "src/mame/drivers/ssfindo.cpp", MAME_DIR .. "src/mame/drivers/aristmk5.cpp", - MAME_DIR .. "src/mame/machine/archimds.cpp", - MAME_DIR .. "src/mame/includes/archimds.h", } createMAMEProjects(_target, _subtarget, "adp") diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 75983e71ea6..dbd542f04fc 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -455,7 +455,6 @@ MACHINES["MPCC68561"] = true MACHINES["68681"] = true MACHINES["7200FIFO"] = true MACHINES["8530SCC"] = true -MACHINES["AAKARTDEV"] = true MACHINES["ACIA6850"] = true MACHINES["ACORN_IOC"] = true MACHINES["ACORN_MEMC"] = true @@ -1484,7 +1483,6 @@ function createProjects_mame_mess(_target, _subtarget) if (_subtarget=="mess") then createMESSProjects(_target, _subtarget, "mameshared") files { - MAME_DIR .. "src/mame/machine/archimds.cpp", MAME_DIR .. "src/mame/machine/amiga.cpp", MAME_DIR .. "src/mame/video/amiga.cpp", MAME_DIR .. "src/mame/video/amigaaga.cpp", diff --git a/src/devices/machine/aakart.cpp b/src/devices/machine/aakart.cpp deleted file mode 100644 index 0ffb88e094e..00000000000 --- a/src/devices/machine/aakart.cpp +++ /dev/null @@ -1,209 +0,0 @@ -// license:LGPL-2.1+ -// copyright-holders:Angelo Salese -/*************************************************************************** - -Acorn Archimedes KART interface - -TODO: -- FIFO - -***************************************************************************/ - -#include "emu.h" -#include "machine/aakart.h" - - - -//************************************************************************** -// GLOBAL VARIABLES -//************************************************************************** - -// device type definition -DEFINE_DEVICE_TYPE(AAKART, aakart_device, "aakart", "Acorn Archimedes KART") - -#define HRST 0xff -#define RAK1 0xfe -#define RAK2 0xfd -#define BACK 0x3f -#define SMAK 0x33 /* keyboard + mouse ack */ -#define MACK 0x32 /* mouse ack */ -#define SACK 0x31 /* keyboard ack */ -#define NACK 0x30 /* no data ack */ -#define RQID 0x20 - -//************************************************************************** -// LIVE DEVICE -//************************************************************************** - -//------------------------------------------------- -// aakart_device - constructor -//------------------------------------------------- - -aakart_device::aakart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, AAKART, tag, owner, clock), m_rxtimer(nullptr), - m_txtimer(nullptr), m_mousetimer(nullptr), m_keybtimer(nullptr), - m_out_tx_cb(*this), - m_out_rx_cb(*this), - m_tx_latch(0), m_rx(0), m_new_command(0), m_status(0), m_mouse_enable(0), m_keyb_enable(0) -{ -} - - -//------------------------------------------------- -// device_validity_check - perform validity checks -// on this device -//------------------------------------------------- - -void aakart_device::device_validity_check(validity_checker &valid) const -{ -} - - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void aakart_device::device_start() -{ - m_out_tx_cb.resolve_safe(); - m_out_rx_cb.resolve_safe(); - m_rxtimer = timer_alloc(RX_TIMER); - m_rxtimer->adjust(attotime::from_hz(clock()), 0, attotime::from_hz(clock())); - m_txtimer = timer_alloc(TX_TIMER); - m_txtimer->adjust(attotime::from_hz(1), 0, attotime::from_hz(clock())); - m_mousetimer = timer_alloc(MOUSE_TIMER); - m_mousetimer->adjust(attotime::from_hz(clock()), 0, attotime::from_hz(clock())); - m_keybtimer = timer_alloc(KEYB_TIMER); - m_keybtimer->adjust(attotime::from_hz(clock()), 0, attotime::from_hz(clock())); -} - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void aakart_device::device_reset() -{ - m_status = STATUS_HRST; - m_new_command = 0; - m_rx = -1; - m_keyb_enable = 0; - m_mouse_enable = 0; - m_queue_size = 0; -} - -//------------------------------------------------- -// device_timer - handler timer events -//------------------------------------------------- - -void aakart_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - if(id == TX_TIMER && m_new_command) - { - switch(m_tx_latch) - { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - // ---- -x-- scroll lock - // ---- --x- num lock - // ---- ---x caps lock - break; - case 0x20: - m_rx = 0x81; - m_out_tx_cb(ASSERT_LINE); - break; - case 0x30: - case 0x31: - case 0x32: - case 0x33: - m_keyb_enable = m_tx_latch & 1; - m_mouse_enable = (m_tx_latch & 2) >> 1; - if(m_queue_size) - { - m_rx = m_queue[0] & 0xff; - m_out_tx_cb(ASSERT_LINE); - } - break; - case 0x3f: - if(m_queue_size) - { - m_rx = (m_queue[0] >> 8) & 0xff; - m_out_tx_cb(ASSERT_LINE); - - m_queue_size--; - for(int i=0; i aakart_device - -class aakart_device : public device_t -{ -public: - // construction/destruction - aakart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - auto out_tx_callback() { return m_out_tx_cb.bind(); } - auto out_rx_callback() { return m_out_rx_cb.bind(); } - - // I/O operations - void write(uint8_t data); - uint8_t read(); - void send_keycode_down(uint8_t row, uint8_t col); - void send_keycode_up(uint8_t row, uint8_t col); - void send_mouse(uint8_t x, uint8_t y); - -protected: - // device-level overrides - virtual void device_validity_check(validity_checker &valid) const override; - virtual void device_start() override; - virtual void device_reset() override; - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - -private: - enum { - STATUS_NORMAL = 0, - STATUS_KEYUP, - STATUS_KEYDOWN, - STATUS_MOUSE, - STATUS_HRST, - STATUS_UNDEFINED - }; - - static const device_timer_id RX_TIMER = 1; - static const device_timer_id TX_TIMER = 2; - static const device_timer_id MOUSE_TIMER = 3; - static const device_timer_id KEYB_TIMER = 4; - emu_timer * m_rxtimer; - emu_timer * m_txtimer; - emu_timer * m_mousetimer; - emu_timer * m_keybtimer; - - devcb_write_line m_out_tx_cb; - devcb_write_line m_out_rx_cb; - uint8_t m_tx_latch; - //uint8_t m_rx_latch; - uint8_t m_rx; - uint8_t m_new_command; - uint8_t m_status; - uint8_t m_mouse_enable; - uint8_t m_keyb_enable; - int m_queue_size; - uint16_t m_queue[0x10]; -}; - - -// device type definition -DECLARE_DEVICE_TYPE(AAKART, aakart_device) - -#endif // MAME_MACHINE_AAKART_H diff --git a/src/mame/drivers/aa310.cpp b/src/mame/drivers/aa310.cpp index 58b4d48e9f7..d614e72961b 100644 --- a/src/mame/drivers/aa310.cpp +++ b/src/mame/drivers/aa310.cpp @@ -73,6 +73,24 @@ * 3400000 - 35FFFFF - VICD10 (write - supervisor only) * 3600000 - 3FFFFFF - MEMC (write - supervisor only) * +======================================================================================= + * + * Archimedes IOC interrupts: + * IL0 Podule FIQ + * IL1 Sound Empty + * IL2 Serial + * IL3 HDD + * IL4 Disc Change + * IL5 Podule IRQ + * IL6 Printer Busy + * IL7 Serial Ring + * IF Printer Ack + * IR VBL + * POR Reset + * FH0 Floppy DRQ + * FH1 Floppy IRQ + * FL Econet + * *****************************************************************************/ /* DASM of code (bios 2 / RISC OS 2) diff --git a/src/mame/drivers/ertictac.cpp b/src/mame/drivers/ertictac.cpp index 2b1274cb6f6..2936f37d545 100644 --- a/src/mame/drivers/ertictac.cpp +++ b/src/mame/drivers/ertictac.cpp @@ -23,17 +23,24 @@ PCB has a single OSC at 24MHz *******************************************************************************************/ #include "emu.h" -#include "includes/archimds.h" #include "cpu/arm/arm.h" -#include "machine/aakart.h" +#include "machine/acorn_ioc.h" +#include "machine/acorn_memc.h" +#include "machine/acorn_vidc.h" +#include "machine/pcf8583.h" #include "screen.h" -class ertictac_state : public archimedes_state +class ertictac_state : public driver_device { public: ertictac_state(const machine_config &mconfig, device_type type, const char *tag) - : archimedes_state(mconfig, type, tag) { } + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_ioc(*this, "ioc") + , m_memc(*this, "memc") + , m_vidc10(*this, "vidc") + { } void ertictac(machine_config &config); @@ -44,15 +51,21 @@ private: virtual void machine_start() override; virtual void machine_reset() override; INTERRUPT_GEN_MEMBER(ertictac_podule_irq); + void ertictac_arm_map(address_map &map); void ertictac_map(address_map &map); + + required_device m_maincpu; + required_device m_ioc; + required_device m_memc; + required_device m_vidc10; }; uint32_t ertictac_state::ertictac_podule_r(offs_t offset) { - archimedes_clear_irq_b(ARCHIMEDES_IRQB_PODULE_IRQ); + m_ioc->il5_w(CLEAR_LINE); - switch(offset) + switch(offset & 0x3fff) { case 0x04/4: return ioport("DSW1")->read() & 0xff; case 0x08/4: return ioport("DSW2")->read() & 0xff; @@ -64,17 +77,22 @@ uint32_t ertictac_state::ertictac_podule_r(offs_t offset) return 0; } + +void ertictac_state::ertictac_arm_map(address_map &map) +{ + map(0x00000000, 0x01ffffff).rw(m_memc, FUNC(acorn_memc_device::logical_r), FUNC(acorn_memc_device::logical_w)); + map(0x02000000, 0x03ffffff).rw(m_memc, FUNC(acorn_memc_device::high_mem_r), FUNC(acorn_memc_device::high_mem_w)); +} + void ertictac_state::ertictac_map(address_map &map) { - map(0x00000000, 0x01ffffff).rw(FUNC(ertictac_state::archimedes_memc_logical_r), FUNC(ertictac_state::archimedes_memc_logical_w)); + map(0x00000000, 0x01ffffff).rw(m_memc, FUNC(acorn_memc_device::logical_r), FUNC(acorn_memc_device::logical_w)); map(0x02000000, 0x02ffffff).ram().share("physicalram"); /* physical RAM - 16 MB for now, should be 512k for the A310 */ - map(0x03000000, 0x033fffff).rw(FUNC(ertictac_state::archimedes_ioc_r), FUNC(ertictac_state::archimedes_ioc_w)); - map(0x03340000, 0x0334001f).r(FUNC(ertictac_state::ertictac_podule_r)); - map(0x033c0000, 0x033c001f).r(FUNC(ertictac_state::ertictac_podule_r)); - map(0x03400000, 0x035fffff).w(m_vidc, FUNC(acorn_vidc10_device::write)); - map(0x03600000, 0x037fffff).w(FUNC(ertictac_state::archimedes_memc_w)); - map(0x03800000, 0x03ffffff).rom().region("maincpu", 0).w(FUNC(ertictac_state::archimedes_memc_page_w)); + map(0x03000000, 0x033fffff).m(m_ioc, FUNC(acorn_ioc_device::map)); + map(0x03400000, 0x035fffff).w(m_vidc10, FUNC(acorn_vidc10_device::write)); + map(0x03600000, 0x037fffff).w(m_memc, FUNC(acorn_memc_device::registers_w)); + map(0x03800000, 0x03ffffff).rom().region("maincpu", 0).w(m_memc, FUNC(acorn_memc_device::page_w)); } static INPUT_PORTS_START( ertictac ) @@ -200,40 +218,48 @@ INPUT_PORTS_END void ertictac_state::init_ertictac() { - archimedes_driver_init(); } void ertictac_state::machine_start() { - archimedes_init(); } void ertictac_state::machine_reset() { - archimedes_reset(); } INTERRUPT_GEN_MEMBER(ertictac_state::ertictac_podule_irq) { - archimedes_request_irq_b(ARCHIMEDES_IRQB_PODULE_IRQ); + m_ioc->il5_w(ASSERT_LINE); } void ertictac_state::ertictac(machine_config &config) { ARM(config, m_maincpu, 24_MHz_XTAL/3); /* guess, 12MHz 8MHz or 6MHz, what's the correct divider 2, 3 or 4? */ - m_maincpu->set_addrmap(AS_PROGRAM, &ertictac_state::ertictac_map); + m_maincpu->set_addrmap(AS_PROGRAM, &ertictac_state::ertictac_arm_map); m_maincpu->set_periodic_int(FUNC(ertictac_state::ertictac_podule_irq), attotime::from_hz(60)); // FIXME: timing of this PCF8583(config, "i2cmem", 32.768_kHz_XTAL); // TODO: Are we sure that this HW have I2C device? -// AAKART(config, m_kart, 24_MHz_XTAL/3); // TODO: frequency + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.screen_vblank().set(m_ioc, FUNC(acorn_ioc_device::ir_w)); + screen.screen_vblank().append(m_memc, FUNC(acorn_memc_device::vidrq_w)); - SCREEN(config, "screen", SCREEN_TYPE_RASTER); + ACORN_MEMC(config, m_memc, 24_MHz_XTAL/3, m_vidc10); + m_memc->set_addrmap(0, &ertictac_state::ertictac_map); + m_memc->sirq_w().set(m_ioc, FUNC(acorn_ioc_device::il1_w)); - ACORN_VIDC10(config, m_vidc, 24_MHz_XTAL); - m_vidc->set_screen("screen"); - m_vidc->vblank().set(FUNC(ertictac_state::vblank_irq)); - m_vidc->sound_drq().set(FUNC(ertictac_state::sound_drq)); + ACORN_IOC(config, m_ioc, 24_MHz_XTAL/3); + m_ioc->fiq_w().set_inputline(m_maincpu, ARM_FIRQ_LINE); + m_ioc->irq_w().set_inputline(m_maincpu, ARM_IRQ_LINE); + m_ioc->peripheral_r<4>().set(FUNC(ertictac_state::ertictac_podule_r)); + m_ioc->gpio_r<0>().set("i2cmem", FUNC(pcf8583_device::sda_r)); + m_ioc->gpio_w<0>().set("i2cmem", FUNC(pcf8583_device::sda_w)); + m_ioc->gpio_w<1>().set("i2cmem", FUNC(pcf8583_device::scl_w)); + + ACORN_VIDC10(config, m_vidc10, 24_MHz_XTAL); + m_vidc10->set_screen("screen"); + m_vidc10->sound_drq().set(m_memc, FUNC(acorn_memc_device::sndrq_w)); } ROM_START( ertictac ) diff --git a/src/mame/includes/archimds.h b/src/mame/includes/archimds.h deleted file mode 100644 index fd97d8414a3..00000000000 --- a/src/mame/includes/archimds.h +++ /dev/null @@ -1,168 +0,0 @@ -// license:LGPL-2.1+ -// copyright-holders:Angelo Salese, R. Belmont, Juergen Buchmueller -/****************************************************************************** - * - * Acorn Archimedes custom chips (IOC, MEMC, VIDC) - * - *****************************************************************************/ - -#ifndef MAME_INCLUDES_ARCHIMEDES_H -#define MAME_INCLUDES_ARCHIMEDES_H - -#include "cpu/arm/arm.h" -#include "imagedev/floppy.h" -#include "machine/aakart.h" -#include "machine/pcf8583.h" -#include "machine/wd_fdc.h" -#include "machine/acorn_vidc.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_FORCE (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) - -class archimedes_state : public driver_device -{ -public: - archimedes_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_kart(*this, "kart"), - m_maincpu(*this, "maincpu"), - m_rtc(*this, "i2cmem"), - m_vidc(*this, "vidc"), - m_fdc(*this, "fdc"), - m_floppy0(*this, "fdc:0"), - m_floppy1(*this, "fdc:1"), - m_region_maincpu(*this, "maincpu"), - m_joy(*this, "joy_p%u",1) - { } - - optional_device m_kart; - void archimedes_init(); - void archimedes_reset(); - void archimedes_driver_init(); - - void archimedes_request_irq_a(int mask); - void archimedes_request_irq_b(int mask); - void archimedes_request_fiq(int mask); - void archimedes_clear_irq_a(int mask); - void archimedes_clear_irq_b(int mask); - void archimedes_clear_fiq(int mask); - - uint32_t aristmk5_drame_memc_logical_r(offs_t offset); - uint32_t archimedes_memc_logical_r(offs_t offset); - void archimedes_memc_logical_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - void archimedes_memc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - void archimedes_memc_page_w(uint32_t data); - uint32_t archimedes_ioc_r(offs_t offset, uint32_t mem_mask = ~0); - void archimedes_ioc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - DECLARE_WRITE_LINE_MEMBER( a310_kart_rx_w ); - DECLARE_WRITE_LINE_MEMBER( a310_kart_tx_w ); - - uint8_t m_i2c_clk; - int16_t m_memc_pages[0x2000]; // the logical RAM area is 32 megs, and the smallest page size is 4k - uint8_t m_ioc_regs[0x80/4]; - - uint32_t 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) override; - -protected: - required_device m_maincpu; - optional_device m_rtc; - required_device m_vidc; - optional_device m_fdc; - optional_device m_floppy0; - optional_device m_floppy1; - required_memory_region m_region_maincpu; - optional_ioport_array<2> m_joy; - - DECLARE_WRITE_LINE_MEMBER( vblank_irq ); - DECLARE_WRITE_LINE_MEMBER( sound_drq ); - -private: - - 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 latch_timer_cnt(int tmr); - void a310_set_timer(int tmr); - uint32_t ioc_ctrl_r(offs_t offset); - void ioc_ctrl_w(offs_t offset, uint32_t data); - - uint32_t *m_archimedes_memc_physmem; - uint32_t m_memc_pagesize; - int m_memc_latchrom; - uint32_t m_ioc_timercnt[4], m_ioc_timerout[4]; - uint32_t m_vidc_vidstart, m_vidc_vidend, m_vidc_vidinit, m_vidc_vidcur, m_vidc_cinit; - uint32_t m_vidc_sndstart, m_vidc_sndend, m_vidc_sndcur, m_vidc_sndendcur; - uint8_t m_video_dma_on,m_audio_dma_on; - bool m_cursor_enabled; - emu_timer *m_timer[4]; - uint8_t m_floppy_select; - bool check_floppy_ready(); - uint8_t m_joy_serial_data; -}; - -/* IOC registers */ - -#define CONTROL 0x00/4 -#define KART 0x04/4 // Keyboard Asynchronous Receiver Transmitter - -#define IRQ_STATUS_A 0x10/4 -#define IRQ_REQUEST_A 0x14/4 -#define IRQ_MASK_A 0x18/4 -#define IRQ_STATUS_B 0x20/4 -#define IRQ_REQUEST_B 0x24/4 -#define IRQ_MASK_B 0x28/4 - -#define FIQ_STATUS 0x30/4 -#define FIQ_REQUEST 0x34/4 -#define FIQ_MASK 0x38/4 - -#define T0_LATCH_LO 0x40/4 -#define T0_LATCH_HI 0x44/4 -#define T0_GO 0x48/4 -#define T0_LATCH 0x4c/4 - -#define T1_LATCH_LO 0x50/4 -#define T1_LATCH_HI 0x54/4 -#define T1_GO 0x58/4 -#define T1_LATCH 0x5c/4 - -#define T2_LATCH_LO 0x60/4 -#define T2_LATCH_HI 0x64/4 -#define T2_GO 0x68/4 -#define T2_LATCH 0x6c/4 - -#define T3_LATCH_LO 0x70/4 -#define T3_LATCH_HI 0x74/4 -#define T3_GO 0x78/4 -#define T3_LATCH 0x7c/4 - -#endif // MAME_INCLUDES_ARCHIMEDES_H diff --git a/src/mame/machine/archimds.cpp b/src/mame/machine/archimds.cpp deleted file mode 100644 index 14e2d3f665b..00000000000 --- a/src/mame/machine/archimds.cpp +++ /dev/null @@ -1,1018 +0,0 @@ -// license:LGPL-2.1+ -// copyright-holders:Angelo Salese, R. Belmont, Juergen Buchmueller -/****************************************************************************** - * - * 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 "emu.h" -#include "includes/archimds.h" -#include "cpu/arm/arm.h" -#include "debugger.h" - -static const int page_sizes[4] = { 4096, 8192, 16384, 32768 }; - -#define IOC_LOG 0 -#define CRTC_LOG 0 - -/* TODO: fix pending irqs */ -void archimedes_state::archimedes_request_irq_a(int mask) -{ - m_ioc_regs[IRQ_STATUS_A] |= mask; - - if ((m_ioc_regs[IRQ_STATUS_A] & m_ioc_regs[IRQ_MASK_A]) || (m_ioc_regs[IRQ_STATUS_B] & m_ioc_regs[IRQ_MASK_B])) - m_maincpu->set_input_line(ARM_IRQ_LINE, ASSERT_LINE); - else - m_maincpu->set_input_line(ARM_IRQ_LINE, CLEAR_LINE); -} - -void archimedes_state::archimedes_request_irq_b(int mask) -{ - m_ioc_regs[IRQ_STATUS_B] |= mask; - - if ((m_ioc_regs[IRQ_STATUS_A] & m_ioc_regs[IRQ_MASK_A]) || (m_ioc_regs[IRQ_STATUS_B] & m_ioc_regs[IRQ_MASK_B])) - m_maincpu->set_input_line(ARM_IRQ_LINE, ASSERT_LINE); - else - m_maincpu->set_input_line(ARM_IRQ_LINE, CLEAR_LINE); -} - -void archimedes_state::archimedes_request_fiq(int mask) -{ - m_ioc_regs[FIQ_STATUS] |= mask; - - //printf("STATUS:%02x IRQ:%02x MASK:%02x\n",m_ioc_regs[FIQ_STATUS],mask,m_ioc_regs[FIQ_MASK]); - - if (m_ioc_regs[FIQ_STATUS] & m_ioc_regs[FIQ_MASK]) - { - m_maincpu->pulse_input_line(ARM_FIRQ_LINE, m_maincpu->minimum_quantum_time()); - - //m_maincpu->set_input_line(ARM_FIRQ_LINE, CLEAR_LINE); - //m_maincpu->set_input_line(ARM_FIRQ_LINE, ASSERT_LINE); - } -} - -void archimedes_state::archimedes_clear_irq_a(int mask) -{ - m_ioc_regs[IRQ_STATUS_A] &= ~mask; - archimedes_request_irq_a(0); -} - -void archimedes_state::archimedes_clear_irq_b(int mask) -{ - m_ioc_regs[IRQ_STATUS_B] &= ~mask; - archimedes_request_irq_b(0); -} - -void archimedes_state::archimedes_clear_fiq(int mask) -{ - m_ioc_regs[FIQ_STATUS] &= ~mask; - //archimedes_request_fiq(0); -} - -void archimedes_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - switch (id) - { - case TIMER_IOC: ioc_timer(param); break; - } -} - - -WRITE_LINE_MEMBER( archimedes_state::vblank_irq ) -{ - if (state) - { - archimedes_request_irq_a(ARCHIMEDES_IRQA_VBL); - if (m_video_dma_on) - vidc_video_tick(); - } -} - -WRITE_LINE_MEMBER( archimedes_state::sound_drq ) -{ - if (state) - vidc_audio_tick(); -} - - -/* 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: Erotictac and Poizone sets up vidinit register AFTER vidend, for double buffering? (fixes Poizone "Eterna" logo display on attract) -// TODO: understand how to make quazer to work (sets video DMA param in-flight) -void archimedes_state::vidc_video_tick() -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - uint32_t size; - uint32_t offset_ptr; - - size = (m_vidc_vidend - m_vidc_vidstart + 0x10) & 0x1fffff; - - offset_ptr = m_vidc_vidinit; - if(offset_ptr >= m_vidc_vidend+0x10) // TODO: correct? - offset_ptr = m_vidc_vidstart; - - //popmessage("%08x %08x %08x",m_vidc_vidstart,m_vidc_vidinit,m_vidc_vidend); - - for(m_vidc_vidcur = 0;m_vidc_vidcur < size;m_vidc_vidcur++) - { - m_vidc->write_vram(m_vidc_vidcur, space.read_byte(offset_ptr)); - offset_ptr++; - if(offset_ptr >= m_vidc_vidend+0x10) // TODO: correct? - offset_ptr = m_vidc_vidstart; - } - - if(m_cursor_enabled == true) - { - uint32_t ccur_size = m_vidc->get_cursor_size(); - - for(uint32_t ccur = 0; ccur < ccur_size; ccur++) - m_vidc->write_cram(ccur, space.read_byte(m_vidc_cinit+ccur)); - } -} - -/* audio DMA */ -void archimedes_state::vidc_audio_tick() -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - uint8_t ch; - - for(ch=0; ch<8; ch++) - m_vidc->write_dac(ch, (space.read_byte(m_vidc_sndcur + ch))); - - m_vidc_sndcur+=8; - - if (m_vidc_sndcur >= m_vidc_sndendcur) - { - archimedes_request_irq_b(ARCHIMEDES_IRQB_SOUND_EMPTY); - - // TODO: nuke this implementation detail, repeated below - m_vidc->update_sound_mode(m_audio_dma_on); - if(!m_audio_dma_on) - { - for(ch=0; ch<8; ch++) - m_vidc->clear_dac(ch); - } - else - { - //printf("Chaining to next: start %x end %x\n", m_vidc_sndstart, m_vidc_sndend); - m_vidc_sndcur = m_vidc_sndstart; - m_vidc_sndendcur = m_vidc_sndend; - } - } -} - -void archimedes_state::a310_set_timer(int tmr) -{ - double freq; - - switch(tmr) - { - case 0: - case 1: - m_timer[tmr]->adjust(attotime::from_usec(m_ioc_timercnt[tmr]/2), tmr); // TODO: ARM timings are quite off there, it should be latch and not latch/2 - break; - case 2: - freq = 1000000.0 / (double)(m_ioc_timercnt[tmr]+1); - m_timer[tmr]->adjust(attotime::from_hz(freq), tmr); - break; - case 3: - freq = 1000000.0 / (double)((m_ioc_timercnt[tmr]+1)*16); - m_timer[tmr]->adjust(attotime::from_hz(freq), tmr); - break; - } -} - -// param -void archimedes_state::ioc_timer(int param) -{ - // all timers always run - a310_set_timer(param); - - // keep FIQ line ASSERTED if there are active requests - if (m_ioc_regs[FIQ_STATUS] & m_ioc_regs[FIQ_MASK]) - archimedes_request_fiq(0); - - // but only timers 0 and 1 generate IRQs - switch (param) - { - case 0: - archimedes_request_irq_a(ARCHIMEDES_IRQA_TIMER0); - break; - - case 1: - archimedes_request_irq_a(ARCHIMEDES_IRQA_TIMER1); - break; - } -} - -void archimedes_state::archimedes_reset() -{ - int i; - - m_memc_latchrom = 1; // map in the boot ROM - - // kill all memc mappings - for (i = 0; i < (32*1024*1024)/(4096); i++) - { - m_memc_pages[i] = -1; // indicate unmapped - } - - m_ioc_regs[IRQ_STATUS_A] = 0x10 | 0x80; //set up POR (Power On Reset) and Force IRQ at start-up - m_ioc_regs[IRQ_STATUS_B] = 0x00; //set up IL[1] On - m_ioc_regs[FIQ_STATUS] = 0x80; //set up Force FIQ - m_ioc_regs[CONTROL] = 0xff; -} - -void archimedes_state::archimedes_init() -{ - m_memc_pagesize = 0; - m_cursor_enabled = false; - - m_timer[0] = timer_alloc(TIMER_IOC); - m_timer[1] = timer_alloc(TIMER_IOC); - m_timer[2] = timer_alloc(TIMER_IOC); - m_timer[3] = timer_alloc(TIMER_IOC); - m_timer[0]->adjust(attotime::never); - m_timer[1]->adjust(attotime::never); - m_timer[2]->adjust(attotime::never); - m_timer[3]->adjust(attotime::never); -} - -uint32_t archimedes_state::archimedes_memc_logical_r(offs_t offset) -{ - uint32_t page, poffs; - - // are we mapping in the boot ROM? - if (m_memc_latchrom) - { - uint32_t *rom; - - rom = (uint32_t *)m_region_maincpu->base(); - - return rom[offset & 0x1fffff]; - } - else - { - // figure out the page number and offset in the page - page = (offset<<2) / page_sizes[m_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]); - - if (m_memc_pages[page] != -1) - { - return m_archimedes_memc_physmem[((m_memc_pages[page] * page_sizes[m_memc_pagesize]) + poffs)>>2]; - } - else - { - //printf("ARCHIMEDES_MEMC: Reading unmapped page %02x\n",page); - return 0xdeadbeef; - } - } - - // never executed - //return 0; -} - - - -void archimedes_state::archimedes_memc_logical_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - uint32_t page, poffs; - - // if the boot ROM is mapped, ignore writes - if (m_memc_latchrom) - { - return; - } - else - { - // figure out the page number and offset in the page - page = (offset<<2) / page_sizes[m_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]); - - if (m_memc_pages[page] != -1) - { - COMBINE_DATA(&m_archimedes_memc_physmem[((m_memc_pages[page] * page_sizes[m_memc_pagesize]) + poffs)>>2]); - } - else - { - //printf("ARCHIMEDES_MEMC: Writing unmapped page %02x, what do we do?\n",page); - } - } -} - -/* Aristocrat Mark 5 - same as normal AA except with Dram emulator */ -uint32_t archimedes_state::aristmk5_drame_memc_logical_r(offs_t offset) -{ - uint32_t page, poffs; - - // are we mapping in the boot ROM? - if (m_memc_latchrom) - { - uint32_t *rom; - - rom = (uint32_t *)m_region_maincpu->base(); - - return rom[offset & 0x1fffff]; - } - else - { - // figure out the page number and offset in the page - page = (offset<<2) / page_sizes[m_memc_pagesize]; - poffs = (offset<<2) % page_sizes[m_memc_pagesize]; - - - - if (m_memc_pages[page] != -1) - { - /******************* DRAM Emulator - gal20v - Aristocrat Mark 5 ************************ - A Dynamic RAM emulator is provided which avoids the need to execute code - in DRAM in those regulatory environments where it is not needed. - - When pin 5 of U36 ( gal20v ) is low, the pin 25 output is high and enables the - logic buffer inputs and provides a fixed jmp address to a plurality - of rom addresses ( 0xEAD0000A shown on logic buffer arrangement in schematics ) - - In this state, DRAM memory space is disabled. - - ****************************************************************************************/ - if(!(m_memc_pages[page] & 0x10) && (offset <= 0x3ff)) - return 0xEAD0000A; - return m_archimedes_memc_physmem[((m_memc_pages[page] * page_sizes[m_memc_pagesize]) + poffs)>>2]; - } - else - { - //printf("ARCHIMEDES_MEMC: Reading unmapped page %02x\n",page); - return 0xdeadbeef; - } - } - - // never executed - //return 0; -} - -void archimedes_state::archimedes_driver_init() -{ - m_archimedes_memc_physmem = reinterpret_cast(memshare("physicalram")->ptr()); -// address_space &space = m_maincpu->space(AS_PROGRAM); -// space.set_direct_update_handler(direct_update_delegate(&a310_setopbase, &machine)); -} - -static const char *const ioc_regnames[] = -{ - "(rw) Control", // 0 - "(read) Keyboard receive (write) keyboard send", // 4 - "?", - "?", - "(read) IRQ status A", // 10 - "(read) IRQ request A (write) IRQ clear", // 14 - "(rw) IRQ mask A", // 18 - "?", - "(read) IRQ status B", // 20 - "(read) IRQ request B", // 24 - "(rw) IRQ mask B", // 28 - "?", - "(read) FIQ status", // 30 - "(read) FIQ request", // 34 - "(rw) FIQ mask", // 38 - "?", - "(read) Timer 0 count low (write) Timer 0 latch low", // 40 - "(read) Timer 0 count high (write) Timer 0 latch high", // 44 - "(write) Timer 0 go command", // 48 - "(write) Timer 0 latch command", // 4c - "(read) Timer 1 count low (write) Timer 1 latch low", // 50 - "(read) Timer 1 count high (write) Timer 1 latch high", // 54 - "(write) Timer 1 go command", // 58 - "(write) Timer 1 latch command", // 5c - "(read) Timer 2 count low (write) Timer 2 latch low", // 60 - "(read) Timer 2 count high (write) Timer 2 latch high", // 64 - "(write) Timer 2 go command", // 68 - "(write) Timer 2 latch command", // 6c - "(read) Timer 3 count low (write) Timer 3 latch low", // 70 - "(read) Timer 3 count high (write) Timer 3 latch high", // 74 - "(write) Timer 3 go command", // 78 - "(write) Timer 3 latch command" // 7c -}; - -void archimedes_state::latch_timer_cnt(int tmr) -{ - double time = m_timer[tmr]->elapsed().as_double(); - time *= 2000000.0; // find out how many 2 MHz ticks have gone by - m_ioc_timerout[tmr] = m_ioc_timercnt[tmr] - (uint32_t)time; -} - -bool archimedes_state::check_floppy_ready() -{ - floppy_image_device *floppy = nullptr; - - if(!m_fdc) - return false; - - switch(m_floppy_select & 3) - { - case 0: - floppy = m_floppy0->get_device(); break; - case 1: - floppy = m_floppy1->get_device(); break; - } - - if(floppy) - return !floppy->ready_r(); - - return false; -} - -/* TODO: should be a 8-bit handler */ -uint32_t archimedes_state::ioc_ctrl_r(offs_t offset) -{ - if(IOC_LOG) - logerror("IOC: R %s = %02x (PC=%x) %02x\n", ioc_regnames[offset&0x1f], m_ioc_regs[offset&0x1f], m_maincpu->pc(),offset & 0x1f); - - switch (offset & 0x1f) - { - case CONTROL: - { - uint8_t i2c_data = 1; - bool floppy_ready_state; - - if ( m_rtc ) - { - i2c_data = (m_rtc->sda_r() & 1); - } - - floppy_ready_state = check_floppy_ready(); - - return (m_vidc->flyback_r()<<7) | (m_ioc_regs[CONTROL] & 0x78) | (floppy_ready_state<<2) | (m_i2c_clk<<1) | i2c_data; - } - - case KART: // keyboard read - return m_kart->read(); - - case IRQ_STATUS_A: - return (m_ioc_regs[IRQ_STATUS_A] & 0x7f) | 0x80; // Force IRQ is always '1' - - case IRQ_REQUEST_A: - return (m_ioc_regs[IRQ_STATUS_A] & m_ioc_regs[IRQ_MASK_A]); - - case IRQ_MASK_A: - return (m_ioc_regs[IRQ_MASK_A]); - - case IRQ_STATUS_B: - return (m_ioc_regs[IRQ_STATUS_B]); - - case IRQ_REQUEST_B: - return (m_ioc_regs[IRQ_STATUS_B] & m_ioc_regs[IRQ_MASK_B]); - - case IRQ_MASK_B: - return (m_ioc_regs[IRQ_MASK_B]); - - case FIQ_STATUS: - return (m_ioc_regs[FIQ_STATUS] & 0x7f) | 0x80; // Force FIQ is always '1' - - case FIQ_REQUEST: - return (m_ioc_regs[FIQ_STATUS] & m_ioc_regs[FIQ_MASK]); - - case FIQ_MASK: - return (m_ioc_regs[FIQ_MASK]); - - case T0_LATCH_LO: return m_ioc_timerout[0]&0xff; - case T0_LATCH_HI: return (m_ioc_timerout[0]>>8)&0xff; - - case T1_LATCH_LO: return m_ioc_timerout[1]&0xff; - case T1_LATCH_HI: return (m_ioc_timerout[1]>>8)&0xff; - - case T2_LATCH_LO: return m_ioc_timerout[2]&0xff; - case T2_LATCH_HI: return (m_ioc_timerout[2]>>8)&0xff; - - case T3_LATCH_LO: return m_ioc_timerout[3]&0xff; - case T3_LATCH_HI: return (m_ioc_timerout[3]>>8)&0xff; - default: - if(!IOC_LOG) - logerror("IOC: R %s = %02x (PC=%x) %02x\n", ioc_regnames[offset&0x1f], m_ioc_regs[offset&0x1f], m_maincpu->pc(), offset & 0x1f); - break; - } - - return m_ioc_regs[offset&0x1f]; -} - -/* TODO: should be a 8-bit handler */ -void archimedes_state::ioc_ctrl_w(offs_t offset, uint32_t data) -{ - if(IOC_LOG) - logerror("IOC: W %02x @ reg %s (PC=%x)\n", data&0xff, ioc_regnames[offset&0x1f], m_maincpu->pc()); - - switch (offset&0x1f) - { - case CONTROL: // I2C bus control - //logerror("IOC I2C: CLK %d DAT %d\n", (data>>1)&1, data&1); - if ( m_rtc ) - { - m_rtc->sda_w(data & 0x01); - m_rtc->scl_w((data & 0x02) >> 1); - } - m_i2c_clk = (data & 2) >> 1; - //TODO: does writing bit 2 here causes a fdc force ready? - /* - -x-- ---- Printer ack - --x- ---- Sound mute - ---x ---- Aux I/O connector - ---- -x-- Floppy ready - ---- --x- I2C clock - ---- ---x I2C data - */ - - //m_ioc_regs[CONTROL] = data & 0x38; - //if(data & 0x40) - // popmessage("Muting sound, contact MAMEdev"); - break; - - case KART: - m_kart->write(data); - break; - - case IRQ_MASK_A: - m_ioc_regs[IRQ_MASK_A] = data & 0xff; - - /* bit 7 forces an IRQ trap */ - archimedes_request_irq_a((data & 0x80) ? ARCHIMEDES_IRQA_FORCE : 0); - - //if(data & 0x08) //set up the VBLANK timer - // m_vbl_timer->adjust(m_screen->time_until_pos(m_vidc_vblank_time)); - - break; - - case IRQ_MASK_B: - m_ioc_regs[IRQ_MASK_B] = data & 0xff; - - archimedes_request_irq_b(0); - break; - - case FIQ_MASK: - m_ioc_regs[FIQ_MASK] = data & 0xff; - - /* bit 7 forces a FIRQ trap */ - archimedes_request_fiq((data & 0x80) ? ARCHIMEDES_FIQ_FORCE : 0); - break; - - case IRQ_REQUEST_A: // IRQ clear A - m_ioc_regs[IRQ_STATUS_A] &= ~(data&0xff); - - // check pending irqs - archimedes_request_irq_a(0); - break; - - case T0_LATCH_LO: - case T0_LATCH_HI: - m_ioc_regs[offset&0x1f] = data & 0xff; - break; - - case T1_LATCH_LO: - case T1_LATCH_HI: - m_ioc_regs[offset&0x1f] = data & 0xff; - break; - - case T2_LATCH_LO: - case T2_LATCH_HI: - m_ioc_regs[offset&0x1f] = data & 0xff; - break; - - case T3_LATCH_LO: - case T3_LATCH_HI: - m_ioc_regs[offset&0x1f] = data & 0xff; - break; - - case T0_LATCH: // Timer 0 latch - latch_timer_cnt(0); - break; - - case T1_LATCH: // Timer 1 latch - latch_timer_cnt(1); - break; - - case T2_LATCH: // Timer 2 latch - latch_timer_cnt(2); - break; - - case T3_LATCH: // Timer 3 latch - latch_timer_cnt(3); - break; - - case T0_GO: // Timer 0 start - m_ioc_timercnt[0] = m_ioc_regs[T0_LATCH_HI]<<8 | m_ioc_regs[T0_LATCH_LO]; - a310_set_timer(0); - break; - - case T1_GO: // Timer 1 start - m_ioc_timercnt[1] = m_ioc_regs[T1_LATCH_HI]<<8 | m_ioc_regs[T1_LATCH_LO]; - a310_set_timer(1); - break; - - case T2_GO: // Timer 2 start - m_ioc_timercnt[2] = m_ioc_regs[T2_LATCH_HI]<<8 | m_ioc_regs[T2_LATCH_LO]; - a310_set_timer(2); - break; - - case T3_GO: // Timer 3 start - m_ioc_timercnt[3] = m_ioc_regs[T3_LATCH_HI]<<8 | m_ioc_regs[T3_LATCH_LO]; - a310_set_timer(3); - break; - - default: - if(!IOC_LOG) - logerror("IOC: W %02x @ reg %s (PC=%x)\n", data&0xff, ioc_regnames[offset&0x1f], m_maincpu->pc()); - - m_ioc_regs[offset&0x1f] = data & 0xff; - break; - } -} - -uint32_t archimedes_state::archimedes_ioc_r(offs_t offset, uint32_t mem_mask) -{ - uint32_t ioc_addr; - - ioc_addr = offset*4; - - switch((ioc_addr & 0x300000) >> 20) - { - /*82c711*/ - case 0: - logerror("82c711 read at address %08x\n",ioc_addr); - return 0; - case 2: - case 3: - { - switch((ioc_addr & 0x70000) >> 16) - { - case 0: return ioc_ctrl_r(offset); - case 1: - if (m_fdc) - { - //printf("17XX: R @ addr %x mask %08x\n", offset*4, mem_mask); - return m_fdc->read((ioc_addr >> 2) & 0x03); - } else { - logerror("Read from FDC device?\n"); - return 0; - } - case 2: - // RTFM joystick interface routes here - // TODO: slot interface for econet (reads registers 0 and 1 during boot) - switch(ioc_addr) - { - case 0x3a0000: - return 0xed; // ID for econet - case 0x3a0004: - return m_joy[0].read_safe(0xff); - case 0x3a0008: - // Top Banana reads there and do various checks, - // disallowing player 1 joy use if they fails (?) - return m_joy[1].read_safe(0xff); - } - - logerror("IOC: Econet Read %08x at PC=%08x\n",ioc_addr, m_maincpu->pc()); - return 0xffff; - case 3: - logerror("IOC: Serial Read\n"); - return 0xffff; - case 4: - logerror("IOC: Internal Podule Read\n"); - return 0xffff; - case 5: - if (m_fdc) - { - // TODO: IOEB slot interface - switch(ioc_addr & 0xfffc) - { - case 0x18: return 0xff; // FDC latch B - case 0x40: return 0xff; // FDC latch A - case 0x50: return 0; //fdc type, an 82c711 returns 5 here - case 0x70: return 0x0f; // monitor type, TBD - case 0x74: return 0xff; // unknown - case 0x78: // serial joystick? - case 0x7c: - logerror("FDC: reading Joystick port %04x at PC=%08x\n",ioc_addr, m_maincpu->pc()); - return 0xff; - - } - } - - //printf("IOC: Internal Latches Read %08x\n",ioc_addr); - - return 0xffff; - } - } - } - - logerror("IOC: Unknown read at %08x\n",ioc_addr); - - return 0; -} - -void archimedes_state::archimedes_ioc_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - uint32_t ioc_addr; - - ioc_addr = offset*4; - - switch((ioc_addr & 0x300000) >> 20) - { - /*82c711*/ - case 0: - logerror("82c711 write %08x to address %08x\n",data,ioc_addr); - return; - case 2: - case 3: - { - switch((ioc_addr & 0x70000) >> 16) - { - case 0: ioc_ctrl_w(offset,data); return; - case 1: - if (m_fdc) - { - //printf("17XX: %x to addr %x mask %08x\n", data, offset*4, mem_mask); - m_fdc->write((ioc_addr >> 2) & 0x03, data); - return; - } - else - { - logerror("Write to FDC device?\n"); - } - return; - case 2: - logerror("IOC: Econet Write %02x at %08x\n",data,ioc_addr); - return; - case 3: - logerror("IOC: Serial Write %02x (%c) at %08x\n",data,data,ioc_addr); - return; - case 4: - logerror("IOC: Internal Podule Write\n"); - return; - case 5: - if (m_fdc) - { - switch(ioc_addr & 0xfffc) - { - // serial joy port (!JS application) - case 0x10: - { - // compared to RTFM they reversed bits 0-3 (or viceversa, dunno what came out first) - // for pragmatic convenience we bitswap here, but this should really be a slot option at some point. - // TODO: understand how player 2 inputs routes, related somehow to CONTROL bit 6 (cfr. blitz in SW list) - // TODO: paradr2k polls here with bit 7 and fails detection (Vertical Twist) - uint8_t cur_joy_in = bitswap<8>(m_joy[0].read_safe(0xff),7,6,5,4,0,1,2,3); - - m_joy_serial_data = (data & 0xff) ^ 0xff; - bool serial_on = false; - - if (m_joy_serial_data == 0x20) - serial_on = true; - else if (m_joy_serial_data & cur_joy_in) - serial_on = true; - - - // wants printer irq for some reason (connected on parallel?) - if (serial_on == true) - { - archimedes_request_irq_a(ARCHIMEDES_IRQA_PRINTER_BUSY); - //m_ioc_regs[CONTROL] |= 0x40; - } - else - { - archimedes_clear_irq_a(ARCHIMEDES_IRQA_PRINTER_BUSY); - //m_ioc_regs[CONTROL] &= ~0x40; - } - - return; - } - case 0x18: // latch B - /* - ---- x--- floppy controller reset - ---x ---- printer strobe - */ - m_fdc->dden_w(BIT(data, 1)); - m_fdc->mr_w(BIT(data, 3)); - if(data & ~0xa) - printf("%02x Latch B\n",data); - return; - - case 0x40: // latch A - /* - -x-- ---- In Use Control (floppy?) - */ - floppy_image_device *floppy = nullptr; - - if (!(data & 1)) { m_floppy_select = 0; floppy = m_floppy0->get_device(); } - if (!(data & 2)) { m_floppy_select = 1; floppy = m_floppy1->get_device(); } - if (!(data & 4)) { m_floppy_select = 2; floppy = nullptr; } // floppy 2 - if (!(data & 8)) { m_floppy_select = 3; floppy = nullptr; } // floppy 3 - - m_fdc->set_floppy(floppy); - - if(floppy) - { - floppy->mon_w(BIT(data, 5)); - floppy->ss_w(!(BIT(data, 4))); - } - //bit 5 is motor on - return; - } - - //printf("%08x\n",ioc_addr); - } - break; - } - } - } - - - logerror("(PC=%08x) I/O: W %x @ %x (mask %08x)\n", m_maincpu->pc(), data, (offset*4)+0x3000000, mem_mask); -} - -void archimedes_state::archimedes_memc_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ - // is it a register? - if ((data & 0x0fe00000) == 0x03600000) - { - switch ((data >> 17) & 7) - { - case 0: /* video init */ - m_vidc_vidinit = 0x2000000 | ((data>>2)&0x7fff)*16; - //printf("MEMC: VIDINIT %08x\n",m_vidc_vidinit); - break; - - case 1: /* video start */ - m_vidc_vidstart = 0x2000000 | (((data>>2)&0x7fff)*16); - //printf("MEMC: VIDSTART %08x\n",m_vidc_vidstart); - break; - - case 2: /* video end */ - m_vidc_vidend = 0x2000000 | (((data>>2)&0x7fff)*16); - //printf("MEMC: VIDEND %08x\n",m_vidc_vidend); - break; - - case 3: /* cursor init */ - m_cursor_enabled = true; - m_vidc->set_cursor_enable(m_cursor_enabled); - m_vidc_cinit = 0x2000000 | (((data>>2)&0x7fff)*16); - //printf("MEMC: CURSOR INIT %08x\n",((data>>2)&0x7fff)*16); - break; - - case 4: /* sound start */ - archimedes_clear_irq_b(ARCHIMEDES_IRQB_SOUND_EMPTY); - m_vidc_sndstart = 0x2000000 | ((data>>2)&0x7fff)*16; - //printf("MEMC: SNDSTART %08x\n",m_vidc_sndstart); - break; - - case 5: /* sound end */ - // end buffer is actually +16 bytes wrt sound start - // TODO: it actually don't apply for ertictac and poizone? - m_vidc_sndend = 0x2000000 | (((data>>2)+1)&0x7fff)*16; - //printf("MEMC: SNDEND %08x\n",m_vidc_sndend); - break; - - case 6: - //printf("MEMC: SNDPTR\n"); - m_vidc_sndcur = m_vidc_sndstart; - m_vidc_sndendcur = m_vidc_sndend; - archimedes_request_irq_b(ARCHIMEDES_IRQB_SOUND_EMPTY); - break; - - case 7: /* Control */ - m_memc_pagesize = ((data>>2) & 3); - - logerror("(PC = %08x) MEMC: %x to Control (page size %d, %s, %s)\n", m_maincpu->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"); - - m_video_dma_on = BIT(data, 10); - m_audio_dma_on = BIT(data, 11); - - if (m_video_dma_on) - { - m_vidc_vidcur = 0; - // TODO: update internally - } - else - { - m_cursor_enabled = false; - m_vidc->set_cursor_enable(m_cursor_enabled); - } - - m_vidc->update_sound_mode(m_audio_dma_on); - if (m_audio_dma_on) - { - //printf("MEMC: Starting audio DMA at %d uSec, buffer from %x to %x\n", ((m_vidc_regs[0xc0]&0xff)-2)*8, m_vidc_sndstart, m_vidc_sndend); - - //printf("MEMC: audio DMA start, sound freq %d, sndhz = %f\n", (m_vidc_regs[0xc0] & 0xff)-2, sndhz); - - m_vidc_sndcur = m_vidc_sndstart; - m_vidc_sndendcur = m_vidc_sndend; - } - - 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 -*/ - -void archimedes_state::archimedes_memc_page_w(uint32_t data) -{ - uint32_t log, phys, memc; - -// perms = (data & 0x300)>>8; - log = phys = memc = 0; - - switch (m_memc_pagesize) - { - case 0: - phys = data & 0x7f; - log = ((data & 0x7ff000)>>12) | ((data & 0xc00)<<1); - memc = (data & 0x80) ? 1 : 0; - break; - - case 1: - phys = ((data & 0x7f) >> 1) | ((data & 1) << 6); - log = ((data & 0x7fe000)>>13) | (data & 0xc00); - memc = ((data & 0x80) ? 1 : 0) | ((data & 0x1000) ? 2 : 0); - break; - - case 2: - phys = ((data & 0x7f) >> 2) | ((data & 3) << 5); - log = ((data & 0x7fc000)>>14) | ((data & 0xc00)>>1); - 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 & 0x7f8000)>>15) | ((data & 0xc00)>>2); - memc = ((data & 0x80) ? 1 : 0) | ((data & 0x1000) ? 2 : 0); - //printf("Mapping %08X to %08X\n",0x2000000+(phys*32768),(((data >> 15)&0xff)|((data >> 2)&0x300))); - break; - } - -// log >>= (12 + memc_pagesize); - - // always make sure ROM mode is disconnected when this occurs - m_memc_latchrom = 0; - - // now go ahead and set the mapping in the page table - 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", m_maincpu->pc(),memc_pagesize, data, log, phys, memc, perms); -}