From 24189a9346d7f3874c47e40060235bdfedffac28 Mon Sep 17 00:00:00 2001 From: Nigel Barnes Date: Fri, 21 May 2021 22:28:44 +0100 Subject: bus/bbc/tube: Added Sprow ARM7TDMI Co-Processor. --- scripts/src/bus.lua | 2 + src/devices/bus/bbc/tube/tube.cpp | 6 +- src/devices/bus/bbc/tube/tube_arm7.cpp | 295 +++++++++++++++++++++++++++++++++ src/devices/bus/bbc/tube/tube_arm7.h | 92 ++++++++++ 4 files changed, 394 insertions(+), 1 deletion(-) create mode 100644 src/devices/bus/bbc/tube/tube_arm7.cpp create mode 100644 src/devices/bus/bbc/tube/tube_arm7.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 1ee46b10559..0587a63ad1d 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -620,6 +620,8 @@ if (BUSES["BBC_TUBE"]~=null) then MAME_DIR .. "src/devices/bus/bbc/tube/tube_a500.h", MAME_DIR .. "src/devices/bus/bbc/tube/tube_arm.cpp", MAME_DIR .. "src/devices/bus/bbc/tube/tube_arm.h", + MAME_DIR .. "src/devices/bus/bbc/tube/tube_arm7.cpp", + MAME_DIR .. "src/devices/bus/bbc/tube/tube_arm7.h", MAME_DIR .. "src/devices/bus/bbc/tube/tube_casper.cpp", MAME_DIR .. "src/devices/bus/bbc/tube/tube_casper.h", MAME_DIR .. "src/devices/bus/bbc/tube/tube_cms6809.cpp", diff --git a/src/devices/bus/bbc/tube/tube.cpp b/src/devices/bus/bbc/tube/tube.cpp index 13a7318d7ef..371326cf487 100644 --- a/src/devices/bus/bbc/tube/tube.cpp +++ b/src/devices/bus/bbc/tube/tube.cpp @@ -95,6 +95,7 @@ void bbc_tube_slot_device::host_w(offs_t offset, uint8_t data) #include "tube_80286.h" #include "tube_a500.h" #include "tube_arm.h" +#include "tube_arm7.h" #include "tube_casper.h" #include "tube_cms6809.h" //#include "tube_pmsb2p.h" @@ -132,6 +133,7 @@ void bbc_tube_devices(device_slot_interface &device) /* Acorn ANC21 Universal 2nd Processor Unit */ device.option_add("65c102", BBC_TUBE_65C102); /* Acorn ADC06 65C102 co-processor */ device.option_add("80186", BBC_TUBE_80186); /* Acorn ADC08 80186 co-processor */ + device.option_add("arm7", BBC_TUBE_ARM7); /* Sprow ARM7 co-processor */ device.option_add("rc6502", BBC_TUBE_RC6502); /* ReCo6502 (6502) */ device.option_add("rc65816", BBC_TUBE_RC65816); /* ReCo6502 (65816) */ } @@ -158,6 +160,7 @@ void bbc_extube_devices(device_slot_interface &device) /* Acorn ANC21 Universal 2nd Processor Unit */ device.option_add("65c102", BBC_TUBE_65C102); /* Acorn ADC06 65C102 co-processor */ device.option_add("80186", BBC_TUBE_80186); /* Acorn ADC08 80186 co-processor */ + device.option_add("arm7", BBC_TUBE_ARM7); /* Sprow ARM7 co-processor */ device.option_add("rc6502", BBC_TUBE_RC6502); /* ReCo6502 (6502) */ device.option_add("rc65816", BBC_TUBE_RC65816); /* ReCo6502 (65816) */ } @@ -171,7 +174,7 @@ void bbc_intube_devices(device_slot_interface &device) { device.option_add("65c102", BBC_TUBE_65C102); /* Acorn ADC06 65C102 co-processor */ device.option_add("80186", BBC_TUBE_80186); /* Acorn ADC08 80186 co-processor */ - //device.option_add("arm7", BBC_TUBE_ARM7); /* Sprow ARM7 co-processor */ + device.option_add("arm7", BBC_TUBE_ARM7); /* Sprow ARM7 co-processor */ device.option_add("rc6502", BBC_TUBE_RC6502); /* ReCo6502 (6502) */ device.option_add("rc65816", BBC_TUBE_RC65816); /* ReCo6502 (65816) */ } @@ -191,6 +194,7 @@ void electron_tube_devices(device_slot_interface &device) device.option_add("65c102", BBC_TUBE_65C102); /* Acorn ADC06 65C102 co-processor */ device.option_add("80186", BBC_TUBE_80186); /* Acorn ADC08 80186 co-processor */ device.option_add("pcplus", BBC_TUBE_PCPLUS); /* Solidisk PC-Plus co-processor */ + device.option_add("arm7", BBC_TUBE_ARM7); /* Sprow ARM7 co-processor */ device.option_add("rc6502", BBC_TUBE_RC6502); /* ReCo6502 (6502) */ device.option_add("rc65816", BBC_TUBE_RC65816); /* ReCo6502 (65816) */ } diff --git a/src/devices/bus/bbc/tube/tube_arm7.cpp b/src/devices/bus/bbc/tube/tube_arm7.cpp new file mode 100644 index 00000000000..e8396129057 --- /dev/null +++ b/src/devices/bus/bbc/tube/tube_arm7.cpp @@ -0,0 +1,295 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Sprow ARM7TDMI Co-Processor (2005) + + http://www.sprow.co.uk/bbc/armcopro.htm + +**********************************************************************/ + + +#include "emu.h" +#include "tube_arm7.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(BBC_TUBE_ARM7, bbc_tube_arm7_device, "bbc_tube_arm7", "Sprow ARM7TDMI Co-Processor") + + +//------------------------------------------------- +// ADDRESS_MAP( arm7_map ) +//------------------------------------------------- + +void bbc_tube_arm7_device::arm7_map(address_map &map) +{ + map(0x00000000, 0x07ffffff).view(m_bank0_view); + m_bank0_view[0](0x00000000, 0x0007ffff).rom().region("flash", 0).mirror(0x07f80000); + m_bank0_view[1](0x00000000, 0x07ffffff).rw(m_ram, FUNC(ram_device::read), FUNC(ram_device::write)); + map(0x50000000, 0x50007fff).ram(); + map(0x78000000, 0xbfffffff).rw(FUNC(bbc_tube_arm7_device::oki_reg_r), FUNC(bbc_tube_arm7_device::oki_reg_w)); + map(0xc0000000, 0xc7ffffff).rw(m_ram, FUNC(ram_device::read), FUNC(ram_device::write)); + map(0xc8000000, 0xc807ffff).rom().region("flash", 0).mirror(0x07f80000); + map(0xf0000000, 0xf000000f).rw(m_ula, FUNC(tube_device::parasite_r), FUNC(tube_device::parasite_w)).umask16(0x00ff); + map(0xf0000010, 0xf0000010).lrw8(NAME([this]() { return m_tube10; }), NAME([this](u8 data) { m_tube10 = data; })); +} + + +//------------------------------------------------- +// ROM( tube_arm7 ) +//------------------------------------------------- + +ROM_START( tube_arm7 ) + ROM_REGION32_LE(0x80000, "flash", 0) + ROM_SYSTEM_BIOS(0, "045", "ARM Tube OS 0.45") + ROMX_LOAD("atos045.rom", 0x00000, 0x80000, CRC(984c594e) SHA1(1909886361c2a143c02a3977f6ce1a529dfc8779), ROM_BIOS(0)) + ROM_SYSTEM_BIOS(1, "040", "ARM Tube OS 0.40") + ROMX_LOAD("atos040.rom", 0x00000, 0x80000, CRC(b34b5011) SHA1(babfb5bdb8265cf3ac7feff254146cb2d2773da1), ROM_BIOS(1)) +ROM_END + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void bbc_tube_arm7_device::device_add_mconfig(machine_config &config) +{ + ARM7(config, m_maincpu, 64_MHz_XTAL); // Oki ML67Q5003 + m_maincpu->set_addrmap(AS_PROGRAM, &bbc_tube_arm7_device::arm7_map); + + TUBE(config, m_ula); + m_ula->pnmi_handler().set(FUNC(bbc_tube_arm7_device::efiq_w)); + m_ula->pirq_handler().set(FUNC(bbc_tube_arm7_device::exint3_w)); + + RAM(config, m_ram).set_default_size("32M").set_extra_options("16M,64M"); +} + + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const tiny_rom_entry *bbc_tube_arm7_device::device_rom_region() const +{ + return ROM_NAME( tube_arm7 ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// bbc_tube_arm7_device - constructor +//------------------------------------------------- + +bbc_tube_arm7_device::bbc_tube_arm7_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, BBC_TUBE_ARM7, tag, owner, clock) + , device_bbc_tube_interface(mconfig, *this) + , m_maincpu(*this, "maincpu") + , m_flash(*this, "flash") + , m_ula(*this, "ula") + , m_ram(*this, "ram") + , m_bank0_view(*this, "bank0") + , m_tube10(0) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bbc_tube_arm7_device::device_start() +{ + save_item(NAME(m_registers)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void bbc_tube_arm7_device::device_reset() +{ + // interrupt states + m_efiq_state = 0; + m_exint3_state = 0; + + // reset registers + memset(m_registers, 0, sizeof(m_registers)); + update_interrupts(); + + // enable rom + m_registers[CHIP_CONFIG][3] = 1; // ROMSEL + update_bank0(); +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +uint8_t bbc_tube_arm7_device::host_r(offs_t offset) +{ + return m_ula->host_r(offset); +} + +void bbc_tube_arm7_device::host_w(offs_t offset, uint8_t data) +{ + m_ula->host_w(offset, data); +} + + +void bbc_tube_arm7_device::update_interrupts() +{ + int firq = BIT(m_registers[INTERRUPT][4], 0) && m_efiq_state; + int irq = BIT(m_registers[EXP_INTERRUPT][6], 28, 4) && m_exint3_state; + + m_maincpu->set_input_line(ARM7_FIRQ_LINE, firq ? ASSERT_LINE : CLEAR_LINE); + m_maincpu->set_input_line(ARM7_IRQ_LINE, irq ? ASSERT_LINE : CLEAR_LINE); +} + +WRITE_LINE_MEMBER(bbc_tube_arm7_device::efiq_w) +{ + m_efiq_state = state; + update_interrupts(); +} + +WRITE_LINE_MEMBER(bbc_tube_arm7_device::exint3_w) +{ + m_exint3_state = state; + if (state) + { + m_registers[INTERRUPT][5] = 31; // IRN + } + update_interrupts(); +} + + +void bbc_tube_arm7_device::update_bank0() +{ + if (BIT(m_registers[CHIP_CONFIG][3], 0) && !BIT(m_registers[SYSTEM][4], 3)) + { + m_bank0_view.select(0); + } + else + { + m_bank0_view.select(1); + } +} + + +uint32_t bbc_tube_arm7_device::oki_reg_r(offs_t offset) +{ + uint32_t data = 0x00; + uint32_t reg_addr = 0x78000000 + (offset * 4); + + switch (reg_addr >> 4) + { + case 0x7800000: case 0x7800001: case 0x7800002: + data = m_registers[INTERRUPT][offset & 0x0f]; + if (reg_addr == 0x78000014) // IRN + { + m_registers[INTERRUPT][5] = 0; // IRN + m_registers[INTERRUPT][6] = 0; // CIL + } + update_interrupts(); + break; + + case 0x7810000: + data = m_registers[EXT_MEMORY][offset & 0x03]; + break; + + case 0x7820000: case 0x7820001: + data = m_registers[CACHE_MEMORY][offset & 0x07]; + break; + + case 0x7818000: case 0x7818001: + data = m_registers[DRAM_CONTROL][offset & 0x07]; + break; + + case 0x7bf0000: case 0x7bf0001: + data = m_registers[EXP_INTERRUPT][offset & 0x07]; + break; + + case 0xb700000: + data = m_registers[CHIP_CONFIG][offset & 0x03]; + break; + + case 0xb7a0100: case 0xb7a0101: case 0xb7a0102: case 0xb7a0103: case 0xb7a0104: case 0xb7a0105: + data = m_registers[PORT_CONTROL][offset & 0x1f]; + break; + + case 0xb800000: case 0xb800001: + data = m_registers[SYSTEM][offset & 0x07]; + break; + + case 0xb800100: case 0xb800101: + data = m_registers[SYSTEM_TIMER][offset & 0x07]; + break; + + default: + logerror("oki_reg_r: Unhandled register %08x\n", reg_addr); + break; + } + + return data; +} + +void bbc_tube_arm7_device::oki_reg_w(offs_t offset, uint32_t data) +{ + uint32_t reg_addr = 0x78000000 + (offset * 4); + + switch (reg_addr >> 4) + { + case 0x7800000: case 0x7800001: case 0x7800002: + m_registers[INTERRUPT][offset & 0x0f] = data; + if (reg_addr == 0x78000028) // CILCL + { + m_registers[INTERRUPT][6] = 0; // CIL + } + update_interrupts(); + break; + + case 0x7810000: + m_registers[EXT_MEMORY][offset & 0x03] = data; + break; + + case 0x7820000: case 0x7820001: + m_registers[CACHE_MEMORY][offset & 0x07] = data; + break; + + case 0x7818000: case 0x7818001: + m_registers[DRAM_CONTROL][offset & 0x07] = data; + break; + + case 0x7bf0000: case 0x7bf0001: + m_registers[EXP_INTERRUPT][offset & 0x07] = data; + update_interrupts(); + break; + + case 0xb700000: + m_registers[CHIP_CONFIG][offset & 0x03] = data; + update_bank0(); + break; + + case 0xb7a0100: case 0xb7a0101: case 0xb7a0102: case 0xb7a0103: case 0xb7a0104: case 0xb7a0105: + m_registers[PORT_CONTROL][offset & 0x1f] = data; + break; + + case 0xb800000: case 0xb800001: + m_registers[SYSTEM][offset & 0x07] = data; + update_bank0(); + break; + + case 0xb800100: case 0xb800101: + m_registers[SYSTEM_TIMER][offset & 0x07] = data; + break; + + default: + logerror("oki_reg_w: Unhandled register %08x = %04x\n", reg_addr, data); + break; + } +} diff --git a/src/devices/bus/bbc/tube/tube_arm7.h b/src/devices/bus/bbc/tube/tube_arm7.h new file mode 100644 index 00000000000..951be2d0209 --- /dev/null +++ b/src/devices/bus/bbc/tube/tube_arm7.h @@ -0,0 +1,92 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Sprow ARM7TDMI Co-Processor + + http://www.sprow.co.uk/bbc/armcopro.htm + +**********************************************************************/ + + +#ifndef MAME_BUS_BBC_TUBE_ARM7_H +#define MAME_BUS_BBC_TUBE_ARM7_H + +#include "tube.h" +#include "cpu/arm7/arm7.h" +#include "cpu/arm7/arm7core.h" +#include "machine/ram.h" +#include "machine/tube.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> bbc_tube_arm7_device + +class bbc_tube_arm7_device : + public device_t, + public device_bbc_tube_interface +{ + enum + { + INTERRUPT = 0, // 7800_0000 + EXT_MEMORY, // 7810_0000 + DRAM_CONTROL, // 7818_0000 + CACHE_MEMORY, // 7820_0000 + EXP_INTERRUPT, // 7BF0_0000 + CHIP_CONFIG, // B700_0000 + PORT_CONTROL, // B7A0_1000 + SYSTEM, // B800_0000 + SYSTEM_TIMER, // B800_1000 + NUM_REGS + }; + +public: + // construction/destruction + bbc_tube_arm7_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + + virtual uint8_t host_r(offs_t offset) override; + virtual void host_w(offs_t offset, uint8_t data) override; + +private: + required_device m_maincpu; + required_memory_region m_flash; + required_device m_ula; + required_device m_ram; + memory_view m_bank0_view; + + void arm7_map(address_map& map); + + uint32_t oki_reg_r(offs_t offset); + void oki_reg_w(offs_t offset, uint32_t data); + + // registers + uint32_t m_registers[NUM_REGS][32]; + uint8_t m_tube10; + + void update_bank0(); + void update_interrupts(); + + DECLARE_WRITE_LINE_MEMBER(efiq_w); + DECLARE_WRITE_LINE_MEMBER(exint3_w); + + int m_efiq_state; + int m_exint3_state; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(BBC_TUBE_ARM7, bbc_tube_arm7_device) + + +#endif // MAME_BUS_BBC_TUBE_ARM7_H -- cgit v1.2.3