summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author MooglyGuy <therealmogminer@gmail.com>2020-01-04 14:02:03 +0100
committer MooglyGuy <therealmogminer@gmail.com>2020-01-04 14:02:35 +0100
commitae494b6d0f45eaf28c71dc8335d9c08c2f5f6483 (patch)
tree4951a636c2312e83ef359aeb0aa4910b464d4b4a
parent88909dc0d01f34bacbbbc3da6a9df705123b2f42 (diff)
-psion5: Renamed to psion5mx, added ETNA device, many fixes, nw
-rw-r--r--src/mame/drivers/psion5.cpp744
-rw-r--r--src/mame/includes/psion5.h194
-rw-r--r--src/mame/machine/etna.cpp257
-rw-r--r--src/mame/machine/etna.h73
4 files changed, 929 insertions, 339 deletions
diff --git a/src/mame/drivers/psion5.cpp b/src/mame/drivers/psion5.cpp
index ad3155128e3..6bec3732199 100644
--- a/src/mame/drivers/psion5.cpp
+++ b/src/mame/drivers/psion5.cpp
@@ -14,234 +14,149 @@
****************************************************************************/
-
-#include "emu.h"
-#include "cpu/arm7/arm7.h"
-#include "cpu/arm7/arm7core.h"
-
-#include "screen.h"
-
-class psion5_state : public driver_device
+#include "includes/psion5.h"
+
+#define LOG_UNKNOWNS (1 << 0)
+#define LOG_IRQ (1 << 1)
+#define LOG_DISPLAY (1 << 2)
+#define LOG_DRAM_READS (1 << 3)
+#define LOG_LCD_READS (1 << 4)
+#define LOG_POWER_READS (1 << 5)
+#define LOG_EOI_READS (1 << 6)
+#define LOG_INT_READS (1 << 7)
+#define LOG_CODEC_READS (1 << 8)
+#define LOG_SSP_READS (1 << 9)
+#define LOG_TIMER_READS (1 << 10)
+#define LOG_BUZZER_READS (1 << 11)
+#define LOG_RTC_READS (1 << 12)
+#define LOG_GPIO_READS (1 << 13)
+#define LOG_KBD_READS (1 << 14)
+#define LOG_DRAM_WRITES (1 << 15)
+#define LOG_LCD_WRITES (1 << 16)
+#define LOG_POWER_WRITES (1 << 17)
+#define LOG_EOI_WRITES (1 << 18)
+#define LOG_INT_WRITES (1 << 19)
+#define LOG_CODEC_WRITES (1 << 20)
+#define LOG_SSP_WRITES (1 << 21)
+#define LOG_TIMER_WRITES (1 << 22)
+#define LOG_BUZZER_WRITES (1 << 23)
+#define LOG_RTC_WRITES (1 << 24)
+#define LOG_GPIO_WRITES (1 << 25)
+#define LOG_PIN_WRITES (1 << 26)
+#define LOG_KBD_WRITES (1 << 27)
+
+#define LOG_WRITES (LOG_DRAM_WRITES | LOG_LCD_WRITES | LOG_POWER_WRITES | LOG_EOI_WRITES | LOG_INT_WRITES | LOG_CODEC_WRITES \
+ | LOG_SSP_WRITES | LOG_TIMER_WRITES | LOG_BUZZER_WRITES | LOG_RTC_WRITES | LOG_GPIO_WRITES | LOG_PIN_WRITES | LOG_KBD_WRITES)
+#define LOG_READS (LOG_DRAM_READS | LOG_LCD_READS | LOG_POWER_READS | LOG_EOI_READS | LOG_INT_READS | LOG_CODEC_READS \
+ | LOG_SSP_READS | LOG_TIMER_READS | LOG_BUZZER_READS | LOG_RTC_READS | LOG_GPIO_READS | LOG_KBD_READS)
+#define LOG_ALL_IRQ (LOG_IRQ | LOG_EOI_WRITES | LOG_INT_WRITES | LOG_EOI_READS | LOG_INT_READS)
+#define LOG_ALL (LOG_UNKNOWNS | LOG_IRQ | LOG_DISPLAY | LOG_WRITES | LOG_READS)
+
+#define VERBOSE (LOG_ALL)
+#include "logmacro.h"
+
+void psion5mx_state::machine_start()
{
-public:
- psion5_state(const machine_config &mconfig, device_type type, const char *tag)
- : driver_device(mconfig, type, tag)
- , m_maincpu(*this, "maincpu")
- {
- }
-
- void psion5mx(machine_config &config);
-
-protected:
- virtual void machine_start() override;
- virtual void machine_reset() override;
+ m_timers[0] = timer_alloc(TID_TIMER1);
+ m_timers[1] = timer_alloc(TID_TIMER2);
+ save_item(NAME(m_timer_reload));
+ save_item(NAME(m_timer_value));
+ save_item(NAME(m_timer_ctrl));
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+ save_item(NAME(m_pending_ints));
+ save_item(NAME(m_int_mask));
-private:
+ save_item(NAME(m_lcd_display_base_addr));
- DECLARE_READ32_MEMBER(periphs_r);
- DECLARE_WRITE32_MEMBER(periphs_w);
+ save_item(NAME(m_rtc));
+ save_item(NAME(m_pwrsr));
+ save_item(NAME(m_last_ssi_request));
+ save_item(NAME(m_ssi_read_counter));
- void set_timer_reload(int timer, uint32_t value);
- void set_timer_ctrl(int timer, uint32_t value);
- void check_timer(int timer);
- void check_interrupts();
+ save_item(NAME(m_ports));
- static constexpr device_timer_id TID_TIMER1 = 0;
- static constexpr device_timer_id TID_TIMER2 = 1;
+ m_periodic = timer_alloc(TID_PERIODIC);
- enum
- {
- REG_MEMCFG1 = 0x0000,
- REG_MEMCFG2 = 0x0004,
-
- REG_DRAMCFG = 0x0100,
-
- REG_LCDCTL = 0x0200,
- REG_LCDST = 0x0204,
- REG_LCD_DBAR1 = 0x0210,
- REG_LCDT0 = 0x0220,
- REG_LCDT1 = 0x0224,
- REG_LCDT2 = 0x0228,
-
- REG_PWRSR = 0x0400,
- REG_PWRCNT = 0x0404,
- REG_HALT = 0x0408,
- REG_STBY = 0x040c,
- REG_BLEOI = 0x0410,
- REG_MCEOI = 0x0414,
- REG_TEOI = 0x0418,
- REG_STFCLR = 0x041c,
- REG_E2EOI = 0x0420,
-
- REG_INTSR = 0x0500,
- REG_INTRSR = 0x0504,
- REG_INTENS = 0x0508,
- REG_INTENC = 0x050c,
- REG_INTTEST1 = 0x0514,
- REG_INTTEST2 = 0x0518,
-
- REG_PUMPCON = 0x0900,
-
- REG_CODR = 0x0a00,
- REG_CONFG = 0x0a04,
- REG_COLFG = 0x0a08,
- REG_COEOI = 0x0a0c,
- REG_COTEST = 0x0a10,
-
- REG_SSCR0 = 0x0b00,
- REG_SSCR1 = 0x0b04,
- REG_SSDR = 0x0b0c,
- REG_SSSR = 0x0b14,
-
- REG_TC1LOAD = 0x0c00,
- REG_TC1VAL = 0x0c04,
- REG_TC1CTRL = 0x0c08,
- REG_TC1EOI = 0x0c0c,
- REG_TC2LOAD = 0x0c20,
- REG_TC2VAL = 0x0c24,
- REG_TC2CTRL = 0x0c28,
- REG_TC2EOI = 0x0c2c,
-
- REG_BZCONT = 0x0c40,
-
- REG_RTCDRL = 0x0d00,
- REG_RTCDRU = 0x0d04,
- REG_RTCMRL = 0x0d08,
- REG_RTCMRU = 0x0d0c,
- REG_RTCEOI = 0x0d10,
-
- REG_PADR = 0x0e00,
- REG_PBDR = 0x0e04,
- REG_PCDR = 0x0e08,
- REG_PDDR = 0x0e0c,
- REG_PADDR = 0x0e10,
- REG_PBDDR = 0x0e14,
- REG_PCDDR = 0x0e18,
- REG_PDDDR = 0x0e1c,
- REG_PEDR = 0x0e20,
- REG_PEDDR = 0x0e24,
-
- REG_KSCAN = 0x0e28,
- REG_LCDMUX = 0x0e2c
- };
-
- enum
- {
- IRQ_EXTFIQ = 0, // FiqExternal
- IRQ_BLINT = 1, // FiqBatLow
- IRQ_WEINT = 2, // FiqWatchDog
- IRQ_MCINT = 3, // FiqMediaChg
- IRQ_CSINT = 4, // IrqCodec
- IRQ_EINT1 = 5, // IrqExt1
- IRQ_EINT2 = 6, // IrqExt2
- IRQ_EINT3 = 7, // IrqExt3
- IRQ_TC1OI = 8, // IrqTimer1
- IRQ_TC2OI = 9, // IrqTimer2
- IRQ_RTCMI = 10, // IrqRtcMatch
- IRQ_TINT = 11, // IrqTick
- IRQ_UART1 = 12, // IrqUart1
- IRQ_UART2 = 13, // IrqUart2
- IRQ_LCDINT = 14, // IrqLcd
- IRQ_SSEOTI = 15, // IrqSpi
- IRQ_FIQ_MASK = 0x000f,
- IRQ_IRQ_MASK = 0xfff0
- };
-
- void main_map(address_map &map);
-
- uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
-
- required_device<arm710t_cpu_device> m_maincpu;
- emu_timer *m_timers[2];
- uint32_t m_timer_reload[2];
- uint32_t m_timer_ctrl[2];
- uint32_t m_pending_ints;
- uint32_t m_int_mask;
-};
-
-void psion5_state::machine_start()
-{
- m_timers[0] = timer_alloc(TID_TIMER1);
- m_timers[1] = timer_alloc(TID_TIMER2);
- save_item(NAME(m_timer_reload[0]));
- save_item(NAME(m_timer_reload[1]));
- save_item(NAME(m_timer_ctrl[0]));
- save_item(NAME(m_timer_ctrl[1]));
- save_item(NAME(m_pending_ints));
- save_item(NAME(m_int_mask));
+ m_rtc_ticker = timer_alloc(TID_RTC_TICKER);
}
-void psion5_state::machine_reset()
+void psion5mx_state::machine_reset()
{
m_timers[0]->adjust(attotime::never);
m_timers[1]->adjust(attotime::never);
m_timer_reload[0] = m_timer_reload[1] = 0;
m_timer_ctrl[0] = m_timer_ctrl[1] = 0;
+
m_pending_ints = 0;
m_int_mask = 0;
-}
-void psion5_state::check_interrupts()
-{
- m_maincpu->set_input_line(ARM7_FIRQ_LINE, m_pending_ints & m_int_mask & IRQ_FIQ_MASK);
- m_maincpu->set_input_line(ARM7_IRQ_LINE, m_pending_ints & m_int_mask & IRQ_IRQ_MASK);
+ m_lcd_display_base_addr = 0;
+
+ m_rtc = 0;
+ m_pwrsr = (1 << 10) | (1 << 13);
+ m_last_ssi_request = 0;
+ m_ssi_read_counter = 0;
+
+ memset(m_ports, 0, ARRAY_LENGTH(m_ports));
+
+ m_periodic->adjust(attotime::from_hz(64), 0, attotime::from_hz(64));
+
+ m_rtc_ticker->adjust(attotime::from_hz(64), 0, attotime::from_hz(64));
}
-void psion5_state::check_timer(int timer)
+void psion5mx_state::check_interrupts()
{
- logerror("Checking Timer %d\n", timer + 1);
- if (BIT(m_timer_ctrl[timer], 7))
- {
- logerror("Bit 7 is set, in %d * %08x\n", BIT(m_timer_ctrl[timer], 3) ? 1 : m_timer_reload[timer], BIT(m_timer_ctrl[timer], 3) ? 512000 : 36000000);
- attotime interval = BIT(m_timer_ctrl[timer], 3) ? attotime::from_ticks(1, 512000) : attotime::from_ticks(m_timer_reload[timer], 36000000);
- if (BIT(m_timer_ctrl[timer], 6))
- {
- logerror("Adjusting periodic\n");
- m_timers[timer]->adjust(interval, 0, interval);
- }
- else
- {
- logerror("Adjusting non-periodic\n");
- m_timers[timer]->adjust(interval, 0);
- }
- }
- else
- {
- logerror("Cancelling\n");
- m_timers[timer]->adjust(attotime::never);
- }
+ LOGMASKED(LOG_IRQ, "Pending FIQs is %08x & %08x & %08x\n", m_pending_ints, m_int_mask, IRQ_FIQ_MASK);
+ LOGMASKED(LOG_IRQ, "Pending IRQs is %08x & %08x & %08x\n", m_pending_ints, m_int_mask, IRQ_IRQ_MASK);
+ m_maincpu->set_input_line(ARM7_FIRQ_LINE, m_pending_ints & m_int_mask & IRQ_FIQ_MASK ? ASSERT_LINE : CLEAR_LINE);
+ m_maincpu->set_input_line(ARM7_IRQ_LINE, m_pending_ints & m_int_mask & IRQ_IRQ_MASK ? ASSERT_LINE : CLEAR_LINE);
}
-void psion5_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+void psion5mx_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
- if (id == TID_TIMER1)
+ switch (id)
{
- logerror("Triggering 1\n");
- m_pending_ints |= (1 << IRQ_TC1OI);
- }
- else if (id == TID_TIMER2)
- {
- logerror("Triggering 2\n");
- m_pending_ints |= (1 << IRQ_TC2OI);
+ case TID_TIMER1:
+ update_timer(0);
+ break;
+ case TID_TIMER2:
+ update_timer(1);
+ break;
+ case TID_PERIODIC:
+ LOGMASKED(LOG_IRQ, "Flagging periodic IRQ\n");
+ m_pending_ints |= (1 << IRQ_TINT);
+ check_interrupts();
+ break;
+ case TID_RTC_TICKER:
+ if ((m_pwrsr & 0x3f) == 0x3f)
+ {
+ m_rtc++;
+ m_pwrsr &= ~0x3f;
+ }
+ else
+ {
+ m_pwrsr++;
+ }
+ break;
}
- check_interrupts();
}
-void psion5_state::set_timer_reload(int timer, uint32_t value)
+void psion5mx_state::update_timer(int timer)
{
- const uint32_t old = m_timer_reload[timer];
- m_timer_reload[timer] = value;
- logerror("%s: Timer %d reload = %08x\n", machine().describe_context(), timer + 1, value);
- if (old != value)
+ m_timer_value[timer]--;
+ if (m_timer_value[timer] == 0)
{
- m_timer_reload[timer] = value;
- check_timer(timer);
+ LOGMASKED(LOG_IRQ, "Flagging Timer %d IRQ\n", timer + 1);
+ m_pending_ints |= (1 << (IRQ_TC1OI + timer));
+ check_interrupts();
+ if (BIT(m_timer_ctrl[timer], 6))
+ {
+ m_timer_value[timer] = m_timer_reload[timer];
+ }
}
}
-void psion5_state::set_timer_ctrl(int timer, uint32_t value)
+void psion5mx_state::set_timer_ctrl(int timer, uint32_t value)
{
const uint32_t old = m_timer_ctrl[timer];
const uint32_t changed = old ^ value;
@@ -249,474 +164,625 @@ void psion5_state::set_timer_ctrl(int timer, uint32_t value)
if (changed != 0)
{
attotime interval = BIT(m_timer_ctrl[timer], 3) ? attotime::from_ticks(1, 512000) : attotime::from_ticks(m_timer_reload[timer], 36000000);
- if (BIT(changed, 6))
+ if (BIT(old, 7) && BIT(value, 7))
{
- logerror("Timer %d, adjusting to an interval\n", timer + 1);
m_timers[timer]->adjust(m_timers[timer]->remaining(), 0, interval);
}
- if (BIT(changed, 7))
+ else if (BIT(value, 7))
{
- logerror("Timer %d, just checking timer\n", timer + 1);
- check_timer(timer);
+ m_timers[timer]->adjust(interval, 0, interval);
+ }
+ else
+ {
+ m_timers[timer]->adjust(attotime::never);
}
}
}
-READ32_MEMBER(psion5_state::periphs_r)
+READ32_MEMBER(psion5mx_state::periphs_r)
{
const uint32_t reg = offset << 2;
uint32_t data = 0;
switch (reg)
{
case REG_MEMCFG1:
- logerror("%s: peripheral read, MEMCFG1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_DRAM_READS, "%s: peripheral read, MEMCFG1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_MEMCFG2:
- logerror("%s: peripheral read, MEMCFG2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_DRAM_READS, "%s: peripheral read, MEMCFG2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_DRAMCFG:
- logerror("%s: peripheral read, DRAMCFG = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_DRAM_READS, "%s: peripheral read, DRAMCFG = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_LCDCTL:
- logerror("%s: peripheral read, LCDCTL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_LCD_READS, "%s: peripheral read, LCDCTL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_LCDST:
- logerror("%s: peripheral read, LCDST = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_LCD_READS, "%s: peripheral read, LCDST = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_LCD_DBAR1:
- logerror("%s: peripheral read, LCD_DBAR1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ data = m_lcd_display_base_addr;
+ LOGMASKED(LOG_LCD_READS, "%s: peripheral read, LCD_DBAR1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_LCDT0:
- logerror("%s: peripheral read, LCDT0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_LCD_READS, "%s: peripheral read, LCDT0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_LCDT1:
- logerror("%s: peripheral read, LCDT1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_LCD_READS, "%s: peripheral read, LCDT1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_LCDT2:
- logerror("%s: peripheral read, LCDT2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_LCD_READS, "%s: peripheral read, LCDT2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PWRSR:
- logerror("%s: peripheral read, PWRSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ data = m_pwrsr;
+ LOGMASKED(LOG_POWER_READS, "%s: peripheral read, PWRSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PWRCNT:
- logerror("%s: peripheral read, PWRCNT = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_POWER_READS, "%s: peripheral read, PWRCNT = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_HALT:
- logerror("%s: peripheral read, HALT = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_POWER_READS, "%s: peripheral read, HALT = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_STBY:
- logerror("%s: peripheral read, STBY = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_POWER_READS, "%s: peripheral read, STBY = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_BLEOI:
- logerror("%s: peripheral read, BLEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_EOI_READS, "%s: peripheral read, BLEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_MCEOI:
- logerror("%s: peripheral read, MCEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_EOI_READS, "%s: peripheral read, MCEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_TEOI:
- logerror("%s: peripheral read, TEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_EOI_READS, "%s: peripheral read, TEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_STFCLR:
- logerror("%s: peripheral read, STFCLR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_POWER_READS, "%s: peripheral read, STFCLR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_E2EOI:
- logerror("%s: peripheral read, E2EOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_EOI_READS, "%s: peripheral read, E2EOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_INTSR:
- data = m_pending_ints;
- logerror("%s: peripheral read, INTSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ data = m_pending_ints & m_int_mask;
+ LOGMASKED(LOG_INT_READS, "%s: peripheral read, INTSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_INTRSR:
data = m_pending_ints;
- logerror("%s: peripheral read, INTRSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INT_READS, "%s: peripheral read, INTRSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_INTENS:
data = m_int_mask;
- logerror("%s: peripheral read, INTENS = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INT_READS, "%s: peripheral read, INTENS = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_INTENC:
- logerror("%s: peripheral read, INTENC = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INT_READS, "%s: peripheral read, INTENC = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_INTTEST1:
- logerror("%s: peripheral read, INTTEST1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INT_READS, "%s: peripheral read, INTTEST1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_INTTEST2:
- logerror("%s: peripheral read, INTTEST2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INT_READS, "%s: peripheral read, INTTEST2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PUMPCON:
- logerror("%s: peripheral read, PUMPCON = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_POWER_READS, "%s: peripheral read, PUMPCON = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_CODR:
- logerror("%s: peripheral read, CODR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_CODEC_READS, "%s: peripheral read, CODR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_CONFG:
- logerror("%s: peripheral read, CONFG = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_CODEC_READS, "%s: peripheral read, CONFG = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_COLFG:
- logerror("%s: peripheral read, COLFG = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_CODEC_READS, "%s: peripheral read, COLFG = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_COEOI:
- logerror("%s: peripheral read, COEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_CODEC_READS | LOG_EOI_READS, "%s: peripheral read, COEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_COTEST:
- logerror("%s: peripheral read, COTEST = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_CODEC_READS, "%s: peripheral read, COTEST = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_SSCR0:
- logerror("%s: peripheral read, SSCR0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_SSP_READS, "%s: peripheral read, SSCR0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_SSCR1:
- logerror("%s: peripheral read, SSCR1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_SSP_READS, "%s: peripheral read, SSCR1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_SSDR:
- logerror("%s: peripheral read, SSDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ {
+ // TODO: Proper SSP support
+ uint16_t value = 0;
+ switch (m_last_ssi_request)
+ {
+ case 0xd0d3: // Touch X
+ value = 50;
+ break;
+ case 0x9093: // Touch Y
+ value = 3834;
+ break;
+ case 0xa4a4: // Main Battery
+ case 0xe4e4: // Backup Battery
+ value = 3100;
+ break;
+ }
+
+ if (m_ssi_read_counter == 4) data = (value >> 5) & 0x7f;
+ if (m_ssi_read_counter == 5) data = (value << 3) & 0xf8;
+ m_ssi_read_counter++;
+ if (m_ssi_read_counter == 6) m_ssi_read_counter = 0;
+
+ // We should be clearing SSEOTI here, possibly,
+ // but for now we just leave it on to simplify things
+ LOGMASKED(LOG_SSP_READS, "%s: peripheral read, SSDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
+ }
case REG_SSSR:
- logerror("%s: peripheral read, SSSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_SSP_READS, "%s: peripheral read, SSSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_TC1LOAD:
data = m_timer_reload[0];
- logerror("%s: peripheral read, TC1LOAD = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_TIMER_READS, "%s: peripheral read, TC1LOAD = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_TC1VAL:
- logerror("%s: peripheral read, TC1VAL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ data = m_timer_value[0];
+ LOGMASKED(LOG_TIMER_READS, "%s: peripheral read, TC1VAL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_TC1CTRL:
data = m_timer_ctrl[0];
- logerror("%s: peripheral read, TC1CTRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_TIMER_READS, "%s: peripheral read, TC1CTRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_TC1EOI:
- logerror("%s: peripheral read, TC1EOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_TIMER_READS | LOG_EOI_READS, "%s: peripheral read, TC1EOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_TC2LOAD:
data = m_timer_reload[1];
- logerror("%s: peripheral read, TC2LOAD = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_TIMER_READS, "%s: peripheral read, TC2LOAD = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_TC2VAL:
- logerror("%s: peripheral read, TC2VAL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ data = m_timer_value[1];
+ LOGMASKED(LOG_TIMER_READS, "%s: peripheral read, TC2VAL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_TC2CTRL:
data = m_timer_ctrl[1];
- logerror("%s: peripheral read, TC2CTRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_TIMER_READS, "%s: peripheral read, TC2CTRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_TC2EOI:
- logerror("%s: peripheral read, TC2EOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_EOI_READS, "%s: peripheral read, TC2EOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_BZCONT:
- logerror("%s: peripheral read, BZCONT = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_BUZZER_READS, "%s: peripheral read, BZCONT = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_RTCDRL:
- logerror("%s: peripheral read, RTCDRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ data = (uint16_t)m_rtc;
+ LOGMASKED(LOG_RTC_READS, "%s: peripheral read, RTCDRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_RTCDRU:
- logerror("%s: peripheral read, RTCDRU = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ data = m_rtc >> 16;
+ LOGMASKED(LOG_RTC_READS, "%s: peripheral read, RTCDRU = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_RTCMRL:
- logerror("%s: peripheral read, RTCMRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_RTC_READS, "%s: peripheral read, RTCMRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_RTCMRU:
- logerror("%s: peripheral read, RTCMRU = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_RTC_READS, "%s: peripheral read, RTCMRU = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_RTCEOI:
- logerror("%s: peripheral read, RTCEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_RTC_READS | LOG_EOI_READS, "%s: peripheral read, RTCEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PADR:
- logerror("%s: peripheral read, PADR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ data = read_keyboard();
+ LOGMASKED(LOG_GPIO_READS, "%s: peripheral read, PADR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PBDR:
- logerror("%s: peripheral read, PBDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ data = m_ports[PORTB];
+ LOGMASKED(LOG_GPIO_READS, "%s: peripheral read, PBDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PCDR:
- logerror("%s: peripheral read, PCDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ data = m_ports[PORTC];
+ LOGMASKED(LOG_GPIO_READS, "%s: peripheral read, PCDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PDDR:
- logerror("%s: peripheral read, PDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ data = m_ports[PORTD];
+ LOGMASKED(LOG_GPIO_READS, "%s: peripheral read, PDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PADDR:
- logerror("%s: peripheral read, PADDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_GPIO_READS, "%s: peripheral read, PADDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PBDDR:
- logerror("%s: peripheral read, PBDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_GPIO_READS, "%s: peripheral read, PBDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PCDDR:
- logerror("%s: peripheral read, PCDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_GPIO_READS, "%s: peripheral read, PCDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PDDDR:
- logerror("%s: peripheral read, PDDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_GPIO_READS, "%s: peripheral read, PDDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PEDR:
- logerror("%s: peripheral read, PEDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_GPIO_READS, "%s: peripheral read, PEDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PEDDR:
- logerror("%s: peripheral read, PEDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_GPIO_READS, "%s: peripheral read, PEDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_KSCAN:
- logerror("%s: peripheral read, KSCAN = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_KBD_READS, "%s: peripheral read, KSCAN = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_LCDMUX:
- logerror("%s: peripheral read, LCDMUX = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_LCD_READS, "%s: peripheral read, LCDMUX = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
default:
- logerror("%s: peripheral read, Unknown = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_UNKNOWNS, "%s: peripheral read, Unknown = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
}
return data;
}
-WRITE32_MEMBER(psion5_state::periphs_w)
+WRITE32_MEMBER(psion5mx_state::periphs_w)
{
const uint32_t reg = offset << 2;
switch (reg)
{
case REG_MEMCFG1:
- logerror("%s: peripheral write, MEMCFG1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_DRAM_WRITES, "%s: peripheral write, MEMCFG1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_MEMCFG2:
- logerror("%s: peripheral write, MEMCFG2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_DRAM_WRITES, "%s: peripheral write, MEMCFG2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_DRAMCFG:
- logerror("%s: peripheral write, DRAMCFG = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_DRAM_WRITES, "%s: peripheral write, DRAMCFG = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_LCDCTL:
- logerror("%s: peripheral write, LCDCTL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_LCD_WRITES, "%s: peripheral write, LCDCTL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_LCDST:
- logerror("%s: peripheral write, LCDST = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_LCD_WRITES, "%s: peripheral write, LCDST = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_LCD_DBAR1:
- logerror("%s: peripheral write, LCD_DBAR1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_LCD_WRITES, "%s: peripheral write, LCD_DBAR1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ COMBINE_DATA(&m_lcd_display_base_addr);
break;
case REG_LCDT0:
- logerror("%s: peripheral write, LCDT0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_LCD_WRITES, "%s: peripheral write, LCDT0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_LCDT1:
- logerror("%s: peripheral write, LCDT1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_LCD_WRITES, "%s: peripheral write, LCDT1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_LCDT2:
- logerror("%s: peripheral write, LCDT2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_LCD_WRITES, "%s: peripheral write, LCDT2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PWRSR:
- logerror("%s: peripheral write, PWRSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ COMBINE_DATA(&m_pwrsr);
+ LOGMASKED(LOG_POWER_WRITES, "%s: peripheral write, PWRSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PWRCNT:
- logerror("%s: peripheral write, PWRCNT = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_POWER_WRITES, "%s: peripheral write, PWRCNT = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_HALT:
- logerror("%s: peripheral write, HALT = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_POWER_WRITES, "%s: peripheral write, HALT = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_STBY:
- logerror("%s: peripheral write, STBY = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_POWER_WRITES, "%s: peripheral write, STBY = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_BLEOI:
- logerror("%s: peripheral write, BLEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_EOI_WRITES, "%s: peripheral write, BLEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_MCEOI:
- logerror("%s: peripheral write, MCEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_EOI_WRITES, "%s: peripheral write, MCEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_TEOI:
- logerror("%s: peripheral write, TEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_EOI_WRITES, "%s: peripheral write, TEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ m_pending_ints &= ~(1 << IRQ_TINT);
+ check_interrupts();
break;
case REG_STFCLR:
- logerror("%s: peripheral write, STFCLR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ m_pwrsr &= ~0x00003e00;
+ LOGMASKED(LOG_POWER_WRITES, "%s: peripheral write, STFCLR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_E2EOI:
- logerror("%s: peripheral write, E2EOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_EOI_WRITES, "%s: peripheral write, E2EOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_INTSR:
- logerror("%s: peripheral write, INTSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INT_WRITES, "%s: peripheral write, INTSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_INTRSR:
- logerror("%s: peripheral write, INTRSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INT_WRITES, "%s: peripheral write, INTRSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_INTENS:
m_int_mask |= data & mem_mask;
- logerror("%s: peripheral write, INTENS = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INT_WRITES, "%s: peripheral write, INTENS = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ check_interrupts();
break;
case REG_INTENC:
m_int_mask &= ~(data & mem_mask);
- logerror("%s: peripheral write, INTENC = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INT_WRITES, "%s: peripheral write, INTENC = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ check_interrupts();
break;
case REG_INTTEST1:
- logerror("%s: peripheral write, INTTEST1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INT_WRITES, "%s: peripheral write, INTTEST1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_INTTEST2:
- logerror("%s: peripheral write, INTTEST2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_INT_WRITES, "%s: peripheral write, INTTEST2 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PUMPCON:
- logerror("%s: peripheral write, PUMPCON = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_POWER_WRITES, "%s: peripheral write, PUMPCON = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_CODR:
- logerror("%s: peripheral write, CODR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_CODEC_WRITES, "%s: peripheral write, CODR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_CONFG:
- logerror("%s: peripheral write, CONFG = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_CODEC_WRITES, "%s: peripheral write, CONFG = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_COLFG:
- logerror("%s: peripheral write, COLFG = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_CODEC_WRITES, "%s: peripheral write, COLFG = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_COEOI:
- logerror("%s: peripheral write, COEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_CODEC_WRITES | LOG_EOI_WRITES, "%s: peripheral write, COEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_COTEST:
- logerror("%s: peripheral write, COTEST = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_CODEC_WRITES, "%s: peripheral write, COTEST = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_SSCR0:
- logerror("%s: peripheral write, SSCR0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_SSP_WRITES, "%s: peripheral write, SSCR0 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_SSCR1:
- logerror("%s: peripheral write, SSCR1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_SSP_WRITES, "%s: peripheral write, SSCR1 = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_SSDR:
- logerror("%s: peripheral write, SSDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_SSP_WRITES, "%s: peripheral write, SSDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ // TODO: Proper SPI support
+ if (data != 0)
+ {
+ m_last_ssi_request = (m_last_ssi_request >> 8) | (data & 0xff00);
+ }
break;
case REG_SSSR:
- logerror("%s: peripheral write, SSSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_SSP_WRITES, "%s: peripheral write, SSSR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_TC1LOAD:
- logerror("%s: peripheral write, TC1LOAD = %08x & %08x\n", machine().describe_context(), data, mem_mask);
- set_timer_reload(0, data);
+ LOGMASKED(LOG_TIMER_WRITES, "%s: peripheral write, TC1LOAD = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ m_timer_reload[0] = data;
break;
case REG_TC1VAL:
- logerror("%s: peripheral write, TC1VAL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_TIMER_WRITES, "%s: peripheral write, TC1VAL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_TC1CTRL:
- logerror("%s: peripheral write, TC1CTRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_TIMER_WRITES, "%s: peripheral write, TC1CTRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
set_timer_ctrl(0, data);
break;
case REG_TC1EOI:
- logerror("%s: peripheral write, TC1EOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_TIMER_WRITES | LOG_EOI_WRITES, "%s: peripheral write, TC1EOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_pending_ints &= ~(1 << IRQ_TC1OI);
check_interrupts();
break;
case REG_TC2LOAD:
- logerror("%s: peripheral write, TC2LOAD = %08x & %08x\n", machine().describe_context(), data, mem_mask);
- set_timer_reload(1, data);
+ LOGMASKED(LOG_TIMER_WRITES, "%s: peripheral write, TC2LOAD = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ m_timer_reload[1] = data;
break;
case REG_TC2VAL:
- logerror("%s: peripheral write, TC2VAL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_TIMER_WRITES, "%s: peripheral write, TC2VAL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_TC2CTRL:
- logerror("%s: peripheral write, TC2CTRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_TIMER_WRITES, "%s: peripheral write, TC2CTRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
set_timer_ctrl(1, data);
break;
case REG_TC2EOI:
- logerror("%s: peripheral write, TC2EOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_TIMER_WRITES | LOG_EOI_WRITES, "%s: peripheral write, TC2EOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_pending_ints &= ~(1 << IRQ_TC2OI);
check_interrupts();
break;
case REG_BZCONT:
- logerror("%s: peripheral write, BZCONT = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_BUZZER_WRITES, "%s: peripheral write, BZCONT = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_RTCDRL:
- logerror("%s: peripheral write, RTCDRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_RTC_WRITES, "%s: peripheral write, RTCDRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ m_rtc &= 0xffff0000;
+ m_rtc |= (uint16_t)data;
break;
case REG_RTCDRU:
- logerror("%s: peripheral write, RTCDRU = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_RTC_WRITES, "%s: peripheral write, RTCDRU = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ m_rtc &= 0x0000ffff;
+ m_rtc |= data << 16;
break;
case REG_RTCMRL:
- logerror("%s: peripheral write, RTCMRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_RTC_WRITES, "%s: peripheral write, RTCMRL = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_RTCMRU:
- logerror("%s: peripheral write, RTCMRU = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_RTC_WRITES, "%s: peripheral write, RTCMRU = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_RTCEOI:
- logerror("%s: peripheral write, RTCEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_RTC_WRITES | LOG_EOI_WRITES, "%s: peripheral write, RTCEOI = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PADR:
- logerror("%s: peripheral write, PADR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
- break;
+ LOGMASKED(LOG_GPIO_WRITES, "%s: peripheral write, PADR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ m_ports[PORTA] = data;
case REG_PBDR:
- logerror("%s: peripheral write, PBDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ {
+ LOGMASKED(LOG_GPIO_WRITES, "%s: peripheral write, PBDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ const uint8_t old = m_ports[PORTB];
+ m_ports[PORTB] = data;
+ const uint8_t diff = old ^ data;
+ if (BIT(diff, 0))
+ m_etna->eeprom_cs_in(BIT(data, 0));
+ if (BIT(diff, 1))
+ m_etna->eeprom_clk_in(BIT(data, 1));
+ if (diff & 0x3c)
+ LOGMASKED(LOG_PIN_WRITES, "Contrast: %d\n", (diff >> 2) & 0x0f);
+ if (BIT(diff, 6))
+ LOGMASKED(LOG_PIN_WRITES, "Case Open: %d\n", BIT(diff, 6));
+ if (BIT(diff, 7))
+ LOGMASKED(LOG_PIN_WRITES, "ETNA CompactFlash Power: %d\n", BIT(diff, 7));
break;
+ }
case REG_PCDR:
- logerror("%s: peripheral write, PCDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ {
+ LOGMASKED(LOG_GPIO_WRITES, "%s: peripheral write, PCDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ const uint8_t old = m_ports[PORTC];
+ m_ports[PORTC] = data;
+ const uint8_t diff = old ^ data;
+ if (BIT(diff, 0))
+ LOGMASKED(LOG_PIN_WRITES, "RS232 RTS: %d\n", BIT(diff, 0));
+ if (BIT(diff, 1))
+ LOGMASKED(LOG_PIN_WRITES, "RS232 DTR Toggle: %d\n", BIT(diff, 1));
+ if (BIT(diff, 2))
+ LOGMASKED(LOG_PIN_WRITES, "Disable Power LED: %d\n", BIT(diff, 2));
+ if (BIT(diff, 3))
+ LOGMASKED(LOG_PIN_WRITES, "Enable UART1: %d\n", BIT(diff, 3));
+ if (BIT(diff, 4))
+ LOGMASKED(LOG_PIN_WRITES, "LCD Backlight: %d\n", BIT(diff, 4));
+ if (BIT(diff, 5))
+ LOGMASKED(LOG_PIN_WRITES, "Enable UART0: %d\n", BIT(diff, 5));
+ if (BIT(diff, 6))
+ LOGMASKED(LOG_PIN_WRITES, "Dictaphone: %d\n", BIT(diff, 6));
break;
+ }
case REG_PDDR:
- logerror("%s: peripheral write, PDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ {
+ LOGMASKED(LOG_GPIO_WRITES, "%s: peripheral write, PDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ const uint8_t old = m_ports[PORTD];
+ m_ports[PORTD] = data;
+ const uint8_t diff = old ^ data;
+ if (BIT(diff, 0))
+ LOGMASKED(LOG_PIN_WRITES, "Codec Enable: %d\n", BIT(diff, 0));
+ if (BIT(diff, 1))
+ LOGMASKED(LOG_PIN_WRITES, "Audio Amp Enable: %d\n", BIT(diff, 1));
+ if (BIT(diff, 2))
+ LOGMASKED(LOG_PIN_WRITES, "LCD Power: %d\n", BIT(diff, 2));
+ if (BIT(diff, 3))
+ LOGMASKED(LOG_PIN_WRITES, "ETNA Door: %d\n", BIT(diff, 3));
+ if (BIT(diff, 4))
+ LOGMASKED(LOG_PIN_WRITES, "Sled: %d\n", BIT(diff, 4));
+ if (BIT(diff, 5))
+ LOGMASKED(LOG_PIN_WRITES, "Pump Power2: %d\n", BIT(diff, 5));
+ if (BIT(diff, 6))
+ LOGMASKED(LOG_PIN_WRITES, "Pump Power1: %d\n", BIT(diff, 6));
+ if (BIT(diff, 7))
+ LOGMASKED(LOG_PIN_WRITES, "ETNA Error: %d\n", BIT(diff, 7));
break;
+ }
case REG_PADDR:
- logerror("%s: peripheral write, PADDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_GPIO_WRITES, "%s: peripheral write, PADDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PBDDR:
- logerror("%s: peripheral write, PBDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_GPIO_WRITES, "%s: peripheral write, PBDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PCDDR:
- logerror("%s: peripheral write, PCDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_GPIO_WRITES, "%s: peripheral write, PCDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PDDDR:
- logerror("%s: peripheral write, PDDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_GPIO_WRITES, "%s: peripheral write, PDDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PEDR:
- logerror("%s: peripheral write, PEDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_GPIO_WRITES, "%s: peripheral write, PEDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_PEDDR:
- logerror("%s: peripheral write, PEDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_GPIO_WRITES, "%s: peripheral write, PEDDR = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_KSCAN:
- logerror("%s: peripheral write, KSCAN = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_KBD_WRITES, "%s: peripheral write, KSCAN = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case REG_LCDMUX:
- logerror("%s: peripheral write, LCDMUX = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_LCD_WRITES, "%s: peripheral write, LCDMUX = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
default:
- logerror("%s: peripheral write, Unknown = %08x & %08x\n", machine().describe_context(), data, mem_mask);
+ LOGMASKED(LOG_UNKNOWNS, "%s: peripheral write, Unknown = %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
}
}
-void psion5_state::main_map(address_map &map)
+uint8_t psion5mx_state::read_keyboard()
+{
+ return 0x00;
+}
+
+void psion5mx_state::main_map(address_map &map)
{
map(0x00000000, 0x009fffff).rom().region("maincpu", 0);
- map(0x80000000, 0x80000fff).rw(FUNC(psion5_state::periphs_r), FUNC(psion5_state::periphs_w));
- map(0xc0000000, 0xc03fffff).ram().mirror(0x1fc00000);
+ map(0x20000000, 0x20000fff).rw(m_etna, FUNC(etna_device::regs_r), FUNC(etna_device::regs_w));
+ map(0x80000000, 0x80000fff).rw(FUNC(psion5mx_state::periphs_r), FUNC(psion5mx_state::periphs_w));
+ map(0xc0000000, 0xc03fffff).ram().mirror(0x1fc00000).share("lcd_ram");
}
-uint32_t psion5_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+uint32_t psion5mx_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
+ uint8_t *lcd_buf = (uint8_t*)&m_lcd_ram[(m_lcd_display_base_addr & 0x003fffff) >> 2];
+ static const int width = 640;
+ static const int height = 240;
+
+ // fetch palette
+ LOGMASKED(LOG_DISPLAY, "%02x %02x %02x %02x\n", lcd_buf[0], lcd_buf[1], lcd_buf[2], lcd_buf[3]);
+
+ const int bpp = 1 << (lcd_buf[0] >> 4);
+ const int ppb = 8 / bpp;
+ LOGMASKED(LOG_DISPLAY, "bpp: %d, ppb: %d\n", bpp, ppb);
+ uint16_t palette[16] = {};
+ for (int i = 0; i < 16; i++)
+ {
+ palette[i] = lcd_buf[i*2] | ((lcd_buf[i*2+1] << 8) & 0xf00);
+ LOGMASKED(LOG_DISPLAY, "palette[%d]: %04x\n", i, palette[i]);
+ }
+
+ // build our image out
+ const int line_width = (width * bpp) / 8;
+ for (int y = 0; y < height; y++)
+ {
+ const int line_offs = 0x20 + (line_width * y);
+ uint32_t *line = &bitmap.pix(y);
+ for (int x = 0; x < width; x++)
+ {
+ const uint8_t byte = lcd_buf[line_offs + (x / ppb)];
+ const int shift = (x & (ppb - 1)) & bpp;
+ const int mask = (1 << bpp) - 1;
+ const int pal_idx = (byte >> shift) & mask;
+ const uint8_t pal_value = palette[pal_idx] | (palette[pal_idx] << 4);
+ //printf("%d:%02x %04x %04x\n", pal_idx, pal_value, palette[0], palette[1]);
+
+ line[x] = 0xff000000 | (0x010101 * pal_value);
+ }
+ }
return 0;
}
/* Input ports */
-INPUT_PORTS_START( psion5 )
+INPUT_PORTS_START( psion5mx )
INPUT_PORTS_END
/* basic configuration for 2 lines display */
-void psion5_state::psion5mx(machine_config &config)
+void psion5mx_state::psion5mx(machine_config &config)
{
/* basic machine hardware */
ARM710T(config, m_maincpu, 18000000); // 18MHz, per wikipedia
- m_maincpu->set_addrmap(AS_PROGRAM, &psion5_state::main_map);
+ m_maincpu->set_addrmap(AS_PROGRAM, &psion5mx_state::main_map);
+
+ ETNA(config, m_etna);
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); /* not accurate */
- screen.set_screen_update(FUNC(psion5_state::screen_update));
+ screen.set_screen_update(FUNC(psion5mx_state::screen_update));
screen.set_size(640, 240);
screen.set_visarea(0, 640-1, 0, 240-1);
}
@@ -730,5 +796,5 @@ ROM_END
/* Driver */
-// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
-COMP( 1999, psion5mx, 0, 0, psion5mx, psion5, psion5_state, empty_init, "Psion", "5mx", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
+// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
+COMP( 1999, psion5mx, 0, 0, psion5mx, psion5mx, psion5mx_state, empty_init, "Psion", "5mx", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
diff --git a/src/mame/includes/psion5.h b/src/mame/includes/psion5.h
new file mode 100644
index 00000000000..d4fc531431f
--- /dev/null
+++ b/src/mame/includes/psion5.h
@@ -0,0 +1,194 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz, Ash Wolf
+/***************************************************************************
+
+ Psion 5mx (EPOC R5) series and peripherals
+
+ Skeleton driver by Ryan Holtz, ported from work by Ash Wolf
+
+****************************************************************************/
+
+#ifndef MAME_INCLUDES_PSION5_H
+#define MAME_INCLUDES_PSION5_H
+
+#pragma once
+
+#include "emu.h"
+#include "cpu/arm7/arm7.h"
+#include "cpu/arm7/arm7core.h"
+#include "machine/etna.h"
+
+#include "screen.h"
+
+class psion5mx_state : public driver_device
+{
+public:
+ psion5mx_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ , m_etna(*this, "etna")
+ , m_lcd_ram(*this, "lcd_ram")
+ {
+ }
+
+ void psion5mx(machine_config &config);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+private:
+
+ DECLARE_READ32_MEMBER(periphs_r);
+ DECLARE_WRITE32_MEMBER(periphs_w);
+
+ void update_timer(int timer);
+ void set_timer_ctrl(int timer, uint32_t value);
+ void check_interrupts();
+
+ static constexpr device_timer_id TID_TIMER1 = 0;
+ static constexpr device_timer_id TID_TIMER2 = 1;
+ static constexpr device_timer_id TID_PERIODIC = 2;
+ static constexpr device_timer_id TID_RTC_TICKER = 3;
+
+ enum
+ {
+ REG_MEMCFG1 = 0x0000,
+ REG_MEMCFG2 = 0x0004,
+
+ REG_DRAMCFG = 0x0100,
+
+ REG_LCDCTL = 0x0200,
+ REG_LCDST = 0x0204,
+ REG_LCD_DBAR1 = 0x0210,
+ REG_LCDT0 = 0x0220,
+ REG_LCDT1 = 0x0224,
+ REG_LCDT2 = 0x0228,
+
+ REG_PWRSR = 0x0400,
+ REG_PWRCNT = 0x0404,
+ REG_HALT = 0x0408,
+ REG_STBY = 0x040c,
+ REG_BLEOI = 0x0410,
+ REG_MCEOI = 0x0414,
+ REG_TEOI = 0x0418,
+ REG_STFCLR = 0x041c,
+ REG_E2EOI = 0x0420,
+
+ REG_INTSR = 0x0500,
+ REG_INTRSR = 0x0504,
+ REG_INTENS = 0x0508,
+ REG_INTENC = 0x050c,
+ REG_INTTEST1 = 0x0514,
+ REG_INTTEST2 = 0x0518,
+
+ REG_PUMPCON = 0x0900,
+
+ REG_CODR = 0x0a00,
+ REG_CONFG = 0x0a04,
+ REG_COLFG = 0x0a08,
+ REG_COEOI = 0x0a0c,
+ REG_COTEST = 0x0a10,
+
+ REG_SSCR0 = 0x0b00,
+ REG_SSCR1 = 0x0b04,
+ REG_SSDR = 0x0b0c,
+ REG_SSSR = 0x0b14,
+
+ REG_TC1LOAD = 0x0c00,
+ REG_TC1VAL = 0x0c04,
+ REG_TC1CTRL = 0x0c08,
+ REG_TC1EOI = 0x0c0c,
+ REG_TC2LOAD = 0x0c20,
+ REG_TC2VAL = 0x0c24,
+ REG_TC2CTRL = 0x0c28,
+ REG_TC2EOI = 0x0c2c,
+
+ REG_BZCONT = 0x0c40,
+
+ REG_RTCDRL = 0x0d00,
+ REG_RTCDRU = 0x0d04,
+ REG_RTCMRL = 0x0d08,
+ REG_RTCMRU = 0x0d0c,
+ REG_RTCEOI = 0x0d10,
+
+ REG_PADR = 0x0e00,
+ REG_PBDR = 0x0e04,
+ REG_PCDR = 0x0e08,
+ REG_PDDR = 0x0e0c,
+ REG_PADDR = 0x0e10,
+ REG_PBDDR = 0x0e14,
+ REG_PCDDR = 0x0e18,
+ REG_PDDDR = 0x0e1c,
+ REG_PEDR = 0x0e20,
+ REG_PEDDR = 0x0e24,
+
+ REG_KSCAN = 0x0e28,
+ REG_LCDMUX = 0x0e2c
+ };
+
+ enum
+ {
+ IRQ_EXTFIQ = 0, // FiqExternal
+ IRQ_BLINT = 1, // FiqBatLow
+ IRQ_WEINT = 2, // FiqWatchDog
+ IRQ_MCINT = 3, // FiqMediaChg
+ IRQ_CSINT = 4, // IrqCodec
+ IRQ_EINT1 = 5, // IrqExt1
+ IRQ_EINT2 = 6, // IrqExt2
+ IRQ_EINT3 = 7, // IrqExt3
+ IRQ_TC1OI = 8, // IrqTimer1
+ IRQ_TC2OI = 9, // IrqTimer2
+ IRQ_RTCMI = 10, // IrqRtcMatch
+ IRQ_TINT = 11, // IrqTick
+ IRQ_UART1 = 12, // IrqUart1
+ IRQ_UART2 = 13, // IrqUart2
+ IRQ_LCDINT = 14, // IrqLcd
+ IRQ_SSEOTI = 15, // IrqSpi
+ IRQ_FIQ_MASK = 0x000f,
+ IRQ_IRQ_MASK = 0xfff0
+ };
+
+ enum
+ {
+ PORTA,
+ PORTB,
+ PORTC,
+ PORTD,
+ PORTE
+ };
+
+ void main_map(address_map &map);
+
+ uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+
+ uint8_t read_keyboard();
+
+ required_device<arm710t_cpu_device> m_maincpu;
+ required_device<etna_device> m_etna;
+ required_shared_ptr<uint32_t> m_lcd_ram;
+
+ emu_timer *m_timers[2];
+ uint16_t m_timer_reload[2];
+ uint16_t m_timer_ctrl[2];
+ uint16_t m_timer_value[2];
+
+ uint32_t m_pending_ints;
+ uint32_t m_int_mask;
+
+ uint32_t m_lcd_display_base_addr;
+
+ uint32_t m_rtc;
+ uint32_t m_pwrsr;
+ uint32_t m_last_ssi_request;
+ uint32_t m_ssi_read_counter;
+
+ uint8_t m_ports[5];
+
+ emu_timer *m_periodic;
+ emu_timer *m_rtc_ticker;
+};
+
+#endif // MAME_INCLUDES_PSION5_H \ No newline at end of file
diff --git a/src/mame/machine/etna.cpp b/src/mame/machine/etna.cpp
new file mode 100644
index 00000000000..856838b7668
--- /dev/null
+++ b/src/mame/machine/etna.cpp
@@ -0,0 +1,257 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz, Ash Wolf
+/***************************************************************************
+
+ Psion 5mx (EPOC R5) series ETNA peripheral
+
+ Skeleton device by Ryan Holtz, ported from work by Ash Wolf
+
+ More info:
+ https://github.com/Treeki/WindEmu
+
+****************************************************************************/
+
+#include "etna.h"
+
+#define LOG_READS (1 << 0)
+#define LOG_WRITES (1 << 1)
+#define LOG_UNKNOWNS (1 << 2)
+#define LOG_PROM (1 << 3)
+#define LOG_ALL (LOG_READS | LOG_WRITES | LOG_UNKNOWNS | LOG_PROM)
+
+#define VERBOSE (LOG_ALL)
+#include "logmacro.h"
+
+DEFINE_DEVICE_TYPE(ETNA, etna_device, "etna", "Psion 5mx ETNA")
+
+etna_device::etna_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, ETNA, tag, owner, clock)
+ , m_eeprom_data_out(*this)
+{
+}
+
+void etna_device::device_start()
+{
+ save_item(NAME(m_prom_addr_count));
+ save_item(NAME(m_prom_addr));
+ save_item(NAME(m_prom_value));
+ save_item(NAME(m_prom_cs));
+ save_item(NAME(m_prom_clk));
+
+ save_item(NAME(m_pending_ints));
+
+ save_item(NAME(m_regs));
+ save_item(NAME(m_prom));
+}
+
+void etna_device::device_reset()
+{
+ m_prom_addr_count = 0;
+ m_prom_addr = 0;
+ m_prom_value = 0;
+ m_prom_cs = false;
+ m_prom_clk = false;
+
+ m_pending_ints = 0;
+
+ memset(m_regs, 0, ARRAY_LENGTH(m_regs));
+ memset(m_prom, 0, ARRAY_LENGTH(m_prom));
+
+ // defaults expected by the touchscreen code
+ m_prom[0x0a] = 20;
+ m_prom[0x0b] = 20;
+ m_prom[0x0c] = 20;
+ m_prom[0x0d] = 30;
+
+ // some basic stuff to begin with
+ // set up the Psion's unique ID
+ m_prom[0x1b] = 0xde;
+ m_prom[0x1a] = 0xad;
+ m_prom[0x19] = 0xbe;
+ m_prom[0x18] = 0xef;
+
+ // give ourselves a neat custom device name
+ const char *key = "PSION";
+ const char *name = "MAME!";
+ m_prom[0x28] = strlen(name);
+ for (int i = 0; i < m_prom[0x28]; i++)
+ m_prom[0x29 + i] = name[i] ^ key[i];
+
+ // calculate the checksum
+ uint8_t chk = 0;
+ for (int i = 0; i < 0x7F; i++)
+ chk ^= m_prom[i];
+
+ // EPOC is expecting 66
+ m_prom[0x7f] = chk ^ 66;
+}
+
+WRITE8_MEMBER(etna_device::regs_w)
+{
+ switch (offset)
+ {
+ case REG_UNK0:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: UNK0 = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_UNK1:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: UNK1 = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_UART_INT_STATUS:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: INT_STATUS = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_UART_INT_MASK:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: INT_MASK = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_UART_BAUD_LO:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: BAUD_LO = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_UART_BAUD_HI:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: BAUD_HI = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_PCCD_INT_STATUS:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: PCCD_INT_STATUS = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_PCCD_INT_MASK:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: PCCD_INT_MASK = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_INT_CLEAR:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: INT_CLEAR = %02x\n", machine().describe_context(), data);
+ m_pending_ints &= ~data;
+ break;
+ case REG_SKT_VAR_A0:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: SKT_VAR_A0 = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_SKT_VAR_A1:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: SKT_VAR_A1 = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_SKT_CTRL:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: SKT_CTRL = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_WAKE1:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: WAKE1 = %02x\n", machine().describe_context(), data);
+ m_regs[REG_WAKE1] = data;
+ break;
+ case REG_SKT_VAR_B0:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: SKT_VAR_B0 = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_SKT_VAR_B1:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: SKT_VAR_B1 = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_WAKE2:
+ LOGMASKED(LOG_WRITES, "%s: etna reg write: WAKE2 = %02x\n", machine().describe_context(), data);
+ m_regs[REG_WAKE2] = data;
+ break;
+ default:
+ LOGMASKED(LOG_UNKNOWNS, "%s: etna reg write: Unknown = %02x\n", machine().describe_context(), data);
+ break;
+ }
+}
+
+READ8_MEMBER(etna_device::regs_r)
+{
+ uint8_t data = 0;
+ switch (offset)
+ {
+ case REG_UNK0:
+ LOGMASKED(LOG_READS, "%s: etna reg read: UNK0 = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_UNK1:
+ LOGMASKED(LOG_READS, "%s: etna reg read: UNK1 = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_UART_INT_STATUS:
+ LOGMASKED(LOG_READS, "%s: etna reg read: INT_STATUS = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_UART_INT_MASK:
+ LOGMASKED(LOG_READS, "%s: etna reg read: INT_MASK = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_UART_BAUD_LO:
+ LOGMASKED(LOG_READS, "%s: etna reg read: BAUD_LO = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_UART_BAUD_HI:
+ LOGMASKED(LOG_READS, "%s: etna reg read: BAUD_HI = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_PCCD_INT_STATUS:
+ LOGMASKED(LOG_READS, "%s: etna reg read: PCCD_INT_STATUS = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_PCCD_INT_MASK:
+ LOGMASKED(LOG_READS, "%s: etna reg read: PCCD_INT_MASK = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_INT_CLEAR:
+ LOGMASKED(LOG_READS, "%s: etna reg read: INT_CLEAR = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_SKT_VAR_A0:
+ LOGMASKED(LOG_READS, "%s: etna reg read: SKT_VAR_A0 = %02x\n", machine().describe_context(), data);
+ data = 1;
+ break;
+ case REG_SKT_VAR_A1:
+ LOGMASKED(LOG_READS, "%s: etna reg read: SKT_VAR_A1 = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_SKT_CTRL:
+ LOGMASKED(LOG_READS, "%s: etna reg read: SKT_CTRL = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_WAKE1:
+ data = m_regs[REG_WAKE1];
+ LOGMASKED(LOG_READS, "%s: etna reg read: WAKE1 = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_SKT_VAR_B0:
+ LOGMASKED(LOG_READS, "%s: etna reg read: SKT_VAR_B0 = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_SKT_VAR_B1:
+ LOGMASKED(LOG_READS, "%s: etna reg read: SKT_VAR_B1 = %02x\n", machine().describe_context(), data);
+ break;
+ case REG_WAKE2:
+ data = m_regs[REG_WAKE2];
+ LOGMASKED(LOG_READS, "%s: etna reg read: WAKE2 = %02x\n", machine().describe_context(), data);
+ break;
+ default:
+ LOGMASKED(LOG_UNKNOWNS, "%s: etna reg read: Unknown = %02x\n", machine().describe_context(), data);
+ break;
+ }
+ return data;
+}
+
+WRITE_LINE_MEMBER(etna_device::eeprom_cs_in)
+{
+ bool old = m_prom_cs;
+ m_prom_cs = state;
+ if (!old && m_prom_cs)
+ {
+ m_prom_addr_count = 0;
+ m_prom_addr = 0;
+ m_prom_value = 0;
+ }
+}
+
+WRITE_LINE_MEMBER(etna_device::eeprom_clk_in)
+{
+ bool old = m_prom_clk;
+ m_prom_clk = state;
+
+ if (!old && m_prom_clk)
+ {
+ if (m_prom_addr_count < 10)
+ {
+ m_prom_addr <<= 1;
+ m_prom_addr |= BIT(m_regs[REG_WAKE1], 2);
+ m_prom_addr_count++;
+ if (m_prom_addr_count == 10)
+ {
+ LOGMASKED(LOG_PROM, "PROM Address: %03x\n", m_prom_addr);
+ uint16_t byte_addr = (m_prom_addr << 1) % ARRAY_LENGTH(m_prom);
+ m_prom_value = m_prom[byte_addr] | (m_prom[byte_addr + 1] << 8);
+ LOGMASKED(LOG_PROM, "PROM Value: %04x\n", m_prom_value);
+ }
+ }
+ else
+ {
+ m_regs[REG_WAKE1] &= ~0x08;
+ m_regs[REG_WAKE1] |= BIT(m_prom_value, 15) << 3;
+ LOGMASKED(LOG_PROM, "PROM Bit: %d\n", BIT(m_prom_value, 15));
+ m_prom_value <<= 1;
+ }
+ }
+}
+
+WRITE_LINE_MEMBER(etna_device::eeprom_data_in)
+{
+}
diff --git a/src/mame/machine/etna.h b/src/mame/machine/etna.h
new file mode 100644
index 00000000000..5e47743f16b
--- /dev/null
+++ b/src/mame/machine/etna.h
@@ -0,0 +1,73 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz, Ash Wolf
+/***************************************************************************
+
+ Psion 5mx (EPOC R5) series ETNA peripheral
+
+ Skeleton driver by Ryan Holtz, ported from work by Ash Wolf
+
+****************************************************************************/
+
+#ifndef MAME_MACHINE_ETNA_H
+#define MAME_MACHINE_ETNA_H
+
+#pragma once
+
+#include "emu.h"
+
+class etna_device : public device_t
+{
+public:
+ etna_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0U);
+
+ DECLARE_WRITE8_MEMBER(regs_w);
+ DECLARE_READ8_MEMBER(regs_r);
+
+ DECLARE_WRITE_LINE_MEMBER(eeprom_cs_in);
+ DECLARE_WRITE_LINE_MEMBER(eeprom_clk_in);
+ DECLARE_WRITE_LINE_MEMBER(eeprom_data_in);
+
+ auto eeprom_data_out() { return m_eeprom_data_out.bind(); }
+
+private:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ enum
+ {
+ REG_UNK0,
+ REG_UNK1,
+ REG_UART_INT_STATUS,
+ REG_UART_INT_MASK,
+ REG_UART_BAUD_LO,
+ REG_UART_BAUD_HI,
+ REG_PCCD_INT_STATUS,
+ REG_PCCD_INT_MASK,
+ REG_INT_CLEAR,
+ REG_SKT_VAR_A0,
+ REG_SKT_VAR_A1,
+ REG_SKT_CTRL,
+ REG_WAKE1,
+ REG_SKT_VAR_B0,
+ REG_SKT_VAR_B1,
+ REG_WAKE2
+ };
+
+ devcb_write_line m_eeprom_data_out;
+
+ uint8_t m_prom_addr_count;
+ uint16_t m_prom_addr;
+ uint16_t m_prom_value;
+ bool m_prom_cs;
+ bool m_prom_clk;
+
+ uint8_t m_pending_ints;
+
+ uint8_t m_regs[0x10];
+ uint8_t m_prom[0x80];
+};
+
+DECLARE_DEVICE_TYPE(ETNA, etna_device)
+
+#endif // MAME_MACHINE_ETNA_H \ No newline at end of file