initial commit
[megatris] / src / io.h
1 #ifndef MEGADRIVE_IO_H_
2 #define MEGADRIVE_IO_H_
3
4 #include <stdint.h>
5
6 #define IO_REG_VER              *((volatile uint8_t*)0xa10001)
7 #define IO_REG_DATA1    *((volatile uint8_t*)0xa10003)
8 #define IO_REG_DATA2    *((volatile uint8_t*)0xa10005)
9 #define IO_REG_DATA3    *((volatile uint8_t*)0xa10007)
10 #define IO_REG_CTRL1    *((volatile uint8_t*)0xa10009)
11 #define IO_REG_CTRL2    *((volatile uint8_t*)0xa1000b)
12 #define IO_REG_CTRL3    *((volatile uint8_t*)0xa1000d)
13 #define IO_REG_TXDATA1  *((volatile uint8_t*)0xa1000f)
14 #define IO_REG_RXDATA1  *((volatile uint8_t*)0xa10011)
15 #define IO_REG_S_CTRL1  *((volatile uint8_t*)0xa10013)
16 #define IO_REG_TXDATA2  *((volatile uint8_t*)0xa10015)
17 #define IO_REG_RXDATA2  *((volatile uint8_t*)0xa10017)
18 #define IO_REG_S_CTRL2  *((volatile uint8_t*)0xa10013)
19 #define IO_REG_TXDATA3  *((volatile uint8_t*)0xa1001b)
20 #define IO_REG_RXDATA3  *((volatile uint8_t*)0xa1001d)
21 #define IO_REG_S_CTRL3  *((volatile uint8_t*)0xa1001f)
22 #define IO_REG_LOCK             *((volatile uint8_t*)0xa14000)
23 #define IO_REG_TMSS             *((volatile uint8_t*)0xa14101)
24
25 #define IO_REG_DATA(x)  *((volatile uint8_t*)0xa10003 + ((x) << 1))
26 #define IO_REG_CTRL(x)  *((volatile uint8_t*)0xa10009 + ((x) << 1))
27
28
29 enum {
30         IO_VER_VERSION_MASK = 0x0f,
31         IO_VER_EXP              = 0x20,
32         IO_VER_PAL              = 0x40,
33         IO_VER_NONJP    = 0x80
34 };
35
36 enum {
37         IO_PAD_UP               = 0x001,
38         IO_PAD_DOWN             = 0x002,
39         IO_PAD_LEFT             = 0x004,
40         IO_PAD_RIGHT    = 0x008,
41         IO_PAD_B                = 0x010,
42         IO_PAD_C                = 0x020,
43         IO_PAD_A                = 0x040,
44         IO_PAD_START    = 0x080,
45
46         IO_PAD_Z                = 0x100,
47         IO_PAD_Y                = 0x200,
48         IO_PAD_X                = 0x400
49 };
50 #define IO_PAD_LOW_MASK         0x3f
51 #define IO_PAD_HIGH_MASK        (IO_PAD_A | IO_PAD_START)
52
53 static inline void io_setdir(int port, uint8_t dir)
54 {
55         IO_REG_CTRL(port) = dir;
56 }
57
58 static inline uint16_t io_readpad(int port)
59 {
60         uint16_t bnstate;
61
62         bnstate = ~(IO_REG_DATA(port) << 2) & IO_PAD_HIGH_MASK;
63
64         IO_REG_DATA(port) = 0x40;       /* select mode 1 */
65         asm volatile("nop");
66         asm volatile("nop");
67         bnstate |= ~IO_REG_DATA(port) & IO_PAD_LOW_MASK;
68
69         IO_REG_DATA(port) = 0;          /* select mode 0 */
70         return bnstate;
71 }
72
73 static inline uint16_t io_readpad6(int port)
74 {
75         uint16_t bnstate;
76
77         IO_REG_DATA(port) = 0x40;       /* start with mode 1 */
78         asm volatile("nop");
79         asm volatile("nop");
80         bnstate = ~IO_REG_DATA(port) & IO_PAD_LOW_MASK;
81
82         IO_REG_DATA(port) = 0;          /* select mode 0 */
83         asm volatile("nop");
84         asm volatile("nop");
85         bnstate |= ~(IO_REG_DATA(port) << 2) & IO_PAD_HIGH_MASK;
86
87         /* then introduce two more rising edges to trigger extended mode */
88         IO_REG_DATA(port) = 0x40;
89         asm volatile("nop");
90         asm volatile("nop");
91         IO_REG_DATA(port) = 0;
92         asm volatile("nop");
93         asm volatile("nop");
94         IO_REG_DATA(port) = 0x40;
95         asm volatile("nop");
96         asm volatile("nop");
97
98         bnstate |= (uint16_t)(~IO_REG_DATA(port) & 0x7) << 8;
99         IO_REG_DATA(port) = 0;          /* return mode to 0 */
100         return bnstate;
101 }
102
103 void io_init(void);
104 /*uint16_t io_readpad(int port);*/
105
106 #endif  /* MEGADRIVE_IO_H_ */