summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/h83002/h8speriph.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/h83002/h8speriph.c')
-rw-r--r--trunk/src/emu/cpu/h83002/h8speriph.c1540
1 files changed, 1540 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/h83002/h8speriph.c b/trunk/src/emu/cpu/h83002/h8speriph.c
new file mode 100644
index 00000000000..458a040b4d1
--- /dev/null
+++ b/trunk/src/emu/cpu/h83002/h8speriph.c
@@ -0,0 +1,1540 @@
+/*
+
+ Hitachi H8S/2xxx MCU peripherals
+
+ (c) 2001-2007 Tim Schuerewegen
+
+ H8S/2241
+ H8S/2246
+ H8S/2323
+
+*/
+
+#include "emu.h"
+#include "debugger.h"
+#include "h8.h"
+#include "h8priv.h"
+
+#define VERBOSE_LEVEL ( 0 )
+
+INLINE void ATTR_PRINTF(3,4) verboselog( running_machine &machine, int n_level, const char *s_fmt, ...)
+{
+ if (VERBOSE_LEVEL >= n_level)
+ {
+ va_list v;
+ char buf[32768];
+ va_start( v, s_fmt);
+ vsprintf( buf, s_fmt, v);
+ va_end( v);
+ logerror( "%s: %s", machine.describe_context( ), buf);
+ }
+}
+
+const UINT8 H8S_RESET_H8S_IO_224x[0x1C0] = // values from "e602100_h8s2245.pdf"
+{
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FE40
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FE50
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FE60
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FE70
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FE80
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FE90
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FEA0
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, // FEB0
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FEC0
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FED0
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FEE0
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FEF0
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FF00
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FF10
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FF20
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, // FF30
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FF40
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FF50
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FF60
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x84, 0x00, 0xF2, 0x00, // FF70
+ 0x00, 0xFF, 0x00, 0xFF, 0x84, 0x00, 0xF2, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x84, 0x00, 0xF2, 0x00, // FF80
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FF90
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FFA0
+ 0x00, 0x00, 0x00, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FFB0
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FFC0
+ 0x00, 0xC0, 0x00, 0x00, 0x40, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // FFD0
+ 0x00, 0xC0, 0x00, 0x00, 0x40, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, // FFE0
+ 0x00, 0xC0, 0x00, 0x00, 0x40, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, // FFF0
+};
+
+const UINT8 H8S_RESET_H8S_IO_2323[0x1C0] = // values from "rej09b0220_h8s2329.pdf"
+{
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FE40
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FE50
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FE60
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FE70
+ 0x00, 0xC0, 0x00, 0x00, 0x40, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // FE80
+ 0x00, 0xC0, 0x00, 0x00, 0x40, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, // FE90
+ 0x00, 0xC0, 0x00, 0x00, 0x40, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, // FEA0
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, // FEB0
+ 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, // FEC0
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x3C, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FED0
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FEE0
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FEF0
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FF00
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FF10
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FF20
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, // FF30
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FF40
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FF50
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FF60
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x84, 0x00, 0xF2, 0x00, // FF70
+ 0x00, 0xFF, 0x00, 0xFF, 0x84, 0x00, 0xF2, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x84, 0x00, 0xF2, 0x00, // FF80
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FF90
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, // FFA0
+ 0x00, 0x00, 0x00, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FFB0
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // FFC0
+ 0x00, 0xC0, 0x00, 0x00, 0x40, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // FFD0
+ 0x00, 0xC0, 0x00, 0x00, 0x40, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, // FFE0
+ 0x00, 0xC0, 0x00, 0x00, 0x40, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, // FFF0
+};
+
+#define SCR_TIE 0x80
+#define SCR_RIE 0x40
+#define SCR_TE 0x20
+#define SCR_RE 0x10
+
+#define SSR_TDRE 0x80
+#define SSR_RDRF 0x40
+#define SSR_ORER 0x20
+#define SSR_FER 0x10
+#define SSR_PER 0x08
+#define SSR_TEND 0x04
+
+#define SMR_CM 0x80
+#define SMR_CHR 0x40
+#define SMR_PE 0x20
+#define SMR_PM 0x10
+#define SMR_STOP 0x08
+#define SMR_MP 0x04
+#define SMR_CKS1 0x02
+#define SMR_CKS0 0x01
+
+#define TCSR_CMFB 0x80
+#define TCSR_CMFA 0x40
+#define TCSR_OVF 0x20
+
+#define TCR_CMIEB 0x80
+#define TCR_CMIEA 0x40
+#define TCR_OVIE 0x20
+
+#define TSR_TCFD 0x80
+#define TSR_TCFU 0x20
+#define TSR_TCFV 0x10
+#define TSR_TGFD 0x08
+#define TSR_TGFC 0x04
+#define TSR_TGFB 0x02
+#define TSR_TGFA 0x01
+
+#define TIER_TCIEU 0x20
+#define TIER_TCIEV 0x10
+#define TIER_TGIED 0x08
+#define TIER_TGIEC 0x04
+#define TIER_TGIEB 0x02
+#define TIER_TGIEA 0x01
+
+#define DTC_MRA_MD_NORMAL 0
+#define DTC_MRA_MD_REPEAT 1
+#define DTC_MRA_MD_BLOCK 2
+
+#define DTC_MRA_SM1 0x80
+#define DTC_MRA_SM0 0x40
+#define DTC_MRA_DM1 0x20
+#define DTC_MRA_DM0 0x10
+#define DTC_MRA_DTS 0x02
+
+#define DTC_MRB_CHNE 0x80
+#define DTC_MRB_DISEL 0x40
+#define DTC_MRB_CHNS 0x20
+
+#define DMABCRL_DTME1 0x80
+#define DMABCRL_DTE1 0x40
+#define DMABCRL_DTME0 0x20
+#define DMABCRL_DTE0 0x10
+#define DMABCRL_DTIE1B 0x08
+#define DMABCRL_DTIE1A 0x04
+#define DMABCRL_DTIE0B 0x02
+#define DMABCRL_DTIE0A 0x01
+
+#define ADCSR_ADF 0x80
+#define ADCSR_ADIE 0x40
+#define ADCSR_ADST 0x20
+#define ADCSR_SCAN 0x10
+
+enum
+{
+ PIN_P10, PIN_P11, PIN_P12, PIN_P13, PIN_P14, PIN_P15, PIN_P16, PIN_P17,
+ PIN_P20, PIN_P21, PIN_P22, PIN_P23, PIN_P24, PIN_P25, PIN_P26, PIN_P27,
+ PIN_P30, PIN_P31, PIN_P32, PIN_P33, PIN_P34, PIN_P35,
+ PIN_P40, PIN_P41, PIN_P42, PIN_P43, PIN_P44, PIN_P45, PIN_P46, PIN_P47,
+ PIN_P50, PIN_P51, PIN_P52, PIN_P53,
+ PIN_P60, PIN_P61, PIN_P62, PIN_P63, PIN_P64, PIN_P65, PIN_P66, PIN_P67,
+ PIN_PA0, PIN_PA1, PIN_PA2, PIN_PA3, PIN_PA4, PIN_PA5, PIN_PA6, PIN_PA7,
+ PIN_PB0, PIN_PB1, PIN_PB2, PIN_PB3, PIN_PB4, PIN_PB5, PIN_PB6, PIN_PB7,
+ PIN_PC0, PIN_PC1, PIN_PC2, PIN_PC3, PIN_PC4, PIN_PC5, PIN_PC6, PIN_PC7,
+ PIN_PD0, PIN_PD1, PIN_PD2, PIN_PD3, PIN_PD4, PIN_PD5, PIN_PD6, PIN_PD7,
+ PIN_PE0, PIN_PE1, PIN_PE2, PIN_PE3, PIN_PE4, PIN_PE5, PIN_PE6, PIN_PE7,
+ PIN_PF0, PIN_PF1, PIN_PF2, PIN_PF3, PIN_PF4, PIN_PF5, PIN_PF6, PIN_PF7,
+ PIN_PG0, PIN_PG1, PIN_PG2, PIN_PG3, PIN_PG4
+};
+
+#define PIN_TIOCA0 PIN_P10
+#define PIN_TIOCB0 PIN_P11
+#define PIN_TIOCC0 PIN_P12
+#define PIN_TIOCD0 PIN_P13
+#define PIN_TIOCA1 PIN_P14
+#define PIN_TIOCB1 PIN_P15
+#define PIN_TIOCA2 PIN_P16
+#define PIN_TIOCB2 PIN_P17
+
+#define PIN_TCLKA PIN_P12
+#define PIN_TCLKB PIN_P13
+#define PIN_TCLKC PIN_P15
+#define PIN_TCLKD PIN_P17
+
+#define PIN_TXD0 PIN_P30
+#define PIN_TXD1 PIN_P31
+#define PIN_RXD0 PIN_P32
+#define PIN_RXD1 PIN_P33
+#define PIN_SCK0 PIN_P34
+#define PIN_SCK1 PIN_P35
+
+#define PIN_TIOCA3 PIN_P20
+#define PIN_TIOCB3 PIN_P21
+#define PIN_TIOCC3 PIN_P22
+#define PIN_TIOCD3 PIN_P23
+#define PIN_TIOCA4 PIN_P24
+#define PIN_TIOCB4 PIN_P25
+#define PIN_TIOCA5 PIN_P26
+#define PIN_TIOCB5 PIN_P27
+
+#define PIN_TMRI0 PIN_P22
+#define PIN_TMCI0 PIN_P23
+#define PIN_TMRI1 PIN_P24
+#define PIN_TMCI1 PIN_P25
+#define PIN_TMO0 PIN_P26
+#define PIN_TMO1 PIN_P27
+
+const int TPU_0_DIV[] = { 1, 4, 16, 64, 0, 0, 0,0 };
+const int TPU_1_DIV[] = { 1, 4, 16, 64, 0, 0, 256, 0 };
+const int TPU_2_DIV[] = { 1, 4, 16, 64, 0, 0, 0, 1024 };
+const int TPU_3_DIV[] = { 1, 4, 16, 64, 0, 1024, 256, 4096 };
+const int TPU_4_DIV[] = { 1, 4, 16, 64, 0, 0, 1024, 0 };
+const int TPU_5_DIV[] = { 1, 4, 16, 64, 0, 0, 256, 0 };
+
+const int H8S_IO_SMR[] = { H8S_IO_SMR0, H8S_IO_SMR1, H8S_IO_SMR2 };
+const int H8S_IO_BRR[] = { H8S_IO_BRR0, H8S_IO_BRR1, H8S_IO_BRR2 };
+const int H8S_IO_SCR[] = { H8S_IO_SCR0, H8S_IO_SCR1, H8S_IO_SCR2 };
+const int H8S_IO_TDR[] = { H8S_IO_TDR0, H8S_IO_TDR1, H8S_IO_TDR2 };
+const int H8S_IO_SSR[] = { H8S_IO_SSR0, H8S_IO_SSR1, H8S_IO_SSR2 };
+const int H8S_IO_RDR[] = { H8S_IO_RDR0, H8S_IO_RDR1, H8S_IO_RDR2 };
+
+const int H8S_INT_TXI[] = { H8S_INT_TXI0, H8S_INT_TXI1, H8S_INT_TXI2 };
+const int H8S_INT_RXI[] = { H8S_INT_RXI0, H8S_INT_RXI1, H8S_INT_RXI2 };
+
+const int H8S_IO_TCORA[] = { H8S_IO_TCORA0, H8S_IO_TCORA1 };
+const int H8S_IO_TCORB[] = { H8S_IO_TCORB0, H8S_IO_TCORB1 };
+const int H8S_IO_TCR[] = { H8S_IO_TCR0, H8S_IO_TCR1 };
+const int H8S_IO_TCNT[] = { H8S_IO_TCNT0, H8S_IO_TCNT1 };
+const int H8S_IO_TCSR[] = { H8S_IO_TCSR0, H8S_IO_TCSR1 };
+
+const int H8S_INT_OVI[] = { H8S_INT_OVI0, H8S_INT_OVI1 };
+const int H8S_INT_CMIA[] = { H8S_INT_CMIA0, H8S_INT_CMIA1 };
+const int H8S_INT_CMIB[] = { H8S_INT_CMIB0, H8S_INT_CMIB1 };
+
+const int H8S_IO_TGRA_H[] = { H8S_IO_TGR0A_H, H8S_IO_TGR1A_H, H8S_IO_TGR2A_H, H8S_IO_TGR3A_H, H8S_IO_TGR4A_H, H8S_IO_TGR5A_H };
+const int H8S_IO_TGRA_L[] = { H8S_IO_TGR0A_L, H8S_IO_TGR1A_L, H8S_IO_TGR2A_L, H8S_IO_TGR3A_L, H8S_IO_TGR4A_L, H8S_IO_TGR5A_L };
+const int H8S_IO_TGRB_H[] = { H8S_IO_TGR0B_H, H8S_IO_TGR1B_H, H8S_IO_TGR2B_H, H8S_IO_TGR3B_H, H8S_IO_TGR4B_H, H8S_IO_TGR5B_H };
+const int H8S_IO_TGRB_L[] = { H8S_IO_TGR0B_L, H8S_IO_TGR1B_L, H8S_IO_TGR2B_L, H8S_IO_TGR3B_L, H8S_IO_TGR4B_L, H8S_IO_TGR5B_L };
+const int H8S_IO_TGRC_H[] = { H8S_IO_TGR0C_H, 0, 0, H8S_IO_TGR3C_H, 0, 0 };
+const int H8S_IO_TGRC_L[] = { H8S_IO_TGR0C_L, 0, 0, H8S_IO_TGR3C_L, 0, 0 };
+const int H8S_IO_TGRD_H[] = { H8S_IO_TGR0D_H, 0, 0, H8S_IO_TGR3D_H, 0, 0 };
+const int H8S_IO_TGRD_L[] = { H8S_IO_TGR0D_L, 0, 0, H8S_IO_TGR3D_L, 0, 0 };
+const int H8S_IO_TCNT_H[] = { H8S_IO_TCNT0_H, H8S_IO_TCNT1_H, H8S_IO_TCNT2_H, H8S_IO_TCNT3_H, H8S_IO_TCNT4_H, H8S_IO_TCNT5_H };
+const int H8S_IO_TCNT_L[] = { H8S_IO_TCNT0_L, H8S_IO_TCNT1_L, H8S_IO_TCNT2_L, H8S_IO_TCNT3_L, H8S_IO_TCNT4_L, H8S_IO_TCNT5_L };
+const int H8S_IO_TIOR_H[] = { H8S_IO_TIOR0_H, H8S_IO_TIOR1, H8S_IO_TIOR2, H8S_IO_TIOR3_H, H8S_IO_TIOR4, H8S_IO_TIOR5 };
+const int H8S_IO_TIOR_L[] = { H8S_IO_TIOR0_L, 0, 0, H8S_IO_TIOR3_L, 0, 0 };
+const int H8S_IO_TTCR[] = { H8S_IO_TTCR0, H8S_IO_TTCR1, H8S_IO_TTCR2, H8S_IO_TTCR3, H8S_IO_TTCR4, H8S_IO_TTCR5 };
+const int H8S_IO_TIER[] = { H8S_IO_TIER0, H8S_IO_TIER1, H8S_IO_TIER2, H8S_IO_TIER3, H8S_IO_TIER4, H8S_IO_TIER5 };
+const int H8S_IO_TSR[] = { H8S_IO_TSR0, H8S_IO_TSR1, H8S_IO_TSR2, H8S_IO_TSR3, H8S_IO_TSR4, H8S_IO_TSR5 };
+
+const int H8S_INT_TCIV[] = { H8S_INT_TCI0V, H8S_INT_TCI1V, H8S_INT_TCI2V, H8S_INT_TCI3V, H8S_INT_TCI4V, H8S_INT_TCI5V };
+const int H8S_INT_TCIU[] = { 0, H8S_INT_TCI1U, H8S_INT_TCI2U, 0, H8S_INT_TCI4U, H8S_INT_TCI5U };
+const int H8S_INT_TGIA[] = { H8S_INT_TGI0A, H8S_INT_TGI1A, H8S_INT_TGI2A, H8S_INT_TGI3A, H8S_INT_TGI4A, H8S_INT_TGI5A };
+const int H8S_INT_TGIB[] = { H8S_INT_TGI0B, H8S_INT_TGI1B, H8S_INT_TGI2B, H8S_INT_TGI3B, H8S_INT_TGI4B, H8S_INT_TGI5B };
+const int H8S_INT_TGIC[] = { H8S_INT_TGI0C, 0, 0, H8S_INT_TGI3C, 0, 0 };
+const int H8S_INT_TGID[] = { H8S_INT_TGI0D, 0, 0, H8S_INT_TGI3D, 0, 0 };
+
+const int PIN_TIOCA[] = { PIN_TIOCA0, PIN_TIOCA1, PIN_TIOCA2, PIN_TIOCA3, PIN_TIOCA4, PIN_TIOCA5 };
+const int PIN_TIOCB[] = { PIN_TIOCB0, PIN_TIOCB1, PIN_TIOCB2, PIN_TIOCB3, PIN_TIOCB4, PIN_TIOCB5 };
+const int PIN_TIOCC[] = { PIN_TIOCC0, 0, 0, PIN_TIOCC3, 0, 0 };
+const int PIN_TIOCD[] = { PIN_TIOCD0, 0, 0, PIN_TIOCD3, 0, 0 };
+
+const int TCR_CCLR_AND[] = { 7, 3, 3, 7, 3, 3 };
+
+// prototypes
+
+void h8s_tmr_x_reset( h83xx_state *h8, int x);
+void h8s_tpu_x_reset( h83xx_state *h8, int x);
+void h8s_tpu_x_tick( h83xx_state *h8, int x);
+
+////////////
+// DTVECR //
+////////////
+
+#define DTVECR_ADDR(x) (0x400 + (x << 1))
+
+///////////////
+// MEMCONV.H //
+///////////////
+
+static TIMER_CALLBACK( h8s_tmr_callback );
+static TIMER_CALLBACK( h8s_tpu_callback );
+static TIMER_CALLBACK( h8s_sci_callback );
+
+/////////////
+// TIMER.C //
+/////////////
+
+UINT16 ptr_read_16( void *ptr)
+{
+ return (*(((UINT8*)ptr) + 0) << 8) | (*(((UINT8*)ptr) + 1) << 0);
+}
+
+void ptr_write_16( void *ptr, UINT16 data)
+{
+ *(((UINT8*)ptr) + 0) = (data >> 8) & 0xFF;
+ *(((UINT8*)ptr) + 1) = (data >> 0) & 0xFF;
+}
+
+int device_icount_min_timer_icount1( h83xx_state *h8, emu_timer *timer)
+{
+ return (timer->elapsed() * h8->device->unscaled_clock()).as_double();
+}
+
+void h8s2xxx_interrupt_request(h83xx_state *h8, UINT32 vecnum)
+{
+ UINT8 idx, bit;
+ idx = vecnum >> 5;
+ bit = vecnum & 0x1F;
+ h8->irq_req[idx] |= (1 << bit);
+}
+
+void h8s_dtce_execute(h83xx_state *h8, UINT32 addr_dtce, UINT8 mask_dtce, UINT32 addr_dtvecr)
+{
+ UINT32 data[3], dtc_vect, dtc_sar, dtc_dar, cnt, i;
+ UINT8 dtc_mra, dtc_mrb, sz;
+ UINT16 dtc_cra, dtc_crb;
+ // get dtc info
+ dtc_vect = 0xFF0000 | h8->program->read_word(addr_dtvecr);
+ data[0] = h8->program->read_dword( dtc_vect + 0);
+ data[1] = h8->program->read_dword( dtc_vect + 4);
+ data[2] = h8->program->read_dword( dtc_vect + 8);
+ dtc_mra = (data[0] >> 24) & 0xFF;
+ dtc_sar = (data[0] >> 0) & 0xFFFFFF;
+ dtc_mrb = (data[1] >> 24) & 0xFF;
+ dtc_dar = (data[1] >> 0) & 0xFFFFFF;
+ dtc_cra = (data[2] >> 16) & 0xFFFF;
+ dtc_crb = (data[2] >> 0) & 0xFFFF;
+ verboselog( h8->device->machine(), 3, "dtc : vect %08X mra %02X sar %08X mrb %02X dar %08X cra %04X crb %04X\n", dtc_vect, dtc_mra, dtc_sar, dtc_mrb, dtc_dar, dtc_cra, dtc_crb);
+ // execute
+ if ((dtc_mra & 0x0E) != 0x00) fatalerror("H8S: dtc unsupported MRA %x\n", dtc_mra&0x0e);
+ sz = 1 << (dtc_mra & 0x01);
+ cnt = dtc_cra;
+ for (i=0;i<cnt;i++)
+ {
+ if (dtc_sar == H8S_IO_ADDR( H8S_IO_RDR1)) h8->program->write_byte( H8S_IO_ADDR( H8S_IO_SSR1), h8->program->read_byte( H8S_IO_ADDR( H8S_IO_SSR1)) & (~H8S_SSR_TDRE));
+ if (dtc_mra & 0x01) h8->program->write_word( dtc_dar, h8->program->read_word( dtc_sar)); else h8->program->write_byte( dtc_dar, h8->program->read_byte( dtc_sar));
+ if (dtc_dar == H8S_IO_ADDR( H8S_IO_TDR0)) h8->program->write_byte( H8S_IO_ADDR( H8S_IO_SSR0), h8->program->read_byte( H8S_IO_ADDR( H8S_IO_SSR0)) & (~H8S_SSR_TDRE));
+ if (dtc_mra & 0x80) { if (dtc_mra & 0x40) dtc_sar -= sz; else dtc_sar += sz; }
+ if (dtc_mra & 0x20) { if (dtc_mra & 0x10) dtc_dar -= sz; else dtc_dar += sz; }
+ }
+ h8->program->write_byte( addr_dtce, h8->program->read_byte( addr_dtce) & (~mask_dtce));
+}
+
+void h8s_dtce_check(h83xx_state *h8, int vecnum)
+{
+ UINT32 dtce = 0;
+ int bit = 0;
+ // get dtce info
+ switch (vecnum)
+ {
+ // DTCEA
+ case H8S_INT_IRQ0 : dtce = H8S_IO_DTCEA; bit = 7; break;
+ case H8S_INT_IRQ1 : dtce = H8S_IO_DTCEA; bit = 6; break;
+ case H8S_INT_IRQ2 : dtce = H8S_IO_DTCEA; bit = 5; break;
+ case H8S_INT_IRQ3 : dtce = H8S_IO_DTCEA; bit = 4; break;
+ case H8S_INT_IRQ4 : dtce = H8S_IO_DTCEA; bit = 3; break;
+ case H8S_INT_IRQ5 : dtce = H8S_IO_DTCEA; bit = 2; break;
+ case H8S_INT_IRQ6 : dtce = H8S_IO_DTCEA; bit = 1; break;
+ case H8S_INT_IRQ7 : dtce = H8S_IO_DTCEA; bit = 0; break;
+ // DTCEB
+ case H8S_INT_ADI : dtce = H8S_IO_DTCEB; bit = 6; break;
+ case H8S_INT_TGI0A : dtce = H8S_IO_DTCEB; bit = 5; break;
+ case H8S_INT_TGI0B : dtce = H8S_IO_DTCEB; bit = 4; break;
+ case H8S_INT_TGI0C : dtce = H8S_IO_DTCEB; bit = 3; break;
+ case H8S_INT_TGI0D : dtce = H8S_IO_DTCEB; bit = 2; break;
+ case H8S_INT_TGI1A : dtce = H8S_IO_DTCEB; bit = 1; break;
+ case H8S_INT_TGI1B : dtce = H8S_IO_DTCEB; bit = 0; break;
+ // DTCEC
+ case H8S_INT_TGI2A : dtce = H8S_IO_DTCEC; bit = 7; break;
+ case H8S_INT_TGI2B : dtce = H8S_IO_DTCEC; bit = 6; break;
+ // DTCED
+ case H8S_INT_CMIA0 : dtce = H8S_IO_DTCED; bit = 3; break;
+ case H8S_INT_CMIB0 : dtce = H8S_IO_DTCED; bit = 2; break;
+ case H8S_INT_CMIA1 : dtce = H8S_IO_DTCED; bit = 1; break;
+ case H8S_INT_CMIB1 : dtce = H8S_IO_DTCED; bit = 0; break;
+ // DTCEE
+ case H8S_INT_RXI0 : dtce = H8S_IO_DTCEE; bit = 3; break;
+ case H8S_INT_TXI0 : dtce = H8S_IO_DTCEE; bit = 2; break;
+ case H8S_INT_RXI1 : dtce = H8S_IO_DTCEE; bit = 1; break;
+ case H8S_INT_TXI1 : dtce = H8S_IO_DTCEE; bit = 0; break;
+ // DTCEF
+ case H8S_INT_RXI2 : dtce = H8S_IO_DTCEF; bit = 7; break;
+ case H8S_INT_TXI2 : dtce = H8S_IO_DTCEF; bit = 6; break;
+ }
+ // execute
+ if ((dtce != 0) && (h8->per_regs[dtce] & (1 << bit))) h8s_dtce_execute(h8, H8S_IO_ADDR( dtce), (1 << bit), DTVECR_ADDR( vecnum));
+}
+
+void h8s_periph_reset(h83xx_state *h8)
+{
+ const int tpu_max = (h8->device->type() == H8S2323) ? 6 : 3;
+ if ((h8->device->type() == H8S2241) || (h8->device->type() == H8S2246))
+ {
+ memcpy( h8->per_regs, H8S_RESET_H8S_IO_224x, sizeof( h8->per_regs));
+ }
+ else if (h8->device->type() == H8S2323)
+ {
+ memcpy( h8->per_regs, H8S_RESET_H8S_IO_2323, sizeof( h8->per_regs));
+ }
+ for (int i = 0; i < 2; i++) h8s_tmr_x_reset( h8, i);
+ for (int i = 0; i < tpu_max; i++) h8s_tpu_x_reset( h8, i);
+}
+
+/////////////////
+// TIMER 8-BIT //
+/////////////////
+
+void h8s_tmr_init(h83xx_state *h8)
+{
+ for (int i = 0; i < 2; i++)
+ {
+ h8->tmr[i].timer = h8->device->machine().scheduler().timer_alloc(FUNC(h8s_tmr_callback), h8);
+ h8->tmr[i].timer->adjust(attotime::never, i);
+ }
+}
+
+void h8s_tmr_x_reset( h83xx_state *h8, int x)
+{
+ H8S2XXX_TMR *tmr = &h8->tmr[x];
+ tmr->cycles_per_tick = 0;
+ tmr->timer->adjust(attotime::never, x);
+}
+
+UINT64 h8s_tmr_x_calculate_ticks( h83xx_state *h8, int x, UINT8 tcnt)
+{
+ UINT64 cycles1, cycles2;
+ UINT8 tcor;
+ // overflow
+ if (tcnt == 0) cycles1 = 0xFF + 1; else cycles1 = (UINT8)(0xFF - tcnt + 1);
+ // tcora
+ tcor = h8->per_regs[H8S_IO_TCORA[x]];
+ if (tcnt == tcor) cycles2 = 0xFF + 1; else cycles2 = (UINT8)(tcor - tcnt);
+ if ((cycles2 > 0) && (cycles2 < cycles1)) cycles1 = cycles2;
+ // tcorb
+ tcor = h8->per_regs[H8S_IO_TCORB[x]];
+ if (tcnt == tcor) cycles2 = 0xFF + 1; else cycles2 = (UINT8)(tcor - tcnt);
+ if ((cycles2 > 0) && (cycles2 < cycles1)) cycles1 = cycles2;
+ // done
+ return cycles1;
+}
+
+void h8s_tmr_x_update( h83xx_state *h8, int x)
+{
+ H8S2XXX_TMR *tmr = &h8->tmr[x];
+ UINT64 cycles;
+ int div = 0;
+ UINT8 tcr, tcnt;
+ tcr = h8->per_regs[H8S_IO_TCR[x]];
+ switch ((tcr >> 0) & 7)
+ {
+ case 1 : div = 8; break;
+ case 2 : div = 64; break;
+ case 3 : div = 8192; break;
+// default : OS_MessageBox( NULL, "tmr_x_update", "error", 0); break;
+ }
+ tmr->cycles_per_tick = div;
+ tcnt = h8->per_regs[H8S_IO_TCNT[x]];
+ verboselog( h8->device->machine(), 5, "TMR %d - update (div %d tcnt %02X)\n", x, div, tcnt);
+ // update timer
+ cycles = h8s_tmr_x_calculate_ticks( h8, x, tcnt) * tmr->cycles_per_tick;
+ tmr->timer_cycles = cycles;
+ tmr->timer->adjust(attotime::from_hz(h8->device->unscaled_clock() / cycles), x);
+}
+
+UINT8 h8s_tmr_x_calculate_tcnt( h83xx_state *h8, int x)
+{
+ H8S2XXX_TMR *tmr = &h8->tmr[x];
+ UINT8 tcnt;
+ tcnt = h8->per_regs[H8S_IO_TCNT[x]];
+ if (tmr->timer->enabled())
+ {
+ tcnt = (UINT8)(tcnt + ((device_icount_min_timer_icount1( h8, tmr->timer)) / tmr->cycles_per_tick));
+ }
+ return tcnt;
+}
+
+void h8s_tmr_x_start( h83xx_state *h8, int x)
+{
+ verboselog( h8->device->machine(), 5, "TMR %d - start\n", x);
+ // ...
+ h8s_tmr_x_update( h8, x);
+}
+
+void h8s_tmr_x_stop( h83xx_state *h8, int x)
+{
+ H8S2XXX_TMR *tmr = &h8->tmr[x];
+ UINT8 tcnt;
+ // ...
+ verboselog( h8->device->machine(), 5, "TMR %d - stop\n", x);
+ // calculate tcnt
+ tcnt = h8s_tmr_x_calculate_tcnt( h8, x);
+ // update tcnt
+ h8->per_regs[H8S_IO_TCNT[x]] = tcnt;
+ // disable timer
+ tmr->timer->reset();
+}
+
+UINT8 h8s_tmr_x_tcnt_change( h83xx_state *h8, int x, UINT8 tcnt)
+{
+ UINT8 tcr, tcor;
+ int clear = 0;
+ // ...
+ verboselog( h8->device->machine(), 9, "TMR %d - tmr_x_tcnt_change (%02X)\n", x, tcnt);
+ // ...
+ tcr = h8->per_regs[H8S_IO_TCR[x]];
+ // overflow
+ if (tcnt == 0)
+ {
+ verboselog( h8->device->machine(), 9, "TMR %d - overflow match\n", x);
+ h8->per_regs[H8S_IO_TCSR[x]] |= TCSR_OVF;
+ if ((tcr & TCR_OVIE) != 0)
+ {
+ h8s2xxx_interrupt_request( h8, H8S_INT_OVI[x]);
+ }
+ }
+ // tcora
+ tcor = h8->per_regs[H8S_IO_TCORA[x]];
+ if (tcnt == tcor)
+ {
+ verboselog( h8->device->machine(), 9, "TMR %d - tcora match\n", x);
+ h8->per_regs[H8S_IO_TCSR[x]] |= TCSR_CMFA;
+ if ((tcr & TCR_CMIEA) != 0)
+ {
+ h8s2xxx_interrupt_request( h8, H8S_INT_CMIA[x]);
+ }
+ if (((tcr >> 3) & 3) == 1) // CCLR 1 -> "clear by compare match a"
+ {
+ clear = 1;
+ }
+ }
+ // tcorb
+ tcor = h8->per_regs[H8S_IO_TCORB[x]];
+ if (tcnt == tcor)
+ {
+ verboselog( h8->device->machine(), 9, "TMR %d - tcorb match\n", x);
+ h8->per_regs[H8S_IO_TCSR[x]] |= TCSR_CMFB;
+ if ((tcr & TCR_CMIEB) != 0)
+ {
+ h8s2xxx_interrupt_request( h8, H8S_INT_CMIB[x]);
+ }
+ if (((tcr >> 3) & 3) == 2) // CCLR 2 -> "clear by compare match b"
+ {
+ clear = 1;
+ }
+ }
+ // ...
+ if (clear)
+ {
+ verboselog( h8->device->machine(), 5, "TMR %d - tcnt clear\n", x);
+ tcnt = 0;
+ }
+ // ...
+ return tcnt;
+}
+
+void h8s_tmr_x_callback( h83xx_state *h8, int x)
+{
+ H8S2XXX_TMR *tmr = &h8->tmr[x];
+ UINT64 cycles;
+ UINT8 tcnt;
+ // calculate tcnt
+ tcnt = h8->per_regs[H8S_IO_TCNT[x]];
+ tcnt = (UINT8)(tcnt + tmr->timer_cycles / tmr->cycles_per_tick);
+ // ...
+ tcnt = h8s_tmr_x_tcnt_change( h8, x, tcnt);
+ // update tcnt
+ h8->per_regs[H8S_IO_TCNT[x]] = tcnt;
+ // update timer
+ cycles = h8s_tmr_x_calculate_ticks( h8, x, tcnt) * tmr->cycles_per_tick;
+ tmr->timer_cycles = cycles;
+ tmr->timer->adjust(attotime::from_hz(h8->device->unscaled_clock() / cycles), x);
+}
+
+void h8s_tmr_x_write_tcr( h83xx_state *h8, int x, UINT8 data)
+{
+ UINT8 old_data = h8->per_regs[H8S_IO_TCR[x]];
+ h8->per_regs[H8S_IO_TCR[x]] = data;
+ if ((data & 0x07) != (old_data & 0x07))
+ {
+ if ((data & 0x07) != 0)
+ {
+ h8s_tmr_x_start( h8, x);
+ }
+ else
+ {
+ h8s_tmr_x_stop( h8, x);
+ }
+ }
+}
+
+void h8s_tmr_x_write_tcnt( h83xx_state *h8, int x, UINT8 data)
+{
+ H8S2XXX_TMR *tmr = &h8->tmr[x];
+ h8->per_regs[H8S_IO_TCNT[x]] = data;
+ if (tmr->timer->enabled())
+ {
+ h8s_tmr_x_update( h8, x);
+ }
+}
+
+void h8s_tmr_x_write_tcor( h83xx_state *h8, int x)
+{
+ H8S2XXX_TMR *tmr = &h8->tmr[x];
+ if ((tmr->timer->enabled()) && (tmr->cycles_per_tick != 0))
+ {
+ UINT8 tcnt1, tcnt2;
+ UINT64 cycles;
+ tcnt1 = h8->per_regs[H8S_IO_TCNT[x]];
+ tcnt2 = (UINT8)(tcnt1 + ((device_icount_min_timer_icount1( h8, tmr->timer)) / tmr->cycles_per_tick));
+ cycles = h8s_tmr_x_calculate_ticks( h8, x, tcnt2) * tmr->cycles_per_tick;
+ cycles = cycles + (tcnt2 - tcnt1) * tmr->cycles_per_tick;
+ tmr->timer_cycles = cycles;
+ tmr->timer->adjust(attotime::from_hz(h8->device->unscaled_clock() / cycles), x);
+ }
+}
+
+UINT8 h8s_tmr_x_read_tcnt( h83xx_state *h8, int x)
+{
+ return h8s_tmr_x_calculate_tcnt( h8, x);
+}
+
+void h8s_tmr_x_write_tcora( h83xx_state *h8, int x, UINT8 data)
+{
+ h8->per_regs[H8S_IO_TCORA[x]] = data;
+ h8s_tmr_x_write_tcor( h8, x);
+}
+
+void h8s_tmr_x_write_tcorb( h83xx_state *h8, int x, UINT8 data)
+{
+ h8->per_regs[H8S_IO_TCORB[x]] = data;
+ h8s_tmr_x_write_tcor( h8, x);
+}
+
+static TIMER_CALLBACK( h8s_tmr_callback)
+{
+ h83xx_state *h8 = (h83xx_state *)ptr;
+ h8s_tmr_x_callback( h8, param);
+}
+
+//////////////////
+// TIMER 16-BIT //
+//////////////////
+
+void h8s_tpu_init(h83xx_state *h8)
+{
+ const int tpu_max = (h8->device->type() == H8S2323) ? 6 : 3;
+ for (int i = 0; i < tpu_max; i++)
+ {
+ h8->tpu[i].timer = h8->device->machine().scheduler().timer_alloc(FUNC(h8s_tpu_callback), h8);
+ h8->tpu[i].timer->adjust(attotime::never, i);
+ }
+}
+
+void h8s_tpu_x_reset( h83xx_state *h8, int x)
+{
+ H8S2XXX_TPU *tpu = &h8->tpu[x];
+ tpu->cycles_per_tick = 0;
+ tpu->timer->reset();
+}
+
+UINT16 h8s_tpu_x_calculate_tcnt( h83xx_state *h8, int x)
+{
+ H8S2XXX_TPU *tpu = &h8->tpu[x];
+ UINT16 tcnt;
+ tcnt = ptr_read_16( h8->per_regs + H8S_IO_TCNT_H[x]);
+ if ((tpu->timer->enabled()) && (tpu->cycles_per_tick > 0))
+ {
+ tcnt = (UINT16)(tcnt + ((device_icount_min_timer_icount1( h8, tpu->timer)) / tpu->cycles_per_tick));
+ }
+ return tcnt;
+}
+
+UINT64 h8s_tpu_x_calculate_ticks( h83xx_state *h8, int x, UINT16 tcnt)
+{
+ UINT64 cycles1, cycles2;
+ UINT16 tgr;
+ // overflow
+ if (tcnt == 0) cycles1 = 0xFFFF + 1; else cycles1 = (UINT16)(0xFFFF - tcnt + 1);
+ // tgra
+ tgr = ptr_read_16( h8->per_regs + H8S_IO_TGRA_H[x]);
+ if (tcnt == tgr) cycles2 = 0xFFFF + 1; else cycles2 = (UINT16)(tgr - tcnt);
+ if ((cycles2 > 0) && (cycles2 < cycles1)) cycles1 = cycles2;
+ // tgrb
+ tgr = ptr_read_16( h8->per_regs + H8S_IO_TGRB_H[x]);
+ if (tcnt == tgr) cycles2 = 0xFFFF + 1; else cycles2 = (UINT16)(tgr - tcnt);
+ if ((cycles2 > 0) && (cycles2 < cycles1)) cycles1 = cycles2;
+ // tgrc
+ if ((x == 0) || (x == 3))
+ {
+ tgr = ptr_read_16( h8->per_regs + H8S_IO_TGRC_H[x]);
+ if (tcnt == tgr) cycles2 = 0xFFFF + 1; else cycles2 = (UINT16)(tgr - tcnt);
+ if ((cycles2 > 0) && (cycles2 < cycles1)) cycles1 = cycles2;
+ }
+ // tgrd
+ if ((x == 0) || (x == 3))
+ {
+ tgr = ptr_read_16( h8->per_regs + H8S_IO_TGRD_H[x]);
+ if (tcnt == tgr) cycles2 = 0xFFFF + 1; else cycles2 = (UINT16)(tgr - tcnt);
+ if ((cycles2 > 0) && (cycles2 < cycles1)) cycles1 = cycles2;
+ }
+ // done
+ return cycles1;
+}
+
+void h8s_pin_write( h83xx_state *h8, int pin, int data)
+{
+ switch (pin)
+ {
+ case PIN_TIOCB1 :
+ {
+ UINT8 p1dr;
+ p1dr = h8->per_regs[H8S_IO_P1DR];
+ if (data) p1dr |= H8S_P1_TIOCB1; else p1dr &= ~H8S_P1_TIOCB1;
+ h8->io->write_byte(H8S_IO_ADDR(H8S_IO_P1DR), p1dr);
+ h8->per_regs[H8S_IO_P1DR] = p1dr;
+ }
+ break;
+ }
+}
+
+int h8s_pin_read( h83xx_state *h8, int pin)
+{
+ switch (pin)
+ {
+ case PIN_TIOCB1 : return (h8->per_regs[H8S_IO_P1DR] & H8S_P1_TIOCB1) ? 1 : 0;
+ }
+ return 0;
+}
+
+void h8s_tioc_pin_update( h83xx_state *h8, int io, int pin)
+{
+ switch (io)
+ {
+ case 1 : h8s_pin_write( h8, pin, 0); break;
+ case 2 : h8s_pin_write( h8, pin, 1); break;
+ case 3 : h8s_pin_write( h8, pin, h8s_pin_read( h8, pin) ? 0 : 1); break;
+ case 5 : h8s_pin_write( h8, pin, 0); break;
+ case 6 : h8s_pin_write( h8, pin, 1); break;
+ case 7 : h8s_pin_write( h8, pin, h8s_pin_read( h8, pin) ? 0 : 1); break;
+ }
+}
+
+void h8s_tioc_pin_reset( h83xx_state *h8, int io, int pin)
+{
+ switch (io)
+ {
+ case 1 : h8s_pin_write( h8, pin, 0); break;
+ case 2 : h8s_pin_write( h8, pin, 0); break;
+ case 3 : h8s_pin_write( h8, pin, 0); break;
+ case 5 : h8s_pin_write( h8, pin, 1); break;
+ case 6 : h8s_pin_write( h8, pin, 1); break;
+ case 7 : h8s_pin_write( h8, pin, 1); break;
+ }
+}
+
+void h8s_tpu_x_tioc_reset( h83xx_state *h8, int x)
+{
+ UINT8 tior;
+ int cclr;
+ // ...
+ cclr = (h8->per_regs[H8S_IO_TTCR[x]] >> 5) & TCR_CCLR_AND[x];
+ // tioca & tiocb
+ tior = h8->per_regs[H8S_IO_TIOR_H[x]];
+ if (cclr != 1) h8s_tioc_pin_reset( h8, (tior >> 0) & 0x0F, PIN_TIOCA[x]);
+ if (cclr != 2) h8s_tioc_pin_reset( h8, (tior >> 4) & 0x0F, PIN_TIOCB[x]);
+ // tiocc & tiocd
+ if ((x == 0) || (x == 3))
+ {
+ tior = h8->per_regs[H8S_IO_TIOR_L[x]];
+ if (cclr != 5) h8s_tioc_pin_reset( h8, (tior >> 0) & 0x0F, PIN_TIOCC[x]);
+ if (cclr != 6) h8s_tioc_pin_reset( h8, (tior >> 4) & 0x0F, PIN_TIOCD[x]);
+ }
+}
+
+void h8s_tpu_x_overflow( h83xx_state *h8, int x)
+{
+ if (x == 2)
+ {
+ UINT8 tcr = h8->per_regs[H8S_IO_TTCR[1]];
+ if (((tcr >> 0) & 7) == 7)
+ {
+ h8s_tpu_x_tick( h8, 1);
+ }
+ }
+ if (x == 5)
+ {
+ UINT8 tcr = h8->per_regs[H8S_IO_TTCR[4]];
+ if (((tcr >> 0) & 7) == 7)
+ {
+ h8s_tpu_x_tick( h8, 4);
+ }
+ }
+}
+
+UINT16 h8s_tpu_x_tcnt_change( h83xx_state *h8, int x, UINT16 tcnt)
+{
+ UINT16 tgr;
+ UINT8 tcr, tier, tior;
+ int clear = 0;
+ // ...
+ verboselog( h8->device->machine(), 9, "TPU %d - tpu_x_tcnt_change (%04X)\n", x, tcnt);
+ // ...
+ tcr = h8->per_regs[H8S_IO_TTCR[x]];
+ tier = h8->per_regs[H8S_IO_TIER[x]];
+ // overflow
+ if (tcnt == 0)
+ {
+ verboselog( h8->device->machine(), 9, "TPU %d - overflow match\n", x);
+ h8->per_regs[H8S_IO_TSR[x]] |= TSR_TCFV;
+ if (tier & TIER_TCIEV)
+ {
+ h8s2xxx_interrupt_request( h8, H8S_INT_TCIV[x]);
+ }
+ h8s_tpu_x_overflow( h8, x);
+ }
+ // tgra
+ tgr = ptr_read_16( h8->per_regs + H8S_IO_TGRA_H[x]);
+ if (tcnt == tgr)
+ {
+ verboselog( h8->device->machine(), 9, "TPU %d - tgra match\n", x);
+ h8->per_regs[H8S_IO_TSR[x]] |= TSR_TGFA;
+ if (tier & TIER_TGIEA)
+ {
+ h8s2xxx_interrupt_request( h8, H8S_INT_TGIA[x]);
+ }
+ if (((tcr >> 5) & TCR_CCLR_AND[x]) == 1) // CCLR 1 -> "TCNT cleared by TGRA compare match/input capture"
+ {
+ clear = 1;
+ }
+ else
+ {
+ tior = h8->per_regs[H8S_IO_TIOR_H[x]];
+ h8s_tioc_pin_update( h8, (tior >> 0) & 0x0F, PIN_TIOCA[x]);
+ }
+ }
+ // tgrb
+ tgr = ptr_read_16( h8->per_regs + H8S_IO_TGRB_H[x]);
+ if (tcnt == tgr)
+ {
+ verboselog( h8->device->machine(), 9, "TPU %d - tgrb match\n", x);
+ h8->per_regs[H8S_IO_TSR[x]] |= TSR_TGFB;
+ if (tier & TIER_TGIEB)
+ {
+ h8s2xxx_interrupt_request( h8, H8S_INT_TGIB[x]);
+ }
+ if (((tcr >> 5) & TCR_CCLR_AND[x]) == 2) // CCLR 2 -> "TCNT cleared by TGRB compare match/input capture"
+ {
+ clear = 1;
+ }
+ else
+ {
+ tior = h8->per_regs[H8S_IO_TIOR_H[x]];
+ h8s_tioc_pin_update( h8, (tior >> 4) & 0x0F, PIN_TIOCB[x]);
+ }
+ }
+ // tgrc
+ if ((x == 0) || (x == 3))
+ {
+ tgr = ptr_read_16( h8->per_regs + H8S_IO_TGRC_H[x]);
+ if (tcnt == tgr)
+ {
+ verboselog( h8->device->machine(), 9, "TPU %d - tgrc match\n", x);
+ h8->per_regs[H8S_IO_TSR[x]] |= TSR_TGFC;
+ if (tier & TIER_TGIEC)
+ {
+ h8s2xxx_interrupt_request( h8, H8S_INT_TGIC[x]);
+ }
+ if (((tcr >> 5) & TCR_CCLR_AND[x]) == 5) // CCLR 5 -> "TCNT cleared by TGRC compare match/input capture"
+ {
+ clear = 1;
+ }
+ else
+ {
+ tior = h8->per_regs[H8S_IO_TIOR_L[x]];
+ h8s_tioc_pin_update( h8, (tior >> 0) & 0x0F, PIN_TIOCC[x]);
+ }
+ }
+ }
+ // tgrd
+ if ((x == 0) || (x == 3))
+ {
+ tgr = ptr_read_16( h8->per_regs + H8S_IO_TGRD_H[x]);
+ if (tcnt == tgr)
+ {
+ verboselog( h8->device->machine(), 9, "TPU %d - tgrd match\n", x);
+ h8->per_regs[H8S_IO_TSR[x]] |= TSR_TGFD;
+ if (tier & TIER_TGIED)
+ {
+ h8s2xxx_interrupt_request( h8, H8S_INT_TGID[x]);
+ }
+ if (((tcr >> 5) & TCR_CCLR_AND[x]) == 6) // CCLR 6 -> "TCNT cleared by TGRD compare match/input capture"
+ {
+ clear = 1;
+ }
+ else
+ {
+ tior = h8->per_regs[H8S_IO_TIOR_L[x]];
+ h8s_tioc_pin_update( h8, (tior >> 4) & 0x0F, PIN_TIOCD[x]);
+ }
+ }
+ }
+ // ...
+ if (clear)
+ {
+ verboselog( h8->device->machine(), 9, "TPU %d - tcnt clear\n", x);
+ h8s_tpu_x_tioc_reset( h8, x);
+ tcnt = 0;
+ }
+ // ...
+ return tcnt;
+}
+
+void h8s_tpu_x_callback( h83xx_state *h8, int x)
+{
+ H8S2XXX_TPU *tpu = &h8->tpu[x];
+ UINT64 cycles;
+ UINT16 tcnt;
+ // calculate tcnt
+ tcnt = ptr_read_16( h8->per_regs + H8S_IO_TCNT_H[x]);
+ tcnt = (UINT16)(tcnt + tpu->timer_cycles / tpu->cycles_per_tick);
+ // ...
+ tcnt = h8s_tpu_x_tcnt_change( h8, x, tcnt);
+ // update tcnt
+ ptr_write_16( h8->per_regs + H8S_IO_TCNT_H[x], tcnt);
+ // update timer
+ cycles = h8s_tpu_x_calculate_ticks( h8, x, tcnt) * tpu->cycles_per_tick;
+ tpu->timer_cycles = cycles;
+ tpu->timer->adjust(attotime::from_hz(h8->device->unscaled_clock() / cycles), x);
+}
+
+void h8s_tpu_x_tick( h83xx_state *h8, int x)
+{
+ UINT16 tcnt;
+ // calculate tcnt
+ tcnt = ptr_read_16( h8->per_regs + H8S_IO_TCNT_H[x]);
+ tcnt = (UINT16)(tcnt + 1);
+ // ...
+ tcnt = h8s_tpu_x_tcnt_change( h8, x, tcnt);
+ // update tcnt
+ ptr_write_16( h8->per_regs + H8S_IO_TCNT_H[x], tcnt);
+}
+
+int h8s_tpu_x_get_div( h83xx_state *h8, int x)
+{
+ UINT8 tcr;
+ int tpsc;
+ const int *TPU_X_DIV[] = { TPU_0_DIV, TPU_1_DIV, TPU_2_DIV, TPU_3_DIV, TPU_4_DIV, TPU_5_DIV };
+ tcr = h8->per_regs[H8S_IO_TTCR[x]];
+ tpsc = (tcr >> 0) & 7;
+ return TPU_X_DIV[x][tpsc];
+}
+
+void h8s_tpu_x_update( h83xx_state *h8, int x)
+{
+ H8S2XXX_TPU *tpu = &h8->tpu[x];
+ // ...
+ tpu->cycles_per_tick = h8s_tpu_x_get_div( h8, x);
+ // update timer
+ if (tpu->cycles_per_tick != 0)
+ {
+ UINT16 tcnt;
+ UINT64 cycles;
+ tcnt = ptr_read_16( h8->per_regs + H8S_IO_TCNT_H[x]);
+ cycles = h8s_tpu_x_calculate_ticks( h8, x, tcnt) * tpu->cycles_per_tick;
+ tpu->timer_cycles = cycles;
+ tpu->timer->adjust(attotime::from_hz(h8->device->unscaled_clock() / cycles), x);
+ }
+ else
+ {
+ tpu->timer->reset();
+ }
+}
+
+void h8s_tpu_x_start( h83xx_state *h8, int x)
+{
+ verboselog( h8->device->machine(), 5, "TPU %d - start\n", x);
+ // ...
+ h8s_tpu_x_update( h8, x);
+}
+
+void h8s_tpu_x_stop( h83xx_state *h8, int x)
+{
+ H8S2XXX_TPU *tpu = &h8->tpu[x];
+ UINT16 tcnt;
+ // ...
+ verboselog( h8->device->machine(), 5, "TPU %d - stop\n", x);
+ // calculate tcnt
+ tcnt = h8s_tpu_x_calculate_tcnt( h8, x);
+ // update tcnt
+ ptr_write_16( h8->per_regs + H8S_IO_TCNT_H[x], tcnt);
+ // disable timer
+ tpu->timer->reset();
+}
+
+UINT16 h8s_tpu_x_read_tcnt( h83xx_state *h8, int x)
+{
+ return h8s_tpu_x_calculate_tcnt( h8, x);
+}
+
+void h8s_tpu_x_write_tcnt( h83xx_state *h8, int x, UINT16 data)
+{
+ H8S2XXX_TPU *tpu = &h8->tpu[x];
+ verboselog( h8->device->machine(), 9, "TPU %d - write tcnt (%04X)\n", x, data);
+ ptr_write_16( h8->per_regs + H8S_IO_TCNT_H[x], data);
+ if (tpu->timer->enabled())
+ {
+ h8s_tpu_x_update( h8, x);
+ }
+}
+
+void h8s_tpu_x_write_tgr( h83xx_state *h8, int x)
+{
+ H8S2XXX_TPU *tpu = &h8->tpu[x];
+ if ((tpu->timer->enabled()) && (tpu->cycles_per_tick != 0))
+ {
+ UINT16 tcnt1, tcnt2;
+ UINT64 cycles;
+ tcnt1 = ptr_read_16( h8->per_regs + H8S_IO_TCNT_H[x]);
+ tcnt2 = (UINT16)(tcnt1 + ((device_icount_min_timer_icount1( h8, tpu->timer)) / tpu->cycles_per_tick));
+ cycles = h8s_tpu_x_calculate_ticks( h8, x, tcnt2) * tpu->cycles_per_tick;
+ cycles = cycles + (tcnt2 - tcnt1) * tpu->cycles_per_tick;
+ tpu->timer_cycles = cycles;
+ tpu->timer->adjust(attotime::from_hz(h8->device->unscaled_clock() / cycles), x);
+ }
+}
+
+void h8s_tpu_x_write_tgra( h83xx_state *h8, int x, UINT16 data)
+{
+ verboselog( h8->device->machine(), 9, "TPU %d - write tgra (%04X)\n", x, data);
+ ptr_write_16( h8->per_regs + H8S_IO_TGRA_H[x], data);
+ h8s_tpu_x_write_tgr( h8, x);
+}
+
+void h8s_tpu_x_write_tgrb( h83xx_state *h8, int x, UINT16 data)
+{
+ verboselog( h8->device->machine(), 9, "TPU %d - write tgrb (%04X)\n", x, data);
+ ptr_write_16( h8->per_regs + H8S_IO_TGRB_H[x], data);
+ h8s_tpu_x_write_tgr( h8, x);
+}
+
+void h8s_tpu_x_write_tgrc( h83xx_state *h8, int x, UINT16 data)
+{
+ verboselog( h8->device->machine(), 9, "TPU %d - write tgrc (%04X)\n", x, data);
+ ptr_write_16( h8->per_regs + H8S_IO_TGRC_H[x], data);
+ h8s_tpu_x_write_tgr( h8, x);
+}
+
+void h8s_tpu_x_write_tgrd( h83xx_state *h8, int x, UINT16 data)
+{
+ verboselog( h8->device->machine(), 9, "TPU %d - write tgrd (%04X)\n", x, data);
+ ptr_write_16( h8->per_regs + H8S_IO_TGRD_H[x], data);
+ h8s_tpu_x_write_tgr( h8, x);
+}
+
+void h8s_tpu_x_write_tior( h83xx_state *h8, int x)
+{
+ UINT8 tstr;
+ tstr = h8->per_regs[H8S_IO_TSTR];
+ if ((tstr & (1 << x)) == 0)
+ {
+ h8s_tpu_x_tioc_reset( h8, x);
+ }
+}
+
+void h8s_tpu_0_write_tior_h( h83xx_state *h8, UINT8 data)
+{
+ h8->per_regs[H8S_IO_TIOR0_H] = data;
+ h8s_tpu_x_write_tior( h8, 0);
+}
+
+void h8s_tpu_0_write_tior_l( h83xx_state *h8, UINT8 data)
+{
+ h8->per_regs[H8S_IO_TIOR0_L] = data;
+ h8s_tpu_x_write_tior( h8, 0);
+}
+
+void h8s_tpu_1_write_tior( h83xx_state *h8, UINT8 data)
+{
+ h8->per_regs[H8S_IO_TIOR1] = data;
+ h8s_tpu_x_write_tior( h8, 1);
+}
+
+void h8s_tpu_2_write_tior( h83xx_state *h8, UINT8 data)
+{
+ h8->per_regs[H8S_IO_TIOR2] = data;
+ h8s_tpu_x_write_tior( h8, 2);
+}
+
+void h8s_tpu_3_write_tior_h( h83xx_state *h8, UINT8 data)
+{
+ h8->per_regs[H8S_IO_TIOR3_H] = data;
+ h8s_tpu_x_write_tior( h8, 3);
+}
+
+void h8s_tpu_3_write_tior_l( h83xx_state *h8, UINT8 data)
+{
+ h8->per_regs[H8S_IO_TIOR3_L] = data;
+ h8s_tpu_x_write_tior( h8, 3);
+}
+
+void h8s_tpu_4_write_tior( h83xx_state *h8, UINT8 data)
+{
+ h8->per_regs[H8S_IO_TIOR4] = data;
+ h8s_tpu_x_write_tior( h8, 4);
+}
+
+void h8s_tpu_5_write_tior( h83xx_state *h8, UINT8 data)
+{
+ h8->per_regs[H8S_IO_TIOR5] = data;
+ h8s_tpu_x_write_tior( h8, 5);
+}
+
+void h8s_tpu_write_tstr( h83xx_state *h8, UINT8 data)
+{
+ const int tpu_max = (h8->device->type() == H8S2323) ? 6 : 3;
+ UINT8 old_data = h8->per_regs[H8S_IO_TSTR];
+ int i;
+ h8->per_regs[H8S_IO_TSTR] = data;
+ for (i = 0; i < tpu_max; i++)
+ {
+ if ((data & (1 << i)) != (old_data & (1 << i)))
+ {
+ if ((data & (1 << i)) != 0)
+ {
+ h8s_tpu_x_start( h8, i);
+ }
+ else
+ {
+ h8s_tpu_x_stop( h8, i);
+ }
+ }
+ }
+}
+
+static TIMER_CALLBACK( h8s_tpu_callback)
+{
+ h83xx_state *h8 = (h83xx_state *)ptr;
+ h8s_tpu_x_callback( h8, param);
+}
+
+/////////////////////////////////
+// SERIAL CONTROLLER INTERFACE //
+/////////////////////////////////
+
+typedef struct
+{
+ UINT32 reg_smr, reg_brr, reg_scr, reg_tdr, reg_ssr, reg_rdr;
+ UINT32 reg_pdr, reg_port;
+ UINT8 port_mask_sck, port_mask_txd, port_mask_rxd;
+ UINT8 int_tx, int_rx;
+} H8S_SCI_ENTRY;
+
+const H8S_SCI_ENTRY H8S_SCI_TABLE[] =
+{
+ // SCI 0
+ {
+ H8S_IO_SMR0, H8S_IO_BRR0, H8S_IO_SCR0, H8S_IO_TDR0, H8S_IO_SSR0, H8S_IO_RDR0,
+ H8S_IO_P3DR, H8S_IO_PORT3,
+ H8S_P3_SCK0, H8S_P3_TXD0, H8S_P3_RXD0,
+ H8S_INT_TXI0, H8S_INT_RXI0
+ },
+ // SCI 1
+ {
+ H8S_IO_SMR1, H8S_IO_BRR1, H8S_IO_SCR1, H8S_IO_TDR1, H8S_IO_SSR1, H8S_IO_RDR1,
+ H8S_IO_P3DR, H8S_IO_PORT3,
+ H8S_P3_SCK1, H8S_P3_TXD1, H8S_P3_RXD1,
+ H8S_INT_TXI1, H8S_INT_RXI1
+ },
+ // SCI 2
+ {
+ H8S_IO_SMR2, H8S_IO_BRR2, H8S_IO_SCR2, H8S_IO_TDR2, H8S_IO_SSR2, H8S_IO_RDR2,
+ H8S_IO_P5DR, H8S_IO_PORT5,
+ H8S_P5_SCK2, H8S_P5_TXD2, H8S_P5_RXD2,
+ H8S_INT_TXI2, H8S_INT_RXI2
+ }
+};
+
+const H8S_SCI_ENTRY *h8s_sci_entry( int num)
+{
+ return &H8S_SCI_TABLE[num];
+}
+
+void h8s_sci_init(h83xx_state *h8)
+{
+ int i;
+ for (i=0;i<3;i++)
+ {
+ h8->sci[i].timer = h8->device->machine().scheduler().timer_alloc(FUNC(h8s_sci_callback), h8);
+ h8->sci[i].timer->adjust(attotime::never, i);
+ }
+}
+
+static TIMER_CALLBACK(h8s_sci_callback)
+{
+ h83xx_state *h8 = (h83xx_state *)ptr;
+ verboselog( h8->device->machine(), 7, "h8s_sci_callback (%d)\n", param);
+}
+
+void h8s_sci_start(h83xx_state *h8, int num)
+{
+ #if 0
+ h8->sci[num].timer->adjust(h8->sci[num].bitrate, num);
+ #endif
+}
+
+void h8s_sci_stop(h83xx_state *h8, int num)
+{
+ h8->sci[num].timer->adjust(attotime::never, num);
+}
+
+void h8s_sci_execute(h83xx_state *h8, int num)
+{
+ UINT8 scr, tdr, ssr, rdr, tsr, rsr, pdr, port;
+ int i;
+ const H8S_SCI_ENTRY *info = h8s_sci_entry( num);
+ verboselog( h8->device->machine(), 5, "h8s_sci_execute(%d)\n", num);
+ // load regs
+ scr = h8->per_regs[info->reg_scr];
+ tdr = h8->per_regs[info->reg_tdr];
+ ssr = h8->per_regs[info->reg_ssr];
+ rdr = h8->per_regs[info->reg_rdr];
+ tsr = 0;
+ rsr = 0;
+ pdr = h8->per_regs[info->reg_pdr] & (~info->port_mask_sck);
+ // move byte from TDR to TSR
+ if (scr & H8S_SCR_TE)
+ {
+ tsr = tdr;
+ ssr |= H8S_SSR_TDRE;
+ }
+ // generate transmit data empty interrupt
+ if ((scr & H8S_SCR_TIE) && (ssr & H8S_SSR_TDRE)) h8s2xxx_interrupt_request(h8, info->int_tx);
+ // transmit/receive bits
+ for (i=0;i<8;i++)
+ {
+ // write bit
+ if (scr & H8S_SCR_TE)
+ {
+ if (tsr & (1 << i)) pdr = pdr | info->port_mask_txd; else pdr = pdr & (~info->port_mask_txd);
+ h8->io->write_byte( H8S_IO_ADDR( info->reg_pdr), pdr);
+ }
+ // clock high to low
+ h8->io->write_byte( H8S_IO_ADDR( info->reg_pdr), pdr | info->port_mask_sck);
+ h8->io->write_byte( H8S_IO_ADDR( info->reg_pdr), pdr);
+ // read bit
+ if (scr & H8S_SCR_RE)
+ {
+ port = h8->io->read_byte(H8S_IO_ADDR( info->reg_port));
+ if (port & info->port_mask_rxd) rsr = rsr | (1 << i);
+ }
+ }
+ // move byte from RSR to RDR
+ if (scr & H8S_SCR_RE)
+ {
+ rdr = rsr;
+ //ssr |= H8S_SSR_RDRF;
+ }
+ // generate receive data full interrupt
+ if ((scr & H8S_SCR_RIE) && (ssr & H8S_SSR_RDRF)) h8s2xxx_interrupt_request(h8, info->int_rx);
+ // save regs
+ h8->per_regs[info->reg_scr] = scr;
+ h8->per_regs[info->reg_tdr] = tdr;
+ h8->per_regs[info->reg_ssr] = ssr;
+ h8->per_regs[info->reg_rdr] = rdr;
+}
+
+const double SCR_CKE[] = { 0.5, 2, 8, 32 }; // = 2 ^ ((2 * cke) - 1)
+const int SMR_MODE[] = { 64, 8 };
+
+void h8s_sci_rate(h83xx_state *h8, int num)
+{
+ UINT8 brr, scr, smr, cke, mode;
+ UINT32 bitrate;
+ const H8S_SCI_ENTRY *info = h8s_sci_entry( num);
+ // read regs
+ brr = h8->per_regs[info->reg_brr];
+ scr = h8->per_regs[info->reg_scr];
+ smr = h8->per_regs[info->reg_smr];
+ verboselog( h8->device->machine(), 2, "BRR %02X SCR %02X SMR %02X\n", brr, scr, smr);
+ // calculate bitrate
+ cke = (scr >> 0) & 3;
+ mode = (smr >> 7) & 1;
+ bitrate = (UINT32)((h8->device->unscaled_clock() / (brr + 1)) / (SMR_MODE[mode] * SCR_CKE[cke]));
+ verboselog( h8->device->machine(), 2, "SCI%d bitrate %d\n", num, bitrate);
+ // store bitrate
+ h8->sci[num].bitrate = bitrate;
+}
+
+////////////////////////////
+// INTERNAL I/O REGISTERS //
+////////////////////////////
+
+void h8s_onchip_reg_write_8(h83xx_state *h8, int offset, UINT8 data)
+{
+ verboselog( h8->device->machine(), 9, "%08X | %08X <- %02X\n", h8->ppc, H8S_IO_ADDR(offset), data);
+ switch (offset)
+ {
+ // SCI 0
+ case H8S_IO_SSR0 : h8->per_regs[offset] = data; if ((data & H8S_SSR_TDRE) == 0) h8s_sci_execute(h8, 0); break;
+ case H8S_IO_SCR0 : h8->per_regs[offset] = data; if (data & H8S_SCR_TIE) h8s2xxx_interrupt_request(h8, h8s_sci_entry(0)->int_tx); break;
+ case H8S_IO_BRR0 : h8->per_regs[offset] = data; h8s_sci_rate(h8, 0); h8s_sci_start(h8, 0); break;
+ // SCI 1
+ case H8S_IO_SSR1 : h8->per_regs[offset] = data; if ((data & H8S_SSR_TDRE) == 0) h8s_sci_execute(h8, 1); break;
+ case H8S_IO_SCR1 : h8->per_regs[offset] = data; if (data & H8S_SCR_RIE) h8s2xxx_interrupt_request(h8, h8s_sci_entry(1)->int_rx); break;
+ case H8S_IO_BRR1 : h8->per_regs[offset] = data; h8s_sci_rate(h8, 1); h8s_sci_start(h8, 1); break;
+ // SCI 2
+ case H8S_IO_SSR2 : h8->per_regs[offset] = data; if ((data & H8S_SSR_TDRE) == 0) h8s_sci_execute(h8, 2); break;
+ case H8S_IO_SCR2 : h8->per_regs[offset] = data; if (data & H8S_SCR_TIE) h8s2xxx_interrupt_request(h8, h8s_sci_entry(2)->int_tx); break;
+ case H8S_IO_BRR2 : h8->per_regs[offset] = data; h8s_sci_rate(h8, 2); h8s_sci_start(h8, 2); break;
+ // TMR 0
+ case H8S_IO_TCR0 : h8s_tmr_x_write_tcr( h8, 0, data); break;
+ case H8S_IO_TCNT0 : h8s_tmr_x_write_tcnt( h8, 0, data); break;
+ case H8S_IO_TCORA0 : h8s_tmr_x_write_tcora( h8, 0, data); break;
+ case H8S_IO_TCORB0 : h8s_tmr_x_write_tcorb( h8, 0, data); break;
+ // TMR 1
+ case H8S_IO_TCR1 : h8s_tmr_x_write_tcr( h8, 1, data); break;
+ case H8S_IO_TCNT1 : h8s_tmr_x_write_tcnt( h8, 1, data); break;
+ case H8S_IO_TCORA1 : h8s_tmr_x_write_tcora( h8, 1, data); break;
+ case H8S_IO_TCORB1 : h8s_tmr_x_write_tcorb( h8, 1, data); break;
+ // ports
+ case H8S_IO_P1DR : case H8S_IO_P2DR : case H8S_IO_P3DR : case H8S_IO_P4DR : case H8S_IO_P5DR :
+ case H8S_IO_PADR : case H8S_IO_PBDR : case H8S_IO_PCDR : case H8S_IO_PDDR : case H8S_IO_PEDR :
+ case H8S_IO_PFDR : h8->per_regs[offset] = data; h8->io->write_byte( H8S_IO_ADDR( offset), data); break;
+ // ...
+ case H8S_IO_PFDDR : h8->per_regs[offset] = data; h8->io->write_byte( H8S_IO_ADDR( offset), data); break;
+ // TPU
+ case H8S_IO_TSTR : h8s_tpu_write_tstr( h8, data); break;
+ // DMA
+ case H8S_IO_DMABCRL :
+ {
+ h8->per_regs[offset] = data;
+ if (h8->device->type() == H8S2323)
+ {
+ if ((data & 0x40) && (data & 0x80))
+ {
+ UINT32 i, dma_src, dma_dst;
+ UINT16 dma_cnt, dma_con;
+ int sz;
+ dma_src = h8->program->read_dword( H8S_IO_ADDR(H8S_IO_MAR1AH));
+ dma_dst = h8->program->read_dword( H8S_IO_ADDR(H8S_IO_MAR1BH));
+ dma_cnt = h8->program->read_word( H8S_IO_ADDR(H8S_IO_ETCR1A));
+ dma_con = h8->program->read_word( H8S_IO_ADDR(H8S_IO_DMACR1A));
+ sz = (dma_con & 0x8000) ? 2 : 1;
+ for (i=0;i<dma_cnt;i++)
+ {
+ if (dma_con & 0x8000) h8->program->write_word( dma_dst, h8->program->read_word( dma_src)); else h8->program->write_byte( dma_dst, h8->program->read_byte( dma_src));
+ if (dma_con & 0x2000) { if (dma_con & 0x4000) dma_src -= sz; else dma_src += sz; }
+ if (dma_con & 0x0020) { if (dma_con & 0x0040) dma_dst -= sz; else dma_dst += sz; }
+ }
+ h8->per_regs[H8S_IO_DMABCRL] &= ~0x40;
+ }
+ }
+ }
+ break;
+ // ...
+ default :
+ {
+ h8->per_regs[offset] = data;
+ }
+ break;
+ }
+}
+
+void h8s_onchip_reg_write_16(h83xx_state *h8, int offset, UINT16 data)
+{
+ verboselog( h8->device->machine(), 9, "%08X | %08X <- %04X\n", h8->ppc, H8S_IO_ADDR(offset), data);
+ switch (offset)
+ {
+ // TPU 0
+ case H8S_IO_TCNT0_H : h8s_tpu_x_write_tcnt( h8, 0, data); break;
+ case H8S_IO_TGR0A_H : h8s_tpu_x_write_tgra( h8, 0, data); break;
+ case H8S_IO_TGR0B_H : h8s_tpu_x_write_tgrb( h8, 0, data); break;
+ case H8S_IO_TGR0C_H : h8s_tpu_x_write_tgrc( h8, 0, data); break;
+ case H8S_IO_TGR0D_H : h8s_tpu_x_write_tgrd( h8, 0, data); break;
+ // TPU 1
+ case H8S_IO_TCNT1_H : h8s_tpu_x_write_tcnt( h8, 1, data); break;
+ case H8S_IO_TGR1A_H : h8s_tpu_x_write_tgra( h8, 1, data); break;
+ case H8S_IO_TGR1B_H : h8s_tpu_x_write_tgrb( h8, 1, data); break;
+ // TPU 2
+ case H8S_IO_TCNT2_H : h8s_tpu_x_write_tcnt( h8, 2, data); break;
+ case H8S_IO_TGR2A_H : h8s_tpu_x_write_tgra( h8, 2, data); break;
+ case H8S_IO_TGR2B_H : h8s_tpu_x_write_tgrb( h8, 2, data); break;
+ // TPU 3
+ case H8S_IO_TCNT3_H : if (h8->device->type() == H8S2323) h8s_tpu_x_write_tcnt( h8, 3, data); break;
+ case H8S_IO_TGR3A_H : if (h8->device->type() == H8S2323) h8s_tpu_x_write_tgra( h8, 3, data); break;
+ case H8S_IO_TGR3B_H : if (h8->device->type() == H8S2323) h8s_tpu_x_write_tgrb( h8, 3, data); break;
+ case H8S_IO_TGR3C_H : if (h8->device->type() == H8S2323) h8s_tpu_x_write_tgrc( h8, 3, data); break;
+ case H8S_IO_TGR3D_H : if (h8->device->type() == H8S2323) h8s_tpu_x_write_tgrd( h8, 3, data); break;
+ // TPU 4
+ case H8S_IO_TCNT4_H : if (h8->device->type() == H8S2323) h8s_tpu_x_write_tcnt( h8, 4, data); break;
+ case H8S_IO_TGR4A_H : if (h8->device->type() == H8S2323) h8s_tpu_x_write_tgra( h8, 4, data); break;
+ case H8S_IO_TGR4B_H : if (h8->device->type() == H8S2323) h8s_tpu_x_write_tgrb( h8, 4, data); break;
+ // TPU 5
+ case H8S_IO_TCNT5_H : if (h8->device->type() == H8S2323) h8s_tpu_x_write_tcnt( h8, 5, data); break;
+ case H8S_IO_TGR5A_H : if (h8->device->type() == H8S2323) h8s_tpu_x_write_tgra( h8, 5, data); break;
+ case H8S_IO_TGR5B_H : if (h8->device->type() == H8S2323) h8s_tpu_x_write_tgrb( h8, 5, data); break;
+ // ...
+ default :
+ {
+ h8s_onchip_reg_write_8( h8, offset + 0, (data >> 8) & 0xFF);
+ h8s_onchip_reg_write_8( h8, offset + 1, (data >> 0) & 0xFF);
+ }
+ break;
+ }
+}
+
+UINT8 h8s_onchip_reg_read_8(h83xx_state *h8, int offset)
+{
+ UINT8 data;
+ switch (offset)
+ {
+ // SCI 0
+ case H8S_IO_SSR0 : data = H8S_SSR_TDRE | H8S_SSR_TEND; break;
+ case H8S_IO_RDR0 : data = h8->io->read_byte( H8S_IO_ADDR( offset)); break;
+ // SCI 1
+ case H8S_IO_SSR1 : data = H8S_SSR_TDRE | H8S_SSR_TEND; break;
+ // SCI 2
+ case H8S_IO_SSR2 :
+ {
+ data = h8->per_regs[offset];
+ if (!(h8->per_regs[H8S_IO_SCR2] & H8S_SCR_TE)) data |= H8S_SSR_TDRE;
+ }
+ break;
+ // ports
+ case H8S_IO_PORT1 : case H8S_IO_PORT2 : case H8S_IO_PORT3 : case H8S_IO_PORT4 : case H8S_IO_PORT5 :
+ case H8S_IO_PORTA : case H8S_IO_PORTB : case H8S_IO_PORTC : case H8S_IO_PORTD : case H8S_IO_PORTE :
+ case H8S_IO_PORTF : data = h8->io->read_byte( H8S_IO_ADDR( offset)); break;
+ // ...
+ case H8S_IO_P3DR : data = 0; break; // todo: without this cybiko hangs
+ // TMR 0
+ case H8S_IO_TCNT0 : data = h8s_tmr_x_read_tcnt( h8, 0); break;
+ // TMR 1
+ case H8S_IO_TCNT1 : data = h8s_tmr_x_read_tcnt( h8, 1); break;
+ // ...
+ // default
+ default : data = h8->per_regs[offset]; break;
+ }
+ verboselog( h8->device->machine(), 9, "%08X | %08X -> %02X\n", h8->ppc, H8S_IO_ADDR(offset), data);
+ return data;
+}
+
+UINT16 h8s_onchip_reg_read_16(h83xx_state *h8, int offset)
+{
+ UINT16 data = 0;
+ switch (offset)
+ {
+ case H8S_IO_TCNT0_H : data = h8s_tpu_x_read_tcnt( h8, 0); break;
+ case H8S_IO_TCNT1_H : data = h8s_tpu_x_read_tcnt( h8, 1); break;
+ case H8S_IO_TCNT2_H : data = h8s_tpu_x_read_tcnt( h8, 2); break;
+ case H8S_IO_TCNT3_H : if (h8->device->type() == H8S2323) data = h8s_tpu_x_read_tcnt( h8, 3); break;
+ case H8S_IO_TCNT4_H : if (h8->device->type() == H8S2323) data = h8s_tpu_x_read_tcnt( h8, 4); break;
+ case H8S_IO_TCNT5_H : if (h8->device->type() == H8S2323) data = h8s_tpu_x_read_tcnt( h8, 5); break;
+ default :
+ {
+ UINT8 b[2];
+ b[0] = h8s_onchip_reg_read_8( h8, offset + 0);
+ b[1] = h8s_onchip_reg_read_8( h8, offset + 1);
+ data = (b[0] << 8) | (b[1] << 0);
+ }
+ break;
+ }
+ verboselog( h8->device->machine(), 9, "%08X | %08X -> %04X\n", h8->ppc, H8S_IO_ADDR(offset), data);
+ return data;
+}
+
+void h8s2241_per_regs_write_8(h83xx_state *h8, int offset, UINT8 data)
+{
+ h8s_onchip_reg_write_8(h8, offset, data);
+}
+
+UINT8 h8s2241_per_regs_read_8(h83xx_state *h8, int offset)
+{
+ return h8s_onchip_reg_read_8(h8, offset);
+}
+
+void h8s2241_per_regs_write_16(h83xx_state *h8, int offset, UINT16 data)
+{
+ h8s_onchip_reg_write_16(h8, offset, data);
+}
+
+UINT16 h8s2241_per_regs_read_16(h83xx_state *h8, int offset)
+{
+ return h8s_onchip_reg_read_16(h8, offset);
+}
+
+void h8s2246_per_regs_write_8(h83xx_state *h8, int offset, UINT8 data)
+{
+ h8s_onchip_reg_write_8(h8, offset, data);
+}
+
+UINT8 h8s2246_per_regs_read_8(h83xx_state *h8, int offset)
+{
+ return h8s_onchip_reg_read_8(h8, offset);
+}
+
+void h8s2246_per_regs_write_16(h83xx_state *h8, int offset, UINT16 data)
+{
+ h8s_onchip_reg_write_16(h8, offset, data);
+}
+
+UINT16 h8s2246_per_regs_read_16(h83xx_state *h8, int offset)
+{
+ return h8s_onchip_reg_read_16(h8, offset);
+}
+
+void h8s2323_per_regs_write_8(h83xx_state *h8, int offset, UINT8 data)
+{
+ h8s_onchip_reg_write_8(h8, offset, data);
+}
+
+UINT8 h8s2323_per_regs_read_8(h83xx_state *h8, int offset)
+{
+ return h8s_onchip_reg_read_8(h8, offset);
+}
+
+void h8s2323_per_regs_write_16(h83xx_state *h8, int offset, UINT16 data)
+{
+ h8s_onchip_reg_write_16(h8, offset, data);
+}
+
+UINT16 h8s2323_per_regs_read_16(h83xx_state *h8, int offset)
+{
+ return h8s_onchip_reg_read_16(h8, offset);
+}