-locomo: Added a skeleton device for the LoCoMo peripheral controller used in some Sharp Zaurus models. [Ryan Holtz]

-sa1110: Added OS Timer, RTC, Reset, GPIO, and partial UART3 controller module support. [Ryan Holtz]
This commit is contained in:
Ryan Holtz 2020-12-04 02:21:35 +01:00
parent fe4ec3a9d7
commit 8287057888
8 changed files with 1772 additions and 180 deletions

View File

@ -1855,6 +1855,18 @@ if (MACHINES["LINFLASH"]~=null) then
}
end
---------------------------------------------------
--
--@src/devices/machine/locomo.h,MACHINES["LOCOMO"] = true
---------------------------------------------------
if (MACHINES["LOCOMO"]~=null) then
files {
MAME_DIR .. "src/devices/machine/locomo.cpp",
MAME_DIR .. "src/devices/machine/locomo.h",
}
end
---------------------------------------------------
--
--@src/devices/machine/m3002.h,MACHINES["M3002"] = true

View File

@ -528,6 +528,7 @@ MACHINES["LDP1450"] = true
MACHINES["LDVP931"] = true
--MACHINES["LH5810"] = true
MACHINES["LINFLASH"] = true
--MACHINES["LOCOMO"] = true
MACHINES["LPCI"] = true
--MACHINES["LSI53C810"] = true
--MACHINES["M3002"] = true

View File

@ -557,6 +557,7 @@ MACHINES["LDV1000"] = true
MACHINES["LDVP931"] = true
MACHINES["LH5810"] = true
MACHINES["LINFLASH"] = true
MACHINES["LOCOMO"] = true
MACHINES["LPCI"] = true
MACHINES["LSI53C810"] = true
MACHINES["M3002"] = true

View File

