summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/mc68328.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/mc68328.h')
-rw-r--r--src/devices/machine/mc68328.h1411
1 files changed, 1140 insertions, 271 deletions
diff --git a/src/devices/machine/mc68328.h b/src/devices/machine/mc68328.h
index 8165fbe6e85..b76323eea67 100644
--- a/src/devices/machine/mc68328.h
+++ b/src/devices/machine/mc68328.h
@@ -90,299 +90,1168 @@
#include "cpu/m68000/m68000.h"
-class mc68328_device : public m68000_device
+class mc68328_base_device : public m68000_device
{
public:
- mc68328_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- auto out_port_a() { return m_out_port_a_cb.bind(); }
- auto out_port_b() { return m_out_port_b_cb.bind(); }
- auto out_port_c() { return m_out_port_c_cb.bind(); }
- auto out_port_d() { return m_out_port_d_cb.bind(); }
- auto out_port_e() { return m_out_port_e_cb.bind(); }
- auto out_port_f() { return m_out_port_f_cb.bind(); }
- auto out_port_g() { return m_out_port_g_cb.bind(); }
- auto out_port_j() { return m_out_port_j_cb.bind(); }
- auto out_port_k() { return m_out_port_k_cb.bind(); }
- auto out_port_m() { return m_out_port_m_cb.bind(); }
- auto in_port_a() { return m_in_port_a_cb.bind(); }
- auto in_port_b() { return m_in_port_b_cb.bind(); }
- auto in_port_c() { return m_in_port_c_cb.bind(); }
- auto in_port_d() { return m_in_port_d_cb.bind(); }
- auto in_port_e() { return m_in_port_e_cb.bind(); }
- auto in_port_f() { return m_in_port_f_cb.bind(); }
- auto in_port_g() { return m_in_port_g_cb.bind(); }
- auto in_port_j() { return m_in_port_j_cb.bind(); }
- auto in_port_k() { return m_in_port_k_cb.bind(); }
- auto in_port_m() { return m_in_port_m_cb.bind(); }
- auto out_pwm() { return m_out_pwm_cb.bind(); }
+ typedef device_delegate<void (double, int, int, u8, u8)> lcd_info_changed_delegate;
+
+ template <int Line> auto out_port_a() { return m_out_port_a_cb[Line].bind(); }
+ template <int Line> auto out_port_b() { return m_out_port_b_cb[Line].bind(); }
+ template <int Line> auto out_port_c() { return m_out_port_c_cb[Line].bind(); }
+ template <int Line> auto out_port_d() { return m_out_port_d_cb[Line].bind(); }
+ template <int Line> auto out_port_e() { return m_out_port_e_cb[Line].bind(); }
+ template <int Line> auto out_port_f() { return m_out_port_f_cb[Line].bind(); }
+ template <int Line> auto out_port_g() { return m_out_port_g_cb[Line].bind(); }
+ template <int Line> auto in_port_a() { return m_in_port_a_cb[Line].bind(); }
+ template <int Line> auto in_port_b() { return m_in_port_b_cb[Line].bind(); }
+ template <int Line> auto in_port_c() { return m_in_port_c_cb[Line].bind(); }
+ template <int Line> auto in_port_d() { return m_in_port_d_cb[Line].bind(); }
+ template <int Line> auto in_port_e() { return m_in_port_e_cb[Line].bind(); }
+ template <int Line> auto in_port_f() { return m_in_port_f_cb[Line].bind(); }
+ template <int Line> auto in_port_g() { return m_in_port_g_cb[Line].bind(); }
+
+ void port_d_in_w(int state, int bit);
+
auto out_spim() { return m_out_spim_cb.bind(); }
auto in_spim() { return m_in_spim_cb.bind(); }
- auto spim_xch_trigger() { return m_spim_xch_trigger_cb.bind(); }
- DECLARE_WRITE_LINE_MEMBER(set_penirq_line);
- void set_port_d_lines(uint8_t state, int bit);
+ auto out_pwm() { return m_out_pwm_cb.bind(); }
+
+ auto out_flm() { return m_out_flm_cb.bind(); }
+ auto out_llp() { return m_out_llp_cb.bind(); }
+ auto out_lsclk() { return m_out_lsclk_cb.bind(); }
+ auto out_ld() { return m_out_ld_cb.bind(); }
- uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ template <typename... T>
+ void set_lcd_info_changed(T &&... args)
+ {
+ m_lcd_info_changed_cb.set(std::forward<T>(args)...);
+ }
+
+ void irq5_w(int state);
protected:
- // device-level overrides
- virtual void device_resolve_objects() override;
- virtual void device_start() override;
- virtual void device_reset() override;
+ mc68328_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
-private:
- struct mc68328_regs_t
+ // device_t implementation
+ virtual void device_resolve_objects() override ATTR_COLD;
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+
+ enum : u8
+ {
+ SCR_WDTH8 = 0x01,
+ SCR_DMAP = 0x04,
+ SCR_SO = 0x08,
+ SCR_BETEN = 0x10,
+ SCR_PRV = 0x20,
+ SCR_WPV = 0x40,
+ SCR_BETO = 0x80,
+
+ PCTLR_WIDTH = 0x1f,
+ PCTLR_STOP = 0x40,
+ PCTLR_PC_EN = 0x80,
+
+ BLKC_BD = 0x7f,
+ BLKC_BKEN = 0x80,
+
+ LPOLCF_PIXPOL = 0x01,
+ LPOLCF_LPPOL_BIT = 1,
+ LPOLCF_FLMPOL_BIT = 2,
+ LPOLCF_LCKPOL = 0x08,
+
+ LACDRC_MASK = 0x0f,
+
+ LPXCD_MASK = 0x3f,
+
+ LBAR_MASK = 0x7f,
+
+ LPOSR_POS = 0x07,
+ LPOSR_BOS = 0x08,
+
+ LFRCM_YMOD = 0x0f,
+ LFRCM_XMOD = 0xf0,
+ };
+
+ enum : u16
+ {
+ GRPBASE_VALID = 0x0001,
+ GRPBASE_BASE_ADDR = 0xfff0,
+
+ GRPMASK_BASE_MASK = 0xfff0,
+
+ PLLCR_DISPLL = 0x0008,
+ PLLCR_CLKEN = 0x0010,
+ PLLCR_SYSCLK_SEL_DIV2 = 0x0000,
+ PLLCR_SYSCLK_SEL_DIV4 = 0x0100,
+ PLLCR_SYSCLK_SEL_DIV8 = 0x0200,
+ PLLCR_SYSCLK_SEL_DIV16 = 0x0300,
+ PLLCR_SYSCLK_SEL_DIV1_0 = 0x0400,
+ PLLCR_SYSCLK_SEL_DIV1_1 = 0x0500,
+ PLLCR_SYSCLK_SEL_DIV1_2 = 0x0600,
+ PLLCR_SYSCLK_SEL_DIV1_3 = 0x0700,
+ PLLCR_SYSCLK_SEL = 0x0700,
+ PLLCR_SYSCLK_SHIFT = 8,
+ PLLCR_PIXCLK_SEL_DIV2 = 0x0000,
+ PLLCR_PIXCLK_SEL_DIV4 = 0x0800,
+ PLLCR_PIXCLK_SEL_DIV8 = 0x1000,
+ PLLCR_PIXCLK_SEL_DIV16 = 0x1800,
+ PLLCR_PIXCLK_SEL_DIV1_0 = 0x2000,
+ PLLCR_PIXCLK_SEL_DIV1_1 = 0x2800,
+ PLLCR_PIXCLK_SEL_DIV1_2 = 0x3000,
+ PLLCR_PIXCLK_SEL_DIV1_3 = 0x3800,
+ PLLCR_PIXCLK_SEL = 0x3800,
+ PLLCR_PIXCLK_SHIFT = 11,
+
+ PLLFSR_PCNT = 0x00ff,
+ PLLFSR_QCNT = 0x0f00,
+ PLLFSR_PROT = 0x4000,
+ PLLFSR_CLK32 = 0x8000,
+
+ ICR_ET6 = 0x0100,
+ ICR_ET3 = 0x0200,
+ ICR_ET2 = 0x0400,
+ ICR_ET1 = 0x0800,
+ ICR_POL6 = 0x1000,
+ ICR_POL3 = 0x2000,
+ ICR_POL2 = 0x4000,
+ ICR_POL1 = 0x8000,
+
+ PWMC_CLKSEL = 0x0007,
+ PWMC_EN = 0x0010,
+ PWMC_POL = 0x0040,
+ PWMC_PIN = 0x0080,
+ PWMC_LOAD = 0x0100,
+ PWMC_IRQ_EN = 0x4000,
+ PWMC_IRQ = 0x8000,
+
+ TCTL_TEN = 0x0001,
+ TCTL_TEN_ENABLE = 0x0001,
+ TCTL_TEN_BIT = 0,
+ TCTL_CLKSOURCE = 0x000e,
+ TCTL_CLKSOURCE_STOP = 0x0000,
+ TCTL_CLKSOURCE_SYSCLK = 0x0002,
+ TCTL_CLKSOURCE_SYSCLK16 = 0x0004,
+ TCTL_CLKSOURCE_TIN = 0x0006,
+ TCTL_CLKSOURCE_32KHZ4 = 0x0008,
+ TCTL_CLKSOURCE_32KHZ5 = 0x000a,
+ TCTL_CLKSOURCE_32KHZ6 = 0x000c,
+ TCTL_CLKSOURCE_32KHZ7 = 0x000e,
+ TCTL_IRQEN = 0x0010,
+ TCTL_IRQEN_ENABLE = 0x0010,
+ TCTL_OM = 0x0020,
+ TCTL_OM_ACTIVELOW = 0x0000,
+ TCTL_OM_TOGGLE = 0x0020,
+ TCTL_CAPTURE = 0x00c0,
+ TCTL_CAPTURE_NOINT = 0x0000,
+ TCTL_CAPTURE_RISING = 0x0040,
+ TCTL_CAPTURE_FALLING = 0x0080,
+ TCTL_CAPTURE_BOTH = 0x00c0,
+ TCTL_FRR = 0x0100,
+ TCTL_FRR_RESTART = 0x0000,
+ TCTL_FRR_FREERUN = 0x0100,
+
+ TSTAT_COMP = 0x0001,
+ TSTAT_CAPT = 0x0002,
+
+ SPIS_SPISEN = 0x0100,
+ SPIS_POL = 0x0200,
+ SPIS_PHA = 0x0400,
+ SPIS_OVRWR = 0x0800,
+ SPIS_DATA_RDY = 0x1000,
+ SPIS_ENPOL = 0x2000,
+ SPIS_IRQEN = 0x4000,
+ SPIS_SPIS_IRQ = 0x8000,
+
+ SPIM_BIT_COUNT = 0x000f,
+ SPIM_POL_BIT = 4,
+ SPIM_PHA_BIT = 5,
+ SPIM_IRQEN_BIT = 6,
+ SPIM_SPIMIRQ_BIT = 7,
+ SPIM_XCH_BIT = 8,
+ SPIM_SPMEN_BIT = 9,
+ SPIM_RATE_MASK = 0xe000,
+ SPIM_RATE_SHIFT = 13,
+
+ USTCNT_TX_AVAIL_EN = 0x0001,
+ USTCNT_TX_HALF_EN = 0x0002,
+ USTCNT_TX_EMPTY_EN = 0x0004,
+ USTCNT_RX_RDY_EN = 0x0008,
+ USTCNT_RX_HALF_EN = 0x0010,
+ USTCNT_RX_FULL_EN = 0x0020,
+ USTCNT_CTS_DELTA_EN = 0x0040,
+ USTCNT_GPIO_DELTA_EN = 0x0080,
+ USTCNT_8_7 = 0x0100,
+ USTCNT_STOP_BITS = 0x0200,
+ USTCNT_ODD_EVEN = 0x0400,
+ USTCNT_PARITY_EN = 0x0800,
+ USTCNT_RX_CLK_CONT = 0x1000,
+ USTCNT_TX_EN = 0x2000,
+ USTCNT_RX_EN = 0x4000,
+ USTCNT_UART_EN = 0x8000,
+
+ UBAUD_PRESCALER = 0x00ff,
+ UBAUD_DIVIDE = 0x0700,
+ UBAUD_DIVIDE_1 = 0x0000,
+ UBAUD_DIVIDE_2 = 0x0100,
+ UBAUD_DIVIDE_4 = 0x0200,
+ UBAUD_DIVIDE_8 = 0x0300,
+ UBAUD_DIVIDE_16 = 0x0400,
+ UBAUD_DIVIDE_32 = 0x0500,
+ UBAUD_DIVIDE_64 = 0x0600,
+ UBAUD_DIVIDE_128 = 0x0700,
+ UBAUD_BAUD_SRC = 0x0800,
+ UBAUD_GPIO_SRC = 0x1000,
+ UBAUD_GPIO_DIR = 0x2000,
+ UBAUD_GPIO = 0x4000,
+ UBAUD_GPIO_DELTA = 0x8000,
+
+ URX_PARITY_ERROR = 0x0100,
+ URX_BREAK = 0x0200,
+ URX_FRAME_ERROR = 0x0400,
+ URX_OVRUN = 0x0800,
+ URX_DATA_READY = 0x2000,
+ URX_FIFO_HALF = 0x4000,
+ URX_FIFO_FULL = 0x8000,
+
+ UTX_CTS_DELTA = 0x0100,
+ UTX_CTS_STATUS = 0x0200,
+ UTX_IGNORE_CTS = 0x0800,
+ UTX_SEND_BREAK = 0x1000,
+ UTX_TX_AVAIL = 0x2000,
+ UTX_FIFO_HALF = 0x4000,
+ UTX_FIFO_EMPTY = 0x8000,
+
+ UMISC_IRDA_LOOP = 0x0010,
+ UMISC_IRDA_ENABLE = 0x0020,
+ UMISC_RTS = 0x0040,
+ UMISC_RTS_CONT = 0x0080,
+ UMISC_LOOP = 0x1000,
+ UMISC_FORCE_PERR = 0x2000,
+ UMISC_CLK_SRC = 0x4000,
+
+ CXP_MASK = 0x03ff,
+ CXP_CC = 0xc000,
+ CXP_CC_XLU = 0x0000,
+ CXP_CC_BLACK = 0x4000,
+ CXP_CC_INVERSE = 0x8000,
+ CXP_CC_INVALID = 0xc000,
+
+ CYP_MASK = 0x01ff,
+
+ CWCH_CH = 0x001f,
+ CWCH_CW = 0x1f00,
+
+ LXMAX_MASK = 0x03ff,
+
+ LYMAX_MASK = 0x03ff,
+
+ RTCCTL_38_4_BIT = 5,
+ RTCCTL_ENABLE_BIT = 7,
+ RTCCTL_MASK = 0x00a0,
+
+ RTCINT_STOPWATCH = 0x0001,
+ RTCINT_MINUTE = 0x0002,
+ RTCINT_ALARM = 0x0004,
+ RTCINT_DAY = 0x0008,
+ RTCINT_SECOND = 0x0010,
+
+ RTCSTPWTCH_MASK = 0x003f,
+ };
+
+ enum : u32
{
- // $(FF)FFF000
- uint8_t scr; // System Control Register
- uint8_t unused0[255];
-
- // $(FF)FFF100
- uint16_t grpbasea; // Chip Select Group A Base Register
- uint16_t grpbaseb; // Chip Select Group B Base Register
- uint16_t grpbasec; // Chip Select Group C Base Register
- uint16_t grpbased; // Chip Select Group D Base Register
- uint16_t grpmaska; // Chip Select Group A Mask Register
- uint16_t grpmaskb; // Chip Select Group B Mask Register
- uint16_t grpmaskc; // Chip Select Group C Mask Register
- uint16_t grpmaskd; // Chip Select Group D Mask Register
- uint32_t csa0; // Group A Chip Select 0 Register
- uint32_t csa1; // Group A Chip Select 1 Register
- uint32_t csa2; // Group A Chip Select 2 Register
- uint32_t csa3; // Group A Chip Select 3 Register
- uint32_t csb0; // Group B Chip Select 0 Register
- uint32_t csb1; // Group B Chip Select 1 Register
- uint32_t csb2; // Group B Chip Select 2 Register
- uint32_t csb3; // Group B Chip Select 3 Register
- uint32_t csc0; // Group C Chip Select 0 Register
- uint32_t csc1; // Group C Chip Select 1 Register
- uint32_t csc2; // Group C Chip Select 2 Register
- uint32_t csc3; // Group C Chip Select 3 Register
- uint32_t csd0; // Group D Chip Select 0 Register
- uint32_t csd1; // Group D Chip Select 1 Register
- uint32_t csd2; // Group D Chip Select 2 Register
- uint32_t csd3; // Group D Chip Select 3 Register
- uint8_t unused1[176];
-
- // $(FF)FFF200
- uint16_t pllcr; // PLL Control Register
- uint16_t pllfsr; // PLL Frequency Select Register
- uint8_t pad2[3];
- uint8_t pctlr; // Power Control Register
- uint8_t unused3[248];
-
- // $(FF)FFF300
- uint8_t ivr; // Interrupt Vector Register
- uint8_t unused4[1];
- uint16_t icr; // Interrupt Control Register
- uint32_t imr; // Interrupt Mask Register
- uint32_t iwr; // Interrupt Wakeup Enable Register
- uint32_t isr; // Interrupt Status Register
- uint32_t ipr; // Interrupt Pending Register
- uint8_t unused5[236];
-
- // $(FF)FFF400
- uint8_t padir; // Port A Direction Register
- uint8_t padata; // Port A Data Register
- uint8_t unused6[1];
- uint8_t pasel; // Port A Select Register
- uint8_t unused7[4];
-
- uint8_t pbdir; // Port B Direction Register
- uint8_t pbdata; // Port B Data Register
- uint8_t unused8[1];
- uint8_t pbsel; // Port B Select Register
- uint8_t unused9[4];
-
- uint8_t pcdir; // Port C Direction Register
- uint8_t pcdata; // Port C Data Register
- uint8_t unused10[1];
- uint8_t pcsel; // Port C Select Register
- uint8_t unused11[4];
-
- uint8_t pddir; // Port D Direction Register
- uint8_t pddata; // Port D Data Register
- uint8_t pdpuen; // Port D Pullup Enable Register
- uint8_t unused12[1];
- uint8_t pdpol; // Port D Polarity Register
- uint8_t pdirqen; // Port D IRQ Enable Register
- uint8_t pddataedge; // Port D Data Edge Level
- uint8_t pdirqedge; // Port D IRQ Edge Register
-
- uint8_t pedir; // Port E Direction Register
- uint8_t pedata; // Port E Data Register
- uint8_t pepuen; // Port E Pullup Enable Register
- uint8_t pesel; // Port E Select Register
- uint8_t unused14[4];
-
- uint8_t pfdir; // Port F Direction Register
- uint8_t pfdata; // Port F Data Register
- uint8_t pfpuen; // Port F Pullup Enable Register
- uint8_t pfsel; // Port F Select Register
- uint8_t unused15[4];
-
- uint8_t pgdir; // Port G Direction Register
- uint8_t pgdata; // Port G Data Register
- uint8_t pgpuen; // Port G Pullup Enable Register
- uint8_t pgsel; // Port G Select Register
- uint8_t unused16[4];
-
- uint8_t pjdir; // Port J Direction Register
- uint8_t pjdata; // Port J Data Register
- uint8_t unused17[1];
- uint8_t pjsel; // Port J Select Register
- uint8_t unused18[4];
- uint8_t pkdir; // Port K Direction Register
- uint8_t pkdata; // Port K Data Register
- uint8_t pkpuen; // Port K Pullup Enable Register
- uint8_t pksel; // Port K Select Register
- uint8_t unused19[4];
-
- uint8_t pmdir; // Port M Direction Register
- uint8_t pmdata; // Port M Data Register
- uint8_t pmpuen; // Port M Pullup Enable Register
- uint8_t pmsel; // Port M Select Register
- uint8_t unused20[180];
-
- // $(FF)FFF500
- uint16_t pwmc; // PWM Control Register
- uint16_t pwmp; // PWM Period Register
- uint16_t pwmw; // PWM Width Register
- uint16_t pwmcnt; // PWN Counter
- uint8_t unused21[248];
-
- // $(FF)FFF600
- uint16_t tctl[2]; // Timer Control Register
- uint16_t tprer[2]; // Timer Prescaler Register
- uint16_t tcmp[2]; // Timer Compare Register
- uint16_t tcr[2]; // Timer Capture Register
- uint16_t tcn[2]; // Timer Counter
- uint16_t tstat[2]; // Timer Status
- uint16_t wctlr; // Watchdog Control Register
- uint16_t wcmpr; // Watchdog Compare Register
- uint16_t wcn; // Watchdog Counter
- uint8_t tclear[2]; // Timer Clearable Status
- uint8_t unused22[224];
-
- // $(FF)FFF700
- uint16_t spisr; // SPIS Register
- uint8_t unused23[254];
-
- // $(FF)FFF800
- uint16_t spimdata; // SPIM Data Register
- uint16_t spimcont; // SPIM Control/Status Register
- uint8_t unused24[252];
-
- // $(FF)FFF900
- uint16_t ustcnt; // UART Status/Control Register
- uint16_t ubaud; // UART Baud Control Register
- uint16_t urx; // UART RX Register
- uint16_t utx; // UART TX Register
- uint16_t umisc; // UART Misc Register
- uint8_t unused25[246];
-
- // $(FF)FFFA00
- uint32_t lssa; // Screen Starting Address Register
- uint8_t unused26[1];
- uint8_t lvpw; // Virtual Page Width Register
- uint8_t unused27[2];
- uint16_t lxmax; // Screen Width Register
- uint16_t lymax; // Screen Height Register
- uint8_t unused28[12];
- uint16_t lcxp; // Cursor X Position
- uint16_t lcyp; // Cursor Y Position
- uint16_t lcwch; // Cursor Width & Height Register
- uint8_t unused29[1];
- uint8_t lblkc; // Blink Control Register
- uint8_t lpicf; // Panel Interface Config Register
- uint8_t lpolcf; // Polarity Config Register
- uint8_t unused30[1];
- uint8_t lacdrc; // ACD (M) Rate Control Register
- uint8_t unused31[1];
- uint8_t lpxcd; // Pixel Clock Divider Register
- uint8_t unused32[1];
- uint8_t lckcon; // Clocking Control Register
- uint8_t unused33[1];
- uint8_t llbar; // Last Buffer Address Register
- uint8_t unused34[1];
- uint8_t lotcr; // Octet Terminal Count Register
- uint8_t unused35[1];
- uint8_t lposr; // Panning Offset Register
- uint8_t unused36[3];
- uint8_t lfrcm; // Frame Rate Control Modulation Register
- uint16_t lgpmr; // Gray Palette Mapping Register
- uint8_t unused37[204];
-
- // $(FF)FFFB00
- uint32_t hmsr; // RTC Hours Minutes Seconds Register
- uint32_t alarm; // RTC Alarm Register
- uint8_t unused38[4];
- uint16_t rtcctl; // RTC Control Register
- uint16_t rtcisr; // RTC Interrupt Status Register
- uint16_t rtcienr; // RTC Interrupt Enable Register
- uint16_t stpwtch; // Stopwatch Minutes
- uint8_t unused42[1260];
+ CSAB_WAIT = 0x00000007,
+ CSAB_RO = 0x00000008,
+ CSAB_MASK = 0x0000ff00,
+ CSAB_BSW = 0x00010000,
+ CSAB_COMPARE = 0xff000000,
+
+ CSCD_WAIT = 0x00000007,
+ CSCD_RO = 0x00000008,
+ CSCD_MASK = 0x0000fff0,
+ CSCD_BSW = 0x00010000,
+ CSCD_COMPARE = 0xfff00000,
+
+ INT_SPIM = 0,
+ INT_SPIM_MASK = (1 << INT_SPIM),
+ INT_TIMER2 = 1,
+ INT_TIMER2_MASK = (1 << INT_TIMER2),
+ INT_UART = 2,
+ INT_UART_MASK = (1 << INT_UART),
+ INT_WDT = 3,
+ INT_WDT_MASK = (1 << INT_WDT),
+ INT_RTC = 4,
+ INT_RTC_MASK = (1 << INT_RTC),
+ INT_KB = 6,
+ INT_KB_MASK = (1 << INT_KB),
+ INT_PWM = 7,
+ INT_PWM_MASK = (1 << INT_PWM),
+ INT_INT0 = 8,
+ INT_INT0_MASK = (1 << INT_INT0),
+ INT_INT1 = 9,
+ INT_INT1_MASK = (1 << INT_INT1),
+ INT_INT2 = 10,
+ INT_INT2_MASK = (1 << INT_INT2),
+ INT_INT3 = 11,
+ INT_INT3_MASK = (1 << INT_INT3),
+ INT_INT4 = 12,
+ INT_INT4_MASK = (1 << INT_INT4),
+ INT_INT5 = 13,
+ INT_INT5_MASK = (1 << INT_INT5),
+ INT_INT6 = 14,
+ INT_INT6_MASK = (1 << INT_INT6),
+ INT_INT7 = 15,
+ INT_INT7_MASK = (1 << INT_INT7),
+ INT_KBDINTS = 8,
+ INT_KBDINTS_MASK = (1 << INT_KBDINTS),
+ INT_IRQ1 = 16,
+ INT_IRQ1_MASK = (1 << INT_IRQ1),
+ INT_IRQ2 = 17,
+ INT_IRQ2_MASK = (1 << INT_IRQ2),
+ INT_IRQ3 = 18,
+ INT_IRQ3_MASK = (1 << INT_IRQ3),
+ INT_IRQ6 = 19,
+ INT_IRQ6_MASK = (1 << INT_IRQ6),
+ INT_IRQ5 = 20,
+ INT_IRQ5_MASK = (1 << INT_IRQ5),
+ INT_SPIS = 21,
+ INT_SPIS_MASK = (1 << INT_SPIS),
+ INT_TIMER1 = 22,
+ INT_TIMER1_MASK = (1 << INT_TIMER1),
+ INT_IRQ7 = 23,
+ INT_IRQ7_MASK = (1 << INT_IRQ7),
+
+ RTCHMSR_SECONDS = 0x0000003f,
+ RTCHMSR_SECONDS_SHIFT = 0,
+ RTCHMSR_MINUTES = 0x003f0000,
+ RTCHMSR_MINUTES_SHIFT = 16,
+ RTCHMSR_HOURS = 0x1f000000,
+ RTCHMSR_HOURS_SHIFT = 24,
};
- void internal_map(address_map &map);
+ virtual void scr_w(u8 data);
+
+ void grpbasea_w(u16 data);
+ void grpbaseb_w(u16 data);
+ void grpbasec_w(u16 data);
+ void grpbased_w(u16 data);
+
+ void pllcr_w(u16 data);
+ void pllfsr_w(u16 data);
+ void pctlr_w(u8 data);
+ void ivr_w(u8 data);
+ void icr_w(u8 data);
+ void imr_msw_w(offs_t offset, u16 data, u16 mem_mask);
+ void imr_lsw_w(offs_t offset, u16 data, u16 mem_mask);
+ void isr_msw_w(offs_t offset, u16 data, u16 mem_mask);
+ void isr_lsw_w(offs_t offset, u16 data, u16 mem_mask);
+ void ipr_msw_w(offs_t offset, u16 data, u16 mem_mask);
+ void ipr_lsw_w(offs_t offset, u16 data, u16 mem_mask);
+
+ void padir_w(u8 data);
+ void padata_w(u8 data);
+ void pbdir_w(u8 data);
+ void pbdata_w(u8 data);
+ void pbsel_w(u8 data);
+ void pcdir_w(u8 data);
+ void pcdata_w(u8 data);
+ void pcsel_w(u8 data);
+ void pddir_w(u8 data);
+ void pddata_w(u8 data);
+ void pdpuen_w(u8 data);
+ void pdpol_w(u8 data);
+ void pdirqen_w(u8 data);
+ void pdirqedge_w(u8 data);
+ void pedir_w(u8 data);
+ void pedata_w(u8 data);
+ void pepuen_w(u8 data);
+ void pesel_w(u8 data);
+ void pfdir_w(u8 data);
+ void pfdata_w(u8 data);
+ void pfpuen_w(u8 data);
+ void pfsel_w(u8 data);
+ void pgdir_w(u8 data);
+ void pgdata_w(u8 data);
+ void pgpuen_w(u8 data);
+ void pgsel_w(u8 data);
+
+ virtual void pwmc_w(u16 data) = 0;
+
+ template <int Timer> void tctl_w(u16 data);
+ template <int Timer> void tprer_w(u16 data);
+ template <int Timer> void tcmp_w(u16 data);
+ template <int Timer> void tcr_w(u16 data);
+ template <int Timer> void tcn_w(u16 data);
+ template <int Timer> void tstat_w(u16 data);
+
+ void spimdata_w(u16 data);
+ void spimcont_w(u16 data);
+
+ void ustcnt_w(u16 data);
+ void ubaud_w(u16 data);
+ void urx_w(u16 data);
+ void utx_w(u16 data);
+ void umisc_w(u16 data);
+
+ void lssa_msw_w(offs_t offset, u16 data, u16 mem_mask);
+ void lssa_lsw_w(offs_t offset, u16 data, u16 mem_mask);
+ void lvpw_w(u8 data);
+ void lxmax_w(u16 data);
+ void lymax_w(u16 data);
+ void lcxp_w(u16 data);
+ void lcyp_w(u16 data);
+ void lcwch_w(u16 data);
+ void lblkc_w(u8 data);
+ virtual void lpicf_w(u8 data) = 0;
+ void lpolcf_w(u8 data);
+ void lacdrc_w(u8 data);
+ void lpxcd_w(u8 data);
+ virtual void lckcon_w(u8 data) = 0;
+ void lposr_w(u8 data);
+ void lfrcm_w(u8 data);
+
+ void hmsr_msw_w(offs_t offset, u16 data, u16 mem_mask);
+ void hmsr_lsw_w(offs_t offset, u16 data, u16 mem_mask);
+ void alarm_msw_w(offs_t offset, u16 data, u16 mem_mask);
+ void alarm_lsw_w(offs_t offset, u16 data, u16 mem_mask);
+ virtual void rtcctl_w(offs_t offset, u16 data, u16 mem_mask);
+ void rtcisr_w(offs_t offset, u16 data, u16 mem_mask);
+ void rtcienr_w(offs_t offset, u16 data, u16 mem_mask);
+ void stpwtch_w(offs_t offset, u16 data, u16 mem_mask);
+
+ u8 scr_r();
+
+ u16 grpbasea_r();
+ u16 grpbaseb_r();
+ u16 grpbasec_r();
+ u16 grpbased_r();
+
+ u16 pllcr_r();
+ u16 pllfsr_r();
+ u8 pctlr_r();
+
+ u8 ivr_r();
+ u16 icr_r();
+ u16 imr_msw_r();
+ u16 imr_lsw_r();
+ u16 isr_msw_r();
+ u16 isr_lsw_r();
+ u16 ipr_msw_r();
+ u16 ipr_lsw_r();
+
+ u8 padir_r();
+ u8 padata_r();
+ u8 pbdir_r();
+ u8 pbdata_r();
+ u8 pbsel_r();
+ u8 pcdir_r();
+ u8 pcdata_r();
+ u8 pcsel_r();
+ u8 pddir_r();
+ u8 pddata_r();
+ u8 pdpuen_r();
+ u8 pdpol_r();
+ u8 pdirqen_r();
+ u8 pdirqedge_r();
+ u8 pedir_r();
+ u8 pedata_r();
+ u8 pepuen_r();
+ u8 pesel_r();
+ u8 pfdir_r();
+ u8 pfdata_r();
+ u8 pfpuen_r();
+ u8 pfsel_r();
+ u8 pgdir_r();
+ u8 pgdata_r();
+ u8 pgpuen_r();
+ u8 pgsel_r();
+
+ virtual u16 pwmc_r() = 0;
+
+ template <int Timer> u16 tctl_r();
+ template <int Timer> u16 tprer_r();
+ template <int Timer> u16 tcmp_r();
+ template <int Timer> u16 tcr_r();
+ template <int Timer> u16 tcn_r();
+ template <int Timer> u16 tstat_r();
+
+ u16 spimdata_r();
+ u16 spimcont_r();
+
+ u16 ustcnt_r();
+ u16 ubaud_r();
+ u16 urx_r();
+ u16 utx_r();
+ u16 umisc_r();
+
+ u16 lssa_msw_r();
+ u16 lssa_lsw_r();
+ u8 lvpw_r();
+ u16 lxmax_r();
+ u16 lymax_r();
+ u16 lcxp_r();
+ u16 lcyp_r();
+ u16 lcwch_r();
+ u8 lblkc_r();
+ u8 lpicf_r();
+ u8 lpolcf_r();
+ u8 lacdrc_r();
+ u8 lpxcd_r();
+ u8 lckcon_r();
+ u8 lposr_r();
+ u8 lfrcm_r();
+
+ u16 hmsr_msw_r();
+ u16 hmsr_lsw_r();
+ u16 alarm_msw_r();
+ u16 alarm_lsw_r();
+ u16 rtcctl_r();
+ u16 rtcisr_r();
+ u16 rtcienr_r();
+ u16 stpwtch_r();
+
+ // $(FF)FFF000
+ u8 m_scr; // System Control Register
+
+ // $(FF)FFF100
+ u16 m_grpbasea; // Chip Select Group A Base Register
+ u16 m_grpbaseb; // Chip Select Group B Base Register
+ u16 m_grpbasec; // Chip Select Group C Base Register
+ u16 m_grpbased; // Chip Select Group D Base Register
+
+ // $(FF)FFF200
+ u16 m_pllcr; // PLL Control Register
+ u16 m_pllfsr; // PLL Frequency Select Register
+ u8 m_pctlr; // Power Control Register
+
+ // $(FF)FFF300
+ u8 m_ivr; // Interrupt Vector Register
+ u16 m_icr; // Interrupt Control Register
+ u32 m_imr; // Interrupt Mask Register
+ u32 m_gisr; // (global) Interrupt Status Register
+ u32 m_ipr; // Interrupt Pending Register
+
+ // $(FF)FFF400
+ u8 m_padir; // Port A Direction Register
+ u8 m_padata; // Port A Data Register
+ u8 m_pasel; // Port A Select Register
+
+ u8 m_pbdir; // Port B Direction Register
+ u8 m_pbdata; // Port B Data Register
+ u8 m_pbsel; // Port B Select Register
+
+ u8 m_pcdir; // Port C Direction Register
+ u8 m_pcdata; // Port C Data Register
+ u8 m_pcsel; // Port C Select Register
+
+ u8 m_pddir; // Port D Direction Register
+ u8 m_pddata; // Port D Data Register
+ u8 m_pdpuen; // Port D Pullup Enable Register
+ u8 m_pdpol; // Port D Polarity Register
+ u8 m_pdirqen; // Port D IRQ Enable Register
+ u8 m_pdirqedge; // Port D IRQ Edge Register
+ u8 m_pdindata; // Port D direct input data (not memory-mapped)
+
+ u8 m_pedir; // Port E Direction Register
+ u8 m_pedata; // Port E Data Register
+ u8 m_pepuen; // Port E Pullup Enable Register
+ u8 m_pesel; // Port E Select Register
+
+ u8 m_pfdir; // Port F Direction Register
+ u8 m_pfdata; // Port F Data Register
+ u8 m_pfpuen; // Port F Pullup Enable Register
+ u8 m_pfsel; // Port F Select Register
+
+ u8 m_pgdir; // Port G Direction Register
+ u8 m_pgdata; // Port G Data Register
+ u8 m_pgpuen; // Port G Pullup Enable Register
+ u8 m_pgsel; // Port G Select Register
+
+ // $(FF)FFF500
+ u16 m_pwmc; // PWM Control Register
+ bool m_pwmo;
+
+ // $(FF)FFF600
+ struct timer_regs
+ {
+ u16 tctl; // Timer Control Register
+ u16 tprer; // Timer Prescaler Register
+ u16 tcmp; // Timer Compare Register
+ u16 tcr; // Timer Capture Register
+ u16 tcn; // Timer Counter
+ u16 tstat; // Timer Status
+ u16 tclear; // Timer Clearable Status
+ };
+
+ // $(FF)FFF800
+ u16 m_spimdata; // SPIM Data Register
+ u16 m_spimcont; // SPIM Control/Status Register
+ bool m_spmtxd; // SPIM Shift-register output (TODO: multiplex onto Port K)
+ bool m_spmrxd; // SPIM Shift-register input (TODO: multiplex onto Port K)
+ bool m_spmclk; // SPIM Shift-register clock (TODO: multiplex onto Port K)
+ u16 m_spim_bit_read_idx; // Starting bit index for SPI transfers
+
+ // $(FF)FFF900
+ u16 m_ustcnt; // UART Status/Control Register
+ u16 m_ubaud; // UART Baud Control Register
+ u16 m_urx; // UART RX Register
+ u16 m_utx; // UART TX Register
+ u16 m_umisc; // UART Misc Register
+
+ // $(FF)FFFA00
+ u32 m_lssa; // Screen Starting Address Register
+ u32 m_lssa_end; // Screen Starting Address Register, buffer end address (not memory-mapped)
+ u8 m_lvpw; // Virtual Page Width Register
+ u16 m_lxmax; // Screen Width Register
+ u16 m_lymax; // Screen Height Register
+ u16 m_lcxp; // Cursor X Position
+ u16 m_lcyp; // Cursor Y Position
+ u16 m_lcwch; // Cursor Width & Height Register
+ u8 m_lblkc; // Blink Control Register
+ u8 m_lpicf; // Panel Interface Config Register
+ u8 m_lpolcf; // Polarity Config Register
+ u8 m_lacdrc; // ACD (M) Rate Control Register
+ u8 m_lpxcd; // Pixel Clock Divider Register
+ u8 m_lckcon; // Clocking Control Register
+ u8 m_lposr; // Panning Offset Register
+ u8 m_lfrcm; // Frame Rate Control Modulation Register
+ bool m_lcd_update_pending;
+
+ // $(FF)FFFB00
+ u32 m_hmsr; // RTC Hours Minutes Seconds Register
+ u32 m_alarm; // RTC Alarm Register
+ u16 m_rtcctl; // RTC Control Register
+ u16 m_rtcisr; // RTC Interrupt Status Register
+ u16 m_rtcienr; // RTC Interrupt Enable Register
+ u16 m_stpwtch; // Stopwatch Minutes
+
+ void base_internal_map(u32 addr_bits, address_map &map);
// internal state
- void set_interrupt_line(uint32_t line, uint32_t active);
- void poll_port_d_interrupts();
- void cpu_space_map(address_map &map);
- uint8_t irq_callback(offs_t offset);
- uint32_t get_timer_frequency(uint32_t index);
- void maybe_start_timer(uint32_t index, uint32_t new_enable);
- void timer_compare_event(uint32_t index);
-
- void register_state_save();
-
- TIMER_CALLBACK_MEMBER(timer1_hit);
- TIMER_CALLBACK_MEMBER(timer2_hit);
- TIMER_CALLBACK_MEMBER(pwm_transition);
- TIMER_CALLBACK_MEMBER(rtc_tick);
+ u8 irq_callback(offs_t offset);
+ virtual void register_state_save();
- void internal_write(offs_t offset, uint16_t data, uint16_t mem_mask = 0xffff);
- uint16_t internal_read(offs_t offset, uint16_t mem_mask = 0xffff);
+ void update_ipr_state(u32 changed_mask);
+ void update_imr_state(u32 changed_mask);
+ void set_interrupt_line(u32 line, u32 active);
+ virtual u32 get_irq_mask_for_level(int level) = 0;
+ virtual int get_irq_level_for_mask(u32 level) = 0;
- mc68328_regs_t m_regs;
+ virtual emu_timer *get_timer(int timer) = 0;
+ virtual timer_regs &get_timer_regs(int timer) = 0;
+ virtual u32 get_timer_int(int timer) = 0;
+ template<int Timer> u32 get_timer_frequency();
+ template<int Timer> void update_gptimer_state();
+ template<int Timer> TIMER_CALLBACK_MEMBER(timer_tick);
- emu_timer *m_gptimer[2];
- emu_timer *m_rtc;
+ virtual void lcd_update_info() = 0;
+ virtual u16 lcd_get_lxmax_mask() = 0;
+ virtual int lcd_get_width() = 0;
+ virtual u32 lcd_get_line_word_count() = 0;
+ virtual attotime lcd_get_line_rate() = 0;
+ virtual u8 lcd_get_panel_bit_size() = 0;
+ virtual attotime get_pixclk_rate() = 0;
+
+ TIMER_CALLBACK_MEMBER(refclk_tick);
+ virtual TIMER_CALLBACK_MEMBER(pwm_tick) = 0;
+ TIMER_CALLBACK_MEMBER(rtc_tick);
+ TIMER_CALLBACK_MEMBER(spim_tick);
+ TIMER_CALLBACK_MEMBER(lcd_scan_tick);
+ void fill_lcd_dma_buffer();
+
+ virtual bool rtc_int_is_active() = 0;
+ virtual void rtc_advance_seconds();
+ virtual u16 rtc_get_int_mask() = 0;
+ virtual bool rtc_get_alarm_match() = 0;
+
+ emu_timer *m_refclk;
emu_timer *m_pwm;
+ emu_timer *m_rtc;
+ emu_timer *m_spim;
+
+ emu_timer *m_lcd_scan;
+ bool m_lcd_first_line;
+ u32 m_lcd_sysmem_ptr;
+ u32 m_lcd_line_bit;
+ u32 m_lcd_line_word;
+ bool m_lsclk;
+ std::unique_ptr<u16[]> m_lcd_line_buffer;
+
+ devcb_write_line::array<8> m_out_port_a_cb;
+ devcb_write_line::array<8> m_out_port_b_cb;
+ devcb_write_line::array<8> m_out_port_c_cb;
+ devcb_write_line::array<8> m_out_port_d_cb;
+ devcb_write_line::array<8> m_out_port_e_cb;
+ devcb_write_line::array<8> m_out_port_f_cb;
+ devcb_write_line::array<8> m_out_port_g_cb;
+
+ devcb_read_line::array<8> m_in_port_a_cb;
+ devcb_read_line::array<8> m_in_port_b_cb;
+ devcb_read_line::array<8> m_in_port_c_cb;
+ devcb_read_line::array<8> m_in_port_d_cb;
+ devcb_read_line::array<8> m_in_port_e_cb;
+ devcb_read_line::array<8> m_in_port_f_cb;
+ devcb_read_line::array<8> m_in_port_g_cb;
- devcb_write8 m_out_port_a_cb; /* 8-bit output */
- devcb_write8 m_out_port_b_cb; /* 8-bit output */
- devcb_write8 m_out_port_c_cb; /* 8-bit output */
- devcb_write8 m_out_port_d_cb; /* 8-bit output */
- devcb_write8 m_out_port_e_cb; /* 8-bit output */
- devcb_write8 m_out_port_f_cb; /* 8-bit output */
- devcb_write8 m_out_port_g_cb; /* 8-bit output */
- devcb_write8 m_out_port_j_cb; /* 8-bit output */
- devcb_write8 m_out_port_k_cb; /* 8-bit output */
- devcb_write8 m_out_port_m_cb; /* 8-bit output */
-
- devcb_read8 m_in_port_a_cb; /* 8-bit input */
- devcb_read8 m_in_port_b_cb; /* 8-bit input */
- devcb_read8 m_in_port_c_cb; /* 8-bit input */
- devcb_read8 m_in_port_d_cb; /* 8-bit input */
- devcb_read8 m_in_port_e_cb; /* 8-bit input */
- devcb_read8 m_in_port_f_cb; /* 8-bit input */
- devcb_read8 m_in_port_g_cb; /* 8-bit input */
- devcb_read8 m_in_port_j_cb; /* 8-bit input */
- devcb_read8 m_in_port_k_cb; /* 8-bit input */
- devcb_read8 m_in_port_m_cb; /* 8-bit input */
-
- devcb_write8 m_out_pwm_cb; /* 1-bit output */
-
- devcb_write16 m_out_spim_cb; /* 16-bit output */
- devcb_read16 m_in_spim_cb; /* 16-bit input */
-
- devcb_write_line m_spim_xch_trigger_cb; /* SPIM exchange trigger */ /*todo: not really a write line, fix*/
+ devcb_write_line m_out_pwm_cb;
+
+ devcb_write_line m_out_spim_cb;
+ devcb_read_line m_in_spim_cb;
+
+ devcb_write_line m_out_flm_cb;
+ devcb_write_line m_out_llp_cb;
+ devcb_write_line m_out_lsclk_cb;
+ devcb_write8 m_out_ld_cb;
+ lcd_info_changed_delegate m_lcd_info_changed_cb;
+
+ static const u32 VCO_DIVISORS[8];
};
+class mc68328_device : public mc68328_base_device
+{
+public:
+ mc68328_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ template <int Line> auto out_port_j() { return m_out_port_j_cb[Line].bind(); }
+ template <int Line> auto out_port_k() { return m_out_port_k_cb[Line].bind(); }
+ template <int Line> auto out_port_m() { return m_out_port_m_cb[Line].bind(); }
+ template <int Line> auto in_port_j() { return m_in_port_j_cb[Line].bind(); }
+ template <int Line> auto in_port_k() { return m_in_port_k_cb[Line].bind(); }
+ template <int Line> auto in_port_m() { return m_in_port_m_cb[Line].bind(); }
+
+protected:
+ // device_t implementation
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+
+private:
+ enum : u8
+ {
+ LPICF_GS = 0x01,
+ LPICF_GS_BIT = 0,
+ LPICF_PBSIZ = 0x06,
+ LPICF_PBSIZ_SHIFT = 1,
+ LPICF_PBSIZ_1 = 0x00,
+ LPICF_PBSIZ_2 = 0x02,
+ LPICF_PBSIZ_4 = 0x04,
+
+ LCKCON_PCDS_BIT = 0,
+ LCKCON_DWIDTH = 0x02,
+ LCKCON_DWIDTH_BIT = 1,
+ LCKCON_WS = 0x30,
+ LCKCON_WS_SHIFT = 4,
+ LCKCON_WS_1 = 0x00,
+ LCKCON_WS_2 = 0x10,
+ LCKCON_WS_3 = 0x20,
+ LCKCON_WS_4 = 0x30,
+ LCKCON_DMA16 = 0x40,
+ LCKCON_DMA16_BIT = 6,
+ LCKCON_LCDON_BIT = 7,
+ };
+
+ enum : u16
+ {
+ PWMC_CLKSEL = 0x0007,
+ PWMC_PWMEN = 0x0010,
+ PWMC_POL = 0x0040,
+ PWMC_PIN = 0x0080,
+ PWMC_LOAD = 0x0100,
+ PWMC_IRQEN = 0x4000,
+ PWMC_PWMIRQ = 0x8000,
+
+ LGPMR_PAL2 = 0x0007,
+ LGPMR_PAL3 = 0x0070,
+ LGPMR_PAL0 = 0x0700,
+ LGPMR_PAL1 = 0x7000,
+
+ WCTLR_WDRST = 0x0008,
+ WCTLR_LOCK = 0x0004,
+ WCTLR_FI = 0x0002,
+ WCTLR_WDEN = 0x0001,
+
+ RTCIENR_MASK = 0x001f,
+ };
+
+ void grpmaska_w(u16 data);
+ void grpmaskb_w(u16 data);
+ void grpmaskc_w(u16 data);
+ void grpmaskd_w(u16 data);
+ template<int ChipSelect> void csa_msw_w(offs_t offset, u16 data, u16 mem_mask);
+ template<int ChipSelect> void csa_lsw_w(offs_t offset, u16 data, u16 mem_mask);
+ template<int ChipSelect> void csb_msw_w(offs_t offset, u16 data, u16 mem_mask);
+ template<int ChipSelect> void csb_lsw_w(offs_t offset, u16 data, u16 mem_mask);
+ template<int ChipSelect> void csc_msw_w(offs_t offset, u16 data, u16 mem_mask);
+ template<int ChipSelect> void csc_lsw_w(offs_t offset, u16 data, u16 mem_mask);
+ template<int ChipSelect> void csd_msw_w(offs_t offset, u16 data, u16 mem_mask);
+ template<int ChipSelect> void csd_lsw_w(offs_t offset, u16 data, u16 mem_mask);
+
+ void iwr_msw_w(offs_t offset, u16 data, u16 mem_mask);
+ void iwr_lsw_w(offs_t offset, u16 data, u16 mem_mask);
+
+ void pasel_w(u8 data);
+ void pjdir_w(u8 data);
+ void pjdata_w(u8 data);
+ void pjsel_w(u8 data);
+ void pkdir_w(u8 data);
+ void pkdata_w(u8 data);
+ void pkpuen_w(u8 data);
+ void pksel_w(u8 data);
+ void pmdir_w(u8 data);
+ void pmdata_w(u8 data);
+ void pmpuen_w(u8 data);
+ void pmsel_w(u8 data);
+
+ virtual void pwmc_w(u16 data) override;
+ void pwmp_w(u16 data);
+ void pwmw_w(u16 data);
+ void pwmcnt_w(u16 data);
+
+ void wctlr_w(u16 data);
+ void wcmpr_w(u16 data);
+ void wcn_w(u16 data);
+
+ void spisr_w(u16 data);
+
+ virtual void lpicf_w(u8 data) override;
+ virtual void lckcon_w(u8 data) override;
+ void llbar_w(u8 data);
+ void lotcr_w(u8 data);
+ void lgpmr_w(u8 data);
+
+ u16 grpmaska_r();
+ u16 grpmaskb_r();
+ u16 grpmaskc_r();
+ u16 grpmaskd_r();
+ template<int ChipSelect> u16 csa_msw_r();
+ template<int ChipSelect> u16 csa_lsw_r();
+ template<int ChipSelect> u16 csb_msw_r();
+ template<int ChipSelect> u16 csb_lsw_r();
+ template<int ChipSelect> u16 csc_msw_r();
+ template<int ChipSelect> u16 csc_lsw_r();
+ template<int ChipSelect> u16 csd_msw_r();
+ template<int ChipSelect> u16 csd_lsw_r();
+
+ u16 iwr_msw_r();
+ u16 iwr_lsw_r();
+
+ u8 pasel_r();
+ u8 pjdir_r();
+ u8 pjdata_r();
+ u8 pjsel_r();
+ u8 pkdir_r();
+ u8 pkdata_r();
+ u8 pkpuen_r();
+ u8 pksel_r();
+ u8 pmdata_r();
+ u8 pmdir_r();
+ u8 pmpuen_r();
+ u8 pmsel_r();
+
+ virtual u16 pwmc_r() override;
+ u16 pwmp_r();
+ u16 pwmw_r();
+ u16 pwmcnt_r();
+
+ u16 wctlr_r();
+ u16 wcmpr_r();
+ u16 wcn_r();
+
+ u16 spisr_r();
+
+ u8 llbar_r();
+ u8 lotcr_r();
+ u16 lgpmr_r();
+
+ // $(FF)FFF108
+ u16 m_grpmaska; // Chip Select Group A Mask Register
+ u16 m_grpmaskb; // Chip Select Group B Mask Register
+ u16 m_grpmaskc; // Chip Select Group C Mask Register
+ u16 m_grpmaskd; // Chip Select Group D Mask Register
+ u32 m_csa[4]; // Group A Chip Select Registers
+ u32 m_csb[4]; // Group B Chip Select Registers
+ u32 m_csc[4]; // Group C Chip Select Registers
+ u32 m_csd[4]; // Group D Chip Select Registers
+
+ // $(FF)FFF300
+ u32 m_iwr; // Interrupt Wakeup Enable Register
+
+ // $(FF)FFF438
+ u8 m_pjdir; // Port J Direction Register
+ u8 m_pjdata; // Port J Data Register
+ u8 m_pjsel; // Port J Select Register
+
+ u8 m_pkdir; // Port K Direction Register
+ u8 m_pkdata; // Port K Data Register
+ u8 m_pkpuen; // Port K Pullup Enable Register
+ u8 m_pksel; // Port K Select Register
+
+ u8 m_pmdir; // Port M Direction Register
+ u8 m_pmdata; // Port M Data Register
+ u8 m_pmpuen; // Port M Pullup Enable Register
+ u8 m_pmsel; // Port M Select Register
+
+ // $(FF)FFF502
+ u16 m_pwmp; // PWM Period Register
+ u16 m_pwmw; // PWM Width Register
+ u16 m_pwmcnt; // PWM Counter
+
+ // $(FF)FFF600
+ timer_regs m_timer_regs[2];
+ u16 m_wctlr; // Watchdog Control Register
+ u16 m_wcmpr; // Watchdog Compare Register
+ u16 m_wcn; // Watchdog Counter
+
+ // $(FF)FFF700
+ u16 m_spisr; // SPIS Register
+
+ // $(FF)FFFA00
+ u8 m_llbar; // Last Buffer Address Register
+ u8 m_lotcr; // Octet Terminal Count Register
+ u16 m_lgpmr; // Gray Palette Mapping Register
+
+ void internal_map(address_map &map) ATTR_COLD;
+ void cpu_space_map(address_map &map) ATTR_COLD;
+
+ // internal state
+ virtual void register_state_save() override;
+
+ virtual u32 get_irq_mask_for_level(int level) override;
+ virtual int get_irq_level_for_mask(u32 level) override;
+
+ virtual TIMER_CALLBACK_MEMBER(pwm_tick) override;
+
+ virtual emu_timer *get_timer(int timer) override;
+ virtual timer_regs &get_timer_regs(int timer) override;
+ virtual u32 get_timer_int(int timer) override;
+
+ virtual void lcd_update_info() override;
+ virtual u16 lcd_get_lxmax_mask() override;
+ virtual int lcd_get_width() override;
+ virtual u32 lcd_get_line_word_count() override;
+ virtual attotime lcd_get_line_rate() override;
+ virtual u8 lcd_get_panel_bit_size() override;
+ virtual attotime get_pixclk_rate() override;
+
+ virtual bool rtc_int_is_active() override;
+ virtual u16 rtc_get_int_mask() override;
+ virtual bool rtc_get_alarm_match() override;
+
+ emu_timer *m_gptimer[2];
+
+ devcb_write_line::array<8> m_out_port_j_cb;
+ devcb_write_line::array<8> m_out_port_k_cb;
+ devcb_write_line::array<8> m_out_port_m_cb;
+
+ devcb_read_line::array<8> m_in_port_j_cb;
+ devcb_read_line::array<8> m_in_port_k_cb;
+ devcb_read_line::array<8> m_in_port_m_cb;
+};
+
+class mc68ez328_device : public mc68328_base_device
+{
+public:
+ mc68ez328_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device_t implementation
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+
+private:
+ enum : u8
+ {
+ LPICF_GS = 0x03,
+ LPICF_GS_2COL = 0x00,
+ LPICF_GS_4COL = 0x01,
+ LPICF_GS_16COL = 0x02,
+ LPICF_PBSIZ = 0x0c,
+ LPICF_PBSIZ_SHIFT = 2,
+ LPICF_PBSIZ_1 = 0x00,
+ LPICF_PBSIZ_2 = 0x04,
+ LPICF_PBSIZ_4 = 0x08,
+
+ LCKCON_DWS = 0x0f,
+ LCKCON_DWS_SHIFT = 0,
+ LCKCON_DWIDTH = 0x40,
+ LCKCON_DWIDTH_BIT = 6,
+ LCKCON_LCDON_BIT = 7,
+ };
+
+ enum : u16
+ {
+ CSA_MASK = 0x81ff,
+ CSB_MASK = 0xf9ff,
+ CSC_MASK = 0xf9ff,
+ CSD_MASK = 0xffff,
+ EMUCS_MASK = 0x0070,
+ CS_EN_BIT = 0,
+ CS_SIZ_MASK = 0x000e,
+ CS_SIZ_SHIFT = 1,
+ CS_WS_MASK = 0x0070,
+ CS_WS_SHIFT = 4,
+ CS_BSW_BIT = 7,
+ CS_FLASH_BIT = 8,
+ CS_DRAM_BIT = 9,
+ CS_COMB_BIT = 10,
+ CS_UPSIZ_MASK = 0x1800,
+ CS_UPSIZ_SHIFT = 11,
+ CS_ROP_BIT = 13,
+ CS_SOP_BIT = 14,
+ CS_RO_BIT = 15,
+
+ PWMC_CLKSEL = 0x0003,
+ PWMC_REPEAT = 0x000c,
+ PWMC_REPEAT_SHIFT = 2,
+ PWMC_EN = 0x0010,
+ PWMC_FIFO_AV = 0x0020,
+ PWMC_IRQ_EN = 0x0040,
+ PWMC_IRQ = 0x0080,
+ PWMC_IRQ_BIT = 7,
+ PWMC_PRESCALE = 0x7f00,
+ PWMC_PRESCALE_SHIFT = 8,
+ PWMC_CLK_SRC = 0x8000,
+ PWMC_RECALC_MASK = PWMC_CLK_SRC | PWMC_PRESCALE | PWMC_CLKSEL | PWMC_EN,
+
+ WATCHDOG_MASK = 0x0083,
+ WATCHDOG_EN_BIT = 0,
+ WATCHDOG_ISEL_BIT = 1,
+ WATCHDOG_INTF = 0x0080,
+ WATCHDOG_INTF_BIT = 7,
+ WATCHDOG_CNT_MASK = 0x0300,
+ WATCHDOG_CNT_SHIFT = 8,
+
+ RTCINT_HOUR = 0x0020,
+ RTCINT_SAM0 = 0x0100,
+ RTCINT_SAM1 = 0x0200,
+ RTCINT_SAM2 = 0x0400,
+ RTCINT_SAM3 = 0x0800,
+ RTCINT_SAM4 = 0x1000,
+ RTCINT_SAM5 = 0x2000,
+ RTCINT_SAM6 = 0x4000,
+ RTCINT_SAM7 = 0x8000,
+ RTCINT_RTCIRQ_MASK = 0x00ff,
+
+ RTC_DAYS_MASK = 0x01ff,
+ };
+
+ enum : u32
+ {
+ INT_MSAM = 22,
+ INT_MSAM_MASK = (1 << INT_MSAM),
+ INT_MEMIQ = 23,
+ INT_MEMIQ_MASK = (1 << INT_MEMIQ),
+ };
+
+ virtual void scr_w(u8 data) override;
+
+ void csa_w(offs_t offset, u16 data, u16 mem_mask);
+ void csb_w(offs_t offset, u16 data, u16 mem_mask);
+ void csc_w(offs_t offset, u16 data, u16 mem_mask);
+ void csd_w(offs_t offset, u16 data, u16 mem_mask);
+ void emucs_w(offs_t offset, u16 data, u16 mem_mask);
+
+ virtual void pwmc_w(u16 data) override;
+ void pwms_w(offs_t offset, u16 data, u16 mem_mask);
+ void pwmp_w(u8 data);
+ void pwmcnt_w(u8 data);
+
+ virtual void lpicf_w(u8 data) override;
+ virtual void lckcon_w(u8 data) override;
+ void lrra_w(u8 data);
+ void pwmr_w(offs_t offset, u16 data, u16 mem_mask);
+
+ void watchdog_w(offs_t offset, u16 data, u16 mem_mask);
+ virtual void rtcctl_w(offs_t offset, u16 data, u16 mem_mask) override;
+ void dayr_w(offs_t offset, u16 data, u16 mem_mask);
+ void dayalarm_w(offs_t offset, u16 data, u16 mem_mask);
+
+ u8 revision_r(offs_t offset);
+
+ u16 csa_r();
+ u16 csb_r();
+ u16 csc_r();
+ u16 csd_r();
+ u16 emucs_r();
+
+ virtual u16 pwmc_r() override;
+ u16 pwms_r();
+ u8 pwmp_r();
+ u8 pwmcnt_r();
+
+ u8 lrra_r();
+ u16 pwmr_r();
+
+ u16 watchdog_r();
+ u16 dayr_r();
+ u16 dayalarm_r();
+
+ // $(FF)FFF100
+ u16 m_csa; // Group A Chip-Select Register
+ u16 m_csb; // Group B Chip-Select Register
+ u16 m_csc; // Group C Chip-Select Register
+ u16 m_csd; // Group D Chip-Select Register
+ u16 m_emucs; // Emulation Chip-Select Register
+
+ // $(FF)FFF502
+ u8 m_pwmp; // PWM Period Register
+ u8 m_pwmcnt; // PWM Counter
+ u8 m_pwmfifo[5]; // PWM FIFO
+ u8 m_pwmfifo_wr; // PWM FIFO Write Index
+ u8 m_pwmfifo_rd; // PWM FIFO Read Index
+ u8 m_pwmfifo_cnt; // PWM FIFO Count
+ u8 m_pwm_rep_cnt; // PWM Repeat Count
+
+ // $(FF)FFF600
+ timer_regs m_timer_regs;
+
+ // $(FF)FFFA00
+ u8 m_lrra; // LCD Refresh Rate Adjustment Register
+ u16 m_pwmr; // PWM Contrast Control Register
+
+ // $(FF)FFFB00
+ u16 m_watchdog; // Watchdog Timer Register
+ u16 m_dayr; // RTC Day Count Register
+ u16 m_dayalarm; // RTC Day Alarm Register
+ u8 m_sam_cnt; // RTC Sample Timer Counter (internal, not readable)
+
+ void internal_map(address_map &map) ATTR_COLD;
+ void cpu_space_map(address_map &map) ATTR_COLD;
+
+ // internal state
+ virtual void register_state_save() override;
+
+ virtual u32 get_irq_mask_for_level(int level) override;
+ virtual int get_irq_level_for_mask(u32 level) override;
+
+ void update_pwm_period(bool high_cycle);
+ void pwm_fifo_push(u8 data);
+ void pwm_fifo_pop();
+ virtual TIMER_CALLBACK_MEMBER(pwm_tick) override;
+
+ virtual emu_timer *get_timer(int timer) override;
+ virtual timer_regs &get_timer_regs(int timer) override;
+ virtual u32 get_timer_int(int timer) override;
+
+ virtual void lcd_update_info() override;
+ virtual u16 lcd_get_lxmax_mask() override;
+ virtual int lcd_get_width() override;
+ virtual u32 lcd_get_line_word_count() override;
+ virtual attotime lcd_get_line_rate() override;
+ virtual u8 lcd_get_panel_bit_size() override;
+ virtual attotime get_pixclk_rate() override;
+
+ TIMER_CALLBACK_MEMBER(sample_timer_tick);
+ virtual bool rtc_int_is_active() override;
+ virtual void rtc_advance_seconds() override;
+ virtual u16 rtc_get_int_mask() override;
+ virtual bool rtc_get_alarm_match() override;
+
+ emu_timer *m_gptimer;
+ emu_timer *m_rtc_sample_timer;
+};
DECLARE_DEVICE_TYPE(MC68328, mc68328_device)
+DECLARE_DEVICE_TYPE(MC68EZ328, mc68ez328_device)
#endif // MAME_MACHINE_MC68328_H