This repository was archived by the owner on Feb 3, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsio2.cpp
112 lines (101 loc) · 2.09 KB
/
sio2.cpp
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
#include <sio2.h>
#include <gamepad.h>
#include <Bus.hpp>
Gamepad gamepad;
SIO2::SIO2(Bus* parent)
: bus(parent)
{
current_device = SIO2Peripheral::None;
}
uint32_t SIO2::read(uint32_t address)
{
switch (address & 0xFF)
{
case 0x64: return read_fifo();
case 0x68: return sio2_ctrl;
case 0x6C: return 0x0D102;
case 0x70: return 0xF;
case 0x74: return 0;
default:
printf("[SIO2]: Read from unknown address 0x%08X\n", address);
exit(1);
}
}
void SIO2::write(uint32_t address, uint32_t data)
{
switch (address & 0xFF)
{
case 0x00 ... 0x3F:
{
int offset = (address & 0x3F) / 4;
send3[offset] = data;
break;
}
case 0x40 ... 0x5F:
{
bool send2 = address & 0x4;
int offset = (address & 0x1F) / 8;
send1_2[offset + send2 * 4] = data;
break;
}
case 0x60:
{
upload_command(data);
break;
}
case 0x68:
{
sio2_ctrl = data;
if (data & 0x1)
{
printf("[SIO2]: Need to enable intr\n");
sio2_ctrl &= ~0x1;
}
if (data & 0xC)
{
command = {};
current_device = SIO2Peripheral::None;
}
break;
}
}
}
void SIO2::upload_command(uint8_t cmd)
{
bool just_started = false;
if (!command.size)
{
auto params = send3[command.index];
if (!params)
{
printf("[SIO2]: SEND3 parameter empty!\n");
exit(1);
}
command.size = (params >> 8) & 0x1FF;
command.index++;
current_device = (SIO2Peripheral)cmd;
just_started = true;
}
command.size--;
switch (current_device)
{
case SIO2Peripheral::Controller:
{
if (just_started) gamepad.written = 0;
auto reply = gamepad.write_byte(cmd);
sio2_fifo.push(reply);
break;
}
case SIO2Peripheral::MemCard:
{
sio2_fifo.push(0xFF);
break;
}
}
}
uint8_t SIO2::read_fifo()
{
auto data = sio2_fifo.front();
sio2_fifo.pop();
return data;
}