@ -0,0 +1,376 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
/***************************************************************************
Sharp LoCoMo peripheral chip emulation
***************************************************************************/
#include "emu.h"
#include "locomo.h"
#define LOG_UNKNOWN (1 << 1)
#define LOG_READS (1 << 2)
#define LOG_WRITES (1 << 3)
#define LOG_ALL (LOG_UNKNOWN | LOG_READS | LOG_WRITES)
#define VERBOSE (LOG_ALL)
#include "logmacro.h"
DEFINE_DEVICE_TYPE(LOCOMO, locomo_device, "locomo", "Sharp LoCoMo Peripheral")
locomo_device::locomo_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, LOCOMO, tag, owner, clock)
{
}
void locomo_device::device_start()
{
save_item(NAME(m_kbd_cmd));
save_item(NAME(m_kbd_row));
save_item(NAME(m_kbd_col));
save_item(NAME(m_kbd_level));
}
void locomo_device::device_reset()
{
m_kbd_cmd = 0;
m_kbd_row = 0;
m_kbd_col = 0;
m_kbd_level = 0;
}
uint32_t locomo_device::read(offs_t offset, uint32_t mem_mask)
{
switch (offset)
{
case 0x00/4:
LOGMASKED(LOG_READS, "%s: read: Version Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x04/4:
LOGMASKED(LOG_READS, "%s: read: Pin Status Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x08/4:
LOGMASKED(LOG_READS, "%s: read: C32K(?) Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x0c/4:
LOGMASKED(LOG_READS, "%s: read: Interrupt Control Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x10/4:
LOGMASKED(LOG_READS, "%s: read: Memory Chip Select 0 Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x14/4:
LOGMASKED(LOG_READS, "%s: read: Memory Chip Select 1 Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x18/4:
LOGMASKED(LOG_READS, "%s: read: Memory Chip Select 2 Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x1c/4:
LOGMASKED(LOG_READS, "%s: read: Memory Chip Select 3 Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x20/4:
LOGMASKED(LOG_READS, "%s: read: A/D Start Delay Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x24/4:
LOGMASKED(LOG_READS, "%s: read: HSYS Delay Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x28/4:
LOGMASKED(LOG_READS, "%s: read: HSYS Period Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x30/4:
LOGMASKED(LOG_READS, "%s: read: Tablet ADC Clock Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x38/4:
LOGMASKED(LOG_READS, "%s: read: TFT Backlight Control Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x3c/4:
LOGMASKED(LOG_READS, "%s: read: TFT CPS Delay Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x40/4:
LOGMASKED(LOG_READS, "%s: read: Keyboard Level Register: %08x & %08x\n", machine().describe_context(), m_kbd_level, mem_mask);
return m_kbd_level;
case 0x44/4:
LOGMASKED(LOG_READS, "%s: read: Keyboard Strobe Control Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x48/4:
LOGMASKED(LOG_READS, "%s: read: Keyboard Strobe Command Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x4c/4:
LOGMASKED(LOG_READS, "%s: read: Keyboard Interrupt Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x54/4:
LOGMASKED(LOG_READS, "%s: read: Audio Clock Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x60/4:
LOGMASKED(LOG_READS, "%s: read: SPI Mode Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x64/4:
LOGMASKED(LOG_READS, "%s: read: SPI Control Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x68/4:
LOGMASKED(LOG_READS, "%s: read: SPI Status Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x70/4:
LOGMASKED(LOG_READS, "%s: read: SPI Interrupt Status Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x74/4:
LOGMASKED(LOG_READS, "%s: read: SPI Interrupt Status Write-Enable Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x78/4:
LOGMASKED(LOG_READS, "%s: read: SPI Interrupt Enable Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x7c/4:
LOGMASKED(LOG_READS, "%s: read: SPI Interrupt Request Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x80/4:
LOGMASKED(LOG_READS, "%s: read: SPI Transmit Data Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x84/4:
LOGMASKED(LOG_READS, "%s: read: SPI Receive Data Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x88/4:
LOGMASKED(LOG_READS, "%s: read: SPI Transmit Shift Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x8c/4:
LOGMASKED(LOG_READS, "%s: read: SPI Receive Shift Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x90/4:
LOGMASKED(LOG_READS, "%s: read: GPIO Direction Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x94/4:
LOGMASKED(LOG_READS, "%s: read: GPIO Input Enable Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x98/4:
LOGMASKED(LOG_READS, "%s: read: GPIO Level Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0x9c/4:
LOGMASKED(LOG_READS, "%s: read: GPIO Output Latch Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0xa0/4:
LOGMASKED(LOG_READS, "%s: read: GPIO Rising-Edge Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0xa4/4:
LOGMASKED(LOG_READS, "%s: read: GPIO Falling-Edge Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0xa8/4:
LOGMASKED(LOG_READS, "%s: read: GPIO Edge-Detect Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0xac/4:
LOGMASKED(LOG_READS, "%s: read: GPIO Status Write-Enable Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0xb0/4:
LOGMASKED(LOG_READS, "%s: read: GPIO Interrupt Enable Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0xb4/4:
LOGMASKED(LOG_READS, "%s: read: GPIO Interrupt Status Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0xc8/4:
LOGMASKED(LOG_READS, "%s: read: Front Light Cycle Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0xcc/4:
LOGMASKED(LOG_READS, "%s: read: Front Light Duty Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0xd8/4:
LOGMASKED(LOG_READS, "%s: read: Long-Time Clock Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0xdc/4:
LOGMASKED(LOG_READS, "%s: read: Long-Time Clock Interrupt Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0xe0/4:
LOGMASKED(LOG_READS, "%s: read: DAC Control Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0xe8/4:
LOGMASKED(LOG_READS, "%s: read: LED 0 Control Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
case 0xec/4:
LOGMASKED(LOG_READS, "%s: read: LED 1 Control Register: %08x & %08x\n", machine().describe_context(), 0, mem_mask);
return 0;
default:
LOGMASKED(LOG_READS | LOG_UNKNOWN, "%s: read: Unknown Register: %08x & %08x\n", machine().describe_context(), offset << 2, mem_mask);
return 0;
}
}
void locomo_device::write(offs_t offset, uint32_t data, uint32_t mem_mask)
{
switch (offset)
{
case 0x00/4:
LOGMASKED(LOG_WRITES, "%s: write: Version Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x04/4:
LOGMASKED(LOG_WRITES, "%s: write: Pin Status Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x08/4:
LOGMASKED(LOG_WRITES, "%s: write: C32K(?) Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x0c/4:
LOGMASKED(LOG_WRITES, "%s: write: Interrupt Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x10/4:
LOGMASKED(LOG_WRITES, "%s: write: Memory Chip Select 0 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x14/4:
LOGMASKED(LOG_WRITES, "%s: write: Memory Chip Select 1 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x18/4:
LOGMASKED(LOG_WRITES, "%s: write: Memory Chip Select 2 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x1c/4:
LOGMASKED(LOG_WRITES, "%s: write: Memory Chip Select 3 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x20/4:
LOGMASKED(LOG_WRITES, "%s: write: A/D Start Delay Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x24/4:
LOGMASKED(LOG_WRITES, "%s: write: HSYS Delay Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x28/4:
LOGMASKED(LOG_WRITES, "%s: write: HSYS Period Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x30/4:
LOGMASKED(LOG_WRITES, "%s: write: Tablet ADC Clock Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x38/4:
LOGMASKED(LOG_WRITES, "%s: write: TFT Backlight Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x3c/4:
LOGMASKED(LOG_WRITES, "%s: write: TFT CPS Delay Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x40/4:
LOGMASKED(LOG_WRITES, "%s: write: Keyboard Level Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x44/4:
LOGMASKED(LOG_WRITES, "%s: write: Keyboard Strobe Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
if (m_kbd_cmd == 1)
{
if (m_kbd_row == 0)
{
m_kbd_row = (uint16_t)data;
}
else if (m_kbd_col == 0)
{
m_kbd_col = (uint16_t)data;
if (m_kbd_col == 0xffff)
{
m_kbd_cmd = 0;
m_kbd_level = 0;
}
else
{
// HACK: Something about this value causes the Zaurus updater to begin booting.
// TODO: Work out the proper keyboard matrix.
m_kbd_level = 0xffff;
}
m_kbd_row = 0;
m_kbd_col = 0;
}
}
break;
case 0x48/4:
{
LOGMASKED(LOG_WRITES, "%s: write: Keyboard Strobe Command Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
const uint16_t old = m_kbd_cmd;
m_kbd_cmd = (uint16_t)data;
if (old == 0)
{
m_kbd_row = 0;
m_kbd_col = 0;
}
break;
}
case 0x4c/4:
LOGMASKED(LOG_WRITES, "%s: write: Keyboard Interrupt Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x54/4:
LOGMASKED(LOG_WRITES, "%s: write: Audio Clock Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x60/4:
LOGMASKED(LOG_WRITES, "%s: write: SPI Mode Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x64/4:
LOGMASKED(LOG_WRITES, "%s: write: SPI Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x68/4:
LOGMASKED(LOG_WRITES, "%s: write: SPI Status Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x70/4:
LOGMASKED(LOG_WRITES, "%s: write: SPI Interrupt Status Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x74/4:
LOGMASKED(LOG_WRITES, "%s: write: SPI Interrupt Status Write-Enable Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x78/4:
LOGMASKED(LOG_WRITES, "%s: write: SPI Interrupt Enable Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x7c/4:
LOGMASKED(LOG_WRITES, "%s: write: SPI Interrupt Request Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x80/4:
LOGMASKED(LOG_WRITES, "%s: write: SPI Transmit Data Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x84/4:
LOGMASKED(LOG_WRITES, "%s: write: SPI Receive Data Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x88/4:
LOGMASKED(LOG_WRITES, "%s: write: SPI Transmit Shift Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x8c/4:
LOGMASKED(LOG_WRITES, "%s: write: SPI Receive Shift Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x90/4:
LOGMASKED(LOG_WRITES, "%s: write: GPIO Direction Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x94/4:
LOGMASKED(LOG_WRITES, "%s: write: GPIO Input Enable Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x98/4:
LOGMASKED(LOG_WRITES, "%s: write: GPIO Level Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x9c/4:
LOGMASKED(LOG_WRITES, "%s: write: GPIO Output Latch Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0xa0/4:
LOGMASKED(LOG_WRITES, "%s: write: GPIO Rising-Edge Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0xa4/4:
LOGMASKED(LOG_WRITES, "%s: write: GPIO Falling-Edge Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0xa8/4:
LOGMASKED(LOG_WRITES, "%s: write: GPIO Edge-Detect Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0xac/4:
LOGMASKED(LOG_WRITES, "%s: write: GPIO Status Write-Enable Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0xb0/4:
LOGMASKED(LOG_WRITES, "%s: write: GPIO Interrupt Enable Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0xb4/4:
LOGMASKED(LOG_WRITES, "%s: write: GPIO Interrupt Status Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0xc8/4:
LOGMASKED(LOG_WRITES, "%s: write: Front Light Cycle Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0xcc/4:
LOGMASKED(LOG_WRITES, "%s: write: Front Light Duty Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0xd8/4:
LOGMASKED(LOG_WRITES, "%s: write: Long-Time Clock Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0xdc/4:
LOGMASKED(LOG_WRITES, "%s: write: Long-Time Clock Interrupt Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0xe0/4:
LOGMASKED(LOG_WRITES, "%s: write: DAC Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0xe8/4:
LOGMASKED(LOG_WRITES, "%s: write: LED 0 Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0xec/4:
LOGMASKED(LOG_WRITES, "%s: write: LED 1 Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
default:
LOGMASKED(LOG_WRITES | LOG_UNKNOWN, "%s: write: Unknown Register: %08x = %08x & %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
break;
}
}

View File

@ -0,0 +1,34 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
/***************************************************************************
Sharp LoCoMo peripheral chip emulation
***************************************************************************/
#ifndef MAME_MACHINE_LOCOMO
#define MAME_MACHINE_LOCOMO
#pragma once
class locomo_device : public device_t
{
public:
locomo_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
uint32_t read(offs_t offset, uint32_t mem_mask = ~0U);
void write(offs_t offset, uint32_t data, uint32_t mem_mask = ~0U);
protected:
virtual void device_start() override;
virtual void device_reset() override;
uint16_t m_kbd_cmd;
uint16_t m_kbd_row;
uint16_t m_kbd_col;
uint16_t m_kbd_level;
};
DECLARE_DEVICE_TYPE(LOCOMO, locomo_device)
#endif // MAME_MACHINE_LOCOMO

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
/**************************************************************************
*
* Intel XScale SA1110 peripheral emulation
*
**************************************************************************/
/***************************************************************************
Intel XScale SA1110 peripheral emulation
***************************************************************************/
#ifndef MAME_MACHINE_SA1110
#define MAME_MACHINE_SA1110
@ -13,10 +13,12 @@
#include "cpu/arm7/arm7.h"
#include "cpu/arm7/arm7core.h"
#include "sound/dmadac.h"
#include "emupal.h"
class sa1110_periphs_device : public device_t
#include "machine/input_merger.h"
#include "diserial.h"
class sa1110_periphs_device : public device_t, public device_serial_interface
{
public:
template <typename T>
@ -28,29 +30,90 @@ public:
sa1110_periphs_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
uint32_t intc_r(offs_t offset, uint32_t mem_mask = ~0);
void intc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
// device_serial overrides
virtual void rcv_complete() override; // Rx completed receiving byte
virtual void tra_complete() override; // Tx completed sending byte
virtual void tra_callback() override; // Tx send bit
void gpio_in(const uint32_t line, const int state);
template <unsigned Line> auto gpio_out() { return m_gpio_out[Line].bind(); }
uint32_t uart3_r(offs_t offset, uint32_t mem_mask = ~0);
void uart3_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
uint32_t ostimer_r(offs_t offset, uint32_t mem_mask = ~0);
void ostimer_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
uint32_t rtc_r(offs_t offset, uint32_t mem_mask = ~0);
void rtc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
uint32_t power_r(offs_t offset, uint32_t mem_mask = ~0);
void power_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
uint32_t reset_r(offs_t offset, uint32_t mem_mask = ~0);
void reset_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
uint32_t gpio_r(offs_t offset, uint32_t mem_mask = ~0);
void gpio_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
uint32_t intc_r(offs_t offset, uint32_t mem_mask = ~0);
void intc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
protected:
virtual void device_add_mconfig(machine_config &config) 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;
void update_interrupts();
static constexpr uint32_t INTERNAL_OSC = 3686400;
DECLARE_WRITE_LINE_MEMBER(uart3_irq_callback);
void uart_recalculate_divisor();
void uart_update_eif_status();
uint8_t uart_read_receive_fifo();
void uart_write_transmit_fifo(uint8_t data);
void uart_check_tx_fifo_service();
void uart_set_receiver_idle();
void uart_begin_of_break();
void uart_end_of_break();
void uart_set_receiver_enabled(bool enabled);
void uart_set_transmitter_enabled(bool enabled);
void uart_set_receive_irq_enabled(bool enabled);
void uart_set_transmit_irq_enabled(bool enabled);
TIMER_CALLBACK_MEMBER(ostimer_tick_cb);
void ostimer_update_count();
void ostimer_update_match_timer(int channel);
TIMER_CALLBACK_MEMBER(rtc_tick_cb);
void gpio_update_interrupts(const uint32_t changed_mask);
void gpio_update_direction(const uint32_t old_gpdr);
void gpio_update_outputs(const uint32_t old_latch, const uint32_t changed);
void gpio_update_alternate_pins(const uint32_t changed_mask);
void set_irq_line(uint32_t line, int state);
void update_interrupts();
// register offsets
enum
{
INTC_BASE_ADDR = 0x90050000,
REG_ICIP = (0x00000000 >> 2),
REG_ICMR = (0x00000004 >> 2),
REG_ICLR = (0x00000008 >> 2),
REG_ICCR = (0x0000000c >> 2),
REG_ICFP = (0x00000010 >> 2),
REG_ICPR = (0x00000020 >> 2),
UART_BASE_ADDR = 0x80050000,
REG_UTCR0 = (0x00000000 >> 2),
REG_UTCR1 = (0x00000004 >> 2),
REG_UTCR2 = (0x00000008 >> 2),
REG_UTCR3 = (0x0000000c >> 2),
REG_UTDR = (0x00000014 >> 2),
REG_UTSR0 = (0x0000001c >> 2),
REG_UTSR1 = (0x00000020 >> 2),
OSTMR_BASE_ADDR = 0x90000000,
REG_OSMR0 = (0x00000000 >> 2),
REG_OSMR1 = (0x00000004 >> 2),
REG_OSMR2 = (0x00000008 >> 2),
REG_OSMR3 = (0x0000000c >> 2),
REG_OSCR = (0x00000010 >> 2),
REG_OSSR = (0x00000014 >> 2),
REG_OWER = (0x00000018 >> 2),
REG_OIER = (0x0000001c >> 2),
RTC_BASE_ADDR = 0x90010000,
REG_RTAR = (0x00000000 >> 2),
REG_RCNR = (0x00000004 >> 2),
REG_RTTR = (0x00000008 >> 2),
REG_RTSR = (0x00000010 >> 2),
POWER_BASE_ADDR = 0x90020000,
REG_PMCR = (0x00000000 >> 2),
@ -60,17 +123,155 @@ protected:
REG_PCFR = (0x00000010 >> 2),
REG_PPCR = (0x00000014 >> 2),
REG_PGSR = (0x00000018 >> 2),
REG_POSR = (0x0000001c >> 2)
REG_POSR = (0x0000001c >> 2),
RESET_BASE_ADDR = 0x90030000,
REG_RSRR = (0x00000000 >> 2),
REG_RCSR = (0x00000004 >> 2),
GPIO_BASE_ADDR = 0x90040000,
REG_GPLR = (0x00000000 >> 2),
REG_GPDR = (0x00000004 >> 2),
REG_GPSR = (0x00000008 >> 2),
REG_GPCR = (0x0000000c >> 2),
REG_GRER = (0x00000010 >> 2),
REG_GFER = (0x00000014 >> 2),
REG_GEDR = (0x00000018 >> 2),
REG_GAFR = (0x0000001c >> 2),
INTC_BASE_ADDR = 0x90050000,
REG_ICIP = (0x00000000 >> 2),
REG_ICMR = (0x00000004 >> 2),
REG_ICLR = (0x00000008 >> 2),
REG_ICCR = (0x0000000c >> 2),
REG_ICFP = (0x00000010 >> 2),
REG_ICPR = (0x00000020 >> 2)
};
struct intc_regs
// register contents
enum : uint32_t
{
uint32_t icip;
uint32_t icmr;
uint32_t iclr;
uint32_t iccr;
uint32_t icfp;
uint32_t icpr;
UART3_FIFO_PRE = 8,
UART3_FIFO_FRE = 9,
UART3_FIFO_ROR = 10,
UTCR3_RXE_BIT = 0,
UTCR3_TXE_BIT = 1,
UTCR3_BRK_BIT = 2,
UTCR3_RIE_BIT = 3,
UTCR3_TIE_BIT = 4,
UTCR3_LBM_BIT = 5,
UTSR0_TFS_BIT = 0,
UTSR0_RFS_BIT = 1,
UTSR0_RID_BIT = 2,
UTSR0_RBB_BIT = 3,
UTSR0_REB_BIT = 4,
UTSR0_EIF_BIT = 5,
UTSR1_TBY_BIT = 0,
UTSR1_RNE_BIT = 1,
UTSR1_TNF_BIT = 2,
UTSR1_PRE_BIT = 3,
UTSR1_FRE_BIT = 4,
UTSR1_ROR_BIT = 5,
RTSR_AL_BIT = 0,
RTSR_AL_MASK = (1 << RTSR_AL_BIT),
RTSR_HZ_BIT = 1,
RTSR_HZ_MASK = (1 << RTSR_HZ_BIT),
RTSR_ALE_BIT = 2,
RTSR_ALE_MASK = (1 << RTSR_ALE_BIT),
RTSR_HZE_BIT = 3,
RTSR_HZE_MASK = (1 << RTSR_HZE_BIT)
};
// interrupt bits
enum : uint32_t
{
INT_GPIO0 = 0,
INT_GPIO1 = 1,
INT_GPIO2 = 2,
INT_GPIO3 = 3,
INT_GPIO4 = 4,
INT_GPIO5 = 5,
INT_GPIO6 = 6,
INT_GPIO7 = 7,
INT_GPIO8 = 8,
INT_GPIO9 = 9,
INT_GPIO10 = 10,
INT_GPIOHI = 11,
INT_LCD = 12,
INT_UDC = 13,
INT_UART1 = 15,
INT_UART2 = 16,
INT_UART3 = 17,
INT_MCP = 18,
INT_SSP = 19,
INT_DMA0 = 20,
INT_DMA1 = 21,
INT_DMA2 = 22,
INT_DMA3 = 23,
INT_DMA4 = 24,
INT_DMA5 = 25,
INT_OSTIMER0 = 26,
INT_OSTIMER1 = 27,
INT_OSTIMER2 = 28,
INT_OSTIMER3 = 29,
INT_RTC_TICK = 30,
INT_RTC_ALARM = 31
};
// UART3 interrupt sources
enum : unsigned
{
UART3_TFS = 0,
UART3_RFS = 1,
UART3_RID = 2,
UART3_RBB = 3,
UART3_REB = 4,
UART3_EIF = 5,
};
struct uart_regs
{
uint32_t utcr[4];
uint32_t utsr0;
uint32_t utsr1;
uint16_t rx_fifo[12];
int rx_fifo_read_idx;
int rx_fifo_write_idx;
int rx_fifo_count;
uint8_t tx_fifo[8];
int tx_fifo_read_idx;
int tx_fifo_write_idx;
int tx_fifo_count;
bool rx_break_interlock;
};
struct ostimer_regs
{
uint32_t osmr[4];
uint32_t oscr;
uint32_t ossr;
uint32_t ower;
uint32_t oier;
emu_timer *timer[4];
attotime last_count_sync;
};
struct rtc_regs
{
uint32_t rtar;
uint32_t rcnr;
uint32_t rttr;
uint32_t rtsr;
emu_timer *tick_timer;
};
struct power_regs
@ -85,10 +286,45 @@ protected:
uint32_t posr;
};
intc_regs m_intc_regs;
struct gpio_regs
{
uint32_t gplr;
uint32_t gpdr;
uint32_t grer;
uint32_t gfer;
uint32_t gedr;
uint32_t gafr;
uint32_t any_edge_mask;
uint32_t output_latch;
uint32_t input_latch;
uint32_t alt_output_latch;
uint32_t alt_input_latch;
};
struct intc_regs
{
uint32_t icip;
uint32_t icmr;
uint32_t iclr;
uint32_t iccr;
uint32_t icfp;
uint32_t icpr;
};
uart_regs m_uart_regs;
ostimer_regs m_ostmr_regs;
rtc_regs m_rtc_regs;
power_regs m_power_regs;
uint32_t m_rcsr;
gpio_regs m_gpio_regs;
intc_regs m_intc_regs;
required_device<cpu_device> m_maincpu;
required_device<input_merger_device> m_uart3_irqs;
devcb_write_line::array<28> m_gpio_out;
};
DECLARE_DEVICE_TYPE(SA1110_PERIPHERALS, sa1110_periphs_device)

View File

@ -1403,6 +1403,7 @@ Note:
#include "emu.h"
#include "cpu/arm7/arm7.h"
#include "cpu/arm7/arm7core.h"
#include "machine/locomo.h"
#include "machine/pxa255.h"
#include "machine/sa1110.h"
#include "machine/timer.h"
@ -1410,12 +1411,14 @@ Note:
#include "screen.h"
#include "speaker.h"
#define SA1110_CLOCK 206000000
#define PXA250_CLOCK 400000000
#define PXA255_CLOCK 400000000
#define PXA270_CLOCK 416000000
namespace
{
class zaurus_state : public driver_device
{
public:
@ -1441,14 +1444,18 @@ public:
zaurus_sa_state(const machine_config &mconfig, device_type type, const char *tag)
: zaurus_state(mconfig, type, tag)
, m_sa_periphs(*this, "sa_periphs")
, m_locomo(*this, "locomo")
{ }
void zaurus_sa1110(machine_config &config);
private:
virtual void device_reset_after_children() override;
void main_map(address_map &map);
required_device<sa1110_periphs_device> m_sa_periphs;
required_device<locomo_device> m_locomo;
};
class zaurus_pxa_state : public zaurus_state
@ -1477,9 +1484,15 @@ private:
void zaurus_sa_state::main_map(address_map &map)
{
map(0x00000000, 0x00ffffff).rom().region("firmware", 0);
map(0x40000000, 0x40001fff).rw(m_locomo, FUNC(locomo_device::read), FUNC(locomo_device::write));
map(0x80050000, 0x80050023).rw(m_sa_periphs, FUNC(sa1110_periphs_device::uart3_r), FUNC(sa1110_periphs_device::uart3_w));
map(0x90000000, 0x9000001f).rw(m_sa_periphs, FUNC(sa1110_periphs_device::ostimer_r), FUNC(sa1110_periphs_device::ostimer_w));
map(0x90010000, 0x9001000f).rw(m_sa_periphs, FUNC(sa1110_periphs_device::rtc_r), FUNC(sa1110_periphs_device::rtc_w));
map(0x90020000, 0x9002001f).rw(m_sa_periphs, FUNC(sa1110_periphs_device::power_r), FUNC(sa1110_periphs_device::power_w));
map(0x90030000, 0x90030007).rw(m_sa_periphs, FUNC(sa1110_periphs_device::reset_r), FUNC(sa1110_periphs_device::reset_w));
map(0x90040000, 0x90040023).rw(m_sa_periphs, FUNC(sa1110_periphs_device::gpio_r), FUNC(sa1110_periphs_device::gpio_w));
map(0x90050000, 0x90050023).rw(m_sa_periphs, FUNC(sa1110_periphs_device::intc_r), FUNC(sa1110_periphs_device::intc_w));
map(0xc0000000, 0xc07fffff).ram().share("ram");
map(0xc0000000, 0xc3ffffff).ram().share("ram");
}
void zaurus_pxa_state::main_map(address_map &map)
@ -1497,6 +1510,11 @@ void zaurus_pxa_state::main_map(address_map &map)
map(0xa0000000, 0xa07fffff).ram().share("ram");
}
void zaurus_sa_state::device_reset_after_children()
{
m_sa_periphs->gpio_in(1, 1);
}
INPUT_CHANGED_MEMBER( zaurus_pxa_state::system_start )
{
m_pxa_periphs->gpio_bit_w(10, m_power->read());
@ -1524,6 +1542,8 @@ void zaurus_sa_state::zaurus_sa1110(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &zaurus_sa_state::main_map);
SA1110_PERIPHERALS(config, m_sa_periphs, SA1110_CLOCK, m_maincpu);
LOCOMO(config, m_locomo);
}
void zaurus_pxa_state::zaurus_pxa250(machine_config &config)
@ -1595,6 +1615,8 @@ ROM_START( zslc1000 )
ROM_LOAD( "openzaurus 3.5.3 - zimage-sharp sl-c1000-20050427214434.bin", 0x000000, 0x128980, BAD_DUMP CRC(1e1a9279) SHA1(909ac3f00385eced55822d6a155b79d9d25f43b3) )
ROM_END
} // anonymous namespace
COMP( 2002, zsl5500, 0, 0, zaurus_sa1110, zaurus_sa, zaurus_sa_state, empty_init, "Sharp", "Zaurus SL-5500 \"Collie\"", MACHINE_IS_SKELETON )
COMP( 2002, zslc500, 0, 0, zaurus_pxa250, zaurus_pxa, zaurus_pxa_state, empty_init, "Sharp", "Zaurus SL-C500", MACHINE_IS_SKELETON )
COMP( 2002, zsl5600, 0, 0, zaurus_pxa250, zaurus_pxa, zaurus_pxa_state, empty_init, "Sharp", "Zaurus SL-5600 / SL-B500 \"Poodle\"", MACHINE_IS_SKELETON )