-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.c
170 lines (148 loc) · 3.39 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include "buffer.h"
#include "serial.h"
#include <genesis.h>
#include <stdbool.h>
#include <vdp.h>
const bool USE_RECV_INT = TRUE;
const u16 BUFFER_MIN_Y = 6;
const u16 BUFFER_MAX_X = 39;
const u16 BUFFER_MAX_LINES = 6;
typedef struct Cursor Cursor;
struct Cursor {
u16 x;
u16 y;
};
static u8 ui_dirty = FALSE;
static u16 baudRate(u8 sctrl)
{
switch (sctrl & 0xC0) {
case SCTRL_300_BPS:
return 300;
case SCTRL_1200_BPS:
return 1200;
case SCTRL_2400_BPS:
return 2400;
default:
return 4800;
}
}
static void printBaudRate(void)
{
char baudRateText[9];
sprintf(baudRateText, "%d bps", baudRate(serial_sctrl()));
VDP_drawText(baudRateText, 0, 2);
}
static void printSCtrlFlags(void)
{
const u8 flags[] = { SCTRL_RERR, SCTRL_RRDY, SCTRL_TFUL };
const char* names[] = { "RERR", "RRDY", "TFUL" };
s8 sctrl = serial_sctrl();
for (u16 i = 0; i < 3; i++) {
if (sctrl & flags[i]) {
VDP_setTextPalette(PAL0);
} else {
VDP_setTextPalette(PAL1);
}
VDP_drawText(names[i], 10 + (i * 5), 2);
}
VDP_setTextPalette(PAL0);
}
static void ui_callback(void)
{
buffer_write(serial_receive());
ui_dirty = TRUE;
}
static void incrementCursor(Cursor* cur)
{
Cursor* cursor = cur;
cursor->x++;
if (cursor->x > BUFFER_MAX_X) {
cursor->y++;
cursor->x = 0;
}
if (cursor->y > BUFFER_MAX_LINES) {
cursor->y = 0;
}
}
static void receiveSerialIntoBuffer(Cursor* cur)
{
while (serial_readyToReceive()) {
buffer_write(serial_receive());
ui_dirty = TRUE;
}
}
static void readFromBuffer(Cursor* cur)
{
VDP_setTextPalette(PAL1);
if (buffer_canRead()) {
u8 data = buffer_read();
char buf[2] = { (char)data, 0 };
VDP_drawText(buf, cur->x, cur->y + BUFFER_MIN_Y);
incrementCursor(cur);
if (cur->x == 0 && cur->y == 0) {
VDP_clearTextArea(
0, BUFFER_MIN_Y, BUFFER_MAX_X + 1, BUFFER_MAX_LINES + 1);
}
ui_dirty = TRUE;
}
VDP_setTextPalette(PAL0);
}
static void printBufferFree(void)
{
if (ui_dirty) {
char text[32];
sprintf(text, "%4d Free", buffer_available());
VDP_drawText(text, 28, 4);
ui_dirty = FALSE;
}
}
static void receive(Cursor* cur)
{
if (!USE_RECV_INT) {
receiveSerialIntoBuffer(cur);
}
readFromBuffer(cur);
printBufferFree();
}
static void send(void)
{
for (u8 i = '0'; i <= '9'; i++) {
serial_sendWhenReady(i);
}
serial_sendWhenReady('\n');
}
static void init(void)
{
VDP_setPaletteColor((PAL1 * 16) + 15, RGB24_TO_VDPCOLOR(0x444444));
VDP_drawText("Mega Drive Serial Port Diagnostics", 3, 0);
VDP_drawText("Recv Buffer:", 0, 4);
u8 sctrlFlags = SCTRL_4800_BPS | SCTRL_SIN | SCTRL_SOUT;
if (USE_RECV_INT) {
sctrlFlags |= SCTRL_RINT;
}
serial_init(sctrlFlags);
serial_setReadyToReceiveCallback(&ui_callback);
printBaudRate();
}
static void sendAndReceiveLoop(void)
{
const bool DO_RECEIVE = TRUE;
const bool DO_SEND = TRUE;
Cursor cur = { 0, 0 };
while (TRUE) {
printSCtrlFlags();
if (DO_RECEIVE) {
receive(&cur);
}
if (DO_SEND) {
send();
}
VDP_waitVSync();
}
}
int main()
{
init();
sendAndReceiveLoop();
return 0;
}