summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2019-07-07 09:11:09 -0400
committer AJR <ajrhacker@users.noreply.github.com>2019-07-07 09:11:09 -0400
commit9b0b9a2f22049493d193a62ce897361e0b53914c (patch)
treea79d5d1995c7df49f70ef2b931fccfb10eeb4703
parentbbe1dbea998c61bd4ea64088ad38ae1787e2e3f2 (diff)
m37710: Break up m37710_internal_r/w and m_m37710_regs block (nw)
-rw-r--r--src/devices/cpu/m37710/m37710.cpp1064
-rw-r--r--src/devices/cpu/m37710/m37710.h95
2 files changed, 709 insertions, 450 deletions
diff --git a/src/devices/cpu/m37710/m37710.cpp b/src/devices/cpu/m37710/m37710.cpp
index 962c03295be..4a6afbff5a1 100644
--- a/src/devices/cpu/m37710/m37710.cpp
+++ b/src/devices/cpu/m37710/m37710.cpp
@@ -59,7 +59,15 @@
#include "m37710cm.h"
#include "m37710il.h"
-#define M37710_DEBUG (0) // enables verbose logging for peripherals, etc.
+// verbose logging for peripherals, etc.
+#define LOG_GENERAL (1U << 0)
+#define LOG_PORTS (1U << 1)
+#define LOG_AD (1U << 2)
+#define LOG_UART (1U << 3)
+#define LOG_TIMER (1U << 4)
+#define LOG_INT (1U << 5)
+//#define VERBOSE (LOG_GENERAL | LOG_PORTS | LOG_AD | LOG_UART | LOG_TIMER | LOG_INT)
+#include "logmacro.h"
DEFINE_DEVICE_TYPE(M37702M2, m37702m2_device, "m37702m2", "Mitsubishi M37702M2")
@@ -74,7 +82,31 @@ DEFINE_DEVICE_TYPE(M37720S1, m37720s1_device, "m37720s1", "Mitsubishi M37720S1")
// (M37702E2: same with EPROM instead of mask ROM)
void m37702m2_device::map(address_map &map)
{
- map(0x000000, 0x00007f).rw(FUNC(m37702m2_device::m37710_internal_r), FUNC(m37702m2_device::m37710_internal_w));
+ map(0x000002, 0x000015).rw(FUNC(m37702m2_device::port_r), FUNC(m37702m2_device::port_w));
+ map(0x00001e, 0x00001e).rw(FUNC(m37702m2_device::ad_control_r), FUNC(m37702m2_device::ad_control_w));
+ map(0x00001f, 0x00001f).rw(FUNC(m37702m2_device::ad_sweep_r), FUNC(m37702m2_device::ad_sweep_w));
+ map(0x000020, 0x00002f).r(FUNC(m37702m2_device::ad_result_r));
+ map(0x000030, 0x000030).rw(FUNC(m37702m2_device::uart0_mode_r), FUNC(m37702m2_device::uart0_mode_w));
+ map(0x000031, 0x000031).w(FUNC(m37702m2_device::uart0_baud_w));
+ map(0x000032, 0x000033).w(FUNC(m37702m2_device::uart0_tbuf_w));
+ map(0x000034, 0x000034).rw(FUNC(m37702m2_device::uart0_ctrl_reg0_r), FUNC(m37702m2_device::uart0_ctrl_reg0_w));
+ map(0x000035, 0x000035).rw(FUNC(m37702m2_device::uart0_ctrl_reg1_r), FUNC(m37702m2_device::uart0_ctrl_reg1_w));
+ map(0x000036, 0x000037).r(FUNC(m37702m2_device::uart0_rbuf_r));
+ map(0x000038, 0x000038).rw(FUNC(m37702m2_device::uart1_mode_r), FUNC(m37702m2_device::uart1_mode_w));
+ map(0x000039, 0x000039).w(FUNC(m37702m2_device::uart1_baud_w));
+ map(0x00003a, 0x00003b).w(FUNC(m37702m2_device::uart1_tbuf_w));
+ map(0x00003c, 0x00003c).rw(FUNC(m37702m2_device::uart1_ctrl_reg0_r), FUNC(m37702m2_device::uart1_ctrl_reg0_w));
+ map(0x00003d, 0x00003d).rw(FUNC(m37702m2_device::uart1_ctrl_reg1_r), FUNC(m37702m2_device::uart1_ctrl_reg1_w));
+ map(0x00003e, 0x00003f).r(FUNC(m37702m2_device::uart1_rbuf_r));
+ map(0x000040, 0x000040).rw(FUNC(m37702m2_device::count_start_r), FUNC(m37702m2_device::count_start_w));
+ map(0x000042, 0x000042).w(FUNC(m37702m2_device::one_shot_start_w));
+ map(0x000044, 0x000044).rw(FUNC(m37702m2_device::up_down_r), FUNC(m37702m2_device::up_down_w));
+ map(0x000046, 0x000055).rw(FUNC(m37702m2_device::timer_reg_r), FUNC(m37702m2_device::timer_reg_w));
+ map(0x000056, 0x00005d).rw(FUNC(m37702m2_device::timer_mode_r), FUNC(m37702m2_device::timer_mode_w));
+ map(0x00005e, 0x00005e).rw(FUNC(m37702m2_device::proc_mode_r), FUNC(m37702m2_device::proc_mode_w));
+ map(0x000060, 0x000060).w(FUNC(m37702m2_device::watchdog_timer_w));
+ map(0x000061, 0x000061).rw(FUNC(m37702m2_device::watchdog_freq_r), FUNC(m37702m2_device::watchdog_freq_w));
+ map(0x00006c, 0x00007f).rw(FUNC(m37702m2_device::int_control_r), FUNC(m37702m2_device::int_control_w));
map(0x000080, 0x00027f).ram();
map(0x00c000, 0x00ffff).rom().region(M37710_INTERNAL_ROM_REGION, 0);
}
@@ -83,7 +115,31 @@ void m37702m2_device::map(address_map &map)
// M37702S1: 512 bytes internal RAM, no internal ROM
void m37702s1_device::map(address_map &map)
{
- map(0x000000, 0x00007f).rw(FUNC(m37702s1_device::m37710_internal_r), FUNC(m37702s1_device::m37710_internal_w));
+ map(0x000002, 0x000015).rw(FUNC(m37702s1_device::port_r), FUNC(m37702s1_device::port_w));
+ map(0x00001e, 0x00001e).rw(FUNC(m37702s1_device::ad_control_r), FUNC(m37702s1_device::ad_control_w));
+ map(0x00001f, 0x00001f).rw(FUNC(m37702s1_device::ad_sweep_r), FUNC(m37702s1_device::ad_sweep_w));
+ map(0x000020, 0x00002f).r(FUNC(m37702s1_device::ad_result_r));
+ map(0x000030, 0x000030).rw(FUNC(m37702s1_device::uart0_mode_r), FUNC(m37702s1_device::uart0_mode_w));
+ map(0x000031, 0x000031).w(FUNC(m37702s1_device::uart0_baud_w));
+ map(0x000032, 0x000033).w(FUNC(m37702s1_device::uart0_tbuf_w));
+ map(0x000034, 0x000034).rw(FUNC(m37702s1_device::uart0_ctrl_reg0_r), FUNC(m37702s1_device::uart0_ctrl_reg0_w));
+ map(0x000035, 0x000035).rw(FUNC(m37702s1_device::uart0_ctrl_reg1_r), FUNC(m37702s1_device::uart0_ctrl_reg1_w));
+ map(0x000036, 0x000037).r(FUNC(m37702s1_device::uart0_rbuf_r));
+ map(0x000038, 0x000038).rw(FUNC(m37702s1_device::uart1_mode_r), FUNC(m37702s1_device::uart1_mode_w));
+ map(0x000039, 0x000039).w(FUNC(m37702s1_device::uart1_baud_w));
+ map(0x00003a, 0x00003b).w(FUNC(m37702s1_device::uart1_tbuf_w));
+ map(0x00003c, 0x00003c).rw(FUNC(m37702s1_device::uart1_ctrl_reg0_r), FUNC(m37702s1_device::uart1_ctrl_reg0_w));
+ map(0x00003d, 0x00003d).rw(FUNC(m37702s1_device::uart1_ctrl_reg1_r), FUNC(m37702s1_device::uart1_ctrl_reg1_w));
+ map(0x00003e, 0x00003f).r(FUNC(m37702s1_device::uart1_rbuf_r));
+ map(0x000040, 0x000040).rw(FUNC(m37702s1_device::count_start_r), FUNC(m37702s1_device::count_start_w));
+ map(0x000042, 0x000042).w(FUNC(m37702s1_device::one_shot_start_w));
+ map(0x000044, 0x000044).rw(FUNC(m37702s1_device::up_down_r), FUNC(m37702s1_device::up_down_w));
+ map(0x000046, 0x000055).rw(FUNC(m37702s1_device::timer_reg_r), FUNC(m37702s1_device::timer_reg_w));
+ map(0x000056, 0x00005d).rw(FUNC(m37702s1_device::timer_mode_r), FUNC(m37702s1_device::timer_mode_w));
+ map(0x00005e, 0x00005e).rw(FUNC(m37702s1_device::proc_mode_r), FUNC(m37702s1_device::proc_mode_w));
+ map(0x000060, 0x000060).w(FUNC(m37702s1_device::watchdog_timer_w));
+ map(0x000061, 0x000061).rw(FUNC(m37702s1_device::watchdog_freq_r), FUNC(m37702s1_device::watchdog_freq_w));
+ map(0x00006c, 0x00007f).rw(FUNC(m37702s1_device::int_control_r), FUNC(m37702s1_device::int_control_w));
map(0x000080, 0x00027f).ram();
}
@@ -91,14 +147,70 @@ void m37702s1_device::map(address_map &map)
// M37710S4: 2048 bytes internal RAM, no internal ROM
void m37710s4_device::map(address_map &map)
{
- map(0x000000, 0x00007f).rw(FUNC(m37710s4_device::m37710_internal_r), FUNC(m37710s4_device::m37710_internal_w));
+ map(0x000002, 0x000015).rw(FUNC(m37710s4_device::port_r), FUNC(m37710s4_device::port_w)); // FIXME: P4-P8 only
+ map(0x00001a, 0x00001d).w(FUNC(m37710s4_device::da_reg_w)).umask16(0x00ff);
+ map(0x00001e, 0x00001e).rw(FUNC(m37710s4_device::ad_control_r), FUNC(m37710s4_device::ad_control_w));
+ map(0x00001f, 0x00001f).rw(FUNC(m37710s4_device::ad_sweep_r), FUNC(m37710s4_device::ad_sweep_w));
+ map(0x000020, 0x00002f).r(FUNC(m37710s4_device::ad_result_r));
+ map(0x000030, 0x000030).rw(FUNC(m37710s4_device::uart0_mode_r), FUNC(m37710s4_device::uart0_mode_w));
+ map(0x000031, 0x000031).w(FUNC(m37710s4_device::uart0_baud_w));
+ map(0x000032, 0x000033).w(FUNC(m37710s4_device::uart0_tbuf_w));
+ map(0x000034, 0x000034).rw(FUNC(m37710s4_device::uart0_ctrl_reg0_r), FUNC(m37710s4_device::uart0_ctrl_reg0_w));
+ map(0x000035, 0x000035).rw(FUNC(m37710s4_device::uart0_ctrl_reg1_r), FUNC(m37710s4_device::uart0_ctrl_reg1_w));
+ map(0x000036, 0x000037).r(FUNC(m37710s4_device::uart0_rbuf_r));
+ map(0x000038, 0x000038).rw(FUNC(m37710s4_device::uart1_mode_r), FUNC(m37710s4_device::uart1_mode_w));
+ map(0x000039, 0x000039).w(FUNC(m37710s4_device::uart1_baud_w));
+ map(0x00003a, 0x00003b).w(FUNC(m37710s4_device::uart1_tbuf_w));
+ map(0x00003c, 0x00003c).rw(FUNC(m37710s4_device::uart1_ctrl_reg0_r), FUNC(m37710s4_device::uart1_ctrl_reg0_w));
+ map(0x00003d, 0x00003d).rw(FUNC(m37710s4_device::uart1_ctrl_reg1_r), FUNC(m37710s4_device::uart1_ctrl_reg1_w));
+ map(0x00003e, 0x00003f).r(FUNC(m37710s4_device::uart1_rbuf_r));
+ map(0x000040, 0x000040).rw(FUNC(m37710s4_device::count_start_r), FUNC(m37710s4_device::count_start_w));
+ map(0x000042, 0x000042).w(FUNC(m37710s4_device::one_shot_start_w));
+ map(0x000044, 0x000044).rw(FUNC(m37710s4_device::up_down_r), FUNC(m37710s4_device::up_down_w));
+ map(0x000046, 0x000055).rw(FUNC(m37710s4_device::timer_reg_r), FUNC(m37710s4_device::timer_reg_w));
+ map(0x000056, 0x00005d).rw(FUNC(m37710s4_device::timer_mode_r), FUNC(m37710s4_device::timer_mode_w));
+ map(0x00005e, 0x00005e).rw(FUNC(m37710s4_device::proc_mode_r), FUNC(m37710s4_device::proc_mode_w));
+ map(0x000060, 0x000060).w(FUNC(m37710s4_device::watchdog_timer_w));
+ map(0x000061, 0x000061).rw(FUNC(m37710s4_device::watchdog_freq_r), FUNC(m37710s4_device::watchdog_freq_w));
+ map(0x000062, 0x000062).rw(FUNC(m37710s4_device::waveform_mode_r), FUNC(m37710s4_device::waveform_mode_w));
+ map(0x000064, 0x000065).w(FUNC(m37710s4_device::pulse_output_w));
+ map(0x00006c, 0x00007f).rw(FUNC(m37710s4_device::int_control_r), FUNC(m37710s4_device::int_control_w));
map(0x000080, 0x00087f).ram();
}
// M37720S1: 512 bytes internal RAM, no internal ROM, built-in DMA
void m37720s1_device::map(address_map &map)
{
- map(0x000000, 0x00007f).rw(FUNC(m37720s1_device::m37710_internal_r), FUNC(m37720s1_device::m37710_internal_w));
+ map(0x000002, 0x000019).rw(FUNC(m37720s1_device::port_r), FUNC(m37720s1_device::port_w)); // FIXME: P4-P10 only
+ map(0x00001a, 0x00001d).w(FUNC(m37720s1_device::pulse_output_w)).umask16(0x00ff);
+ map(0x00001e, 0x00001e).rw(FUNC(m37720s1_device::ad_control_r), FUNC(m37720s1_device::ad_control_w));
+ map(0x00001f, 0x00001f).rw(FUNC(m37720s1_device::ad_sweep_r), FUNC(m37720s1_device::ad_sweep_w));
+ map(0x000020, 0x00002f).r(FUNC(m37720s1_device::ad_result_r));
+ map(0x000030, 0x000030).rw(FUNC(m37720s1_device::uart0_mode_r), FUNC(m37720s1_device::uart0_mode_w));
+ map(0x000031, 0x000031).w(FUNC(m37720s1_device::uart0_baud_w));
+ map(0x000032, 0x000033).w(FUNC(m37720s1_device::uart0_tbuf_w));
+ map(0x000034, 0x000034).rw(FUNC(m37720s1_device::uart0_ctrl_reg0_r), FUNC(m37720s1_device::uart0_ctrl_reg0_w));
+ map(0x000035, 0x000035).rw(FUNC(m37720s1_device::uart0_ctrl_reg1_r), FUNC(m37720s1_device::uart0_ctrl_reg1_w));
+ map(0x000036, 0x000037).r(FUNC(m37720s1_device::uart0_rbuf_r));
+ map(0x000038, 0x000038).rw(FUNC(m37720s1_device::uart1_mode_r), FUNC(m37720s1_device::uart1_mode_w));
+ map(0x000039, 0x000039).w(FUNC(m37720s1_device::uart1_baud_w));
+ map(0x00003a, 0x00003b).w(FUNC(m37720s1_device::uart1_tbuf_w));
+ map(0x00003c, 0x00003c).rw(FUNC(m37720s1_device::uart1_ctrl_reg0_r), FUNC(m37720s1_device::uart1_ctrl_reg0_w));
+ map(0x00003d, 0x00003d).rw(FUNC(m37720s1_device::uart1_ctrl_reg1_r), FUNC(m37720s1_device::uart1_ctrl_reg1_w));
+ map(0x00003e, 0x00003f).r(FUNC(m37720s1_device::uart1_rbuf_r));
+ map(0x000040, 0x000040).rw(FUNC(m37720s1_device::count_start_r), FUNC(m37720s1_device::count_start_w));
+ map(0x000042, 0x000042).w(FUNC(m37720s1_device::one_shot_start_w));
+ map(0x000044, 0x000044).rw(FUNC(m37720s1_device::up_down_r), FUNC(m37720s1_device::up_down_w));
+ map(0x000046, 0x000055).rw(FUNC(m37720s1_device::timer_reg_r), FUNC(m37720s1_device::timer_reg_w));
+ map(0x000056, 0x00005d).rw(FUNC(m37720s1_device::timer_mode_r), FUNC(m37720s1_device::timer_mode_w));
+ map(0x00005e, 0x00005e).rw(FUNC(m37720s1_device::proc_mode_r), FUNC(m37720s1_device::proc_mode_w));
+ map(0x000060, 0x000060).w(FUNC(m37720s1_device::watchdog_timer_w));
+ map(0x000061, 0x000061).rw(FUNC(m37720s1_device::watchdog_freq_r), FUNC(m37720s1_device::watchdog_freq_w));
+ map(0x000062, 0x000062).rw(FUNC(m37720s1_device::rto_control_r), FUNC(m37720s1_device::rto_control_w));
+ map(0x000064, 0x000064).rw(FUNC(m37720s1_device::dram_control_r), FUNC(m37720s1_device::dram_control_w));
+ map(0x000066, 0x000066).w(FUNC(m37720s1_device::refresh_timer_w));
+ map(0x000068, 0x000069).rw(FUNC(m37720s1_device::dmac_control_r), FUNC(m37720s1_device::dmac_control_w));
+ map(0x00006c, 0x00007f).rw(FUNC(m37720s1_device::int_control_r), FUNC(m37720s1_device::int_control_w));
map(0x000080, 0x00027f).ram();
}
@@ -152,36 +264,28 @@ std::vector<std::pair<int, const address_space_config *>> m37710_cpu_device::mem
/* interrupt control mapping */
-const int m37710_cpu_device::m37710_irq_levels[M37710_INTERRUPT_MAX] =
-{
- // maskable
- 0x6f, // DMA3 0
- 0x6e, // DMA2 1
- 0x6d, // DMA1 2
- 0x6c, // DMA0 3
- 0x70, // ADC 4
- 0x73, // UART 1 XMIT 5
- 0x74, // UART 1 RECV 6
- 0x71, // UART 0 XMIT 7
- 0x72, // UART 0 RECV 8
- 0x7c, // Timer B2 9
- 0x7b, // Timer B1 10
- 0x7a, // Timer B0 11
- 0x79, // Timer A4 12
- 0x78, // Timer A3 13
- 0x77, // Timer A2 14
- 0x76, // Timer A1 15
- 0x75, // Timer A0 16
- 0x7f, // IRQ 2 13
- 0x7e, // IRQ 1 18
- 0x7d, // IRQ 0 19
-
- // non-maskable
- 0, // watchdog
- 0, // debugger control
- 0, // BRK
- 0, // divide by zero
- 0, // reset
+const int m37710_cpu_device::m37710_int_reg_map[M37710_MASKABLE_INTERRUPTS] =
+{
+ M37710_LINE_DMA0, // level 3 (0x6c)
+ M37710_LINE_DMA1, // level 2 (0x6d)
+ M37710_LINE_DMA2, // level 1 (0x6e)
+ M37710_LINE_DMA3, // level 0 (0x6f)
+ M37710_LINE_ADC, // level 4 (0x70)
+ M37710_LINE_UART0XMIT, // level 7 (0x71)
+ M37710_LINE_UART0RECV, // level 8 (0x72)
+ M37710_LINE_UART1XMIT, // level 5 (0x73)
+ M37710_LINE_UART1RECV, // level 6 (0x74)
+ M37710_LINE_TIMERB2, // level 16 (0x75)
+ M37710_LINE_TIMERB1, // level 15 (0x76)
+ M37710_LINE_TIMERB0, // level 14 (0x77)
+ M37710_LINE_TIMERA4, // level 13 (0x78)
+ M37710_LINE_TIMERA3, // level 12 (0x79)
+ M37710_LINE_TIMERA2, // level 11 (0x7a)
+ M37710_LINE_TIMERA1, // level 10 (0x7b)
+ M37710_LINE_TIMERA0, // level 9 (0x7c)
+ M37710_LINE_IRQ2, // level 19 (0x7d)
+ M37710_LINE_IRQ1, // level 18 (0x7e)
+ M37710_LINE_IRQ0, // level 17 (0x7f)
};
const int m37710_cpu_device::m37710_irq_vectors[M37710_INTERRUPT_MAX] =
@@ -218,143 +322,23 @@ const int m37710_cpu_device::m37710_irq_vectors[M37710_INTERRUPT_MAX] =
// M37710 internal peripherals
-const char *const m37710_cpu_device::m37710_rnames[128] =
-{
- "",
- "",
- "Port P0 reg",
- "Port P1 reg",
- "Port P0 dir reg",
- "Port P1 dir reg",
- "Port P2 reg",
- "Port P3 reg",
- "Port P2 dir reg",
- "Port P3 dir reg",
- "Port P4 reg", // 10 (0x0A) - ports 0, 1, 2, 3 don't exist on 37720
- "Port P5 reg",
- "Port P4 dir reg",
- "Port P5 dir reg",
- "Port P6 reg",
- "Port P7 reg",
- "Port P6 dir reg", // 16 (0x10)
- "Port P7 dir reg",
- "Port P8 reg",
- "",
- "Port P8 dir reg",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "A/D control reg",
- "A/D sweep pin select",
- "A/D 0", // 32 (0x20)
- "",
- "A/D 1",
- "",
- "A/D 2",
- "",
- "A/D 3",
- "",
- "A/D 4",
- "",
- "A/D 5",
- "",
- "A/D 6",
- "",
- "A/D 7",
- "",
- "UART0 transmit/recv mode", // 48 (0x30)
- "UART0 baud rate", // 0x31
- "UART0 transmit buf L", // 0x32
- "UART0 transmit buf H", // 0x33
- "UART0 transmit/recv ctrl 0", // 0x34
- "UART0 transmit/recv ctrl 1", // 0x35
- "UART0 recv buf L", // 0x36
- "UART0 recv buf H", // 0x37
- "UART1 transmit/recv mode", // 0x38
- "UART1 baud rate",
- "UART1 transmit buf L",
- "UART1 transmit buf H",
- "UART1 transmit/recv ctrl 0",
- "UART1 transmit/recv ctrl 1",
- "UART1 recv buf L",
- "UART1 recv buf H",
- "Count start", // 0x40
- "",
- "One-shot start",
- "",
- "Up-down register",
- "",
- "Timer A0 L", // 0x46
- "Timer A0 H",
- "Timer A1 L",
- "Timer A1 H",
- "Timer A2 L",
- "Timer A2 H",
- "Timer A3 L",
- "Timer A3 H",
- "Timer A4 L",
- "Timer A4 H",
- "Timer B0 L",
- "Timer B0 H", // 0x50
- "Timer B1 L",
- "Timer B1 H",
- "Timer B2 L",
- "Timer B2 H",
- "Timer A0 mode",
- "Timer A1 mode",
- "Timer A2 mode",
- "Timer A3 mode",
- "Timer A4 mode",
- "Timer B0 mode",
- "Timer B1 mode",
- "Timer B2 mode",
- "Processor mode",
- "",
- "Watchdog reset", // 0x60
- "Watchdog frequency", // 0x61
- "Real-time output control",
- "",
- "DRAM control",
- "",
- "Refresh timer",
- "",
- "DMAC control L",
- "DMAC control H",
- "",
- "",
- "DMA0 IRQ ctrl",
- "DMA1 IRQ ctrl",
- "DMA2 IRQ ctrl",
- "DMA3 IRQ ctrl",
- "A/D IRQ ctrl",
- "UART0 xmit IRQ ctrl", // 0x70
- "UART0 recv IRQ ctrl",
- "UART1 xmit IRQ ctrl",
- "UART1 recv IRQ ctrl",
- "Timer A0 IRQ ctrl", // 0x74
- "Timer A1 IRQ ctrl", // 0x75
- "Timer A2 IRQ ctrl", // 0x76
- "Timer A3 IRQ ctrl",
- "Timer A4 IRQ ctrl", // 0x78
- "Timer B0 IRQ ctrl",
- "Timer B1 IRQ ctrl",
- "Timer B2 IRQ ctrl",
- "INT0 IRQ ctrl",
- "INT1 IRQ ctrl",
- "INT2 IRQ ctrl",
-};
-
const char *const m37710_cpu_device::m37710_tnames[8] =
{
"A0", "A1", "A2", "A3", "A4", "B0", "B1", "B2"
};
+const char *const m37710_cpu_device::m37710_intnames[M37710_INTERRUPT_MAX] =
+{
+ "DMA3", "DMA2", "DMA1", "DMA0",
+ "A/D",
+ "UART1 xmit", "UART1 recv",
+ "UART0 xmit", "UART0 recv",
+ "Timer B2", "Timer B1", "Timer B0",
+ "Timer A4", "Timer A3", "Timer A2", "Timer A1", "Timer A0",
+ "INT2", "INT1", "INT0",
+ "Watchdog timer", "DBC", "BRK", "Zero division", "RESET" // nonmaskable
+};
+
TIMER_CALLBACK_MEMBER( m37710_cpu_device::m37710_timer_cb )
{
int which = param;
@@ -377,30 +361,28 @@ void m37710_cpu_device::m37710_external_tick(int timer, int state)
}
// check if enabled and in event counter mode
- if (m_m37710_regs[0x40] & (1<<timer))
+ if (BIT(m_count_start, timer))
{
- if ((m_m37710_regs[0x56+timer] & 0x3) == 1)
+ if ((m_timer_mode[timer] & 0x3) == 1)
{
int upcount = 0;
// timer b always counts down
if (timer <= 4)
{
- if (m_m37710_regs[0x56+timer] & 0x10)
+ if (BIT(m_timer_mode[timer], 4))
{
// up/down determined by timer out pin
upcount = m_timer_out[timer];
}
else
- upcount = m_m37710_regs[0x44] >> timer & 1;
+ upcount = m_up_down_reg >> timer & 1;
}
- int incval = (upcount) ? 1 : -1;
- int edgeval = (upcount) ? 0xff : 0x00;
-
- if (m_m37710_regs[0x46+(timer*2)] == edgeval)
- m_m37710_regs[0x46+(timer*2)+1] += incval;
- m_m37710_regs[0x46+(timer*2)] += incval;
+ if (upcount)
+ m_timer_reg[timer]++;
+ else
+ m_timer_reg[timer]--;
}
else
{
@@ -416,292 +398,474 @@ void m37710_cpu_device::m37710_recalc_timer(int timer)
static const int tscales[4] = { 2, 16, 64, 512 };
// check if enabled
- if (m_m37710_regs[0x40] & (1<<timer))
+ if (BIT(m_count_start, timer))
{
- #if M37710_DEBUG
- logerror("Timer %d (%s) is enabled\n", timer, m37710_tnames[timer]);
- #endif
+ LOGMASKED(LOG_TIMER, "Timer %d (%s) is enabled\n", timer, m37710_tnames[timer]);
// set the timer's value
- tval = m_m37710_regs[0x46+(timer*2)] | (m_m37710_regs[0x47+(timer*2)]<<8);
+ tval = m_timer_reg[timer];
// HACK: ignore if timer is 8MHz (MAME slows down to a crawl)
- if (tval == 0 && (m_m37710_regs[0x56+timer]&0xc0) == 0) return;
+ if (tval == 0 && (m_timer_mode[timer]&0xc0) == 0) return;
// check timer's mode
// modes are slightly different between timer groups A and B
if (timer < 5)
{
- switch (m_m37710_regs[0x56+timer] & 0x3)
+ switch (m_timer_mode[timer] & 0x3)
{
case 0: // timer mode
- time = attotime::from_hz(unscaled_clock()) * tscales[m_m37710_regs[0x56+timer]>>6];
+ time = attotime::from_hz(unscaled_clock()) * tscales[m_timer_mode[timer]>>6];
time *= (tval + 1);
- #if M37710_DEBUG
- logerror("Timer %d in timer mode, %f Hz\n", timer, 1.0 / time.as_double());
- #endif
+ LOGMASKED(LOG_TIMER, "Timer %d in timer mode, %f Hz\n", timer, 1.0 / time.as_double());
m_timers[timer]->adjust(time, timer);
m_reload[timer] = time;
break;
case 1: // event counter mode
- #if M37710_DEBUG
- logerror("Timer %d in event counter mode\n", timer);
- #endif
+ LOGMASKED(LOG_TIMER, "Timer %d in event counter mode\n", timer);
break;
case 2: // one-shot pulse mode
- #if M37710_DEBUG
- logerror("Timer %d in one-shot mode\n", timer);
- #endif
+ LOGMASKED(LOG_TIMER, "Timer %d in one-shot mode\n", timer);
break;
case 3: // PWM mode
- #if M37710_DEBUG
- logerror("Timer %d in PWM mode\n", timer);
- #endif
+ LOGMASKED(LOG_TIMER, "Timer %d in PWM mode\n", timer);
break;
}
}
else
{
- switch (m_m37710_regs[0x56+timer] & 0x3)
+ switch (m_timer_mode[timer] & 0x3)
{
case 0: // timer mode
- time = attotime::from_hz(unscaled_clock()) * tscales[m_m37710_regs[0x56+timer]>>6];
+ time = attotime::from_hz(unscaled_clock()) * tscales[m_timer_mode[timer]>>6];
time *= (tval + 1);
- #if M37710_DEBUG
- logerror("Timer %d in timer mode, %f Hz\n", timer, 1.0 / time.as_double());
- #endif
+ LOGMASKED(LOG_TIMER, "Timer %d in timer mode, %f Hz\n", timer, 1.0 / time.as_double());
m_timers[timer]->adjust(time, timer);
m_reload[timer] = time;
break;
case 1: // event counter mode
- #if M37710_DEBUG
- logerror("Timer %d in event counter mode\n", timer);
- #endif
+ LOGMASKED(LOG_TIMER, "Timer %d in event counter mode\n", timer);
break;
case 2: // pulse period/pulse width measurement mode
- #if M37710_DEBUG
- logerror("Timer %d in pulse period/width measurement mode\n", timer);
- #endif
+ LOGMASKED(LOG_TIMER, "Timer %d in pulse period/width measurement mode\n", timer);
break;
case 3:
- #if M37710_DEBUG
- logerror("Timer %d in unknown mode!\n", timer);
- #endif
+ LOGMASKED(LOG_TIMER, "Timer %d in unknown mode!\n", timer);
break;
}
}
}
}
-READ8_MEMBER(m37710_cpu_device::m37710_internal_r)
+uint8_t m37710_cpu_device::port_r(offs_t offset)
{
- uint8_t d;
-
- #if M37710_DEBUG
- if (offset > 1)
- logerror("m37710_internal_r from %02x: %s (PC=%x)\n", (int)offset, m37710_rnames[(int)offset], REG_PB<<16 | REG_PC);
- #endif
+ int p = (offset & 0x1c) >> 1 | (offset & 0x01);
- switch (offset)
+ uint8_t result = 0;
+ if (p < 11)
{
- // ports
- case 0x02: // p0
- d = m_m37710_regs[0x04];
- if (d != 0xff)
- return (m_port_in_cb[0](0,~d)&~d) | (m_m37710_regs[offset]&d);
- break;
- case 0x03: // p1
- d = m_m37710_regs[0x05];
- if (d != 0xff)
- return (m_port_in_cb[1](0,~d)&~d) | (m_m37710_regs[offset]&d);
- break;
- case 0x06: // p2
- d = m_m37710_regs[0x08];
- if (d != 0xff)
- return (m_port_in_cb[2](0,~d)&~d) | (m_m37710_regs[offset]&d);
- break;
- case 0x07: // p3
- d = m_m37710_regs[0x09];
- if (d != 0xff)
- return (m_port_in_cb[3](0,~d)&~d) | (m_m37710_regs[offset]&d);
- break;
- case 0x0a: // p4
- d = m_m37710_regs[0x0c];
- if (d != 0xff)
- return (m_port_in_cb[4](0,~d)&~d) | (m_m37710_regs[offset]&d);
- break;
- case 0x0b: // p5
- d = m_m37710_regs[0x0d];
- if (d != 0xff)
- return (m_port_in_cb[5](0,~d)&~d) | (m_m37710_regs[offset]&d);
- break;
- case 0x0e: // p6
- d = m_m37710_regs[0x10];
- if (d != 0xff)
- return (m_port_in_cb[6](0,~d)&~d) | (m_m37710_regs[offset]&d);
- break;
- case 0x0f: // p7
- d = m_m37710_regs[0x11];
- if (d != 0xff)
- return (m_port_in_cb[7](0,~d)&~d) | (m_m37710_regs[offset]&d);
- break;
- case 0x12: // p8
- d = m_m37710_regs[0x14];
+ if (BIT(offset, 1))
+ result = m_port_dir[p];
+ else
+ {
+ uint8_t d = m_port_dir[p];
if (d != 0xff)
- return (m_port_in_cb[8](0,~d)&~d) | (m_m37710_regs[offset]&d);
- break;
+ result = (m_port_in_cb[p](0, ~d) & ~d) | (m_port_regs[p] & d);
+ else
+ result = m_port_regs[p];
+ }
+ }
+
+ LOGMASKED(LOG_PORTS, "port_r from %02x: Port P%d %s = %x\n", (int)offset + 0x02, p, BIT(offset, 1) ? "dir reg" : "reg", result);
+
+ return result;
+}
+
+void m37710_cpu_device::port_w(offs_t offset, uint8_t data)
+{
+ int p = (offset & 0x1c) >> 1 | (offset & 0x01);
+
+ if (p < 11)
+ {
+ LOGMASKED(LOG_PORTS, "port_w %x to %02x: Port P%d %s = %x\n", data, (int)offset + 0x02, p,
+ BIT(offset, 1) ? "dir reg" : "reg",
+ BIT(offset, 1) ? m_port_dir[p] : m_port_regs[p]);
- // A-D regs
- case 0x20:
- return m_analog_cb[0]() & 0xff;
- case 0x21:
- return m_analog_cb[0]() >> 8;
- case 0x22:
- return m_analog_cb[1]() & 0xff;
- case 0x23:
- return m_analog_cb[1]() >> 8;
- case 0x24:
- return m_analog_cb[2]() & 0xff;
- case 0x25:
- return m_analog_cb[2]() >> 8;
- case 0x26:
- return m_analog_cb[3]() & 0xff;
- case 0x27:
- return m_analog_cb[3]() >> 8;
- case 0x28:
- return m_analog_cb[4]() & 0xff;
- case 0x29:
- return m_analog_cb[4]() >> 8;
- case 0x2a:
- return m_analog_cb[5]() & 0xff;
- case 0x2b:
- return m_analog_cb[5]() >> 8;
- case 0x2c:
- return m_analog_cb[6]() & 0xff;
- case 0x2d:
- return m_analog_cb[6]() >> 8;
- case 0x2e:
- return m_analog_cb[7]() & 0xff;
- case 0x2f:
- return m_analog_cb[7]() >> 8;
-
- // UART control (not hooked up yet)
- case 0x34: case 0x3c:
- return 0x08;
- case 0x35: case 0x3d:
- return 0xff;
-
- // A-D IRQ control (also not properly hooked up yet)
- case 0x70:
- return m_m37710_regs[offset] | 8;
-
- default:
- return m_m37710_regs[offset];
+ if (BIT(offset, 1))
+ m_port_dir[p] = data;
+ else
+ {
+ uint8_t d = m_port_dir[p];
+ if (d != 0xff)
+ m_port_out_cb[p](0, data & d, d);
+ m_port_regs[p] = data;
+ }
}
+}
- return m_m37710_regs[offset];
+void m37710_cpu_device::da_reg_w(offs_t offset, uint8_t data)
+{
+ LOGMASKED(LOG_GENERAL, "da_reg_w %x to %02X: D/A %d\n", data, (int)(offset * 2) + 0x1a, offset);
}
-WRITE8_MEMBER(m37710_cpu_device::m37710_internal_w)
+void m37710_cpu_device::pulse_output_w(offs_t offset, uint8_t data)
{
- int i;
- uint8_t prevdata;
- uint8_t d;
+ LOGMASKED(LOG_GENERAL, "pulse_output_w %x: Pulse output data register %d\n", data, offset);
+}
- #if M37710_DEBUG
- if (offset != 0x60) // filter out watchdog
- logerror("m37710_internal_w %x to %02x: %s = %x\n", data, (int)offset, m37710_rnames[(int)offset], m_m37710_regs[offset]);
- #endif
+uint8_t m37710_cpu_device::ad_control_r()
+{
+ return m_ad_control;
+}
- prevdata = m_m37710_regs[offset];
- m_m37710_regs[offset] = data;
+void m37710_cpu_device::ad_control_w(uint8_t data)
+{
+ LOGMASKED(LOG_AD, "ad_control_w %x: A/D control reg = %x\n", data, m_ad_control);
- switch(offset)
- {
- // ports
- case 0x02: // p0
- d = m_m37710_regs[0x04];
- if (d != 0)
- m_port_out_cb[0](0,data&d,d);
- break;
- case 0x03: // p1
- d = m_m37710_regs[0x05];
- if (d != 0)
- m_port_out_cb[1](0,data&d,d);
- break;
- case 0x06: // p2
- d = m_m37710_regs[0x08];
- if (d != 0)
- m_port_out_cb[2](0,data&d,d);
- break;
- case 0x07: // p3
- d = m_m37710_regs[0x09];
- if (d != 0)
- m_port_out_cb[3](0,data&d,d);
- break;
- case 0x0a: // p4
- d = m_m37710_regs[0x0c];
- if (d != 0)
- m_port_out_cb[4](0,data&d,d);
- break;
- case 0x0b: // p5
- d = m_m37710_regs[0x0d];
- if (d != 0)
- m_port_out_cb[5](0,data&d,d);
- break;
- case 0x0e: // p6
- d = m_m37710_regs[0x10];
- if (d != 0)
- m_port_out_cb[6](0,data&d,d);
- break;
- case 0x0f: // p7
- d = m_m37710_regs[0x11];
- if (d != 0)
- m_port_out_cb[7](0,data&d,d);
- break;
- case 0x12: // p8
- d = m_m37710_regs[0x14];
- if (d != 0)
- m_port_out_cb[8](0,data&d,d);
- break;
+ m_ad_control = data;
+}
- case 0x40: // count start
- for (i = 0; i < 8; i++)
- {
- if ((data & (1<<i)) && !(prevdata & (1<<i)))
- m37710_recalc_timer(i);
- }
- break;
+uint8_t m37710_cpu_device::ad_sweep_r()
+{
+ return m_ad_sweep;
+}
- // internal interrupt control
- case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75:
- case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c:
- m37710_set_irq_line(offset, (data & 8) ? HOLD_LINE : CLEAR_LINE);
- m37710i_update_irqs();
- break;
+void m37710_cpu_device::ad_sweep_w(uint8_t data)
+{
+ LOGMASKED(LOG_AD, "ad_sweep_w %x: A/D sweep pin select = %x\n", data, m_ad_sweep);
- // external interrupt control
- case 0x7d: case 0x7e: case 0x7f:
- m37710_set_irq_line(offset, (data & 8) ? HOLD_LINE : CLEAR_LINE);
- m37710i_update_irqs();
+ m_ad_sweep = data;
+}
- // level-sense interrupts are not implemented yet
- if (data & 0x20) logerror("error M37710: INT%d level-sense\n",offset-0x7d);
- break;
+uint16_t m37710_cpu_device::ad_result_r(offs_t offset)
+{
+ uint16_t result = m_analog_cb[offset]();
- default:
- break;
- }
+ LOGMASKED(LOG_AD, "ad_result_r from %02x: A/D %d = %x (PC=%x)\n", (int)(offset * 2) + 0x20, offset, result, REG_PB<<16 | REG_PC);
+
+ return result;
+}
+
+uint8_t m37710_cpu_device::uart0_mode_r()
+{
+ LOGMASKED(LOG_UART, "uart0_mode_r: UART0 transmit/recv mode = %x (PC=%x)\n", m_uart_mode[0], REG_PB<<16 | REG_PC);
+
+ return m_uart_mode[0];
+}
+
+void m37710_cpu_device::uart0_mode_w(uint8_t data)
+{
+ LOGMASKED(LOG_UART, "uart0_mode_w %x: UART0 transmit/recv mode = %x\n", data, m_uart_mode[0]);
+
+ m_uart_mode[0] = data;
+}
+
+uint8_t m37710_cpu_device::uart1_mode_r()
+{
+ LOGMASKED(LOG_UART, "uart1_mode_r: UART1 transmit/recv mode = %x (PC=%x)\n", m_uart_mode[1], REG_PB<<16 | REG_PC);
+
+ return m_uart_mode[1];
+}
+
+void m37710_cpu_device::uart1_mode_w(uint8_t data)
+{
+ LOGMASKED(LOG_UART, "uart1_mode_w %x: UART1 transmit/recv mode = %x\n", data, m_uart_mode[1]);
+
+ m_uart_mode[1] = data;
+}
+
+void m37710_cpu_device::uart0_baud_w(uint8_t data)
+{
+ LOGMASKED(LOG_UART, "uart0_baud_w %x: UART0 baud rate = %x\n", data, m_uart_baud[0]);
+
+ m_uart_baud[0] = data;
+}
+
+void m37710_cpu_device::uart1_baud_w(uint8_t data)
+{
+ LOGMASKED(LOG_UART, "uart1_baud_w %x: UART1 baud rate = %x\n", data, m_uart_baud[1]);
+
+ m_uart_baud[1] = data;
+}
+
+void m37710_cpu_device::uart0_tbuf_w(uint16_t data)
+{
+ LOGMASKED(LOG_UART, "uart0_tbuf_w %x: UART0 transmit buf\n", data);
+}
+
+void m37710_cpu_device::uart1_tbuf_w(uint16_t data)
+{
+ LOGMASKED(LOG_UART, "uart1_tbuf_w %x: UART1 transmit buf\n", data);
+}
+
+uint8_t m37710_cpu_device::uart0_ctrl_reg0_r()
+{
+ LOGMASKED(LOG_UART, "uart0_ctrl_reg0_r: UART0 transmit/recv ctrl 0 = %x (PC=%x)\n", m_uart_ctrl_reg0[0], REG_PB<<16 | REG_PC);
+
+ //return m_uart_ctrl_reg0[0];
+ return 0x08; // not hooked up yet
+}
+
+void m37710_cpu_device::uart0_ctrl_reg0_w(uint8_t data)
+{
+ LOGMASKED(LOG_UART, "uart0_ctrl_reg0_w %x: UART0 transmit/recv ctrl 0 = %x\n", data, m_uart_ctrl_reg0[0]);
+
+ m_uart_ctrl_reg0[0] = data;
+}
+
+uint8_t m37710_cpu_device::uart1_ctrl_reg0_r()
+{
+ LOGMASKED(LOG_UART, "uart1_ctrl_reg0_r: UART1 transmit/recv ctrl 0 = %x (PC=%x)\n", m_uart_ctrl_reg0[1], REG_PB<<16 | REG_PC);
+
+ //return m_uart_ctrl_reg0[1];
+ return 0xff; // not hooked up yet
+}
+
+void m37710_cpu_device::uart1_ctrl_reg0_w(uint8_t data)
+{
+ LOGMASKED(LOG_UART, "uart1_ctrl_reg0_w %x: UART1 transmit/recv ctrl 0 = %x\n", data, m_uart_ctrl_reg0[1]);
+
+ m_uart_ctrl_reg0[1] = data;
+}
+
+uint8_t m37710_cpu_device::uart0_ctrl_reg1_r()
+{
+ LOGMASKED(LOG_UART, "uart0_ctrl_reg1_r: UART0 transmit/recv ctrl 1 = %x (PC=%x)\n", m_uart_ctrl_reg1[0], REG_PB<<16 | REG_PC);
+
+ return m_uart_ctrl_reg1[0];
+}
+
+void m37710_cpu_device::uart0_ctrl_reg1_w(uint8_t data)
+{
+ LOGMASKED(LOG_UART, "uart0_ctrl_reg0_w %x: UART0 transmit/recv ctrl 1 = %x\n", data, m_uart_ctrl_reg1[0]);
+
+ m_uart_ctrl_reg1[0] = data;
+}
+
+uint8_t m37710_cpu_device::uart1_ctrl_reg1_r()
+{
+ LOGMASKED(LOG_UART, "uart1_ctrl_reg1_r: UART1 transmit/recv ctrl 1 = %x (PC=%x)\n", m_uart_ctrl_reg1[1], REG_PB<<16 | REG_PC);
+
+ return m_uart_ctrl_reg1[1];
+}
+
+void m37710_cpu_device::uart1_ctrl_reg1_w(uint8_t data)
+{
+ LOGMASKED(LOG_UART, "uart1_ctrl_reg1_w %x: UART1 transmit/recv ctrl 1 = %x\n", data, m_uart_ctrl_reg1[1]);
+
+ m_uart_ctrl_reg1[1] = data;
+}
+
+uint16_t m37710_cpu_device::uart0_rbuf_r()
+{
+ LOGMASKED(LOG_UART, "uart0_rbuf_r: UART0 recv buf (PC=%x)\n", REG_PB<<16 | REG_PC);
+
+ return 0;
+}
+
+uint16_t m37710_cpu_device::uart1_rbuf_r()
+{
+ LOGMASKED(LOG_UART, "uart1_rbuf_r: UART1 recv buf (PC=%x)\n", REG_PB<<16 | REG_PC);
+
+ return 0;
+}
+
+uint8_t m37710_cpu_device::count_start_r()
+{
+ LOGMASKED(LOG_TIMER, "count_start_r: Count start = %x (PC=%x)\n", m_count_start, REG_PB<<16 | REG_PC);
+
+ return m_count_start;
+}
+
+void m37710_cpu_device::count_start_w(uint8_t data)
+{
+ uint8_t prevdata = m_count_start;
+ m_count_start = data;
+
+ LOGMASKED(LOG_TIMER, "count_start_w %x: Count start = %x\n", data, prevdata);
+
+ for (int i = 0; i < 8; i++)
+ if (BIT(data, i) && !BIT(prevdata, i))
+ m37710_recalc_timer(i);
+}
+
+void m37710_cpu_device::one_shot_start_w(uint8_t data)
+{
+ LOGMASKED(LOG_TIMER, "one_shot_start_w %x: One-shot start = %x\n", data, m_one_shot_start);
+
+ m_one_shot_start = data;
+}
+
+uint8_t m37710_cpu_device::up_down_r()
+{
+ LOGMASKED(LOG_TIMER, "up_down_r: Up-down register = %x (PC=%x)\n", m_up_down_reg, REG_PB<<16 | REG_PC);
+
+ // bits 7-5 read back as 0
+ return m_up_down_reg & 0x1f;
+}
+
+void m37710_cpu_device::up_down_w(uint8_t data)
+{
+ LOGMASKED(LOG_TIMER, "up_down_w %x: Up-down register = %x\n", data, m_up_down_reg);
+
+ m_up_down_reg = data;
+}
+
+uint16_t m37710_cpu_device::timer_reg_r(offs_t offset, uint16_t mem_mask)
+{
+ return m_timer_reg[offset] & mem_mask;
+}
+
+void m37710_cpu_device::timer_reg_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ LOGMASKED(LOG_TIMER, "timer_reg_w %04x & %04x to %02x: Timer %s = %04x\n", data, mem_mask, (int)(offset * 2) + 0x46, m37710_tnames[offset], m_timer_reg[offset]);
+
+ m_timer_reg[offset] = (data & mem_mask) | (m_timer_reg[offset] & ~mem_mask);
+}
+
+uint8_t m37710_cpu_device::timer_mode_r(offs_t offset)
+{
+ LOGMASKED(LOG_TIMER, "timer_mode_r from %02x: Timer %s mode = %x (PC=%x)\n", (int)offset + 0x56, m37710_tnames[offset], m_timer_mode[offset], REG_PB<<16 | REG_PC);
+
+ return m_timer_mode[offset];
+}
+
+void m37710_cpu_device::timer_mode_w(offs_t offset, uint8_t data)
+{
+ LOGMASKED(LOG_TIMER, "timer_mode_w %x to %02x: Timer %s mode = %x\n", data, (int)offset + 0x56, m37710_tnames[offset], m_timer_mode[offset]);
+
+ m_timer_mode[offset] = data;
+}
+
+uint8_t m37710_cpu_device::proc_mode_r(offs_t offset)
+{
+ LOGMASKED(LOG_GENERAL, "proc_mode_r: Processor mode = %x (PC=%x)\n", m_proc_mode, REG_PB<<16 | REG_PC);
+
+ return m_proc_mode & 0xf7;
+}
+
+void m37710_cpu_device::proc_mode_w(uint8_t data)
+{
+ LOGMASKED(LOG_GENERAL, "proc_mode_w %x: Processor mode = %x\n", data, m_proc_mode);
+
+ m_proc_mode = data;
+}
+
+void m37710_cpu_device::watchdog_timer_w(uint8_t data)
+{
+ // TODO: reset watchdog timer (data is irrelevant)
+}
+
+uint8_t m37710_cpu_device::watchdog_freq_r()
+{
+ return m_watchdog_freq;
+}
+
+void m37710_cpu_device::watchdog_freq_w(uint8_t data)
+{
+ LOGMASKED(LOG_GENERAL, "watchdog_freq_w %x: Watchdog timer frequency = %x\n", data, m_watchdog_freq);
+
+ m_watchdog_freq = data;
+}
+
+uint8_t m37710_cpu_device::waveform_mode_r()
+{
+ LOGMASKED(LOG_GENERAL, "waveform_mode_r: Waveform output mode (PC=%x)\n", REG_PB<<16 | REG_PC);
+
+ return 0;
+}
+
+void m37710_cpu_device::waveform_mode_w(uint8_t data)
+{
+ LOGMASKED(LOG_GENERAL, "waveform_mode_w %x: Waveform output mode\n", data);
+}
+
+uint8_t m37710_cpu_device::rto_control_r()
+{
+ LOGMASKED(LOG_GENERAL, "rto_control_r: Real-time output control = %x (PC=%x)\n", m_rto_control, REG_PB<<16 | REG_PC);
+
+ return m_rto_control;
+}
+
+void m37710_cpu_device::rto_control_w(uint8_t data)
+{
+ LOGMASKED(LOG_GENERAL, "rto_control_w %x: Real-time output control = %x\n", data, m_rto_control);
+
+ m_rto_control = data;
+}
+
+uint8_t m37710_cpu_device::dram_control_r()
+{
+ LOGMASKED(LOG_GENERAL, "dram_control_r: DRAM control = %x (PC=%x)\n", m_dram_control, REG_PB<<16 | REG_PC);
+
+ return m_dram_control;
+}
+
+void m37710_cpu_device::dram_control_w(uint8_t data)
+{
+ LOGMASKED(LOG_GENERAL, "dram_control_w %x: DRAM control = %x\n", data, m_dram_control);
+
+ m_dram_control = data;
+}
+
+void m37710_cpu_device::refresh_timer_w(uint8_t data)
+{
+ LOGMASKED(LOG_GENERAL, "refresh_timer_w %x: Set refresh timer\n", data);
+}
+
+uint16_t m37710_cpu_device::dmac_control_r(offs_t offset, uint16_t mem_mask)
+{
+ return m_dmac_control & mem_mask;
+}
+
+void m37710_cpu_device::dmac_control_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ LOGMASKED(LOG_GENERAL, "dmac_control_w %04x & %04x: DMAC control = %04x\n", data, mem_mask, m_dmac_control);
+
+ m_dmac_control = (data & mem_mask) | (m_timer_reg[offset] & ~mem_mask);
+}
+
+uint8_t m37710_cpu_device::int_control_r(offs_t offset)
+{
+ assert(offset < M37710_MASKABLE_INTERRUPTS);
+ int level = m37710_int_reg_map[offset];
+
+ //LOGMASKED(LOG_INT, "int_control_r from %02x: %s IRQ ctrl = %x (PC=%x)\n", (int)offset + 0x6c, m37710_intnames[level], m_int_control[level], REG_PB<<16 | REG_PC);
+
+ uint8_t result = m_int_control[level];
+
+ // A-D IRQ not properly hooked up yet
+ if (level == M37710_LINE_ADC)
+ result |= 8;
+
+ return result;
+}
+
+void m37710_cpu_device::int_control_w(offs_t offset, uint8_t data)
+{
+ assert(offset < M37710_MASKABLE_INTERRUPTS);
+ int level = m37710_int_reg_map[offset];
+
+ LOGMASKED(LOG_INT, "int_control_w %x to %02x: %s IRQ ctrl = %x\n", data, (int)offset + 0x6c, m37710_intnames[level], m_int_control[level]);
+
+ m_int_control[level] = data;
+
+ //m37710_set_irq_line(offset, (data & 8) ? HOLD_LINE : CLEAR_LINE);
+ m37710i_update_irqs();
+
+ // level-sense interrupts are not implemented yet
+ if ((level == M37710_LINE_IRQ0 || level == M37710_LINE_IRQ1 || level == M37710_LINE_IRQ2) && BIT(data, 5))
+ logerror("error M37710: INT%d level-sense\n", M37710_LINE_IRQ0 - level);
}
const m37710_cpu_device::opcode_func *const m37710_cpu_device::m37710i_opcodes[4] =
@@ -765,9 +929,9 @@ void m37710_cpu_device::m37710i_update_irqs()
if ((pending & (1 << curirq)))
{
// this IRQ is set
- if (m37710_irq_levels[curirq])
+ if (curirq < M37710_MASKABLE_INTERRUPTS)
{
- int control = m_m37710_regs[m37710_irq_levels[curirq]];
+ int control = m_int_control[curirq];
int thispri = control & 7;
// logerror("line %d set, level %x curpri %x IPL %x\n", curirq, thispri, curpri, m_ipl);
// it's maskable, check if the level works, also make sure it's acceptable for the current CPU level
@@ -833,45 +997,37 @@ void m37710_cpu_device::device_reset()
/* Reset internal registers */
// port direction
- m_m37710_regs[0x04] = 0;
- m_m37710_regs[0x05] = 0;
- m_m37710_regs[0x08] = 0;
- m_m37710_regs[0x09] = 0;
- m_m37710_regs[0x0c] = 0;
- m_m37710_regs[0x0d] = 0;
- m_m37710_regs[0x10] = 0;
- m_m37710_regs[0x11] = 0;
- m_m37710_regs[0x14] = 0;
-
- m_m37710_regs[0x1e] &= 7; // A-D control
- m_m37710_regs[0x1f] |= 3; // A-D sweep
-
- // UART
- m_m37710_regs[0x30] = 0;
- m_m37710_regs[0x38] = 0;
- m_m37710_regs[0x34] = (m_m37710_regs[0x34] & 0xf0) | 8;
- m_m37710_regs[0x3c] = (m_m37710_regs[0x3c] & 0xf0) | 8;
- m_m37710_regs[0x35] = 2;
- m_m37710_regs[0x3d] = 2;
- m_m37710_regs[0x37]&= 1;
- m_m37710_regs[0x3f]&= 1;
-
- // timer
- m_m37710_regs[0x40] = 0;
- m_m37710_regs[0x42]&= 0x1f;
- m_m37710_regs[0x44] = 0;
- for (i = 0x56; i < 0x5e; i++)
- m_m37710_regs[i] = 0;
-
- m_m37710_regs[0x5e] = 0; // processor mode
- m_m37710_regs[0x61]&= 1; // watchdog frequency
+ std::fill(std::begin(m_port_dir), std::end(m_port_dir), 0);
+
+ // A-D
+ m_ad_control &= 7;
+ m_ad_sweep = (m_ad_sweep & ~0xdc) | 3;
+
+ // UARTs
+ for (i = 0; i < 2; i++)
+ {
+ m_uart_mode[i] = 0;
+ m_uart_ctrl_reg0[i] = (m_uart_ctrl_reg0[i] & 0xe0) | 8;
+ m_uart_ctrl_reg1[i] = 2;
+ }
+
+ // timers
+ m_count_start = 0;
+ m_one_shot_start &= ~0x1f;
+ m_up_down_reg = 0;
+ for (i = 0; i < 8; i++)
+ m_timer_mode[i] = 0;
+
+ m_proc_mode = 0; // processor mode
+ m_watchdog_freq &= ~1; // watchdog timer frequency
+ m_rto_control &= ~3;
+ m_dram_control &= ~0x8f;
// interrupt control
- m_m37710_regs[0x7d] &= 0x3f;
- m_m37710_regs[0x7e] &= 0x3f;
- m_m37710_regs[0x7f] &= 0x3f;
- for (i = 0x70; i < 0x7d; i++)
- m_m37710_regs[i] &= 0xf;
+ for (i = 0; i <= M37710_LINE_TIMERA0; i++)
+ m_int_control[i] &= ~0xf;
+ for (i = M37710_LINE_IRQ2; i <= M37710_LINE_IRQ0; i++)
+ m_int_control[i] &= ~0x3f;
/* Clear IPL, m, x, D and set I */
m_ipl = 0;
@@ -971,19 +1127,13 @@ void m37710_cpu_device::m37710_set_irq_line(int line, int state)
{
case CLEAR_LINE:
LINE_IRQ &= ~(1 << line);
- if (m37710_irq_levels[line])
- {
- m_m37710_regs[m37710_irq_levels[line]] &= ~8;
- }
+ m_int_control[line] &= ~8;
break;
case ASSERT_LINE:
case HOLD_LINE:
LINE_IRQ |= (1 << line);
- if (m37710_irq_levels[line])
- {
- m_m37710_regs[m37710_irq_levels[line]] |= 8;
- }
+ m_int_control[line] |= 8;
break;
default: break;
@@ -1048,9 +1198,23 @@ void m37710_cpu_device::device_start()
m_im3 = 0;
m_im4 = 0;
m_irq_delay = 0;
- m_irq_level = 0;
m_stopped = 0;
- memset(m_m37710_regs, 0, sizeof(m_m37710_regs));
+ std::fill(std::begin(m_port_regs), std::end(m_port_regs), 0);
+ std::fill(std::begin(m_port_dir), std::end(m_port_dir), 0);
+ m_ad_control = 0;
+ m_ad_sweep = 0;
+ std::fill(std::begin(m_uart_mode), std::end(m_uart_mode), 0);
+ std::fill(std::begin(m_uart_baud), std::end(m_uart_baud), 0);
+ std::fill(std::begin(m_uart_ctrl_reg0), std::end(m_uart_ctrl_reg0), 0);
+ std::fill(std::begin(m_uart_ctrl_reg1), std::end(m_uart_ctrl_reg1), 0);
+ m_count_start = 0;
+ m_one_shot_start = 0;
+ m_up_down_reg = 0;
+ std::fill(std::begin(m_timer_reg), std::end(m_timer_reg), 0);
+ std::fill(std::begin(m_timer_mode), std::end(m_timer_mode), 0);
+ m_proc_mode = 0;
+ m_watchdog_freq = 0;
+ std::fill(std::begin(m_int_control), std::end(m_int_control), 0);
m_program = &space(AS_PROGRAM);
m_cache = m_program->cache<1, 0, ENDIANNESS_LITTLE>();
@@ -1105,9 +1269,20 @@ void m37710_cpu_device::device_start()
save_item(NAME(m_im3));
save_item(NAME(m_im4));
save_item(NAME(m_irq_delay));
- save_item(NAME(m_irq_level));
save_item(NAME(m_stopped));
- save_item(NAME(m_m37710_regs));
+ save_item(NAME(m_port_regs));
+ save_item(NAME(m_port_dir));
+ save_item(NAME(m_ad_control));
+ save_item(NAME(m_ad_sweep));
+ save_item(NAME(m_uart_mode));
+ save_item(NAME(m_uart_baud));
+ save_item(NAME(m_uart_ctrl_reg0));
+ save_item(NAME(m_uart_ctrl_reg1));
+ save_item(NAME(m_count_start));
+ save_item(NAME(m_one_shot_start));
+ save_item(NAME(m_up_down_reg));
+ save_item(NAME(m_timer_reg));
+ save_item(NAME(m_timer_mode));
save_item(NAME(m_reload[0]));
save_item(NAME(m_reload[1]));
save_item(NAME(m_reload[2]));
@@ -1117,6 +1292,9 @@ void m37710_cpu_device::device_start()
save_item(NAME(m_reload[6]));
save_item(NAME(m_reload[7]));
save_item(NAME(m_timer_out));
+ save_item(NAME(m_proc_mode));
+ save_item(NAME(m_watchdog_freq));
+ save_item(NAME(m_int_control));
machine().save().register_postload(save_prepost_delegate(save_prepost_delegate(FUNC(m37710_cpu_device::m37710_restore_state), this)));
diff --git a/src/devices/cpu/m37710/m37710.h b/src/devices/cpu/m37710/m37710.h
index c495b451d7b..a4a339de2c7 100644
--- a/src/devices/cpu/m37710/m37710.h
+++ b/src/devices/cpu/m37710/m37710.h
@@ -77,6 +77,7 @@ enum
};
#define M37710_INTERRUPT_MAX (M37710_LINE_RESET + 1)
+#define M37710_MASKABLE_INTERRUPTS (M37710_INTERRUPT_MAX - 5)
/* Registers - used by m37710_set_reg() and m37710_get_reg() */
@@ -127,8 +128,59 @@ public:
auto an7_cb() { return m_analog_cb[7].bind(); }
protected:
- DECLARE_READ8_MEMBER( m37710_internal_r );
- DECLARE_WRITE8_MEMBER( m37710_internal_w );
+ // internal registers
+ uint8_t port_r(offs_t offset);
+ void port_w(offs_t offset, uint8_t data);
+ void da_reg_w(offs_t offset, uint8_t data);
+ void pulse_output_w(offs_t offset, uint8_t data);
+ uint8_t ad_control_r();
+ void ad_control_w(uint8_t data);
+ uint8_t ad_sweep_r();
+ void ad_sweep_w(uint8_t data);
+ uint16_t ad_result_r(offs_t offset);
+ uint8_t uart0_mode_r();
+ void uart0_mode_w(uint8_t data);
+ uint8_t uart1_mode_r();
+ void uart1_mode_w(uint8_t data);
+ void uart0_baud_w(uint8_t data);
+ void uart1_baud_w(uint8_t data);
+ void uart0_tbuf_w(uint16_t data);
+ void uart1_tbuf_w(uint16_t data);
+ uint8_t uart0_ctrl_reg0_r();
+ void uart0_ctrl_reg0_w(uint8_t data);
+ uint8_t uart1_ctrl_reg0_r();
+ void uart1_ctrl_reg0_w(uint8_t data);
+ uint8_t uart0_ctrl_reg1_r();
+ void uart0_ctrl_reg1_w(uint8_t data);
+ uint8_t uart1_ctrl_reg1_r();
+ void uart1_ctrl_reg1_w(uint8_t data);
+ uint16_t uart0_rbuf_r();
+ uint16_t uart1_rbuf_r();
+ uint8_t count_start_r();
+ void count_start_w(uint8_t data);
+ void one_shot_start_w(uint8_t data);
+ uint8_t up_down_r();
+ void up_down_w(uint8_t data);
+ uint16_t timer_reg_r(offs_t offset, uint16_t mem_mask);
+ void timer_reg_w(offs_t offset, uint16_t data, uint16_t mem_mask);
+ uint8_t timer_mode_r(offs_t offset);
+ void timer_mode_w(offs_t offset, uint8_t data);
+ uint8_t proc_mode_r(offs_t offset);
+ void proc_mode_w(uint8_t data);
+ void watchdog_timer_w(uint8_t data);
+ uint8_t watchdog_freq_r();
+ void watchdog_freq_w(uint8_t data);
+ uint8_t waveform_mode_r();
+ void waveform_mode_w(uint8_t data);
+ uint8_t rto_control_r();
+ void rto_control_w(uint8_t data);
+ uint8_t dram_control_r();
+ void dram_control_w(uint8_t data);
+ void refresh_timer_w(uint8_t data);
+ uint16_t dmac_control_r(offs_t offset, uint16_t mem_mask);
+ void dmac_control_w(offs_t offset, uint16_t data, uint16_t mem_mask);
+ uint8_t int_control_r(offs_t offset);
+ void int_control_w(offs_t offset, uint8_t data);
// construction/destruction
m37710_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor map_delegate);
@@ -199,7 +251,6 @@ private:
uint32_t m_im3; /* Immediate load target */
uint32_t m_im4; /* Immediate load target */
uint32_t m_irq_delay; /* delay 1 instruction before checking irq */
- uint32_t m_irq_level; /* irq level */
int m_ICount; /* cycle count */
uint32_t m_source; /* temp register */
uint32_t m_destination; /* temp register */
@@ -207,16 +258,46 @@ private:
memory_access_cache<1, 0, ENDIANNESS_LITTLE> *m_cache;
uint32_t m_stopped; /* Sets how the CPU is stopped */
- // on-board peripheral stuff
- uint8_t m_m37710_regs[128];
+ // ports
+ uint8_t m_port_regs[11];
+ uint8_t m_port_dir[11];
+
+ // A/D
+ uint8_t m_ad_control;
+ uint8_t m_ad_sweep;
+
+ // UARTs
+ uint8_t m_uart_mode[2];
+ uint8_t m_uart_baud[2];
+ uint8_t m_uart_ctrl_reg0[2];
+ uint8_t m_uart_ctrl_reg1[2];
+
+ // timers
+ uint8_t m_count_start;
+ uint8_t m_one_shot_start;
+ uint8_t m_up_down_reg;
+ uint16_t m_timer_reg[8];
+ uint8_t m_timer_mode[8];
attotime m_reload[8];
emu_timer *m_timers[8];
int m_timer_out[8];
+
+ // misc. internal registers
+ uint8_t m_proc_mode;
+ uint8_t m_watchdog_freq;
+ uint8_t m_rto_control;
+ uint8_t m_dram_control;
+ uint16_t m_dmac_control;
+
+ // DMA
uint32_t m_dma0_src, m_dma0_dst, m_dma0_cnt, m_dma0_mode;
uint32_t m_dma1_src, m_dma1_dst, m_dma1_cnt, m_dma1_mode;
uint32_t m_dma2_src, m_dma2_dst, m_dma2_cnt, m_dma2_mode;
uint32_t m_dma3_src, m_dma3_dst, m_dma3_cnt, m_dma3_mode;
+ // interrupt controller
+ uint8_t m_int_control[M37710_MASKABLE_INTERRUPTS];
+
// for debugger
uint32_t m_debugger_pc;
uint32_t m_debugger_pb;
@@ -231,10 +312,10 @@ private:
typedef void (m37710_cpu_device::*set_reg_func)(int regnum, uint32_t val);
typedef int (m37710_cpu_device::*execute_func)(int cycles);
- static const int m37710_irq_levels[M37710_INTERRUPT_MAX];
+ static const int m37710_int_reg_map[M37710_MASKABLE_INTERRUPTS];
static const int m37710_irq_vectors[M37710_INTERRUPT_MAX];
- static const char *const m37710_rnames[128];
static const char *const m37710_tnames[8];
+ static const char *const m37710_intnames[M37710_INTERRUPT_MAX];
static const opcode_func *const m37710i_opcodes[4];
static const opcode_func *const m37710i_opcodes2[4];
static const opcode_func *const m37710i_opcodes3[4];