mirror of
https://github.com/holub/mame
synced 2025-04-16 21:44:32 +03:00
- m950x0: Added implementation for STmicro M950x0 SPI EEPROM series. [Ryan Holtz]
- sa1110: Added rudimentary support for the ICP and DMA blocks. [Ryan Holtz] - sa1111: Various changes. [Ryan Holtz] * Hooked up I2S audio DMA support. * Hooked up IRQ support. * Hooked up basic GPIO support. - uda1344: Added initial pass at audio support, based on DMADAC. [Ryan Holtz] - sed1356: Added support for BitBLT solid-fill command. [Ryan Holtz] - jornada: Added more keys, touch pen support, and fixed EEPROM access. [Ryan Holtz]
This commit is contained in:
parent
e125fbbc06
commit
1fad52d8ee
@ -1721,6 +1721,18 @@ if (MACHINES["K056230"]~=null) then
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/m950x0.h,MACHINES["M950X0"] = true
|
||||
---------------------------------------------------
|
||||
|
||||
if (MACHINES["M950X0"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/machine/m950x0.cpp",
|
||||
MAME_DIR .. "src/devices/machine/m950x0.h",
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/mm5740.h,MACHINES["MM5740"] = true
|
||||
|
@ -558,6 +558,7 @@ MACHINES["MC68901"] = true
|
||||
MACHINES["MCCS1850"] = true
|
||||
MACHINES["M68307"] = true
|
||||
MACHINES["M68340"] = true
|
||||
--MACHINES["M950X0"] = true
|
||||
MACHINES["MCF5206E"] = true
|
||||
MACHINES["METERS"] = true
|
||||
MACHINES["MICROTOUCH"] = true
|
||||
|
@ -569,6 +569,7 @@ MACHINES["LSI53C810"] = true
|
||||
MACHINES["M3002"] = true
|
||||
MACHINES["M68307"] = true
|
||||
MACHINES["M68340"] = true
|
||||
MACHINES["M950X0"] = true
|
||||
MACHINES["M68SFDC"] = true
|
||||
MACHINES["M6M80011AP"] = true
|
||||
MACHINES["MB14241"] = true
|
||||
|
207
src/devices/machine/m950x0.cpp
Normal file
207
src/devices/machine/m950x0.cpp
Normal file
@ -0,0 +1,207 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/***************************************************************************
|
||||
|
||||
m950x0.cpp
|
||||
|
||||
STmicro M95010/20/40 SPI-bus EEPROM
|
||||
|
||||
Common characteristics:
|
||||
- 16-byte page size
|
||||
- Write protection selectable in quarter, half, or full sizes
|
||||
|
||||
Part variants with a -DF designation have additional support for an
|
||||
identification page, which is not currently emulated.
|
||||
|
||||
Sizes:
|
||||
M95010 - 1kbit
|
||||
M95020 - 2kbit
|
||||
M95040 - 4kbit, slightly altered instructions for 9th address bit
|
||||
|
||||
Current issues:
|
||||
- Implementation currently operates in a parallel manner, rather than
|
||||
serial.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "m950x0.h"
|
||||
|
||||
#define VERBOSE (0)
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(M95010, m95010_device, "m95010", "STmicro M95010 1kbit SPI EEPROM")
|
||||
DEFINE_DEVICE_TYPE(M95020, m95020_device, "m95020", "STmicro M95020 2kbit SPI EEPROM")
|
||||
DEFINE_DEVICE_TYPE(M95040, m95040_device, "m95040", "STmicro M95040 4kbit SPI EEPROM")
|
||||
|
||||
m950x0_device::m950x0_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, int capacity)
|
||||
: eeprom_base_device(mconfig, type, tag, owner)
|
||||
, m_check_a8(capacity > 0x100)
|
||||
, m_addr_mask((uint16_t)capacity - 1)
|
||||
, m_state(STATE_IDLE)
|
||||
{
|
||||
size(capacity, 8);
|
||||
}
|
||||
|
||||
m95010_device::m95010_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: m950x0_device(mconfig, M95010, tag, owner, 0x80)
|
||||
{
|
||||
}
|
||||
|
||||
m95020_device::m95020_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: m950x0_device(mconfig, M95010, tag, owner, 0x100)
|
||||
{
|
||||
}
|
||||
|
||||
m95040_device::m95040_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: m950x0_device(mconfig, M95010, tag, owner, 0x200)
|
||||
{
|
||||
}
|
||||
|
||||
void m950x0_device::device_start()
|
||||
{
|
||||
eeprom_base_device::device_start();
|
||||
|
||||
save_item(NAME(m_state));
|
||||
save_item(NAME(m_selected));
|
||||
save_item(NAME(m_status));
|
||||
save_item(NAME(m_addr));
|
||||
}
|
||||
|
||||
void m950x0_device::device_reset()
|
||||
{
|
||||
eeprom_base_device::device_reset();
|
||||
|
||||
m_state = STATE_IDLE;
|
||||
m_selected = false;
|
||||
m_status = 0xf0;
|
||||
m_addr = 0;
|
||||
}
|
||||
|
||||
uint8_t m950x0_device::access(uint8_t data)
|
||||
{
|
||||
if (!m_selected)
|
||||
return 0;
|
||||
|
||||
uint8_t response = 0;
|
||||
|
||||
switch (m_state)
|
||||
{
|
||||
case STATE_IDLE:
|
||||
process_instruction(data);
|
||||
break;
|
||||
|
||||
case STATE_RDSR:
|
||||
response = m_status;
|
||||
m_state = STATE_IDLE;
|
||||
LOG("Status Register read, value: %02x\n", response);
|
||||
break;
|
||||
|
||||
case STATE_WRSR:
|
||||
m_status &= 0xf0;
|
||||
m_status |= data & 0x0f;
|
||||
m_state = STATE_IDLE;
|
||||
LOG("Status Register write, new value: %02x\n", m_status);
|
||||
break;
|
||||
|
||||
case STATE_READ_ADDR:
|
||||
m_addr |= data;
|
||||
m_state = STATE_READ_DATA;
|
||||
LOG("Read command, starting address: %03x, entering read-data state\n", m_addr);
|
||||
break;
|
||||
|
||||
case STATE_WRITE_ADDR:
|
||||
m_addr |= data;
|
||||
m_state = STATE_WRITE_DATA;
|
||||
LOG("Write command, starting address: %03x, entering write-data state\n", m_addr);
|
||||
break;
|
||||
|
||||
case STATE_READ_DATA:
|
||||
response = (uint8_t)internal_read(m_addr);
|
||||
LOG("Read command, data: %02x, at address %03x\n", response, m_addr);
|
||||
m_addr++;
|
||||
m_addr &= m_addr_mask;
|
||||
break;
|
||||
|
||||
case STATE_WRITE_DATA:
|
||||
internal_write(m_addr, data);
|
||||
LOG("Write command, data: %02x to address %03x\n", data, m_addr);
|
||||
m_addr++;
|
||||
m_addr &= m_addr_mask;
|
||||
break;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
void m950x0_device::process_instruction(const uint8_t insn)
|
||||
{
|
||||
switch (insn)
|
||||
{
|
||||
case INSN_WREN0:
|
||||
case INSN_WREN1:
|
||||
LOG("Instruction: Write enable\n");
|
||||
m_status |= (1 << STATUS_WEL_BIT);
|
||||
break;
|
||||
|
||||
case INSN_WRDI0:
|
||||
case INSN_WRDI1:
|
||||
LOG("Instruction: Write disable\n");
|
||||
m_status &= ~(1 << STATUS_WEL_BIT);
|
||||
break;
|
||||
|
||||
case INSN_RDSR0:
|
||||
case INSN_RDSR1:
|
||||
LOG("Instruction: Read status register\n");
|
||||
m_state = STATE_RDSR;
|
||||
break;
|
||||
|
||||
case INSN_WRSR0:
|
||||
case INSN_WRSR1:
|
||||
LOG("Instruction: Write status register\n");
|
||||
m_state = STATE_WRSR;
|
||||
break;
|
||||
|
||||
case INSN_READ0:
|
||||
LOG("Instruction: Read, A8=0\n");
|
||||
m_state = STATE_READ_ADDR;
|
||||
break;
|
||||
case INSN_READ1:
|
||||
LOG("Instruction: Read, A8=1\n");
|
||||
m_state = STATE_READ_ADDR;
|
||||
if (m_check_a8)
|
||||
m_addr |= 0x100;
|
||||
break;
|
||||
|
||||
case INSN_WRITE0:
|
||||
LOG("Instruction: Write, A8=0\n");
|
||||
m_state = STATE_WRITE_ADDR;
|
||||
break;
|
||||
case INSN_WRITE1:
|
||||
LOG("Instruction: Write, A8=1\n");
|
||||
m_state = STATE_WRITE_ADDR;
|
||||
if (m_check_a8)
|
||||
m_addr |= 0x100;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG("Unrecognized instruction byte: %02x, deselecting\n", insn);
|
||||
m_selected = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void m950x0_device::select_w(int selected)
|
||||
{
|
||||
if (m_selected == (bool)selected)
|
||||
return;
|
||||
|
||||
m_selected = (bool)selected;
|
||||
|
||||
if (!selected)
|
||||
{
|
||||
LOG("Deselected, resetting address to 0 and entering idle state.\n");
|
||||
m_state = STATE_IDLE;
|
||||
m_addr = 0;
|
||||
}
|
||||
}
|
98
src/devices/machine/m950x0.h
Normal file
98
src/devices/machine/m950x0.h
Normal file
@ -0,0 +1,98 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/***************************************************************************
|
||||
|
||||
m950x0.h
|
||||
|
||||
STmicro M95010/20/40 SPI-bus EEPROM
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_MACHINE_M950X0_H
|
||||
#define MAME_MACHINE_M950X0_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/eeprom.h"
|
||||
|
||||
class m950x0_device : public eeprom_base_device
|
||||
{
|
||||
public:
|
||||
uint8_t access(uint8_t data);
|
||||
void select_w(int selected);
|
||||
|
||||
protected:
|
||||
m950x0_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, int capacity);
|
||||
|
||||
private:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
void process_instruction(const uint8_t insn);
|
||||
|
||||
enum : uint32_t
|
||||
{
|
||||
STATE_IDLE,
|
||||
|
||||
// Status-register accesses expect two sequential bytes (instruction + status)
|
||||
STATE_RDSR,
|
||||
STATE_WRSR,
|
||||
|
||||
// Reads and writes expect a minimum of 3 bytes (instruction + address + data)
|
||||
STATE_READ_ADDR,
|
||||
STATE_READ_DATA,
|
||||
STATE_WRITE_ADDR,
|
||||
STATE_WRITE_DATA
|
||||
};
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
INSN_WRSR0 = 0x01,
|
||||
INSN_WRITE0 = 0x02,
|
||||
INSN_READ0 = 0x03,
|
||||
INSN_WRDI0 = 0x04,
|
||||
INSN_RDSR0 = 0x05,
|
||||
INSN_WREN0 = 0x06,
|
||||
|
||||
INSN_WRSR1 = 0x09,
|
||||
INSN_WRITE1 = 0x0a,
|
||||
INSN_READ1 = 0x0b,
|
||||
INSN_WRDI1 = 0x0c,
|
||||
INSN_RDSR1 = 0x0d,
|
||||
INSN_WREN1 = 0x0e,
|
||||
|
||||
STATUS_WEL_BIT = 1
|
||||
};
|
||||
|
||||
const bool m_check_a8;
|
||||
const uint16_t m_addr_mask;
|
||||
|
||||
uint32_t m_state;
|
||||
bool m_selected;
|
||||
uint8_t m_status;
|
||||
uint16_t m_addr;
|
||||
};
|
||||
|
||||
class m95010_device : public m950x0_device
|
||||
{
|
||||
public:
|
||||
m95010_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
||||
};
|
||||
|
||||
class m95020_device : public m950x0_device
|
||||
{
|
||||
public:
|
||||
m95020_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
||||
};
|
||||
|
||||
class m95040_device : public m950x0_device
|
||||
{
|
||||
public:
|
||||
m95040_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(M95010, m95010_device)
|
||||
DECLARE_DEVICE_TYPE(M95020, m95020_device)
|
||||
DECLARE_DEVICE_TYPE(M95040, m95040_device)
|
||||
|
||||
#endif // MAME_MACHINE_M950X0_H
|
@ -10,21 +10,26 @@
|
||||
#include "sa1110.h"
|
||||
|
||||
#define LOG_UNKNOWN (1 << 1)
|
||||
#define LOG_UART (1 << 2)
|
||||
#define LOG_UART_HF (1 << 3)
|
||||
#define LOG_MCP (1 << 4)
|
||||
#define LOG_SSP (1 << 5)
|
||||
#define LOG_OSTIMER (1 << 6)
|
||||
#define LOG_OSTIMER_HF (1 << 7)
|
||||
#define LOG_RTC (1 << 8)
|
||||
#define LOG_POWER (1 << 9)
|
||||
#define LOG_RESET (1 << 10)
|
||||
#define LOG_GPIO (1 << 11)
|
||||
#define LOG_GPIO_HF (1 << 12)
|
||||
#define LOG_INTC (1 << 13)
|
||||
#define LOG_ALL (LOG_UNKNOWN | LOG_UART | LOG_MCP | LOG_SSP | LOG_OSTIMER | LOG_RTC | LOG_POWER | LOG_RESET | LOG_GPIO | LOG_INTC)
|
||||
#define LOG_ICP (1 << 2)
|
||||
#define LOG_UART3 (1 << 3)
|
||||
#define LOG_UART3_HF (1 << 4)
|
||||
#define LOG_MCP (1 << 5)
|
||||
#define LOG_SSP (1 << 6)
|
||||
#define LOG_OSTIMER (1 << 7)
|
||||
#define LOG_OSTIMER_HF (1 << 8)
|
||||
#define LOG_RTC (1 << 9)
|
||||
#define LOG_RTC_HF (1 << 10)
|
||||
#define LOG_POWER (1 << 11)
|
||||
#define LOG_POWER_HF (1 << 12)
|
||||
#define LOG_RESET (1 << 13)
|
||||
#define LOG_GPIO (1 << 14)
|
||||
#define LOG_GPIO_HF (1 << 15)
|
||||
#define LOG_INTC (1 << 16)
|
||||
#define LOG_PPC (1 << 17)
|
||||
#define LOG_DMA (1 << 18)
|
||||
#define LOG_ALL (LOG_UNKNOWN | LOG_ICP | LOG_UART3 | LOG_MCP | LOG_OSTIMER | LOG_RTC | LOG_POWER | LOG_RESET | LOG_GPIO | LOG_INTC | LOG_PPC | LOG_DMA)
|
||||
|
||||
#define VERBOSE (0) // (LOG_ALL)
|
||||
#define VERBOSE (0)
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(SA1110_PERIPHERALS, sa1110_periphs_device, "sa1110_periphs", "Intel XScale SA1110 Peripherals")
|
||||
@ -42,6 +47,252 @@ sa1110_periphs_device::sa1110_periphs_device(const machine_config &mconfig, cons
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Intel SA-1110 ICP - Serial Port 2
|
||||
|
||||
pg. 264 to 288 Intel StrongARM SA-1110 Microprocessor Developer's Manual
|
||||
|
||||
*/
|
||||
|
||||
TIMER_CALLBACK_MEMBER(sa1110_periphs_device::icp_rx_callback)
|
||||
{
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(sa1110_periphs_device::icp_tx_callback)
|
||||
{
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(sa1110_periphs_device::hssp_rx_callback)
|
||||
{
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(sa1110_periphs_device::hssp_tx_callback)
|
||||
{
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::icp_uart_set_receiver_enabled(bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::icp_uart_set_transmitter_enabled(bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::icp_uart_set_receive_irq_enabled(bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::icp_uart_set_transmit_irq_enabled(bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t sa1110_periphs_device::icp_uart_read_receive_fifo()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::icp_uart_write_transmit_fifo(uint8_t data)
|
||||
{
|
||||
}
|
||||
|
||||
uint16_t sa1110_periphs_device::icp_hssp_read_receive_fifo()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::icp_hssp_write_transmit_fifo(uint8_t data)
|
||||
{
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::icp_uart_set_receiver_idle()
|
||||
{
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::icp_uart_begin_of_break()
|
||||
{
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::icp_uart_end_of_break()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
uint32_t sa1110_periphs_device::icp_r(offs_t offset, uint32_t mem_mask)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case REG_UTCR0:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_r: UART Control Register 0: %08x & %08x\n", machine().describe_context(), m_icp_regs.uart.utcr[0], mem_mask);
|
||||
return m_icp_regs.uart.utcr[0];
|
||||
case REG_UTCR1:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_r: UART Control Register 1: %08x & %08x\n", machine().describe_context(), m_icp_regs.uart.utcr[1], mem_mask);
|
||||
return m_icp_regs.uart.utcr[1];
|
||||
case REG_UTCR2:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_r: UART Control Register 2: %08x & %08x\n", machine().describe_context(), m_icp_regs.uart.utcr[2], mem_mask);
|
||||
return m_icp_regs.uart.utcr[2];
|
||||
case REG_UTCR3:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_r: UART Control Register 3: %08x & %08x\n", machine().describe_context(), m_icp_regs.uart.utcr[3], mem_mask);
|
||||
return m_icp_regs.uart.utcr[3];
|
||||
case REG_UTCR4:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_r: UART Control Register 4: %08x & %08x\n", machine().describe_context(), m_icp_regs.utcr4, mem_mask);
|
||||
return m_icp_regs.utcr4;
|
||||
case REG_UTDR:
|
||||
{
|
||||
const uint8_t data = icp_uart_read_receive_fifo();
|
||||
LOGMASKED(LOG_ICP, "%s: icp_r: UART Data Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
return data;
|
||||
}
|
||||
case REG_UTSR0:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_r: UART Status Register 0: %08x & %08x\n", machine().describe_context(), m_icp_regs.uart.utsr0, mem_mask);
|
||||
return m_icp_regs.uart.utsr0;
|
||||
case REG_UTSR1:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_r: UART Status Register 1: %08x & %08x\n", machine().describe_context(), m_icp_regs.uart.utsr1, mem_mask);
|
||||
return m_icp_regs.uart.utsr1;
|
||||
case REG_HSCR0:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_r: HSSP Control Register 0: %08x & %08x\n", machine().describe_context(), m_icp_regs.hssp.hscr0, mem_mask);
|
||||
return m_icp_regs.hssp.hscr0;
|
||||
case REG_HSCR1:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_r: HSSP Control Register 1: %08x & %08x\n", machine().describe_context(), m_icp_regs.hssp.hscr1, mem_mask);
|
||||
return m_icp_regs.hssp.hscr1;
|
||||
case REG_HSDR:
|
||||
{
|
||||
const uint16_t data = icp_hssp_read_receive_fifo();
|
||||
LOGMASKED(LOG_ICP, "%s: icp_r: HSSP Data Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
return data;
|
||||
}
|
||||
case REG_HSSR0:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_r: HSSP Status Register 0: %08x & %08x\n", machine().describe_context(), m_icp_regs.hssp.hssr0, mem_mask);
|
||||
return m_icp_regs.hssp.hssr0;
|
||||
case REG_HSSR1:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_r: HSSP Status Register 1: %08x & %08x\n", machine().describe_context(), m_icp_regs.hssp.hssr1, mem_mask);
|
||||
return m_icp_regs.hssp.hssr1;
|
||||
default:
|
||||
LOGMASKED(LOG_ICP | LOG_UNKNOWN, "%s: icp_r: Unknown address: %08x & %08x\n", machine().describe_context(), ICP_BASE_ADDR | (offset << 2), mem_mask);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::icp_w(offs_t offset, uint32_t data, uint32_t mem_mask)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case REG_UTCR0:
|
||||
{
|
||||
LOGMASKED(LOG_ICP, "%s: icp_w: UART Control Register 0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_ICP, "%s: Parity Enable: %d\n", machine().describe_context(), BIT(data, 0));
|
||||
LOGMASKED(LOG_ICP, "%s: Parity Mode: %s\n", machine().describe_context(), BIT(data, 1) ? "Even" : "Odd");
|
||||
LOGMASKED(LOG_ICP, "%s: Stop Bits: %d\n", machine().describe_context(), BIT(data, 2) + 1);
|
||||
LOGMASKED(LOG_ICP, "%s: Data Size: %d\n", machine().describe_context(), BIT(data, 3) ? 8 : 7);
|
||||
LOGMASKED(LOG_ICP, "%s: Sample Clock: %s\n", machine().describe_context(), BIT(data, 4) ? "External" : "Internal");
|
||||
LOGMASKED(LOG_ICP, "%s: Receive Edge: %s\n", machine().describe_context(), BIT(data, 5) ? "Falling" : "Rising");
|
||||
LOGMASKED(LOG_ICP, "%s: Transmit Edge: %s\n", machine().describe_context(), BIT(data, 6) ? "Falling" : "Rising");
|
||||
|
||||
//stop_bits_t stop_bits = (BIT(data, 2) ? STOP_BITS_2 : STOP_BITS_1);
|
||||
|
||||
//parity_t parity = PARITY_NONE;
|
||||
//if (BIT(data, 0))
|
||||
//{
|
||||
// parity = (BIT(data, 1) ? PARITY_EVEN : PARITY_ODD);
|
||||
//}
|
||||
|
||||
//set_data_frame(1, BIT(data, 3) ? 8 : 7, parity, stop_bits);
|
||||
//receive_register_reset();
|
||||
//transmit_register_reset();
|
||||
|
||||
COMBINE_DATA(&m_icp_regs.uart.utcr[0]);
|
||||
break;
|
||||
}
|
||||
case REG_UTCR1:
|
||||
{
|
||||
LOGMASKED(LOG_ICP, "%s: icp_w: UART Control Register 1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_ICP, "%s: Baud Rate Divisor MSB: %02x\n", machine().describe_context(), data & 0x0f);
|
||||
//const uint8_t old = m_uart_regs.utcr[1] & 0x0f;
|
||||
COMBINE_DATA(&m_icp_regs.uart.utcr[1]);
|
||||
//if ((m_uart_regs.utcr[1] & 0x0f) != old)
|
||||
// icp_uart_recalculate_divisor();
|
||||
break;
|
||||
}
|
||||
case REG_UTCR2:
|
||||
{
|
||||
LOGMASKED(LOG_ICP, "%s: icp_w: UART Control Register 2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_ICP, "%s: Baud Rate Divisor LSB: %02x\n", machine().describe_context(), (uint8_t)data);
|
||||
//const uint8_t old = m_uart_regs.utcr[2] & 0xff;
|
||||
COMBINE_DATA(&m_icp_regs.uart.utcr[2]);
|
||||
//if ((m_uart_regs.utcr[2] & 0xff) != old)
|
||||
// icp_uart_recalculate_divisor();
|
||||
break;
|
||||
}
|
||||
case REG_UTCR3:
|
||||
{
|
||||
LOGMASKED(LOG_ICP, "%s: icp_w: UART Control Register 3 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_ICP, "%s: Receive Enable: %d\n", machine().describe_context(), BIT(data, 0));
|
||||
LOGMASKED(LOG_ICP, "%s: Transmit Enable: %d\n", machine().describe_context(), BIT(data, 1));
|
||||
LOGMASKED(LOG_ICP, "%s: Send Break: %d\n", machine().describe_context(), BIT(data, 2));
|
||||
LOGMASKED(LOG_ICP, "%s: Receive FIFO IRQ Enable: %d\n", machine().describe_context(), BIT(data, 3));
|
||||
LOGMASKED(LOG_ICP, "%s: Transmit FIFO IRQ Enable: %d\n", machine().describe_context(), BIT(data, 4));
|
||||
LOGMASKED(LOG_ICP, "%s: Loopback Enable: %d\n", machine().describe_context(), BIT(data, 5));
|
||||
const uint32_t old = m_icp_regs.uart.utcr[3];
|
||||
COMBINE_DATA(&m_icp_regs.uart.utcr[3]);
|
||||
const uint32_t changed = old ^ m_icp_regs.uart.utcr[3];
|
||||
if (BIT(changed, 0))
|
||||
icp_uart_set_receiver_enabled(BIT(data, 0));
|
||||
if (BIT(changed, 1))
|
||||
icp_uart_set_transmitter_enabled(BIT(data, 1));
|
||||
if (BIT(changed, 3))
|
||||
icp_uart_set_receive_irq_enabled(BIT(data, 3));
|
||||
if (BIT(changed, 4))
|
||||
icp_uart_set_transmit_irq_enabled(BIT(data, 4));
|
||||
break;
|
||||
}
|
||||
case REG_UTCR4:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_w: UART Control Register 4 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_ICP, "%s: HP-SIR enable: %d\n", machine().describe_context(), BIT(data, UTCR4_HSE_BIT), mem_mask);
|
||||
LOGMASKED(LOG_ICP, "%s: Low-Power enable: %d\n", machine().describe_context(), BIT(data, UTCR4_LPM_BIT), mem_mask);
|
||||
COMBINE_DATA(&m_icp_regs.utcr4);
|
||||
break;
|
||||
case REG_UTDR:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_w: UART Data Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
if (data == 0x0d || data == 0x0a || (data >= 0x20 && data < 0x7f))
|
||||
{
|
||||
printf("%c", (char)data);
|
||||
}
|
||||
icp_uart_write_transmit_fifo((uint8_t)data);
|
||||
break;
|
||||
case REG_UTSR0:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_w: UART Status Register 0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_ICP, "%s: Receiver Idle Status: %d\n", machine().describe_context(), BIT(data, 2));
|
||||
LOGMASKED(LOG_ICP, "%s: Receiver Begin of Break Status: %d\n", machine().describe_context(), BIT(data, 3));
|
||||
LOGMASKED(LOG_ICP, "%s: Receiver End of Break Status: %d\n", machine().describe_context(), BIT(data, 4));
|
||||
if (BIT(data, 2))
|
||||
icp_uart_set_receiver_idle();
|
||||
if (BIT(data, 3))
|
||||
icp_uart_begin_of_break();
|
||||
if (BIT(data, 4))
|
||||
icp_uart_end_of_break();
|
||||
break;
|
||||
case REG_HSCR0:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_w: HSSP Control Register 0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
break;
|
||||
case REG_HSCR1:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_w: HSSP Control Register 1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
break;
|
||||
case REG_HSDR:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_w: HSSP Data Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
icp_hssp_write_transmit_fifo((uint8_t)data);
|
||||
break;
|
||||
case REG_HSSR0:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_w: HSSP Status Register 0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
break;
|
||||
case REG_HSSR1:
|
||||
LOGMASKED(LOG_ICP, "%s: icp_w: HSSP Status Register 1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
break;
|
||||
default:
|
||||
LOGMASKED(LOG_ICP | LOG_UNKNOWN, "%s: icp_w: Unknown address: %08x = %08x & %08x\n", machine().describe_context(), ICP_BASE_ADDR | (offset << 2), data, mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Intel SA-1110 Serial Port 3 - UART
|
||||
@ -140,9 +391,6 @@ void sa1110_periphs_device::uart_write_receive_fifo(uint16_t data_and_flags)
|
||||
m_uart_regs.rx_fifo_count++;
|
||||
m_uart_regs.rx_fifo_write_idx = (m_uart_regs.rx_fifo_write_idx + 1) % ARRAY_LENGTH(m_uart_regs.rx_fifo);
|
||||
|
||||
// update receiver-not-full flag
|
||||
m_uart_regs.utsr1 |= (1 << UTSR1_RNE_BIT);
|
||||
|
||||
// update error flags
|
||||
uart_update_eif_status();
|
||||
|
||||
@ -163,18 +411,20 @@ uint8_t sa1110_periphs_device::uart_read_receive_fifo()
|
||||
m_uart_regs.utsr1 &= ~((1 << UTSR1_PRE_BIT) | (1 << UTSR1_FRE_BIT) | (1 << UTSR1_ROR_BIT));
|
||||
m_uart_regs.utsr1 |= fifo_bottom_flags << UTSR1_PRE_BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uart_regs.utsr1 &= ~(1 << UTSR1_RNE_BIT);
|
||||
}
|
||||
uart_update_eif_status();
|
||||
}
|
||||
uart_check_rx_fifo_service();
|
||||
return data;
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::uart_check_rx_fifo_service()
|
||||
{
|
||||
if (m_uart_regs.rx_fifo_count > 4 && BIT(m_uart_regs.utcr[3], UTCR3_RXE_BIT))
|
||||
if (m_uart_regs.rx_fifo_count != 0)
|
||||
m_uart_regs.utsr1 |= (1 << UTSR1_RNE_BIT);
|
||||
else
|
||||
m_uart_regs.utsr1 &= ~(1 << UTSR1_RNE_BIT);
|
||||
|
||||
if (m_uart_regs.rx_fifo_count > 4)
|
||||
{
|
||||
m_uart_regs.utsr0 |= (1 << UTSR0_RFS_BIT);
|
||||
if (BIT(m_uart_regs.utcr[3], UTCR3_RIE_BIT))
|
||||
@ -208,19 +458,18 @@ void sa1110_periphs_device::uart_write_transmit_fifo(uint8_t data)
|
||||
m_uart_regs.tx_fifo_count++;
|
||||
m_uart_regs.tx_fifo_write_idx = (m_uart_regs.tx_fifo_write_idx + 1) % ARRAY_LENGTH(m_uart_regs.tx_fifo);
|
||||
|
||||
// update transmitter-not-full flag
|
||||
if (m_uart_regs.tx_fifo_count == ARRAY_LENGTH(m_uart_regs.tx_fifo))
|
||||
m_uart_regs.utsr1 &= ~(1 << UTSR1_TNF_BIT);
|
||||
else
|
||||
m_uart_regs.utsr1 |= (1 << UTSR1_TNF_BIT);
|
||||
|
||||
// update FIFO-service interrupt
|
||||
uart_check_tx_fifo_service();
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::uart_check_tx_fifo_service()
|
||||
{
|
||||
if (m_uart_regs.tx_fifo_count <= 4 && BIT(m_uart_regs.utcr[3], UTCR3_TXE_BIT))
|
||||
if (m_uart_regs.tx_fifo_count < ARRAY_LENGTH(m_uart_regs.tx_fifo))
|
||||
m_uart_regs.utsr1 |= (1 << UTSR1_TNF_BIT);
|
||||
else
|
||||
m_uart_regs.utsr1 &= ~(1 << UTSR1_TNF_BIT);
|
||||
|
||||
if (m_uart_regs.tx_fifo_count <= 4)
|
||||
{
|
||||
m_uart_regs.utsr0 |= (1 << UTSR0_TFS_BIT);
|
||||
if (BIT(m_uart_regs.utcr[3], UTCR3_TIE_BIT))
|
||||
@ -268,18 +517,18 @@ void sa1110_periphs_device::uart_set_transmitter_enabled(bool enabled)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
m_uart_regs.utsr0 |= (1 << UTSR0_TFS_BIT);
|
||||
m_uart3_irqs->in_w<UART3_TFS>(1);
|
||||
//m_uart_regs.utsr0 |= (1 << UTSR0_TFS_BIT);
|
||||
//m_uart3_irqs->in_w<UART3_TFS>(1);
|
||||
|
||||
m_uart_regs.utsr1 |= (1 << UTSR1_TNF_BIT);
|
||||
//m_uart_regs.utsr1 |= (1 << UTSR1_TNF_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uart_regs.utsr0 &= ~(1 << UTSR0_TFS_BIT);
|
||||
m_uart3_irqs->in_w<UART3_TFS>(0);
|
||||
//m_uart_regs.utsr0 &= ~(1 << UTSR0_TFS_BIT);
|
||||
//m_uart3_irqs->in_w<UART3_TFS>(0);
|
||||
|
||||
m_uart_regs.utsr1 &= ~(1 << UTSR1_TBY_BIT);
|
||||
m_uart_regs.utsr1 &= ~(1 << UTSR1_TNF_BIT);
|
||||
//m_uart_regs.utsr1 &= ~(1 << UTSR1_TBY_BIT);
|
||||
//m_uart_regs.utsr1 &= ~(1 << UTSR1_TNF_BIT);
|
||||
|
||||
m_uart_regs.tx_fifo_count = 0;
|
||||
m_uart_regs.tx_fifo_read_idx = 0;
|
||||
@ -287,6 +536,8 @@ void sa1110_periphs_device::uart_set_transmitter_enabled(bool enabled)
|
||||
|
||||
transmit_register_reset();
|
||||
}
|
||||
|
||||
uart_check_tx_fifo_service();
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::uart_set_receive_irq_enabled(bool enabled)
|
||||
@ -302,31 +553,31 @@ uint32_t sa1110_periphs_device::uart3_r(offs_t offset, uint32_t mem_mask)
|
||||
switch (offset)
|
||||
{
|
||||
case REG_UTCR0:
|
||||
LOGMASKED(LOG_UART, "%s: uart3_r: UART Control Register 0: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[0], mem_mask);
|
||||
LOGMASKED(LOG_UART3, "%s: uart3_r: UART Control Register 0: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[0], mem_mask);
|
||||
return m_uart_regs.utcr[0];
|
||||
case REG_UTCR1:
|
||||
LOGMASKED(LOG_UART, "%s: uart3_r: UART Control Register 1: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[1], mem_mask);
|
||||
LOGMASKED(LOG_UART3, "%s: uart3_r: UART Control Register 1: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[1], mem_mask);
|
||||
return m_uart_regs.utcr[1];
|
||||
case REG_UTCR2:
|
||||
LOGMASKED(LOG_UART, "%s: uart3_r: UART Control Register 2: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[2], mem_mask);
|
||||
LOGMASKED(LOG_UART3, "%s: uart3_r: UART Control Register 2: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[2], mem_mask);
|
||||
return m_uart_regs.utcr[2];
|
||||
case REG_UTCR3:
|
||||
LOGMASKED(LOG_UART, "%s: uart3_r: UART Control Register 3: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[3], mem_mask);
|
||||
LOGMASKED(LOG_UART3, "%s: uart3_r: UART Control Register 3: %08x & %08x\n", machine().describe_context(), m_uart_regs.utcr[3], mem_mask);
|
||||
return m_uart_regs.utcr[3];
|
||||
case REG_UTDR:
|
||||
{
|
||||
const uint8_t data = uart_read_receive_fifo();
|
||||
LOGMASKED(LOG_UART, "%s: uart3_r: UART Data Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_UART3, "%s: uart3_r: UART Data Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
return data;
|
||||
}
|
||||
case REG_UTSR0:
|
||||
LOGMASKED(LOG_UART_HF, "%s: uart3_r: UART Status Register 0: %08x & %08x\n", machine().describe_context(), m_uart_regs.utsr0, mem_mask);
|
||||
LOGMASKED(LOG_UART3, "%s: uart3_r: UART Status Register 0: %08x & %08x\n", machine().describe_context(), m_uart_regs.utsr0, mem_mask);
|
||||
return m_uart_regs.utsr0;
|
||||
case REG_UTSR1:
|
||||
LOGMASKED(LOG_UART_HF, "%s: uart3_r: UART Status Register 1: %08x & %08x\n", machine().describe_context(), m_uart_regs.utsr1, mem_mask);
|
||||
LOGMASKED(LOG_UART3, "%s: uart3_r: UART Status Register 1: %08x & %08x\n", machine().describe_context(), m_uart_regs.utsr1, mem_mask);
|
||||
return m_uart_regs.utsr1;
|
||||
default:
|
||||
LOGMASKED(LOG_UART | LOG_UNKNOWN, "%s: uart3_r: Unknown address: %08x & %08x\n", machine().describe_context(), UART_BASE_ADDR | (offset << 2), mem_mask);
|
||||
LOGMASKED(LOG_UART3 | LOG_UNKNOWN, "%s: uart3_r: Unknown address: %08x & %08x\n", machine().describe_context(), UART_BASE_ADDR | (offset << 2), mem_mask);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -337,14 +588,14 @@ void sa1110_periphs_device::uart3_w(offs_t offset, uint32_t data, uint32_t mem_m
|
||||
{
|
||||
case REG_UTCR0:
|
||||
{
|
||||
LOGMASKED(LOG_UART, "%s: uart3_w: UART Control Register 0: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_UART, "%s: Parity Enable: %d\n", machine().describe_context(), BIT(data, 0));
|
||||
LOGMASKED(LOG_UART, "%s: Parity Mode: %s\n", machine().describe_context(), BIT(data, 1) ? "Even" : "Odd");
|
||||
LOGMASKED(LOG_UART, "%s: Stop Bits: %d\n", machine().describe_context(), BIT(data, 2) + 1);
|
||||
LOGMASKED(LOG_UART, "%s: Data Size: %d\n", machine().describe_context(), BIT(data, 3) ? 8 : 7);
|
||||
LOGMASKED(LOG_UART, "%s: Sample Clock: %s\n", machine().describe_context(), BIT(data, 4) ? "External" : "Internal");
|
||||
LOGMASKED(LOG_UART, "%s: Receive Edge: %s\n", machine().describe_context(), BIT(data, 5) ? "Falling" : "Rising");
|
||||
LOGMASKED(LOG_UART, "%s: Transmit Edge: %s\n", machine().describe_context(), BIT(data, 6) ? "Falling" : "Rising");
|
||||
LOGMASKED(LOG_UART3, "%s: uart3_w: UART Control Register 0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_UART3, "%s: Parity Enable: %d\n", machine().describe_context(), BIT(data, 0));
|
||||
LOGMASKED(LOG_UART3, "%s: Parity Mode: %s\n", machine().describe_context(), BIT(data, 1) ? "Even" : "Odd");
|
||||
LOGMASKED(LOG_UART3, "%s: Stop Bits: %d\n", machine().describe_context(), BIT(data, 2) + 1);
|
||||
LOGMASKED(LOG_UART3, "%s: Data Size: %d\n", machine().describe_context(), BIT(data, 3) ? 8 : 7);
|
||||
LOGMASKED(LOG_UART3, "%s: Sample Clock: %s\n", machine().describe_context(), BIT(data, 4) ? "External" : "Internal");
|
||||
LOGMASKED(LOG_UART3, "%s: Receive Edge: %s\n", machine().describe_context(), BIT(data, 5) ? "Falling" : "Rising");
|
||||
LOGMASKED(LOG_UART3, "%s: Transmit Edge: %s\n", machine().describe_context(), BIT(data, 6) ? "Falling" : "Rising");
|
||||
|
||||
stop_bits_t stop_bits = (BIT(data, 2) ? STOP_BITS_2 : STOP_BITS_1);
|
||||
|
||||
@ -363,8 +614,8 @@ void sa1110_periphs_device::uart3_w(offs_t offset, uint32_t data, uint32_t mem_m
|
||||
}
|
||||
case REG_UTCR1:
|
||||
{
|
||||
LOGMASKED(LOG_UART, "%s: uart3_w: UART Control Register 1: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_UART, "%s: Baud Rate Divisor MSB: %02x\n", machine().describe_context(), data & 0x0f);
|
||||
LOGMASKED(LOG_UART3, "%s: uart3_w: UART Control Register 1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_UART3, "%s: Baud Rate Divisor MSB: %02x\n", machine().describe_context(), data & 0x0f);
|
||||
const uint8_t old = m_uart_regs.utcr[1] & 0x0f;
|
||||
COMBINE_DATA(&m_uart_regs.utcr[1]);
|
||||
if ((m_uart_regs.utcr[1] & 0x0f) != old)
|
||||
@ -373,8 +624,8 @@ void sa1110_periphs_device::uart3_w(offs_t offset, uint32_t data, uint32_t mem_m
|
||||
}
|
||||
case REG_UTCR2:
|
||||
{
|
||||
LOGMASKED(LOG_UART, "%s: uart3_w: UART Control Register 2: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_UART, "%s: Baud Rate Divisor LSB: %02x\n", machine().describe_context(), (uint8_t)data);
|
||||
LOGMASKED(LOG_UART3, "%s: uart3_w: UART Control Register 2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_UART3, "%s: Baud Rate Divisor LSB: %02x\n", machine().describe_context(), (uint8_t)data);
|
||||
const uint8_t old = m_uart_regs.utcr[2] & 0xff;
|
||||
COMBINE_DATA(&m_uart_regs.utcr[2]);
|
||||
if ((m_uart_regs.utcr[2] & 0xff) != old)
|
||||
@ -383,13 +634,13 @@ void sa1110_periphs_device::uart3_w(offs_t offset, uint32_t data, uint32_t mem_m
|
||||
}
|
||||
case REG_UTCR3:
|
||||
{
|
||||
LOGMASKED(LOG_UART, "%s: uart3_w: UART Control Register 3: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_UART, "%s: Receive Enable: %d\n", machine().describe_context(), BIT(data, 0));
|
||||
LOGMASKED(LOG_UART, "%s: Transmit Enable: %d\n", machine().describe_context(), BIT(data, 1));
|
||||
LOGMASKED(LOG_UART, "%s: Send Break: %d\n", machine().describe_context(), BIT(data, 2));
|
||||
LOGMASKED(LOG_UART, "%s: Receive FIFO IRQ Enable: %d\n", machine().describe_context(), BIT(data, 3));
|
||||
LOGMASKED(LOG_UART, "%s: Transmit FIFO IRQ Enable: %d\n", machine().describe_context(), BIT(data, 4));
|
||||
LOGMASKED(LOG_UART, "%s: Loopback Enable: %d\n", machine().describe_context(), BIT(data, 5));
|
||||
LOGMASKED(LOG_UART3, "%s: uart3_w: UART Control Register 3 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_UART3, "%s: Receive Enable: %d\n", machine().describe_context(), BIT(data, 0));
|
||||
LOGMASKED(LOG_UART3, "%s: Transmit Enable: %d\n", machine().describe_context(), BIT(data, 1));
|
||||
LOGMASKED(LOG_UART3, "%s: Send Break: %d\n", machine().describe_context(), BIT(data, 2));
|
||||
LOGMASKED(LOG_UART3, "%s: Receive FIFO IRQ Enable: %d\n", machine().describe_context(), BIT(data, 3));
|
||||
LOGMASKED(LOG_UART3, "%s: Transmit FIFO IRQ Enable: %d\n", machine().describe_context(), BIT(data, 4));
|
||||
LOGMASKED(LOG_UART3, "%s: Loopback Enable: %d\n", machine().describe_context(), BIT(data, 5));
|
||||
const uint32_t old = m_uart_regs.utcr[3];
|
||||
COMBINE_DATA(&m_uart_regs.utcr[3]);
|
||||
const uint32_t changed = old ^ m_uart_regs.utcr[3];
|
||||
@ -404,7 +655,7 @@ void sa1110_periphs_device::uart3_w(offs_t offset, uint32_t data, uint32_t mem_m
|
||||
break;
|
||||
}
|
||||
case REG_UTDR:
|
||||
LOGMASKED(LOG_UART, "%s: uart3_w: UART Data Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_UART3, "%s: uart3_w: UART Data Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
if (data == 0x0d || data == 0x0a || (data >= 0x20 && data < 0x7f))
|
||||
{
|
||||
printf("%c", (char)data);
|
||||
@ -412,10 +663,10 @@ void sa1110_periphs_device::uart3_w(offs_t offset, uint32_t data, uint32_t mem_m
|
||||
uart_write_transmit_fifo((uint8_t)data);
|
||||
break;
|
||||
case REG_UTSR0:
|
||||
LOGMASKED(LOG_UART, "%s: uart3_w: UART Status Register 0: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_UART, "%s: Receiver Idle Status: %d\n", machine().describe_context(), BIT(data, 2));
|
||||
LOGMASKED(LOG_UART, "%s: Receiver Begin of Break Status: %d\n", machine().describe_context(), BIT(data, 3));
|
||||
LOGMASKED(LOG_UART, "%s: Receiver End of Break Status: %d\n", machine().describe_context(), BIT(data, 4));
|
||||
LOGMASKED(LOG_UART3, "%s: uart3_w: UART Status Register 0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_UART3, "%s: Receiver Idle Status: %d\n", machine().describe_context(), BIT(data, 2));
|
||||
LOGMASKED(LOG_UART3, "%s: Receiver Begin of Break Status: %d\n", machine().describe_context(), BIT(data, 3));
|
||||
LOGMASKED(LOG_UART3, "%s: Receiver End of Break Status: %d\n", machine().describe_context(), BIT(data, 4));
|
||||
if (BIT(data, 2))
|
||||
uart_set_receiver_idle();
|
||||
if (BIT(data, 3))
|
||||
@ -424,7 +675,7 @@ void sa1110_periphs_device::uart3_w(offs_t offset, uint32_t data, uint32_t mem_m
|
||||
uart_end_of_break();
|
||||
break;
|
||||
default:
|
||||
LOGMASKED(LOG_UART | LOG_UNKNOWN, "%s: uart3_w: Unknown address: %08x = %08x & %08x\n", machine().describe_context(), UART_BASE_ADDR | (offset << 2), data, mem_mask);
|
||||
LOGMASKED(LOG_UART3 | LOG_UNKNOWN, "%s: uart3_w: Unknown address: %08x = %08x & %08x\n", machine().describe_context(), UART_BASE_ADDR | (offset << 2), data, mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1198,7 +1449,7 @@ uint32_t sa1110_periphs_device::rtc_r(offs_t offset, uint32_t mem_mask)
|
||||
LOGMASKED(LOG_RTC, "%s: rtc_r: RTC Alarm Register: %08x & %08x\n", machine().describe_context(), m_rtc_regs.rtar, mem_mask);
|
||||
return m_rtc_regs.rtar;
|
||||
case REG_RCNR:
|
||||
LOGMASKED(LOG_RTC, "%s: rtc_r: RTC Count Register: %08x & %08x\n", machine().describe_context(), m_rtc_regs.rcnr, mem_mask);
|
||||
LOGMASKED(LOG_RTC_HF, "%s: rtc_r: RTC Count Register: %08x & %08x\n", machine().describe_context(), m_rtc_regs.rcnr, mem_mask);
|
||||
return m_rtc_regs.rcnr;
|
||||
case REG_RTTR:
|
||||
LOGMASKED(LOG_RTC, "%s: rtc_r: RTC Timer Trim Register: %08x & %08x\n", machine().describe_context(), m_rtc_regs.rttr, mem_mask);
|
||||
@ -1276,7 +1527,7 @@ uint32_t sa1110_periphs_device::power_r(offs_t offset, uint32_t mem_mask)
|
||||
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager Sleep Status Register: %08x & %08x\n", machine().describe_context(), m_power_regs.pssr, mem_mask);
|
||||
return m_power_regs.pssr;
|
||||
case REG_PSPR:
|
||||
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager Scratch Pad Register: %08x & %08x\n", machine().describe_context(), m_power_regs.pspr, mem_mask);
|
||||
LOGMASKED(LOG_POWER_HF, "%s: power_r: Power Manager Scratch Pad Register: %08x & %08x\n", machine().describe_context(), m_power_regs.pspr, mem_mask);
|
||||
return m_power_regs.pspr;
|
||||
case REG_PWER:
|
||||
LOGMASKED(LOG_POWER, "%s: power_r: Power Manager Wake-up Enable Register: %08x & %08x\n", machine().describe_context(), m_power_regs.pwer, mem_mask);
|
||||
@ -1312,7 +1563,7 @@ void sa1110_periphs_device::power_w(offs_t offset, uint32_t data, uint32_t mem_m
|
||||
m_power_regs.pssr &= ~(data & 0x0000001f);
|
||||
break;
|
||||
case REG_PSPR:
|
||||
LOGMASKED(LOG_POWER, "%s: power_w: Power Manager Scratch Pad Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_POWER_HF, "%s: power_w: Power Manager Scratch Pad Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_power_regs.pspr);
|
||||
break;
|
||||
case REG_PWER:
|
||||
@ -1398,6 +1649,7 @@ void sa1110_periphs_device::gpio_in(const uint32_t line, const int state)
|
||||
m_gpio_regs.input_latch &= ~mask;
|
||||
m_gpio_regs.input_latch |= (state << line);
|
||||
|
||||
LOGMASKED(LOG_GPIO, "gpio_in: Line %d, state %d\n", line, state);
|
||||
if (old_latch != m_gpio_regs.input_latch && !BIT(m_gpio_regs.gafr, line))
|
||||
{
|
||||
// TODO: The manual is unclear if edge detection functions on both inputs and outputs.
|
||||
@ -1414,6 +1666,7 @@ void sa1110_periphs_device::gpio_in(const uint32_t line, const int state)
|
||||
}
|
||||
|
||||
m_gpio_regs.gplr = (m_gpio_regs.input_latch & ~m_gpio_regs.gafr) | (m_gpio_regs.alt_input_latch & m_gpio_regs.gafr);
|
||||
LOGMASKED(LOG_GPIO, "gpio_in: New GPLR: %08x\n", m_gpio_regs.gplr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1557,7 +1810,7 @@ void sa1110_periphs_device::gpio_w(offs_t offset, uint32_t data, uint32_t mem_ma
|
||||
const uint32_t old = m_gpio_regs.gedr;
|
||||
m_gpio_regs.gedr &= ~(data & mem_mask);
|
||||
if (old != m_gpio_regs.gedr)
|
||||
gpio_update_interrupts(old);
|
||||
gpio_update_interrupts(old ^ m_gpio_regs.gedr);
|
||||
break;
|
||||
}
|
||||
case REG_GAFR:
|
||||
@ -1566,7 +1819,7 @@ void sa1110_periphs_device::gpio_w(offs_t offset, uint32_t data, uint32_t mem_ma
|
||||
const uint32_t old = m_gpio_regs.gafr;
|
||||
COMBINE_DATA(&m_gpio_regs.gafr);
|
||||
if (old != m_gpio_regs.gafr)
|
||||
gpio_update_alternate_pins(old);
|
||||
gpio_update_alternate_pins(old ^ m_gpio_regs.gafr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1649,11 +1902,11 @@ void sa1110_periphs_device::intc_w(offs_t offset, uint32_t data, uint32_t mem_ma
|
||||
switch (offset)
|
||||
{
|
||||
case REG_ICIP:
|
||||
LOGMASKED(LOG_INTC, "%s: intc_w: (Invalid Write) Interrupt Controller IRQ Pending Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_INTC, "%s: intc_w: (Invalid Write) Interrupt Controller IRQ Pending Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
break;
|
||||
case REG_ICMR:
|
||||
{
|
||||
LOGMASKED(LOG_INTC, "%s: intc_w: Interrupt Controller Mask Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_INTC, "%s: intc_w: Interrupt Controller Mask Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
const uint32_t old = m_intc_regs.icmr;
|
||||
COMBINE_DATA(&m_intc_regs.icmr);
|
||||
if (old != m_intc_regs.icmr)
|
||||
@ -1662,7 +1915,7 @@ void sa1110_periphs_device::intc_w(offs_t offset, uint32_t data, uint32_t mem_ma
|
||||
}
|
||||
case REG_ICLR:
|
||||
{
|
||||
LOGMASKED(LOG_INTC, "%s: intc_w: Interrupt Controller Level Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_INTC, "%s: intc_w: Interrupt Controller Level Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
const uint32_t old = m_intc_regs.iclr;
|
||||
COMBINE_DATA(&m_intc_regs.iclr);
|
||||
if (old != m_intc_regs.iclr)
|
||||
@ -1670,13 +1923,13 @@ void sa1110_periphs_device::intc_w(offs_t offset, uint32_t data, uint32_t mem_ma
|
||||
break;
|
||||
}
|
||||
case REG_ICFP:
|
||||
LOGMASKED(LOG_INTC, "%s: intc_w: (Invalid Write) Interrupt Controller FIQ Pending Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_INTC, "%s: intc_w: (Invalid Write) Interrupt Controller FIQ Pending Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
break;
|
||||
case REG_ICPR:
|
||||
LOGMASKED(LOG_INTC, "%s: intc_w: (Invalid Write) Interrupt Controller Pending Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_INTC, "%s: intc_w: (Invalid Write) Interrupt Controller Pending Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
break;
|
||||
case REG_ICCR:
|
||||
LOGMASKED(LOG_INTC, "%s: intc_w: Interrupt Controller Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_INTC, "%s: intc_w: Interrupt Controller Control Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
m_intc_regs.iccr = BIT(data, 0);
|
||||
break;
|
||||
default:
|
||||
@ -1685,8 +1938,292 @@ void sa1110_periphs_device::intc_w(offs_t offset, uint32_t data, uint32_t mem_ma
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Intel SA-1110 Peripheral Pin Controller
|
||||
|
||||
pg. 347 to 357 Intel StrongARM SA-1110 Microprocessor Developer's Manual
|
||||
|
||||
*/
|
||||
|
||||
uint32_t sa1110_periphs_device::ppc_r(offs_t offset, uint32_t mem_mask)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case REG_PPDR:
|
||||
LOGMASKED(LOG_PPC, "%s: ppc_r: PPC Pin Direction Register: %08x & %08x\n", machine().describe_context(), m_ppc_regs.ppdr, mem_mask);
|
||||
return m_ppc_regs.ppdr;
|
||||
case REG_PPSR:
|
||||
LOGMASKED(LOG_PPC, "%s: ppc_r: PPC Pin State Register: %08x & %08x\n", machine().describe_context(), m_ppc_regs.ppsr, mem_mask);
|
||||
return m_ppc_regs.ppsr;
|
||||
case REG_PPAR:
|
||||
LOGMASKED(LOG_PPC, "%s: ppc_r: PPC Pin Assignment Register: %08x & %08x\n", machine().describe_context(), m_ppc_regs.ppar, mem_mask);
|
||||
return m_ppc_regs.ppar;
|
||||
case REG_PSDR:
|
||||
LOGMASKED(LOG_PPC, "%s: ppc_r: PPC Sleep Mode Direction Register: %08x & %08x\n", machine().describe_context(), m_ppc_regs.psdr, mem_mask);
|
||||
return m_ppc_regs.psdr;
|
||||
case REG_PPFR:
|
||||
LOGMASKED(LOG_PPC, "%s: ppc_r: PPC Pin Flag Register: %08x & %08x\n", machine().describe_context(), m_ppc_regs.ppfr, mem_mask);
|
||||
return m_ppc_regs.ppfr;
|
||||
default:
|
||||
LOGMASKED(LOG_PPC | LOG_UNKNOWN, "%s: ppc_r: Unknown address: %08x & %08x\n", machine().describe_context(), PPC_BASE_ADDR | (offset << 2), mem_mask);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::ppc_w(offs_t offset, uint32_t data, uint32_t mem_mask)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case REG_PPDR:
|
||||
{
|
||||
LOGMASKED(LOG_PPC, "%s: ppc_w: PPC Pin Direction Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_ppc_regs.ppdr);
|
||||
//const uint32_t old_ppsr = m_ppc_regs.ppsr;
|
||||
m_ppc_regs.ppsr = (m_ppc_regs.ppsr_out & m_ppc_regs.ppdr) | (m_ppc_regs.ppsr_in & ~m_ppc_regs.ppdr);
|
||||
//const uint32_t changed_states = old_ppsr ^ m_ppc_regs.ppsr;
|
||||
//if (changed_states)
|
||||
//{
|
||||
//}
|
||||
break;
|
||||
}
|
||||
case REG_PPSR:
|
||||
{
|
||||
LOGMASKED(LOG_PPC, "%s: ppc_w: PPC Pin State Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
//const uint32_t old_latch = m_ppc_regs.ppsr_out;
|
||||
COMBINE_DATA(&m_ppc_regs.ppsr_out);
|
||||
m_ppc_regs.ppsr = (m_ppc_regs.ppsr_out & m_ppc_regs.ppdr) | (m_ppc_regs.ppsr_in & ~m_ppc_regs.ppdr);
|
||||
//const uint32_t changed_outputs = (old ^ m_ppc_regs.ppsr_out) & m_ppc_regs.ppdr;
|
||||
//if (changed_outputs)
|
||||
//{
|
||||
// Do stuff
|
||||
//}
|
||||
break;
|
||||
}
|
||||
case REG_PPAR:
|
||||
LOGMASKED(LOG_PPC, "%s: ppc_w: PPC Pin Assignment Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_ppc_regs.ppar);
|
||||
break;
|
||||
case REG_PSDR:
|
||||
LOGMASKED(LOG_PPC, "%s: ppc_w: PPC Sleep Mode Direction Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_ppc_regs.psdr);
|
||||
break;
|
||||
case REG_PPFR:
|
||||
LOGMASKED(LOG_PPC, "%s: ppc_w: PPC Pin Flag Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
COMBINE_DATA(&m_ppc_regs.ppfr);
|
||||
break;
|
||||
default:
|
||||
LOGMASKED(LOG_PPC | LOG_UNKNOWN, "%s: ppc_w: Unknown address: %08x = %08x & %08x\n", machine().describe_context(), PPC_BASE_ADDR | (offset << 2), data, mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Intel SA-1110 Peripheral Pin Controller
|
||||
|
||||
pg. 186 to 194 Intel StrongARM SA-1110 Microprocessor Developer's Manual
|
||||
|
||||
*/
|
||||
|
||||
void sa1110_periphs_device::dma_set_control_bits(int channel, uint32_t bits)
|
||||
{
|
||||
dma_regs ®s = m_dma_regs[channel];
|
||||
const uint32_t old = regs.dsr;
|
||||
regs.dsr |= bits;
|
||||
const uint32_t newly_set = ~old & bits;
|
||||
if (newly_set == 0)
|
||||
return;
|
||||
|
||||
const uint32_t irq_mask = (1 << DSR_ERROR_BIT) | (1 << DSR_DONEA_BIT) | (1 << DSR_DONEB_BIT);
|
||||
|
||||
if (BIT(newly_set, DSR_RUN_BIT))
|
||||
regs.dsr &= ~(1 << DSR_ERROR_BIT);
|
||||
if (BIT(newly_set, DSR_DONEA_BIT) || BIT(newly_set, DSR_STRTA_BIT))
|
||||
regs.dsr &= ~(1 << DSR_DONEA_BIT);
|
||||
if (BIT(newly_set, DSR_DONEB_BIT) || BIT(newly_set, DSR_STRTB_BIT))
|
||||
regs.dsr &= ~(1 << DSR_DONEB_BIT);
|
||||
|
||||
if (regs.ddar == 0x81400580 && BIT(regs.dsr, DSR_RUN_BIT))
|
||||
{
|
||||
const uint32_t buf = BIT(regs.dsr, DSR_BIU_BIT);
|
||||
const uint32_t count = regs.dbt[buf];
|
||||
if (count)
|
||||
{
|
||||
const uint32_t start_mask = (buf ? (1 << DSR_STRTB_BIT) : (1 << DSR_STRTA_BIT));
|
||||
const uint32_t done_mask = (buf ? (1 << DSR_DONEB_BIT) : (1 << DSR_DONEA_BIT));
|
||||
const uint32_t addr = regs.dbs[buf];
|
||||
address_space &space = m_maincpu->space(AS_PROGRAM);
|
||||
if (regs.dsr & start_mask)
|
||||
{
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
const uint8_t value = space.read_byte(addr + i);
|
||||
if (value == 0x0d || value == 0x0a || (value >= 0x20 && value < 0x7f))
|
||||
{
|
||||
printf("%c", (char)value);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
regs.dsr &= ~start_mask;
|
||||
regs.dsr |= done_mask;
|
||||
regs.dsr ^= (1 << DSR_BIU_BIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_irq_line(INT_DMA0 + channel, (BIT(regs.dsr, DSR_IE_BIT) && (regs.dsr & irq_mask)) ? 1 : 0);
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::dma_clear_control_bits(int channel, uint32_t bits)
|
||||
{
|
||||
dma_regs ®s = m_dma_regs[channel];
|
||||
|
||||
const uint32_t irq_mask = (1 << DSR_ERROR_BIT) | (1 << DSR_DONEA_BIT) | (1 << DSR_DONEB_BIT);
|
||||
|
||||
regs.dsr &= ~bits;
|
||||
set_irq_line(INT_DMA0 + channel, (BIT(regs.dsr, DSR_IE_BIT) && (regs.dsr & irq_mask)) ? 1 : 0);
|
||||
}
|
||||
|
||||
uint32_t sa1110_periphs_device::dma_r(offs_t offset, uint32_t mem_mask)
|
||||
{
|
||||
uint32_t channel = (offset >> 3) & 7;
|
||||
if (channel < 6)
|
||||
{
|
||||
switch (offset & 7)
|
||||
{
|
||||
case REG_DDAR:
|
||||
LOGMASKED(LOG_DMA, "%s: dma_r: DMA%d Device Address Register: %08x & %08x\n", machine().describe_context(), channel, m_dma_regs[channel].ddar, mem_mask);
|
||||
return m_dma_regs[channel].ddar;
|
||||
case REG_DSSR:
|
||||
case REG_DCSR:
|
||||
case REG_DSR:
|
||||
LOGMASKED(LOG_DMA, "%s: dma_r: DMA%d Control/Status Register: %08x & %08x\n", machine().describe_context(), channel, m_dma_regs[channel].dsr, mem_mask);
|
||||
return m_dma_regs[channel].dsr;
|
||||
case REG_DBSA:
|
||||
LOGMASKED(LOG_DMA, "%s: dma_r: DMA%d Buffer A Start Address: %08x & %08x\n", machine().describe_context(), channel, m_dma_regs[channel].dbs[0], mem_mask);
|
||||
return m_dma_regs[channel].dbs[0];
|
||||
case REG_DBTA:
|
||||
LOGMASKED(LOG_DMA, "%s: dma_r: DMA%d Buffer A Transfer Count: %08x & %08x\n", machine().describe_context(), channel, m_dma_regs[channel].dbt[0], mem_mask);
|
||||
return m_dma_regs[channel].dbt[0];
|
||||
case REG_DBSB:
|
||||
LOGMASKED(LOG_DMA, "%s: dma_r: DMA%d Buffer B Start Address: %08x & %08x\n", machine().describe_context(), channel, m_dma_regs[channel].dbs[1], mem_mask);
|
||||
return m_dma_regs[channel].dbs[1];
|
||||
case REG_DBTB:
|
||||
LOGMASKED(LOG_DMA, "%s: dma_r: DMA%d Buffer B Transfer Count: %08x & %08x\n", machine().describe_context(), channel, m_dma_regs[channel].dbt[1], mem_mask);
|
||||
return m_dma_regs[channel].dbt[1];
|
||||
default:
|
||||
LOGMASKED(LOG_DMA | LOG_UNKNOWN, "%s: dma_r: Unknown address: %08x & %08x\n", machine().describe_context(), DMA_BASE_ADDR | (offset << 2), mem_mask);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::dma_w(offs_t offset, uint32_t data, uint32_t mem_mask)
|
||||
{
|
||||
uint32_t channel = (offset >> 3) & 7;
|
||||
if (channel < 6)
|
||||
{
|
||||
switch (offset & 7)
|
||||
{
|
||||
case REG_DDAR:
|
||||
LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Device Address Register = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
|
||||
COMBINE_DATA(&m_dma_regs[channel].ddar);
|
||||
break;
|
||||
case REG_DSSR:
|
||||
LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Control/Status Register (1S) = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
|
||||
LOGMASKED(LOG_DMA, "%s: Run Set: %d\n", machine().describe_context(), BIT(data, DSR_RUN_BIT));
|
||||
LOGMASKED(LOG_DMA, "%s: Interrupt Enable Set: %d\n", machine().describe_context(), BIT(data, DSR_IE_BIT));
|
||||
LOGMASKED(LOG_DMA, "%s: Error Set: %d\n", machine().describe_context(), BIT(data, DSR_ERROR_BIT));
|
||||
LOGMASKED(LOG_DMA, "%s: Done A Set: %d\n", machine().describe_context(), BIT(data, DSR_DONEA_BIT));
|
||||
LOGMASKED(LOG_DMA, "%s: Start A Set: %d\n", machine().describe_context(), BIT(data, DSR_STRTA_BIT));
|
||||
LOGMASKED(LOG_DMA, "%s: Done B Set: %d\n", machine().describe_context(), BIT(data, DSR_DONEB_BIT));
|
||||
LOGMASKED(LOG_DMA, "%s: Start B Set: %d\n", machine().describe_context(), BIT(data, DSR_STRTB_BIT));
|
||||
LOGMASKED(LOG_DMA, "%s: Buffer In Use Set: %d\n", machine().describe_context(), BIT(data, DSR_BIU_BIT));
|
||||
dma_set_control_bits(channel, data & mem_mask);
|
||||
break;
|
||||
case REG_DCSR:
|
||||
LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Control/Status Register (1C) = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
|
||||
LOGMASKED(LOG_DMA, "%s: Run Clear: %d\n", machine().describe_context(), BIT(data, DSR_RUN_BIT));
|
||||
LOGMASKED(LOG_DMA, "%s: Interrupt Enable Clear: %d\n", machine().describe_context(), BIT(data, DSR_IE_BIT));
|
||||
LOGMASKED(LOG_DMA, "%s: Error Clear: %d\n", machine().describe_context(), BIT(data, DSR_ERROR_BIT));
|
||||
LOGMASKED(LOG_DMA, "%s: Done A Clear: %d\n", machine().describe_context(), BIT(data, DSR_DONEA_BIT));
|
||||
LOGMASKED(LOG_DMA, "%s: Start A Clear: %d\n", machine().describe_context(), BIT(data, DSR_STRTA_BIT));
|
||||
LOGMASKED(LOG_DMA, "%s: Done B Clear: %d\n", machine().describe_context(), BIT(data, DSR_DONEB_BIT));
|
||||
LOGMASKED(LOG_DMA, "%s: Start B Clear: %d\n", machine().describe_context(), BIT(data, DSR_STRTB_BIT));
|
||||
LOGMASKED(LOG_DMA, "%s: Buffer In Use Clear: %d\n", machine().describe_context(), BIT(data, DSR_BIU_BIT));
|
||||
dma_clear_control_bits(channel, data & mem_mask);
|
||||
break;
|
||||
case REG_DSR:
|
||||
LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Control/Status Register (RO) = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
|
||||
break;
|
||||
case REG_DBSA:
|
||||
LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Buffer A Start Address = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
|
||||
if (!BIT(m_dma_regs[channel].dsr, DSR_STRTA_BIT))
|
||||
COMBINE_DATA(&m_dma_regs[channel].dbs[0]);
|
||||
break;
|
||||
case REG_DBTA:
|
||||
LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Buffer A Transfer Count = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
|
||||
if (!BIT(m_dma_regs[channel].dsr, DSR_STRTA_BIT))
|
||||
{
|
||||
COMBINE_DATA(&m_dma_regs[channel].dbt[0]);
|
||||
m_dma_regs[channel].dbt[0] &= DBT_MASK;
|
||||
}
|
||||
break;
|
||||
case REG_DBSB:
|
||||
LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Buffer B Start Address = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
|
||||
if (!BIT(m_dma_regs[channel].dsr, DSR_STRTB_BIT))
|
||||
COMBINE_DATA(&m_dma_regs[channel].dbs[1]);
|
||||
break;
|
||||
case REG_DBTB:
|
||||
LOGMASKED(LOG_DMA, "%s: dma_w: DMA%d Buffer B Transfer Count = %08x & %08x\n", machine().describe_context(), channel, data, mem_mask);
|
||||
if (!BIT(m_dma_regs[channel].dsr, DSR_STRTB_BIT))
|
||||
{
|
||||
COMBINE_DATA(&m_dma_regs[channel].dbt[1]);
|
||||
m_dma_regs[channel].dbt[1] &= DBT_MASK;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOGMASKED(LOG_DMA | LOG_UNKNOWN, "%s: dma_w: Unknown address %08x = %08x & %08x\n", machine().describe_context(), DMA_BASE_ADDR | (offset << 2), data, mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_icp_regs.uart.utcr));
|
||||
save_item(NAME(m_icp_regs.uart.utsr0));
|
||||
save_item(NAME(m_icp_regs.uart.utsr1));
|
||||
save_item(NAME(m_icp_regs.uart.rx_fifo));
|
||||
save_item(NAME(m_icp_regs.uart.rx_fifo_read_idx));
|
||||
save_item(NAME(m_icp_regs.uart.rx_fifo_write_idx));
|
||||
save_item(NAME(m_icp_regs.uart.rx_fifo_count));
|
||||
m_icp_regs.uart_rx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sa1110_periphs_device::icp_rx_callback), this));
|
||||
save_item(NAME(m_icp_regs.uart.tx_fifo));
|
||||
save_item(NAME(m_icp_regs.uart.tx_fifo_read_idx));
|
||||
save_item(NAME(m_icp_regs.uart.tx_fifo_write_idx));
|
||||
save_item(NAME(m_icp_regs.uart.tx_fifo_count));
|
||||
m_icp_regs.uart_tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sa1110_periphs_device::icp_tx_callback), this));
|
||||
save_item(NAME(m_icp_regs.uart.rx_break_interlock));
|
||||
|
||||
save_item(NAME(m_icp_regs.utcr4));
|
||||
save_item(NAME(m_icp_regs.hssp.hscr0));
|
||||
save_item(NAME(m_icp_regs.hssp.hscr1));
|
||||
save_item(NAME(m_icp_regs.hssp.hssr0));
|
||||
save_item(NAME(m_icp_regs.hssp.hssr1));
|
||||
save_item(NAME(m_icp_regs.hssp.rx_fifo));
|
||||
save_item(NAME(m_icp_regs.hssp.rx_fifo_read_idx));
|
||||
save_item(NAME(m_icp_regs.hssp.rx_fifo_write_idx));
|
||||
save_item(NAME(m_icp_regs.hssp.rx_fifo_count));
|
||||
m_icp_regs.hssp.rx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sa1110_periphs_device::hssp_rx_callback), this));
|
||||
save_item(NAME(m_icp_regs.hssp.tx_fifo));
|
||||
save_item(NAME(m_icp_regs.hssp.tx_fifo_read_idx));
|
||||
save_item(NAME(m_icp_regs.hssp.tx_fifo_write_idx));
|
||||
save_item(NAME(m_icp_regs.hssp.tx_fifo_count));
|
||||
m_icp_regs.hssp.tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sa1110_periphs_device::hssp_tx_callback), this));
|
||||
|
||||
save_item(NAME(m_uart_regs.utcr));
|
||||
save_item(NAME(m_uart_regs.utsr0));
|
||||
save_item(NAME(m_uart_regs.utsr1));
|
||||
@ -1783,6 +2320,18 @@ void sa1110_periphs_device::device_start()
|
||||
save_item(NAME(m_intc_regs.icfp));
|
||||
save_item(NAME(m_intc_regs.icpr));
|
||||
|
||||
save_item(NAME(m_ppc_regs.ppdr));
|
||||
save_item(NAME(m_ppc_regs.ppsr));
|
||||
save_item(NAME(m_ppc_regs.ppar));
|
||||
save_item(NAME(m_ppc_regs.psdr));
|
||||
save_item(NAME(m_ppc_regs.ppfr));
|
||||
|
||||
save_item(STRUCT_MEMBER(m_dma_regs, ddar));
|
||||
save_item(STRUCT_MEMBER(m_dma_regs, dsr));
|
||||
save_item(STRUCT_MEMBER(m_dma_regs, dbs));
|
||||
save_item(STRUCT_MEMBER(m_dma_regs, dbt));
|
||||
save_item(NAME(m_dma_active_mask));
|
||||
|
||||
m_gpio_out.resolve_all_safe();
|
||||
m_ssp_out.resolve_safe();
|
||||
m_uart3_tx_out.resolve_safe();
|
||||
@ -1790,6 +2339,38 @@ void sa1110_periphs_device::device_start()
|
||||
|
||||
void sa1110_periphs_device::device_reset()
|
||||
{
|
||||
// init ICP
|
||||
memset(m_icp_regs.uart.utcr, 0, sizeof(uint32_t) * 4);
|
||||
m_icp_regs.uart.utsr0 = 0;
|
||||
m_icp_regs.uart.utsr1 = 0;
|
||||
memset(m_icp_regs.uart.rx_fifo, 0, sizeof(uint16_t) * 12);
|
||||
m_icp_regs.uart.rx_fifo_read_idx = 0;
|
||||
m_icp_regs.uart.rx_fifo_write_idx = 0;
|
||||
m_icp_regs.uart.rx_fifo_count = 0;
|
||||
m_icp_regs.uart_rx_timer->adjust(attotime::never);
|
||||
memset(m_icp_regs.uart.tx_fifo, 0, 8);
|
||||
m_icp_regs.uart.tx_fifo_read_idx = 0;
|
||||
m_icp_regs.uart.tx_fifo_write_idx = 0;
|
||||
m_icp_regs.uart.tx_fifo_count = 0;
|
||||
m_icp_regs.uart_tx_timer->adjust(attotime::never);
|
||||
m_icp_regs.uart.rx_break_interlock = false;
|
||||
|
||||
m_icp_regs.utcr4 = 0;
|
||||
m_icp_regs.hssp.hscr0 = 0;
|
||||
m_icp_regs.hssp.hscr1 = 0;
|
||||
m_icp_regs.hssp.hssr0 = 0;
|
||||
m_icp_regs.hssp.hssr1 = 0;
|
||||
memset(m_icp_regs.hssp.rx_fifo, 0, sizeof(uint16_t) * 8);
|
||||
m_icp_regs.hssp.rx_fifo_read_idx = 0;
|
||||
m_icp_regs.hssp.rx_fifo_write_idx = 0;
|
||||
m_icp_regs.hssp.rx_fifo_count = 0;
|
||||
m_icp_regs.hssp.rx_timer->adjust(attotime::never);
|
||||
memset(m_icp_regs.hssp.tx_fifo, 0, sizeof(uint16_t) * 8);
|
||||
m_icp_regs.hssp.tx_fifo_read_idx = 0;
|
||||
m_icp_regs.hssp.tx_fifo_write_idx = 0;
|
||||
m_icp_regs.hssp.tx_fifo_count = 0;
|
||||
m_icp_regs.hssp.tx_timer->adjust(attotime::never);
|
||||
|
||||
// init UART3
|
||||
memset(m_uart_regs.utcr, 0, sizeof(uint32_t) * 4);
|
||||
m_uart_regs.utsr0 = 0;
|
||||
@ -1868,10 +2449,28 @@ void sa1110_periphs_device::device_reset()
|
||||
memset(&m_power_regs, 0, sizeof(m_power_regs));
|
||||
m_power_regs.posr = 1; // flag oscillator OK
|
||||
|
||||
// init PPC regs
|
||||
m_ppc_regs.ppdr = 0;
|
||||
m_ppc_regs.ppsr = 0;
|
||||
m_ppc_regs.ppar = 0;
|
||||
m_ppc_regs.psdr = 0x003fffff;
|
||||
m_ppc_regs.ppfr = 0x0007f001;
|
||||
|
||||
// init DMA regs
|
||||
for (int channel = 0; channel < 6; channel++)
|
||||
{
|
||||
m_dma_regs[channel].ddar = 0;
|
||||
m_dma_regs[channel].dsr = 0;
|
||||
memset(m_dma_regs[channel].dbs, 0, sizeof(uint32_t) * 2);
|
||||
memset(m_dma_regs[channel].dbt, 0, sizeof(uint32_t) * 2);
|
||||
}
|
||||
// bulk-init other registers
|
||||
m_rcsr = 0x00000001; // indicate hardware reset
|
||||
memset(&m_gpio_regs, 0, sizeof(m_gpio_regs));
|
||||
memset(&m_intc_regs, 0, sizeof(m_intc_regs));
|
||||
|
||||
uart_check_rx_fifo_service();
|
||||
uart_check_tx_fifo_service();
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::device_add_mconfig(machine_config &config)
|
||||
|
@ -46,6 +46,8 @@ public:
|
||||
|
||||
auto uart3_tx_out() { return m_uart3_tx_out.bind(); }
|
||||
|
||||
uint32_t icp_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void icp_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
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 mcp_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
@ -64,6 +66,10 @@ public:
|
||||
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);
|
||||
uint32_t ppc_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void ppc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t dma_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void dma_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
|
||||
protected:
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
@ -71,6 +77,23 @@ protected:
|
||||
virtual void device_reset() override;
|
||||
|
||||
static constexpr uint32_t INTERNAL_OSC = 3686400;
|
||||
|
||||
TIMER_CALLBACK_MEMBER(icp_rx_callback);
|
||||
TIMER_CALLBACK_MEMBER(icp_tx_callback);
|
||||
TIMER_CALLBACK_MEMBER(hssp_rx_callback);
|
||||
TIMER_CALLBACK_MEMBER(hssp_tx_callback);
|
||||
void icp_uart_set_receiver_enabled(bool enabled);
|
||||
void icp_uart_set_transmitter_enabled(bool enabled);
|
||||
void icp_uart_set_receive_irq_enabled(bool enabled);
|
||||
void icp_uart_set_transmit_irq_enabled(bool enabled);
|
||||
uint8_t icp_uart_read_receive_fifo();
|
||||
void icp_uart_write_transmit_fifo(uint8_t data);
|
||||
uint16_t icp_hssp_read_receive_fifo();
|
||||
void icp_hssp_write_transmit_fifo(uint8_t data);
|
||||
void icp_uart_set_receiver_idle();
|
||||
void icp_uart_begin_of_break();
|
||||
void icp_uart_end_of_break();
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(uart3_irq_callback);
|
||||
void uart_recalculate_divisor();
|
||||
void uart_update_eif_status();
|
||||
@ -125,9 +148,20 @@ protected:
|
||||
void set_irq_line(uint32_t line, int state);
|
||||
void update_interrupts();
|
||||
|
||||
void dma_set_control_bits(int channel, uint32_t bits);
|
||||
void dma_clear_control_bits(int channel, uint32_t bits);
|
||||
|
||||
// register offsets
|
||||
enum
|
||||
{
|
||||
ICP_BASE_ADDR = 0x80030000,
|
||||
REG_UTCR4 = (0x00000010 >> 2),
|
||||
REG_HSCR0 = (0x00000060 >> 2),
|
||||
REG_HSCR1 = (0x00000064 >> 2),
|
||||
REG_HSDR = (0x0000006c >> 2),
|
||||
REG_HSSR0 = (0x00000074 >> 2),
|
||||
REG_HSSR1 = (0x00000078 >> 2),
|
||||
|
||||
UART_BASE_ADDR = 0x80050000,
|
||||
REG_UTCR0 = (0x00000000 >> 2),
|
||||
REG_UTCR1 = (0x00000004 >> 2),
|
||||
@ -196,7 +230,24 @@ protected:
|
||||
REG_ICLR = (0x00000008 >> 2),
|
||||
REG_ICCR = (0x0000000c >> 2),
|
||||
REG_ICFP = (0x00000010 >> 2),
|
||||
REG_ICPR = (0x00000020 >> 2)
|
||||
REG_ICPR = (0x00000020 >> 2),
|
||||
|
||||
PPC_BASE_ADDR = 0x90060000,
|
||||
REG_PPDR = (0x00000000 >> 2),
|
||||
REG_PPSR = (0x00000004 >> 2),
|
||||
REG_PPAR = (0x00000008 >> 2),
|
||||
REG_PSDR = (0x0000000c >> 2),
|
||||
REG_PPFR = (0x00000010 >> 2),
|
||||
|
||||
DMA_BASE_ADDR = 0xb0000000,
|
||||
REG_DDAR = (0x00000000 >> 2),
|
||||
REG_DSSR = (0x00000004 >> 2),
|
||||
REG_DCSR = (0x00000008 >> 2),
|
||||
REG_DSR = (0x0000000c >> 2),
|
||||
REG_DBSA = (0x00000010 >> 2),
|
||||
REG_DBTA = (0x00000014 >> 2),
|
||||
REG_DBSB = (0x00000018 >> 2),
|
||||
REG_DBTB = (0x0000001c >> 2)
|
||||
};
|
||||
|
||||
// register contents
|
||||
@ -213,6 +264,9 @@ protected:
|
||||
UTCR3_TIE_BIT = 4,
|
||||
UTCR3_LBM_BIT = 5,
|
||||
|
||||
UTCR4_HSE_BIT = 0,
|
||||
UTCR4_LPM_BIT = 1,
|
||||
|
||||
UTSR0_TFS_BIT = 0,
|
||||
UTSR0_RFS_BIT = 1,
|
||||
UTSR0_RID_BIT = 2,
|
||||
@ -227,6 +281,37 @@ protected:
|
||||
UTSR1_FRE_BIT = 4,
|
||||
UTSR1_ROR_BIT = 5,
|
||||
|
||||
HSCR0_ITR_BIT = 0,
|
||||
HSCR0_LBM_BIT = 1,
|
||||
HSCR0_TUS_BIT = 2,
|
||||
HSCR0_TXE_BIT = 3,
|
||||
HSCR0_RXE_BIT = 4,
|
||||
HSCR0_RIE_BIT = 5,
|
||||
HSCR0_TIE_BIT = 6,
|
||||
HSCR0_AME_BIT = 7,
|
||||
|
||||
HSCR2_TXP_BIT = 18,
|
||||
HSCR2_RXP_BIT = 19,
|
||||
|
||||
HSDR_EOF_BIT = 8,
|
||||
HSDR_CRE_BIT = 9,
|
||||
HSDR_ROR_BIT = 10,
|
||||
|
||||
HSSR0_EIF_BIT = 0,
|
||||
HSSR0_TUR_BIT = 1,
|
||||
HSSR0_RAB_BIT = 2,
|
||||
HSSR0_TFS_BIT = 3,
|
||||
HSSR0_RFS_BIT = 4,
|
||||
HSSR0_FRE_BIT = 5,
|
||||
|
||||
HSSR1_RSY_BIT = 0,
|
||||
HSSR1_TBY_BIT = 1,
|
||||
HSSR1_RNE_BIT = 2,
|
||||
HSSR1_TNF_BIT = 3,
|
||||
HSSR1_EOF_BIT = 4,
|
||||
HSSR1_CRE_BIT = 5,
|
||||
HSSR1_ROR_BIT = 6,
|
||||
|
||||
MCCR0_ASD_BIT = 0,
|
||||
MCCR0_ASD_MASK = 0x0000007f,
|
||||
MCCR0_TSD_BIT = 8,
|
||||
@ -294,7 +379,27 @@ protected:
|
||||
RTSR_ALE_BIT = 2,
|
||||
RTSR_ALE_MASK = (1 << RTSR_ALE_BIT),
|
||||
RTSR_HZE_BIT = 3,
|
||||
RTSR_HZE_MASK = (1 << RTSR_HZE_BIT)
|
||||
RTSR_HZE_MASK = (1 << RTSR_HZE_BIT),
|
||||
|
||||
DDAR_RW_BIT = 0,
|
||||
DDAR_E_BIT = 1,
|
||||
DDAR_BS_BIT = 2,
|
||||
DDAR_DW_BIT = 3,
|
||||
DDAR_DA0_BIT = 4,
|
||||
DDAR_DA0_MASK = 0x000000f0,
|
||||
DDAR_DA8_BIT = 8,
|
||||
DDAR_DA8_MASK = 0xffffff00,
|
||||
|
||||
DSR_RUN_BIT = 0,
|
||||
DSR_IE_BIT = 1,
|
||||
DSR_ERROR_BIT = 2,
|
||||
DSR_DONEA_BIT = 3,
|
||||
DSR_STRTA_BIT = 4,
|
||||
DSR_DONEB_BIT = 5,
|
||||
DSR_STRTB_BIT = 6,
|
||||
DSR_BIU_BIT = 7,
|
||||
|
||||
DBT_MASK = 0x00001fff
|
||||
};
|
||||
|
||||
// interrupt bits
|
||||
@ -376,6 +481,36 @@ protected:
|
||||
bool rx_break_interlock;
|
||||
};
|
||||
|
||||
struct hssp_regs
|
||||
{
|
||||
uint32_t hscr0;
|
||||
uint32_t hscr1;
|
||||
uint32_t hssr0;
|
||||
uint32_t hssr1;
|
||||
|
||||
uint16_t rx_fifo[8];
|
||||
int rx_fifo_read_idx;
|
||||
int rx_fifo_write_idx;
|
||||
int rx_fifo_count;
|
||||
emu_timer *rx_timer;
|
||||
|
||||
uint16_t tx_fifo[8];
|
||||
int tx_fifo_read_idx;
|
||||
int tx_fifo_write_idx;
|
||||
int tx_fifo_count;
|
||||
emu_timer *tx_timer;
|
||||
};
|
||||
|
||||
struct icp_regs
|
||||
{
|
||||
uart_regs uart;
|
||||
uint32_t utcr4;
|
||||
emu_timer *uart_rx_timer;
|
||||
emu_timer *uart_tx_timer;
|
||||
|
||||
hssp_regs hssp;
|
||||
};
|
||||
|
||||
struct mcp_regs
|
||||
{
|
||||
uint32_t mccr0;
|
||||
@ -486,7 +621,27 @@ protected:
|
||||
uint32_t icpr;
|
||||
};
|
||||
|
||||
struct ppc_regs
|
||||
{
|
||||
uint32_t ppdr;
|
||||
uint32_t ppsr_out;
|
||||
uint32_t ppsr_in;
|
||||
uint32_t ppsr;
|
||||
uint32_t ppar;
|
||||
uint32_t psdr;
|
||||
uint32_t ppfr;
|
||||
};
|
||||
|
||||
struct dma_regs
|
||||
{
|
||||
uint32_t ddar;
|
||||
uint32_t dsr;
|
||||
uint32_t dbs[2];
|
||||
uint32_t dbt[2];
|
||||
};
|
||||
|
||||
uart_regs m_uart_regs;
|
||||
icp_regs m_icp_regs;
|
||||
mcp_regs m_mcp_regs;
|
||||
ssp_regs m_ssp_regs;
|
||||
ostimer_regs m_ostmr_regs;
|
||||
@ -495,8 +650,11 @@ protected:
|
||||
uint32_t m_rcsr;
|
||||
gpio_regs m_gpio_regs;
|
||||
intc_regs m_intc_regs;
|
||||
ppc_regs m_ppc_regs;
|
||||
dma_regs m_dma_regs[6];
|
||||
uint8_t m_dma_active_mask;
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<sa1110_cpu_device> m_maincpu;
|
||||
required_device<input_merger_device> m_uart3_irqs;
|
||||
required_device<input_merger_device> m_mcp_irqs;
|
||||
optional_device<ucb1200_device> m_codec;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -11,25 +11,38 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/input_merger.h"
|
||||
#include "cpu/arm7/arm7.h"
|
||||
#include "cpu/arm7/arm7core.h"
|
||||
|
||||
class sa1111_device : public device_t
|
||||
{
|
||||
public:
|
||||
sa1111_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
||||
template <typename T>
|
||||
sa1111_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag)
|
||||
: sa1111_device(mconfig, tag, owner, clock)
|
||||
{
|
||||
m_maincpu.set_tag(std::forward<T>(cpu_tag));
|
||||
}
|
||||
|
||||
template <unsigned Line> void pa_in(int state) { gpio_in(0 + Line, state); }
|
||||
template <unsigned Line> void pb_in(int state) { gpio_in(8 + Line, state); }
|
||||
template <unsigned Line> void pc_in(int state) { gpio_in(16 + Line, state); }
|
||||
template <unsigned Line> auto pa_out() { return m_gpio_out[0 + Line].bind(); }
|
||||
template <unsigned Line> auto pb_out() { return m_gpio_out[8 + Line].bind(); }
|
||||
template <unsigned Line> auto pc_out() { return m_gpio_out[16 + Line].bind(); }
|
||||
sa1111_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
template <typename T> void set_audio_codec_tag(T &&tag) { m_audio_codec.set_tag(std::forward<T>(tag)); }
|
||||
|
||||
auto irq_out() { return m_irq_out.bind(); }
|
||||
|
||||
template <int Line> void pa_in(int state) { gpio_in(0 + Line, state); }
|
||||
template <int Line> void pb_in(int state) { gpio_in(8 + Line, state); }
|
||||
template <int Line> void pc_in(int state) { gpio_in(16 + Line, state); }
|
||||
template <int Line> auto pa_out() { return m_gpio_out[0 + Line].bind(); }
|
||||
template <int Line> auto pb_out() { return m_gpio_out[8 + Line].bind(); }
|
||||
template <int Line> auto pc_out() { return m_gpio_out[16 + Line].bind(); }
|
||||
|
||||
void ssp_in(uint16_t data) { ssp_rx_fifo_push(data); }
|
||||
auto ssp_out() { return m_ssp_out.bind(); }
|
||||
|
||||
auto l3_addr_out() { return m_l3_addr_out.bind(); }
|
||||
auto l3_data_out() { return m_l3_data_out.bind(); }
|
||||
auto i2s_out() { return m_i2s_out.bind(); }
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(l3wd_in);
|
||||
|
||||
@ -40,11 +53,31 @@ protected:
|
||||
virtual void device_reset() override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
|
||||
void set_irq_line(uint32_t line, int state);
|
||||
void update_interrupts();
|
||||
|
||||
TIMER_CALLBACK_MEMBER(ssp_rx_callback);
|
||||
TIMER_CALLBACK_MEMBER(ssp_tx_callback);
|
||||
|
||||
TIMER_CALLBACK_MEMBER(audio_rx_dma_callback);
|
||||
TIMER_CALLBACK_MEMBER(audio_rx_callback);
|
||||
TIMER_CALLBACK_MEMBER(audio_tx_dma_callback);
|
||||
TIMER_CALLBACK_MEMBER(audio_tx_callback);
|
||||
void audio_update_mode();
|
||||
void audio_clear_interrupts();
|
||||
void audio_set_enabled(bool enabled);
|
||||
void audio_controller_reset();
|
||||
void audio_set_tx_dma_enabled(bool enabled);
|
||||
void audio_set_rx_dma_enabled(bool enabled);
|
||||
void audio_start_tx_dma(const uint32_t buf);
|
||||
void audio_start_rx_dma(const uint32_t buf);
|
||||
void audio_update_tx_fifo_levels();
|
||||
void audio_update_rx_fifo_levels();
|
||||
void audio_update_busy_flag();
|
||||
void audio_tx_fifo_push(uint32_t data);
|
||||
uint32_t audio_tx_fifo_pop();
|
||||
void audio_rx_fifo_push(uint32_t data);
|
||||
uint32_t audio_rx_fifo_pop();
|
||||
|
||||
uint32_t unknown_r(offs_t offset, uint32_t mem_mask);
|
||||
void unknown_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
@ -161,30 +194,30 @@ protected:
|
||||
void mouse_kbdprecnt_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void mouse_kbditr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
|
||||
template <unsigned Block> uint32_t ddr_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Block> uint32_t drr_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Block> uint32_t sdr_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Block> uint32_t ssr_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Block> void ddr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Block> void dwr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Block> void sdr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Block> void ssr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <int Block> uint32_t ddr_r(offs_t offset, uint32_t mem_mask);
|
||||
template <int Block> uint32_t drr_r(offs_t offset, uint32_t mem_mask);
|
||||
template <int Block> uint32_t sdr_r(offs_t offset, uint32_t mem_mask);
|
||||
template <int Block> uint32_t ssr_r(offs_t offset, uint32_t mem_mask);
|
||||
template <int Block> void ddr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <int Block> void dwr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <int Block> void sdr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <int Block> void ssr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
|
||||
template <unsigned Set> uint32_t inttest_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Set> uint32_t inten_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Set> uint32_t intpol_r(offs_t offset, uint32_t mem_mask);
|
||||
template <int Set> uint32_t inttest_r(offs_t offset, uint32_t mem_mask);
|
||||
template <int Set> uint32_t inten_r(offs_t offset, uint32_t mem_mask);
|
||||
template <int Set> uint32_t intpol_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t inttstsel_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Set> uint32_t intstat_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Set> uint32_t wake_en_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Set> uint32_t wake_pol_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Set> void inttest_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Set> void inten_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Set> void intpol_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <int Set> uint32_t intstat_r(offs_t offset, uint32_t mem_mask);
|
||||
template <int Set> uint32_t wake_en_r(offs_t offset, uint32_t mem_mask);
|
||||
template <int Set> uint32_t wake_pol_r(offs_t offset, uint32_t mem_mask);
|
||||
template <int Set> void inttest_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <int Set> void inten_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <int Set> void intpol_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void inttstsel_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Set> void intclr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Set> void intset_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Set> void wake_en_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Set> void wake_pol_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <int Set> void intclr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <int Set> void intset_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <int Set> void wake_en_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <int Set> void wake_pol_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
|
||||
uint32_t pccr_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t pcssr_r(offs_t offset, uint32_t mem_mask);
|
||||
@ -201,13 +234,7 @@ protected:
|
||||
|
||||
void gpio_in(const uint32_t line, const int state);
|
||||
void gpio_update_direction(const uint32_t block, const uint32_t old_dir);
|
||||
void gpio_update_outputs(const uint32_t block, const uint32_t old_latch);
|
||||
|
||||
// interrupt lines
|
||||
enum : uint32_t
|
||||
{
|
||||
INT_AUDDTS = 40
|
||||
};
|
||||
void gpio_update_outputs(const uint32_t block, const uint32_t changed);
|
||||
|
||||
// register contents
|
||||
enum : uint32_t
|
||||
@ -220,7 +247,7 @@ protected:
|
||||
SKCR_SCANTST_BIT = 5,
|
||||
SKCR_CLKTST_BIT = 6,
|
||||
SKCR_RDY_BIT = 7,
|
||||
SKCR_SLAC_BIT = 8,
|
||||
SKCR_SACMDSL_BIT = 8,
|
||||
SKCR_OPPC_BIT = 9,
|
||||
SKCR_PII_BIT = 10,
|
||||
SKCR_UIOTEN_BIT = 11,
|
||||
@ -319,31 +346,23 @@ protected:
|
||||
SASCR_RDD_BIT = 17,
|
||||
SASCR_STO_BIT = 18,
|
||||
|
||||
SASR0_TNF_BIT = 0,
|
||||
SASR0_RNE_BIT = 1,
|
||||
SASR0_BSY_BIT = 2,
|
||||
SASR0_TFS_BIT = 3,
|
||||
SASR0_RFS_BIT = 4,
|
||||
SASR0_TUR_BIT = 5,
|
||||
SASR0_ROR_BIT = 6,
|
||||
SASR0_TFL_BIT = 7,
|
||||
SASR0_TFL_MASK = 0x00000f00,
|
||||
SASR0_RFL_BIT = 12,
|
||||
SASR0_RFL_MASK = 0x0000f000,
|
||||
SASR_TNF_BIT = 0,
|
||||
SASR_RNE_BIT = 1,
|
||||
SASR_BSY_BIT = 2,
|
||||
SASR_TFS_BIT = 3,
|
||||
SASR_RFS_BIT = 4,
|
||||
SASR_TUR_BIT = 5,
|
||||
SASR_ROR_BIT = 6,
|
||||
SASR_TFL_BIT = 8,
|
||||
SASR_TFL_MASK = 0x00000f00,
|
||||
SASR_RFL_BIT = 12,
|
||||
SASR_RFL_MASK = 0x0000f000,
|
||||
SASR_SEND_BIT = 16,
|
||||
SASR_RECV_BIT = 17,
|
||||
|
||||
SASR0_L3WD_BIT = 16,
|
||||
SASR0_L3RD_BIT = 17,
|
||||
|
||||
SASR1_TNF_BIT = 0,
|
||||
SASR1_RNE_BIT = 1,
|
||||
SASR1_BSY_BIT = 2,
|
||||
SASR1_TFS_BIT = 3,
|
||||
SASR1_RFS_BIT = 4,
|
||||
SASR1_TUR_BIT = 5,
|
||||
SASR1_ROR_BIT = 6,
|
||||
SASR1_TFL_BIT = 8,
|
||||
SASR1_TFL_MASK = 0x00000f00,
|
||||
SASR1_RFL_BIT = 12,
|
||||
SASR1_RFL_MASK = 0x0000f000,
|
||||
SASR1_CADT_BIT = 16,
|
||||
SASR1_SADR_BIT = 17,
|
||||
SASR1_RSTO_BIT = 18,
|
||||
@ -357,12 +376,14 @@ protected:
|
||||
SADTCS_TDSTA_BIT = 4,
|
||||
SADTCS_TDBDB_BIT = 5,
|
||||
SADTCS_TDSTB_BIT = 6,
|
||||
SADTCS_TBIU_BIT = 7,
|
||||
|
||||
SADRCS_RDEN_BIT = 0,
|
||||
SADRCS_RDBDA_BIT = 3,
|
||||
SADRCS_RDSTA_BIT = 4,
|
||||
SADRCS_RDBDB_BIT = 5,
|
||||
SADRCS_RDSTB_BIT = 6,
|
||||
SADRCS_RBIU_BIT = 7,
|
||||
|
||||
SAITR_TFS_BIT = 0,
|
||||
SAITR_RFS_BIT = 1,
|
||||
@ -456,6 +477,61 @@ protected:
|
||||
PCSSR_S1SLP_BIT = 1
|
||||
};
|
||||
|
||||
// interrupt lines
|
||||
enum : uint32_t
|
||||
{
|
||||
INT_GPA0 = 0,
|
||||
INT_GPA1 = 1,
|
||||
INT_GPA2 = 2,
|
||||
INT_GPA3 = 3,
|
||||
INT_GPB0 = 4,
|
||||
INT_GPB1 = 5,
|
||||
INT_GPB2 = 6,
|
||||
INT_GPB3 = 7,
|
||||
INT_GPB4 = 8,
|
||||
INT_GPB5 = 9,
|
||||
INT_GPC0 = 10,
|
||||
INT_GPC1 = 11,
|
||||
INT_GPC2 = 12,
|
||||
INT_GPC3 = 13,
|
||||
INT_GPC4 = 14,
|
||||
INT_GPC5 = 15,
|
||||
INT_GPC6 = 16,
|
||||
INT_GPC7 = 17,
|
||||
INT_MSTX = 18,
|
||||
INT_MSRX = 19,
|
||||
INT_MSERR = 20,
|
||||
INT_TPTX = 21,
|
||||
INT_TPRX = 22,
|
||||
INT_TPERR = 23,
|
||||
INT_SSPTX = 24,
|
||||
INT_SSPRX = 25,
|
||||
INT_SSPROR = 26,
|
||||
INT_AUDTXA = 32,
|
||||
INT_AUDRXA = 33,
|
||||
INT_AUDTXB = 34,
|
||||
INT_AUDRXB = 35,
|
||||
INT_AUDTFS = 36,
|
||||
INT_AUDRFS = 37,
|
||||
INT_AUDTUR = 38,
|
||||
INT_AUDROR = 39,
|
||||
INT_AUDDTS = 40,
|
||||
INT_AUDRDD = 41,
|
||||
INT_AUDSTO = 42,
|
||||
INT_USBPWR = 43,
|
||||
INT_USBHCIM = 44,
|
||||
INT_USBHCIBUF = 45,
|
||||
INT_USBHCIWAKE = 46,
|
||||
INT_USBHCIMFC = 47,
|
||||
INT_USBRESUME = 48,
|
||||
INT_S0RDY = 49,
|
||||
INT_S1RDY = 50,
|
||||
INT_S0CD = 51,
|
||||
INT_S1CD = 52,
|
||||
INT_S0BVD = 53,
|
||||
INT_S1BVD = 54
|
||||
};
|
||||
|
||||
struct sbi_regs
|
||||
{
|
||||
uint32_t skcr;
|
||||
@ -499,15 +575,15 @@ protected:
|
||||
uint32_t acsar;
|
||||
uint32_t acsdr;
|
||||
uint32_t sadtcs;
|
||||
uint32_t sadtsa;
|
||||
uint32_t sadtca;
|
||||
uint32_t sadtsb;
|
||||
uint32_t sadtcb;
|
||||
uint32_t sadts[2];
|
||||
uint32_t sadtc[2];
|
||||
uint32_t sadta;
|
||||
uint32_t sadtcc;
|
||||
uint32_t sadrcs;
|
||||
uint32_t sadrsa;
|
||||
uint32_t sadrca;
|
||||
uint32_t sadrsb;
|
||||
uint32_t sadrcb;
|
||||
uint32_t sadrs[2];
|
||||
uint32_t sadrc[2];
|
||||
uint32_t sadra;
|
||||
uint32_t sadrcc;
|
||||
uint32_t saitr;
|
||||
|
||||
uint32_t rx_fifo[16];
|
||||
@ -515,12 +591,14 @@ protected:
|
||||
int rx_fifo_write_idx;
|
||||
int rx_fifo_count;
|
||||
emu_timer *rx_timer;
|
||||
emu_timer *rx_dma_timer;
|
||||
|
||||
uint32_t tx_fifo[16];
|
||||
int tx_fifo_read_idx;
|
||||
int tx_fifo_write_idx;
|
||||
int tx_fifo_count;
|
||||
emu_timer *tx_timer;
|
||||
emu_timer *tx_dma_timer;
|
||||
};
|
||||
|
||||
struct ssp_regs
|
||||
@ -573,6 +651,8 @@ protected:
|
||||
uint32_t intstat[2];
|
||||
uint32_t wake_en[2];
|
||||
uint32_t wake_pol[2];
|
||||
|
||||
uint32_t intraw[2];
|
||||
};
|
||||
|
||||
struct card_regs
|
||||
@ -593,10 +673,15 @@ protected:
|
||||
intc_regs m_intc_regs;
|
||||
card_regs m_card_regs;
|
||||
|
||||
required_device<sa1110_cpu_device> m_maincpu;
|
||||
optional_device<device_t> m_audio_codec;
|
||||
|
||||
devcb_write_line m_irq_out;
|
||||
devcb_write_line::array<24> m_gpio_out;
|
||||
devcb_write16 m_ssp_out;
|
||||
devcb_write8 m_l3_addr_out;
|
||||
devcb_write8 m_l3_data_out;
|
||||
devcb_write32 m_i2s_out;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(SA1111, sa1111_device)
|
||||
|
@ -12,9 +12,11 @@
|
||||
#define LOG_ADDR (1 << 1)
|
||||
#define LOG_STATUS_REG (1 << 2)
|
||||
#define LOG_DATA_REG (1 << 3)
|
||||
#define LOG_ALL (LOG_ADDR | LOG_STATUS_REG | LOG_DATA_REG)
|
||||
#define LOG_INPUT (1 << 4)
|
||||
#define LOG_OVERRUNS (1 << 5)
|
||||
#define LOG_ALL (LOG_ADDR | LOG_STATUS_REG | LOG_DATA_REG | LOG_INPUT | LOG_OVERRUNS)
|
||||
|
||||
#define VERBOSE (LOG_ALL)
|
||||
#define VERBOSE (0)
|
||||
#include "logmacro.h"
|
||||
|
||||
|
||||
@ -26,52 +28,138 @@ uda1344_device::uda1344_device(const machine_config &mconfig, const char *tag, d
|
||||
: device_t(mconfig, UDA1344, tag, owner, clock)
|
||||
, device_sound_interface(mconfig, *this)
|
||||
, m_stream(nullptr)
|
||||
, m_volume(1.0)
|
||||
, m_frequency(BASE_FREQUENCY)
|
||||
, m_data_transfer_mode(0)
|
||||
, m_status_reg(0)
|
||||
, m_clock_divider(512)
|
||||
, m_volume_reg(0)
|
||||
, m_equalizer_reg(0)
|
||||
, m_filter_reg(0)
|
||||
, m_power_reg(0)
|
||||
, m_dac_enable(false)
|
||||
, m_adc_enable(false)
|
||||
, m_l3_ack_out(*this)
|
||||
{
|
||||
}
|
||||
|
||||
void uda1344_device::device_start()
|
||||
{
|
||||
m_stream = stream_alloc(0, 2, 44100);
|
||||
m_stream = stream_alloc(0, 2, BASE_FREQUENCY);
|
||||
|
||||
save_item(NAME(m_buffer[0]));
|
||||
save_item(NAME(m_buffer[1]));
|
||||
save_item(NAME(m_bufin));
|
||||
save_item(NAME(m_bufout));
|
||||
save_item(NAME(m_volume));
|
||||
save_item(NAME(m_frequency));
|
||||
|
||||
save_item(NAME(m_data_transfer_mode));
|
||||
save_item(NAME(m_status_reg));
|
||||
save_item(NAME(m_clock_divider));
|
||||
save_item(NAME(m_volume_reg));
|
||||
save_item(NAME(m_equalizer_reg));
|
||||
save_item(NAME(m_filter_reg));
|
||||
save_item(NAME(m_power_reg));
|
||||
save_item(NAME(m_dac_enable));
|
||||
save_item(NAME(m_adc_enable));
|
||||
|
||||
m_l3_ack_out.resolve_safe();
|
||||
|
||||
m_buffer[0].resize(BUFFER_SIZE);
|
||||
m_buffer[1].resize(BUFFER_SIZE);
|
||||
}
|
||||
|
||||
void uda1344_device::device_reset()
|
||||
{
|
||||
m_data_transfer_mode = 0;
|
||||
m_status_reg = 0;
|
||||
m_clock_divider = 512;
|
||||
m_volume_reg = 0;
|
||||
m_equalizer_reg = 0;
|
||||
m_filter_reg = 0;
|
||||
m_power_reg = 0;
|
||||
|
||||
m_dac_enable = false;
|
||||
m_adc_enable = false;
|
||||
|
||||
m_volume = 1.0;
|
||||
m_frequency = BASE_FREQUENCY;
|
||||
|
||||
memset(m_bufin, 0, sizeof(uint32_t) * 2);
|
||||
memset(m_bufout, 0, sizeof(uint32_t) * 2);
|
||||
}
|
||||
|
||||
void uda1344_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
|
||||
{
|
||||
auto &buffer = outputs[0];
|
||||
|
||||
/* fill in the samples */
|
||||
for (int sampindex = 0; sampindex < buffer.samples(); sampindex++)
|
||||
for (int channel = 0; channel < 2 && channel < outputs.size(); channel++)
|
||||
{
|
||||
// TODO: Generate audio
|
||||
buffer.put(sampindex, 0);
|
||||
auto &output = outputs[channel];
|
||||
uint32_t curout = m_bufout[channel];
|
||||
uint32_t curin = m_bufin[channel];
|
||||
|
||||
// feed as much as we can
|
||||
int sampindex;
|
||||
for (sampindex = 0; curout != curin && sampindex < output.samples(); sampindex++)
|
||||
{
|
||||
output.put(sampindex, stream_buffer::sample_t(m_buffer[channel][curout]) * m_volume);
|
||||
curout = (curout + 1) % BUFFER_SIZE;
|
||||
}
|
||||
|
||||
// fill the rest with silence
|
||||
output.fill(0, sampindex);
|
||||
|
||||
// save the new output pointer
|
||||
m_bufout[channel] = curout;
|
||||
}
|
||||
}
|
||||
|
||||
void uda1344_device::ingest_samples(int16_t left, int16_t right)
|
||||
{
|
||||
const int16_t samples[2] = { left, right };
|
||||
|
||||
const stream_buffer::sample_t sample_scale = 1.0 / 32768.0;
|
||||
const stream_buffer::sample_t enable_scale = m_dac_enable ? 1.0 : 0.0;
|
||||
|
||||
m_stream->update();
|
||||
|
||||
for (int channel = 0; channel < 2; channel++)
|
||||
{
|
||||
int maxin = (m_bufout[channel] + BUFFER_SIZE - 1) % BUFFER_SIZE;
|
||||
if (m_bufin[channel] != maxin)
|
||||
{
|
||||
m_buffer[channel][m_bufin[channel]] = stream_buffer::sample_t(samples[channel]) * sample_scale * enable_scale;
|
||||
m_bufin[channel] = (m_bufin[channel] + 1) % BUFFER_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_OVERRUNS, "ingest_samples: buffer overrun (short 1 frame on channel %d)\n", channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uda1344_device::device_clock_changed()
|
||||
{
|
||||
if (clock() == 0)
|
||||
return;
|
||||
|
||||
m_stream->update();
|
||||
m_stream->set_sample_rate(clock() / m_clock_divider);
|
||||
}
|
||||
|
||||
void uda1344_device::set_clock_divider(const uint32_t divider)
|
||||
{
|
||||
m_clock_divider = divider;
|
||||
device_clock_changed();
|
||||
}
|
||||
|
||||
void uda1344_device::i2s_input_w(uint32_t data)
|
||||
{
|
||||
const int16_t left = (int16_t)(data >> 16);
|
||||
const int16_t right = (int16_t)data;
|
||||
ingest_samples(left, right);
|
||||
}
|
||||
|
||||
void uda1344_device::l3_addr_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
// Check for L3 address match, ignore if not addressed to us
|
||||
@ -115,6 +203,19 @@ void uda1344_device::l3_data_w(offs_t offset, uint8_t data)
|
||||
s_format_names[(reg_bits & STATUS_IF_MASK) >> STATUS_IF_BIT],
|
||||
BIT(reg_bits, STATUS_DC_BIT) ? "on" : "off");
|
||||
m_status_reg = reg_bits;
|
||||
|
||||
switch ((reg_bits & STATUS_SC_MASK) >> STATUS_SC_BIT)
|
||||
{
|
||||
case 1:
|
||||
set_clock_divider(384);
|
||||
break;
|
||||
case 2:
|
||||
set_clock_divider(256);
|
||||
break;
|
||||
default:
|
||||
set_clock_divider(512);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -123,13 +224,24 @@ void uda1344_device::l3_data_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
case VOLUME_REG:
|
||||
{
|
||||
m_stream->update();
|
||||
|
||||
const uint8_t reg_bits = data & VOLUME_REG_MASK;
|
||||
if (reg_bits < 2)
|
||||
{
|
||||
LOGMASKED(LOG_DATA_REG, "%s: Volume register data: %02x, no attenuation\n", machine().describe_context(), reg_bits);
|
||||
m_volume = 1.0;
|
||||
}
|
||||
else if (reg_bits >= 62)
|
||||
{
|
||||
LOGMASKED(LOG_DATA_REG, "%s: Volume register data: %02x, full attenuation\n", machine().describe_context(), reg_bits);
|
||||
m_volume = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_DATA_REG, "%s: Volume register data: %02x, -%ddB attenuation\n", machine().describe_context(), reg_bits, reg_bits - 1);
|
||||
m_volume = 1.0 - ((reg_bits - 1) / 62.0);
|
||||
}
|
||||
|
||||
m_volume_reg = reg_bits;
|
||||
break;
|
||||
@ -163,6 +275,10 @@ void uda1344_device::l3_data_w(offs_t offset, uint8_t data)
|
||||
BIT(reg_bits, POWER_ADC_BIT) ? "on" : "off",
|
||||
BIT(reg_bits, POWER_DAC_BIT) ? "on" : "off");
|
||||
m_power_reg = reg_bits;
|
||||
|
||||
m_stream->update();
|
||||
m_dac_enable = BIT(reg_bits, POWER_DAC_BIT);
|
||||
m_adc_enable = BIT(reg_bits, POWER_ADC_BIT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -21,14 +21,24 @@ public:
|
||||
|
||||
auto l3_ack_out() { return m_l3_ack_out.bind(); }
|
||||
|
||||
void i2s_input_w(uint32_t data);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_clock_changed() override;
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
|
||||
|
||||
void ingest_samples(int16_t left, int16_t right);
|
||||
|
||||
void set_clock_divider(const uint32_t divider);
|
||||
|
||||
static constexpr double BASE_FREQUENCY = 44100;
|
||||
static constexpr size_t BUFFER_SIZE = 65536;
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
CHIP_ADDR_MASK = 0xfc,
|
||||
@ -63,20 +73,29 @@ protected:
|
||||
STATUS_REG_MASK = 0x3f,
|
||||
STATUS_SC_MASK = 0x30,
|
||||
STATUS_SC_BIT = 4,
|
||||
STATUS_IF_MASK = 0xe0,
|
||||
STATUS_IF_MASK = 0x0e,
|
||||
STATUS_IF_BIT = 1,
|
||||
STATUS_DC_BIT = 0
|
||||
};
|
||||
|
||||
sound_stream *m_stream;
|
||||
std::vector<stream_buffer::sample_t> m_buffer[2];
|
||||
uint32_t m_bufin[2];
|
||||
uint32_t m_bufout[2];
|
||||
stream_buffer::sample_t m_volume;
|
||||
double m_frequency;
|
||||
|
||||
uint8_t m_data_transfer_mode;
|
||||
uint8_t m_status_reg;
|
||||
uint32_t m_clock_divider;
|
||||
uint8_t m_volume_reg;
|
||||
uint8_t m_equalizer_reg;
|
||||
uint8_t m_filter_reg;
|
||||
uint8_t m_power_reg;
|
||||
|
||||
bool m_dac_enable;
|
||||
bool m_adc_enable;
|
||||
|
||||
devcb_write_line m_l3_ack_out;
|
||||
};
|
||||
|
||||
|
@ -23,13 +23,16 @@
|
||||
#define LOG_CRT_WR (1 << 6)
|
||||
#define LOG_BITBLT_RD (1 << 7)
|
||||
#define LOG_BITBLT_WR (1 << 8)
|
||||
#define LOG_LUT_RD (1 << 9)
|
||||
#define LOG_LUT_WR (1 << 10)
|
||||
#define LOG_MPLUG_RD (1 << 11)
|
||||
#define LOG_MPLUG_WR (1 << 12)
|
||||
#define LOG_ALL (LOG_MISC_RD | LOG_MISC_WR | LOG_LCD_RD | LOG_LCD_WR | LOG_CRT_RD | LOG_CRT_WR | LOG_BITBLT_RD | LOG_BITBLT_WR | LOG_LUT_RD | LOG_LUT_WR | LOG_MPLUG_RD | LOG_MPLUG_WR)
|
||||
#define LOG_BITBLT_OP (1 << 9)
|
||||
#define LOG_LUT_RD (1 << 10)
|
||||
#define LOG_LUT_WR (1 << 11)
|
||||
#define LOG_MPLUG_RD (1 << 12)
|
||||
#define LOG_MPLUG_WR (1 << 13)
|
||||
#define LOG_LCD_RD_HF (1 << 14)
|
||||
#define LOG_ALL (LOG_MISC_RD | LOG_MISC_WR | LOG_LCD_RD | LOG_LCD_WR | LOG_CRT_RD | LOG_CRT_WR | LOG_BITBLT_RD | LOG_BITBLT_WR | LOG_BITBLT_OP | LOG_LUT_RD \
|
||||
| LOG_LUT_WR | LOG_MPLUG_RD | LOG_MPLUG_WR)
|
||||
|
||||
#define VERBOSE (0) // (LOG_ALL)
|
||||
#define VERBOSE (0)
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(SED1356, sed1356_device, "sed1356", "Epson SED1356")
|
||||
@ -398,8 +401,10 @@ uint8_t sed1356_device::lcd_display_height_r(offs_t offset)
|
||||
|
||||
uint8_t sed1356_device::lcd_vblank_period_r(offs_t offset)
|
||||
{
|
||||
LOGMASKED(LOG_LCD_RD, "%s: lcd_vblank_period_r: %02x\n", machine().describe_context(), m_lcd_vblank_period);
|
||||
return m_lcd_vblank_period;
|
||||
const uint8_t vblank = screen().vblank() ? (1 << LCDVBL_STATUS_BIT) : 0x00;
|
||||
const uint8_t data = m_lcd_vblank_period | vblank;
|
||||
LOGMASKED(LOG_LCD_RD, "%s: lcd_vblank_period_r: %02x\n", machine().describe_context(), data);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t sed1356_device::tft_fpframe_start_pos_r(offs_t offset)
|
||||
@ -1016,6 +1021,83 @@ void sed1356_device::crt_cursor_fifo_thresh_w(offs_t offset, uint8_t data)
|
||||
}
|
||||
|
||||
|
||||
template <bool Linear>
|
||||
void sed1356_device::bitblt_solid_fill()
|
||||
{
|
||||
uint16_t *dst = (uint16_t*)&m_vram[m_bitblt_dst_addr >> 2];
|
||||
if (m_bitblt_dst_addr & 2)
|
||||
dst++;
|
||||
|
||||
for (uint32_t y = 0; y <= m_bitblt_height; y++)
|
||||
{
|
||||
for (uint32_t x = 0; x <= m_bitblt_width; x++)
|
||||
{
|
||||
if (Linear)
|
||||
*dst++ = m_bitblt_fgcolor;
|
||||
else
|
||||
dst[x] = m_bitblt_fgcolor;
|
||||
}
|
||||
|
||||
if (!Linear)
|
||||
dst += m_bitblt_mem_offset;
|
||||
}
|
||||
}
|
||||
|
||||
void sed1356_device::bitblt_execute_command()
|
||||
{
|
||||
switch (m_bitblt_op)
|
||||
{
|
||||
case 0:
|
||||
LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Write BitBLT with ROP\n");
|
||||
return;
|
||||
case 1:
|
||||
LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Read BitBLT\n");
|
||||
return;
|
||||
case 2:
|
||||
LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Move BitBLT in + direction with ROP\n");
|
||||
return;
|
||||
case 3:
|
||||
LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Move BitBLT in - direction with ROP\n");
|
||||
return;
|
||||
case 4:
|
||||
LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Transparent Write BitBLT\n");
|
||||
return;
|
||||
case 5:
|
||||
LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Transparent Move BitBLT in + direction\n");
|
||||
return;
|
||||
case 6:
|
||||
LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Pattern Fill with ROP\n");
|
||||
return;
|
||||
case 7:
|
||||
LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Pattern Fill with transparency\n");
|
||||
return;
|
||||
case 8:
|
||||
LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Color Expansion\n");
|
||||
return;
|
||||
case 9:
|
||||
LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Color Expansion with transparency\n");
|
||||
return;
|
||||
case 10:
|
||||
LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Move BitBLT with Color Expansion\n");
|
||||
return;
|
||||
case 11:
|
||||
LOGMASKED(LOG_BITBLT_OP, "bitblt: Command not yet implemented: Move BitBLT with Color Expansion and transparency\n");
|
||||
return;
|
||||
case 12:
|
||||
{
|
||||
LOGMASKED(LOG_BITBLT_OP, "bitblt: Solid Fill\n");
|
||||
if (BIT(m_bitblt_ctrl[0], BBCTRL0_DSTLIN_BIT))
|
||||
bitblt_solid_fill<true>();
|
||||
else
|
||||
bitblt_solid_fill<false>();
|
||||
return;
|
||||
}
|
||||
default:
|
||||
LOGMASKED(LOG_BITBLT_OP, "bitblt: Unsupported command type: %02x\n", m_bitblt_op);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t sed1356_device::bitblt_ctrl0_r(offs_t offset)
|
||||
{
|
||||
LOGMASKED(LOG_BITBLT_RD, "%s: bitblt_ctrl0_r: %02x\n", machine().describe_context(), m_bitblt_ctrl[0]);
|
||||
@ -1098,6 +1180,10 @@ void sed1356_device::bitblt_ctrl0_w(offs_t offset, uint8_t data)
|
||||
LOGMASKED(LOG_BITBLT_WR, "%s: bitblt_ctrl0_w = %02x\n", machine().describe_context(), data);
|
||||
m_bitblt_ctrl[0] &= ~BBCTRL0_WR_MASK;
|
||||
m_bitblt_ctrl[0] |= data & BBCTRL0_WR_MASK;
|
||||
if (BIT(data, BBCTRL0_ACTIVE_BIT))
|
||||
{
|
||||
bitblt_execute_command();
|
||||
}
|
||||
}
|
||||
|
||||
void sed1356_device::bitblt_ctrl1_w(offs_t offset, uint8_t data)
|
||||
|
@ -170,6 +170,8 @@ protected:
|
||||
void crt_cursor_color1_red_w(offs_t offset, uint8_t data);
|
||||
void crt_cursor_fifo_thresh_w(offs_t offset, uint8_t data);
|
||||
|
||||
template <bool Linear> void bitblt_solid_fill();
|
||||
void bitblt_execute_command();
|
||||
uint8_t bitblt_ctrl0_r(offs_t offset);
|
||||
uint8_t bitblt_ctrl1_r(offs_t offset);
|
||||
uint8_t bitblt_rop_code_r(offs_t offset);
|
||||
|
@ -4,29 +4,33 @@
|
||||
|
||||
HP Jornada PDA skeleton driver
|
||||
|
||||
Notes:
|
||||
- GPIO1: IRQ from SA-1111
|
||||
To boot:
|
||||
- Start MAME with the debugger enabled
|
||||
- Use the following breakpoint command: bp 13E2C,R3==3 && R1==10
|
||||
- Close the debugger and allow the machine to run
|
||||
- When the breakpoint is hit, use the following command: R3=0
|
||||
- Close the debugger, booting will proceed
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/arm7/arm7.h"
|
||||
#include "cpu/arm7/arm7core.h"
|
||||
#include "machine/m950x0.h"
|
||||
#include "machine/sa1110.h"
|
||||
#include "machine/sa1111.h"
|
||||
#include "sound/uda1344.h"
|
||||
#include "video/sed1356.h"
|
||||
#include "screen.h"
|
||||
#include "emupal.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#define LOG_MCU (1 << 1)
|
||||
#define LOG_ALL (LOG_MCU)
|
||||
|
||||
#define VERBOSE (LOG_ALL)
|
||||
#define VERBOSE (0)
|
||||
#include "logmacro.h"
|
||||
|
||||
#define SA1110_CLOCK 206000000
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
@ -39,26 +43,58 @@ public:
|
||||
, m_ram(*this, "ram")
|
||||
, m_sa_periphs(*this, "onboard")
|
||||
, m_companion(*this, "companion")
|
||||
, m_eeprom_data(*this, "eeprom")
|
||||
, m_epson(*this, "epson")
|
||||
, m_codec(*this, "codec")
|
||||
, m_kbd_port(*this, "KBD0")
|
||||
, m_nvram(*this, "nvram")
|
||||
, m_kbd_ports(*this, "KBD%u", 0U)
|
||||
, m_pen_x(*this, "PENX")
|
||||
, m_pen_y(*this, "PENY")
|
||||
, m_pen_button(*this, "PENZ")
|
||||
{ }
|
||||
|
||||
void jornada720(machine_config &config);
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER(key_changed);
|
||||
DECLARE_INPUT_CHANGED_MEMBER(pen_changed);
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
MCU_TXDUMMY = 0x11,
|
||||
MCU_TXDUMMY2 = 0x88
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
KEY_ON_OFF,
|
||||
KEY_S,
|
||||
KEY_K,
|
||||
KEY_1,
|
||||
KEY_2,
|
||||
KEY_3,
|
||||
KEY_4,
|
||||
KEY_9
|
||||
KEY_ON_OFF = 0x7f,
|
||||
KEY_S = 0x32,
|
||||
KEY_K = 0x38,
|
||||
KEY_1 = 0x11,
|
||||
KEY_2 = 0x12,
|
||||
KEY_3 = 0x13,
|
||||
KEY_4 = 0x14,
|
||||
KEY_9 = 0x19,
|
||||
KEY_TAB = 0x51,
|
||||
KEY_ENTER = 0x4c,
|
||||
KEY_A = 0x31,
|
||||
KEY_N = 0x46,
|
||||
KEY_L = 0x39,
|
||||
KEY_M = 0x47,
|
||||
KEY_P = 0x2a,
|
||||
KEY_C = 0x43,
|
||||
KEY_B = 0x45,
|
||||
KEY_ALT = 0x65,
|
||||
KEY_SPACE = 0x74,
|
||||
KEY_BACKSPACE = 0x2c,
|
||||
KEY_LSHIFT = 0x53,
|
||||
KEY_RSHIFT = 0x5c
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PEN_X,
|
||||
PEN_Y,
|
||||
PEN_BUTTON
|
||||
};
|
||||
|
||||
protected:
|
||||
@ -67,17 +103,23 @@ protected:
|
||||
virtual void machine_reset() override;
|
||||
virtual void device_reset_after_children() override;
|
||||
|
||||
static constexpr uint32_t SA1110_CLOCK = 206000000;
|
||||
|
||||
void main_map(address_map &map);
|
||||
|
||||
void mcu_assemble_touch_data();
|
||||
void mcu_byte_received(uint16_t data);
|
||||
void eeprom_cmd_received(uint16_t data);
|
||||
void eeprom_data_received(uint16_t data);
|
||||
void eeprom_select(int state);
|
||||
|
||||
enum mcu_state : int
|
||||
{
|
||||
MCU_IDLE,
|
||||
|
||||
MCU_KBD_SEND_COUNT,
|
||||
MCU_KBD_SEND_CODES
|
||||
MCU_KBD_SEND_CODES,
|
||||
|
||||
MCU_TOUCH_SEND_DATA
|
||||
};
|
||||
|
||||
// devices
|
||||
@ -85,22 +127,25 @@ protected:
|
||||
required_shared_ptr<uint32_t> m_ram;
|
||||
required_device<sa1110_periphs_device> m_sa_periphs;
|
||||
required_device<sa1111_device> m_companion;
|
||||
required_region_ptr<uint8_t> m_eeprom_data;
|
||||
required_device<sed1356_device> m_epson;
|
||||
required_device<uda1344_device> m_codec;
|
||||
required_device<m95020_device> m_nvram;
|
||||
|
||||
required_ioport m_kbd_port;
|
||||
required_ioport_array<3> m_kbd_ports;
|
||||
required_ioport m_pen_x;
|
||||
required_ioport m_pen_y;
|
||||
required_ioport m_pen_button;
|
||||
|
||||
// MCU-related members
|
||||
int m_mcu_state;
|
||||
uint8_t m_mcu_key_send_idx;
|
||||
uint8_t m_mcu_key_codes[2][8];
|
||||
uint8_t m_mcu_key_count[2];
|
||||
|
||||
// EEPROM-related members
|
||||
uint8_t m_eeprom_cmd;
|
||||
uint8_t m_eeprom_count;
|
||||
uint8_t m_eeprom_read_idx;
|
||||
uint8_t m_mcu_key_idx[2];
|
||||
uint8_t m_mcu_touch_send_idx;
|
||||
uint8_t m_mcu_touch_data[2][8];
|
||||
uint8_t m_mcu_touch_count[2];
|
||||
uint8_t m_mcu_touch_idx[2];
|
||||
};
|
||||
|
||||
void jornada_state::main_map(address_map &map)
|
||||
@ -110,6 +155,7 @@ void jornada_state::main_map(address_map &map)
|
||||
map(0x40000000, 0x40001fff).m(m_companion, FUNC(sa1111_device::map));
|
||||
map(0x48000000, 0x481fffff).m(m_epson, FUNC(sed1356_device::map));
|
||||
map(0x48200000, 0x4827ffff).m(m_epson, FUNC(sed1356_device::vram_map));
|
||||
map(0x80030000, 0x8003007b).rw(m_sa_periphs, FUNC(sa1110_periphs_device::icp_r), FUNC(sa1110_periphs_device::icp_w));
|
||||
map(0x80050000, 0x80050023).rw(m_sa_periphs, FUNC(sa1110_periphs_device::uart3_r), FUNC(sa1110_periphs_device::uart3_w));
|
||||
map(0x80060000, 0x8006001b).rw(m_sa_periphs, FUNC(sa1110_periphs_device::mcp_r), FUNC(sa1110_periphs_device::mcp_w));
|
||||
map(0x80070000, 0x80070077).rw(m_sa_periphs, FUNC(sa1110_periphs_device::ssp_r), FUNC(sa1110_periphs_device::ssp_w));
|
||||
@ -119,6 +165,8 @@ void jornada_state::main_map(address_map &map)
|
||||
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(0x90060000, 0x90060013).rw(m_sa_periphs, FUNC(sa1110_periphs_device::ppc_r), FUNC(sa1110_periphs_device::ppc_w));
|
||||
map(0xb0000000, 0xb00000bf).rw(m_sa_periphs, FUNC(sa1110_periphs_device::dma_r), FUNC(sa1110_periphs_device::dma_w));
|
||||
map(0xc0000000, 0xc1ffffff).ram().share("ram");
|
||||
map(0xe0000000, 0xe0003fff).noprw(); // Cache-Flush Region 0
|
||||
map(0xe0100000, 0xe01003ff).noprw(); // Cache-Flush Region 1
|
||||
@ -126,6 +174,23 @@ void jornada_state::main_map(address_map &map)
|
||||
|
||||
void jornada_state::device_reset_after_children()
|
||||
{
|
||||
m_sa_periphs->gpio_in<9>(1);
|
||||
}
|
||||
|
||||
void jornada_state::mcu_assemble_touch_data()
|
||||
{
|
||||
const uint16_t pen_x = m_pen_x->read();
|
||||
const uint16_t pen_y = m_pen_y->read();
|
||||
const uint8_t touch_recv_idx = 1 - m_mcu_touch_send_idx;
|
||||
m_mcu_touch_data[touch_recv_idx][0] = (uint8_t)pen_x;
|
||||
m_mcu_touch_data[touch_recv_idx][1] = (uint8_t)pen_x;
|
||||
m_mcu_touch_data[touch_recv_idx][2] = (uint8_t)pen_x;
|
||||
m_mcu_touch_data[touch_recv_idx][3] = (uint8_t)pen_y;
|
||||
m_mcu_touch_data[touch_recv_idx][4] = (uint8_t)pen_y;
|
||||
m_mcu_touch_data[touch_recv_idx][5] = (uint8_t)pen_y;
|
||||
m_mcu_touch_data[touch_recv_idx][6] = (uint8_t)((pen_x >> 8) * 0x15);
|
||||
m_mcu_touch_data[touch_recv_idx][7] = (uint8_t)((pen_y >> 8) * 0x15);
|
||||
m_mcu_touch_count[touch_recv_idx] = 8;
|
||||
}
|
||||
|
||||
void jornada_state::mcu_byte_received(uint16_t data)
|
||||
@ -133,7 +198,7 @@ void jornada_state::mcu_byte_received(uint16_t data)
|
||||
const uint8_t raw_value = (uint8_t)(data >> 8);
|
||||
const uint8_t value = bitswap<8>(raw_value, 0, 1, 2, 3, 4, 5, 6, 7);
|
||||
|
||||
uint8_t response = 0x11;
|
||||
uint8_t response = MCU_TXDUMMY;
|
||||
switch (m_mcu_state)
|
||||
{
|
||||
case MCU_IDLE:
|
||||
@ -144,6 +209,11 @@ void jornada_state::mcu_byte_received(uint16_t data)
|
||||
m_mcu_state = MCU_KBD_SEND_COUNT;
|
||||
m_mcu_key_send_idx = 1 - m_mcu_key_send_idx;
|
||||
break;
|
||||
case 0xa0:
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_IDLE: GetTouchSamples, entering TOUCH_SEND_DATA state\n");
|
||||
m_mcu_state = MCU_TOUCH_SEND_DATA;
|
||||
m_mcu_touch_send_idx = 1 - m_mcu_touch_send_idx;
|
||||
break;
|
||||
default:
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_IDLE: Unknown (%02x), ignoring and sending TxDummy response\n", value);
|
||||
break;
|
||||
@ -151,7 +221,7 @@ void jornada_state::mcu_byte_received(uint16_t data)
|
||||
break;
|
||||
|
||||
case MCU_KBD_SEND_COUNT:
|
||||
if (value == 0x11)
|
||||
if (value == MCU_TXDUMMY || value == MCU_TXDUMMY2)
|
||||
{
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_KBD_SEND_COUNT: TxDummy, entering KBD_SEND_CODES state\n");
|
||||
response = m_mcu_key_count[m_mcu_key_send_idx];
|
||||
@ -159,16 +229,42 @@ void jornada_state::mcu_byte_received(uint16_t data)
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_KBD_SEND_COUNT: Unknown (%02x), sending ErrorCode response and returning to IDLE state\n");
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_KBD_SEND_COUNT: Unknown (%02x), sending ErrorCode response and returning to IDLE state\n", value);
|
||||
response = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case MCU_TOUCH_SEND_DATA:
|
||||
if (value == MCU_TXDUMMY || value == MCU_TXDUMMY2)
|
||||
{
|
||||
m_mcu_touch_count[m_mcu_touch_send_idx]--;
|
||||
response = m_mcu_touch_data[m_mcu_touch_send_idx][m_mcu_touch_idx[m_mcu_touch_send_idx]];
|
||||
m_mcu_touch_idx[m_mcu_touch_send_idx]++;
|
||||
if (m_mcu_touch_count[m_mcu_touch_send_idx])
|
||||
{
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_TOUCH_SEND_DATA: TxDummy, sending touch data %02x with %d remaining\n", response, m_mcu_touch_count[m_mcu_touch_send_idx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_TOUCH_SEND_DATA: TxDummy, sending touch data %02x and returning to IDLE state\n", response);
|
||||
m_mcu_state = MCU_IDLE;
|
||||
m_mcu_touch_idx[m_mcu_touch_send_idx] = 0;
|
||||
//machine().debug_break();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_TOUCH_SEND_DATA: Unknown (%02x), sending ErrorCode response and returning to IDLE state\n", value);
|
||||
response = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case MCU_KBD_SEND_CODES:
|
||||
if (value == 0x11)
|
||||
if (value == MCU_TXDUMMY || value == MCU_TXDUMMY2)
|
||||
{
|
||||
m_mcu_key_count[m_mcu_key_send_idx]--;
|
||||
response = m_mcu_key_codes[m_mcu_key_send_idx][m_mcu_key_count[m_mcu_key_send_idx]];
|
||||
response = m_mcu_key_codes[m_mcu_key_send_idx][m_mcu_key_idx[m_mcu_key_send_idx]];
|
||||
m_mcu_key_idx[m_mcu_key_send_idx]++;
|
||||
if (m_mcu_key_count[m_mcu_key_send_idx])
|
||||
{
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_KBD_SEND_CODES: TxDummy, sending scan code %02x with %d remaining\n", response, m_mcu_key_count[m_mcu_key_send_idx]);
|
||||
@ -177,6 +273,7 @@ void jornada_state::mcu_byte_received(uint16_t data)
|
||||
{
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_KBD_SEND_CODES: TxDummy, sending scan code %02x and returning to IDLE state\n", response);
|
||||
m_mcu_state = MCU_IDLE;
|
||||
m_mcu_key_idx[m_mcu_key_send_idx] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -190,59 +287,20 @@ void jornada_state::mcu_byte_received(uint16_t data)
|
||||
m_sa_periphs->ssp_in((uint16_t)response);
|
||||
}
|
||||
|
||||
void jornada_state::eeprom_cmd_received(uint16_t data)
|
||||
void jornada_state::eeprom_select(int state)
|
||||
{
|
||||
bool reset_state = true;
|
||||
uint8_t response = 0;
|
||||
|
||||
if (m_eeprom_cmd == 0)
|
||||
{
|
||||
m_eeprom_cmd = (uint8_t)data;
|
||||
if (m_eeprom_cmd == 3)
|
||||
reset_state = false;
|
||||
}
|
||||
else if (m_eeprom_count == 0)
|
||||
{
|
||||
if (m_eeprom_cmd == 3)
|
||||
{
|
||||
m_eeprom_count = (uint8_t)data;
|
||||
m_eeprom_read_idx = 0;
|
||||
reset_state = false;
|
||||
}
|
||||
}
|
||||
else if (m_eeprom_read_idx < m_eeprom_count)
|
||||
{
|
||||
response = m_eeprom_data[m_eeprom_read_idx];
|
||||
m_eeprom_read_idx++;
|
||||
if (m_eeprom_read_idx < m_eeprom_count)
|
||||
reset_state = false;
|
||||
}
|
||||
m_nvram->select_w(!state);
|
||||
}
|
||||
|
||||
void jornada_state::eeprom_data_received(uint16_t data)
|
||||
{
|
||||
const uint8_t response = m_nvram->access((uint8_t)data);
|
||||
m_companion->ssp_in((uint16_t)response);
|
||||
|
||||
if (reset_state)
|
||||
{
|
||||
m_eeprom_cmd = 0;
|
||||
m_eeprom_count = 0;
|
||||
m_eeprom_read_idx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(jornada_state::key_changed)
|
||||
{
|
||||
uint8_t scan_code = 0;
|
||||
switch (param)
|
||||
{
|
||||
case KEY_ON_OFF: scan_code = 0x7f; break;
|
||||
case KEY_S: scan_code = 0x32; break;
|
||||
case KEY_K: scan_code = 0x38; break;
|
||||
case KEY_1: scan_code = 0x11; break;
|
||||
case KEY_2: scan_code = 0x12; break;
|
||||
case KEY_3: scan_code = 0x13; break;
|
||||
case KEY_4: scan_code = 0x14; break;
|
||||
case KEY_9: scan_code = 0x19; break;
|
||||
default: return;
|
||||
}
|
||||
uint8_t scan_code = (uint8_t)param;
|
||||
|
||||
m_sa_periphs->gpio_in<0>(1);
|
||||
m_sa_periphs->gpio_in<0>(0);
|
||||
@ -255,16 +313,72 @@ INPUT_CHANGED_MEMBER(jornada_state::key_changed)
|
||||
}
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(jornada_state::pen_changed)
|
||||
{
|
||||
switch (param)
|
||||
{
|
||||
case PEN_X:
|
||||
case PEN_Y:
|
||||
if (m_pen_button->read() && m_mcu_state == MCU_IDLE)
|
||||
{
|
||||
mcu_assemble_touch_data();
|
||||
m_sa_periphs->gpio_in<9>(1);
|
||||
m_sa_periphs->gpio_in<9>(0);
|
||||
}
|
||||
break;
|
||||
case PEN_BUTTON:
|
||||
if (newval)
|
||||
{
|
||||
m_sa_periphs->gpio_in<9>(0);
|
||||
mcu_assemble_touch_data();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sa_periphs->gpio_in<9>(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( jornada720 )
|
||||
PORT_START("KBD0")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("On/Off") PORT_CODE(KEYCODE_HOME) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_ON_OFF)
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_S)
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_K)
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_1)
|
||||
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_2)
|
||||
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("3") PORT_CODE(KEYCODE_1) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_3)
|
||||
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("4") PORT_CODE(KEYCODE_2) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_4)
|
||||
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("9") PORT_CODE(KEYCODE_2) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_9)
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("On/Off") PORT_CODE(KEYCODE_HOME) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_ON_OFF)
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_S)
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_K)
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_1)
|
||||
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_2)
|
||||
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_1) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_3)
|
||||
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_2) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_4)
|
||||
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_2) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_9)
|
||||
|
||||
PORT_START("KBD1")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_TAB)
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_ENTER)
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_A)
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_N)
|
||||
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_L)
|
||||
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_M)
|
||||
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_P)
|
||||
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_C)
|
||||
|
||||
PORT_START("KBD2")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_B)
|
||||
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Alt") PORT_CODE(KEYCODE_LALT) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_ALT)
|
||||
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_SPACE)
|
||||
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_BACKSPACE)
|
||||
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Left Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_LSHIFT)
|
||||
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Right Shift") PORT_CODE(KEYCODE_RSHIFT) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_RSHIFT)
|
||||
PORT_BIT(0xc0, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
|
||||
PORT_START("PENX")
|
||||
PORT_BIT(0x3ff, 590, IPT_LIGHTGUN_X) PORT_NAME("Pen X") PORT_MINMAX(270, 910) PORT_SENSITIVITY(50) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, pen_changed, jornada_state::PEN_X)
|
||||
|
||||
PORT_START("PENY")
|
||||
PORT_BIT(0x3ff, 500, IPT_LIGHTGUN_Y) PORT_NAME("Pen Y") PORT_MINMAX(180, 820) PORT_SENSITIVITY(50) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, pen_changed, jornada_state::PEN_Y)
|
||||
|
||||
PORT_START("PENZ")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Pen Touch") PORT_CODE(MOUSECODE_BUTTON1) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, pen_changed, jornada_state::PEN_BUTTON)
|
||||
PORT_BIT(0xfe, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
INPUT_PORTS_END
|
||||
|
||||
void jornada_state::machine_start()
|
||||
@ -273,23 +387,28 @@ void jornada_state::machine_start()
|
||||
save_item(NAME(m_mcu_key_send_idx));
|
||||
save_item(NAME(m_mcu_key_codes));
|
||||
save_item(NAME(m_mcu_key_count));
|
||||
|
||||
save_item(NAME(m_eeprom_cmd));
|
||||
save_item(NAME(m_eeprom_count));
|
||||
save_item(NAME(m_eeprom_read_idx));
|
||||
save_item(NAME(m_mcu_key_idx));
|
||||
save_item(NAME(m_mcu_touch_send_idx));
|
||||
save_item(NAME(m_mcu_touch_data));
|
||||
save_item(NAME(m_mcu_touch_count));
|
||||
save_item(NAME(m_mcu_touch_idx));
|
||||
}
|
||||
|
||||
void jornada_state::machine_reset()
|
||||
{
|
||||
m_mcu_state = MCU_IDLE;
|
||||
|
||||
m_mcu_key_send_idx = 0;
|
||||
memset(m_mcu_key_codes[0], 0, 8);
|
||||
memset(m_mcu_key_codes[1], 0, 8);
|
||||
memset(m_mcu_key_count, 0, 2);
|
||||
memset(m_mcu_key_idx, 0, 2);
|
||||
|
||||
m_eeprom_cmd = 0;
|
||||
m_eeprom_count = 0;
|
||||
m_eeprom_read_idx = 0;
|
||||
m_mcu_touch_send_idx = 0;
|
||||
memset(m_mcu_touch_data[0], 0, 8);
|
||||
memset(m_mcu_touch_data[1], 0, 8);
|
||||
memset(m_mcu_touch_count, 0, 2);
|
||||
memset(m_mcu_touch_idx, 0, 2);
|
||||
}
|
||||
|
||||
void jornada_state::jornada720(machine_config &config)
|
||||
@ -300,13 +419,24 @@ void jornada_state::jornada720(machine_config &config)
|
||||
SA1110_PERIPHERALS(config, m_sa_periphs, SA1110_CLOCK, m_maincpu);
|
||||
m_sa_periphs->ssp_out().set(FUNC(jornada_state::mcu_byte_received));
|
||||
|
||||
SA1111(config, m_companion);
|
||||
m_companion->ssp_out().set(FUNC(jornada_state::eeprom_cmd_received));
|
||||
SA1111(config, m_companion, 3.6864_MHz_XTAL, m_maincpu);
|
||||
m_companion->set_audio_codec_tag(m_codec);
|
||||
m_companion->pb_out<0>().set(FUNC(jornada_state::eeprom_select));
|
||||
m_companion->ssp_out().set(FUNC(jornada_state::eeprom_data_received));
|
||||
m_companion->l3_addr_out().set(m_codec, FUNC(uda1344_device::l3_addr_w));
|
||||
m_companion->l3_data_out().set(m_codec, FUNC(uda1344_device::l3_data_w));
|
||||
m_companion->i2s_out().set(m_codec, FUNC(uda1344_device::i2s_input_w));
|
||||
m_companion->irq_out().set(m_sa_periphs, FUNC(sa1110_periphs_device::gpio_in<1>));
|
||||
|
||||
M95020(config, m_nvram);
|
||||
|
||||
UDA1344(config, m_codec);
|
||||
m_codec->l3_ack_out().set(m_companion, FUNC(sa1111_device::l3wd_in));
|
||||
m_codec->add_route(0, "lspeaker", 0.5);
|
||||
m_codec->add_route(1, "rspeaker", 0.5);
|
||||
|
||||
SPEAKER(config, "lspeaker").front_left();
|
||||
SPEAKER(config, "rspeaker").front_right();
|
||||
|
||||
SED1356(config, m_epson);
|
||||
m_epson->set_screen("screen");
|
||||
@ -328,8 +458,8 @@ ROM_START( jorn720 )
|
||||
ROM_REGION32_LE( 0x2000000, "firmware", ROMREGION_ERASE00 )
|
||||
ROM_LOAD( "jornada720.bin", 0x0000000, 0x2000000, CRC(5fcd433a) SHA1(f05f7b377b582a7355bf119d74435f0ee6104cca) )
|
||||
|
||||
ROM_REGION( 0x80, "eeprom", ROMREGION_ERASE00 )
|
||||
ROM_LOAD( "jorn720_eeprom.bin", 0x00, 0x80, CRC(54ffaaff) SHA1(5b8296782b6dc1c60b80169c071fb157d0681567) BAD_DUMP )
|
||||
ROM_REGION( 0x100, "nvram", ROMREGION_ERASE00 )
|
||||
ROM_LOAD( "jorn720_eeprom.bin", 0x000, 0x100, CRC(9bc1d53a) SHA1(793d6ff355e2e9b3e75574ff80edfa5af2aaeee6) BAD_DUMP )
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
Loading…
Reference in New Issue
Block a user