Skip to content

Commit f5bfbac

Browse files
committed
More organization, added sio reset, r/w calls
1 parent 3312b15 commit f5bfbac

7 files changed

Lines changed: 176 additions & 85 deletions

File tree

src/core/logger.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ enum class LogClass : unsigned {
3232
MIPS, // only the things coming from MIPS code
3333
UI, // messages from the UI specifically
3434
SIO0, // pad and memory card information
35-
SIO1, // uart information
35+
SIO1, // uart/sio1 information
36+
SIO1SERVER, // uart/sio1 server information
3637
GTE, // gte information
3738
CDROM, // low level cdrom information
3839
CDROM_IO, // high level cdrom information (iso file access)
@@ -68,7 +69,7 @@ struct Logger {
6869
// The rule of thumb is they typically can be spammy or costly,
6970
// and shouldn't be enabled on a retail build.
7071
typedef Logger<LogClass::SIO0, false> SIO0_LOGGER;
71-
typedef Logger<LogClass::SIO1, true> SIO1_LOGGER;
72+
typedef Logger<LogClass::SIO1, false> SIO1_LOGGER;
7273
typedef Logger<LogClass::GTE, false> GTE_LOGGER;
7374
typedef Logger<LogClass::CDROM, false> CDROM_LOGGER;
7475
typedef Logger<LogClass::CDROM_IO, false> CDROM_IO_LOGGER;

src/core/psxemulator.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ void PCSX::Emulator::EmuReset() {
103103
m_gpu->clearVRAM();
104104
m_pads->shutdown();
105105
m_pads->init();
106+
m_sio1->sio1Reset();
106107
}
107108

108109
void PCSX::Emulator::EmuShutdown() {

src/core/psxhw.cc

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,27 @@ uint8_t PCSX::HW::psxHwRead8(uint32_t add) {
5454
case 0x1f801040:
5555
hard = PCSX::g_emulator->m_sio->sioRead8();
5656
break;
57-
case 0x1f801050:
57+
case 0x1f801050: // rx/tx data register
5858
hard = PCSX::g_emulator->m_sio1->readData8();
5959
SIO1_LOG("SIO1.DATA read8 %x; ret = %x\n", add & 0xf, hard);
6060
break;
61-
case 0x1f801054:
61+
case 0x1f801054: // stat register
6262
hard = PCSX::g_emulator->m_sio1->readStat8();
63+
// Log command below is overly spammy
6364
//SIO1_LOG("SIO1.STAT read8 %x; ret = %x\n", add & 0xf, hard);
64-
return hard;
65+
break;
66+
case 0x1f801058: // mode register
67+
hard = PCSX::g_emulator->m_sio1->readMode8();
68+
SIO1_LOG("SIO1.MODE read8 %x; ret = %x\n", add & 0xf, hard);
69+
break;
70+
case 0x1f80105a: // control register
71+
hard = PCSX::g_emulator->m_sio1->readCtrl8();
72+
SIO1_LOG("SIO1.CTRL read8 %x; ret = %x\n", add & 0xf, hard);
73+
break;
74+
case 0x1f80105e: // baudrate register
75+
hard = PCSX::g_emulator->m_sio1->readBaud8();
76+
SIO1_LOG("SIO1.BAUD read8 %x; ret = %x\n", add & 0xf, hard);
77+
break;
6578
case 0x1f801800:
6679
hard = PCSX::g_emulator->m_cdrom->read0();
6780
break;
@@ -130,23 +143,24 @@ uint16_t PCSX::HW::psxHwRead16(uint32_t add) {
130143
hard = PCSX::g_emulator->m_sio->readBaud16();
131144
SIO0_LOG("sio read16 %x; ret = %x\n", add & 0xf, hard);
132145
return hard;
133-
case 0x1f801050:
146+
case 0x1f801050: // rx/tx data register
134147
hard = PCSX::g_emulator->m_sio1->readData16();
135148
SIO1_LOG("SIO1.DATA read16 %x; ret = %x\n", add & 0xf, hard);
136149
return hard;
137-
case 0x1f801054:
150+
case 0x1f801054: // stat register
138151
hard = PCSX::g_emulator->m_sio1->readStat16();
139-
SIO1_LOG("SIO1.STAT read16 %x; ret = %x\n", add & 0xf, hard);
152+
// Log command below is overly spammy
153+
//SIO1_LOG("SIO1.STAT read16 %x; ret = %x\n", add & 0xf, hard);
140154
return hard;
141-
case 0x1f801058:
155+
case 0x1f801058: // mode register
142156
hard = PCSX::g_emulator->m_sio1->readMode16();
143157
SIO1_LOG("SIO1.MODE read16 %x; ret = %x\n", add & 0xf, hard);
144158
return hard;
145-
case 0x1f80105a:
159+
case 0x1f80105a: // control register
146160
hard = PCSX::g_emulator->m_sio1->readCtrl16();
147161
SIO1_LOG("SIO1.CTRL read16 %x; ret = %x\n", add & 0xf, hard);
148162
return hard;
149-
case 0x1f80105e:
163+
case 0x1f80105e: // baudrate register
150164
hard = PCSX::g_emulator->m_sio1->readBaud16();
151165
SIO1_LOG("SIO1.BAUD read16 %x; ret = %x\n", add & 0xf, hard);
152166
return hard;
@@ -231,10 +245,15 @@ uint32_t PCSX::HW::psxHwRead32(uint32_t add) {
231245
hard |= PCSX::g_emulator->m_sio->sioRead8() << 24;
232246
SIO0_LOG("sio read32 ;ret = %x\n", hard);
233247
return hard;
234-
case 0x1f801050:
248+
case 0x1f801050: // rx/tx data register
235249
hard = PCSX::g_emulator->m_sio1->readData32();
236250
SIO1_LOG("SIO1.DATA read32 ;ret = %x\n", hard);
237251
return hard;
252+
case 0x1f801054: // stat register
253+
hard = PCSX::g_emulator->m_sio1->readStat32();
254+
// Log command below is overly spammy
255+
//SIO1_LOG("SIO1.STAT read32 ;ret = %x\n", hard);
256+
return hard;
238257
case 0x1f801060:
239258
PSXHW_LOG("RAM size read %x\n", psxHu32(0x1060));
240259
return psxHu32(0x1060);
@@ -350,6 +369,18 @@ void PCSX::HW::psxHwWrite8(uint32_t add, uint8_t value) {
350369
PCSX::g_emulator->m_sio1->writeStat8(value);
351370
SIO1_LOG("SIO1.STAT write8 %x; ret = %x\n", add & 0xf, value);
352371
break;
372+
case 0x1f801058: // mode register
373+
PCSX::g_emulator->m_sio1->writeMode8(value);
374+
SIO1_LOG("SIO1.MODE write8 %x; ret = %x\n", add & 0xf, value);
375+
break;
376+
case 0x1f80105a: // control register
377+
PCSX::g_emulator->m_sio1->writeCtrl8(value);
378+
SIO1_LOG("SIO1.CTRL write8 %x; ret = %x\n", add & 0xf, value);
379+
break;
380+
case 0x1f80105e: // baudrate register
381+
PCSX::g_emulator->m_sio1->writeBaud8(value);
382+
SIO1_LOG("SIO1.Baud write8 %x; ret = %x\n", add & 0xf, value);
383+
break;
353384
case 0x1f801800:
354385
PCSX::g_emulator->m_cdrom->write0(value);
355386
break;
@@ -539,6 +570,10 @@ void PCSX::HW::psxHwWrite32(uint32_t add, uint32_t value) {
539570
PCSX::g_emulator->m_sio1->writeData32(value);
540571
SIO1_LOG("SIO1.DATA write32 %x\n", value);
541572
return;
573+
case 0x1f801054:
574+
PCSX::g_emulator->m_sio1->writeStat32(value);
575+
SIO1_LOG("SIO1.STAT write32 %x\n", value);
576+
return;
542577
case 0x1f801060:
543578
PSXHW_LOG("RAM size write %x\n", value);
544579
psxHu32ref(add) = SWAP_LEu32(value);

src/core/sio1-server.cc

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ PCSX::SIO1Client::SIO1Client(uv_tcp_t* server) : m_listener(g_system->m_eventBus
2626
m_loop = server->loop;
2727
uv_tcp_init(m_loop, &m_tcp);
2828
m_tcp.data = this;
29-
memset(m_buffer, 0, BUFFER_SIZE);
3029
}
3130

3231
bool PCSX::SIO1Client::accept(uv_tcp_t* server) {
@@ -45,12 +44,22 @@ void PCSX::SIO1Client::alloc(size_t suggestedSize, uv_buf_t* buf) {
4544
buf->len = sizeof(m_buffer);
4645
}
4746

47+
void PCSX::SIO1Client::allocTrampoline(uv_handle_t* handle, size_t suggestedSize, uv_buf_t* buf) {
48+
SIO1Client* client = static_cast<SIO1Client*>(handle->data);
49+
client->alloc(suggestedSize, buf);
50+
}
51+
4852
void PCSX::SIO1Client::close() {
4953
if (m_status != SIO1ClientStatus::OPEN) return;
5054
m_status = SIO1ClientStatus::CLOSING;
5155
uv_close(reinterpret_cast<uv_handle_t*>(&m_tcp), closeCB);
5256
}
5357

58+
void PCSX::SIO1Client::closeCB(uv_handle_t* handle) {
59+
SIO1Client* client = static_cast<SIO1Client*>(handle->data);
60+
delete client;
61+
}
62+
5463
void PCSX::SIO1Client::processData(const Slice& slice) {
5564
PCSX::g_emulator->m_sio1->pushSlice(slice);
5665
PCSX::g_emulator->m_sio1->receiveCallback();
@@ -63,17 +72,43 @@ void PCSX::SIO1Client::read(ssize_t nread, const uv_buf_t* buf) {
6372
return;
6473
}
6574

75+
if (nread > BUFFER_SIZE) {
76+
g_system->log(LogClass::SIO1SERVER,
77+
"SIO1Server: Received more data[%i] than buffer[%i] can store, data truncated.\n", nread,
78+
BUFFER_SIZE);
79+
nread = BUFFER_SIZE;
80+
}
81+
6682
Slice slice;
67-
slice.borrow(m_buffer, static_cast <uint32_t>(nread));
83+
slice.borrow(m_buffer, static_cast<uint32_t>(nread));
6884
processData(slice);
6985
}
7086

87+
void PCSX::SIO1Client::readTrampoline(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
88+
SIO1Client* client = static_cast<SIO1Client*>(stream->data);
89+
client->read(nread, buf);
90+
}
91+
7192
void PCSX::SIO1Client::write(unsigned char c) {
7293
auto* req = new WriteRequest();
7394
req->m_slice.copy(static_cast<void*>(&c), 1);
7495
req->enqueue(this);
7596
}
7697

98+
void PCSX::SIO1Client::WriteRequest::enqueue(SIO1Client* client) {
99+
m_buf.base = static_cast<char*>(const_cast<void*>(m_slice.data()));
100+
m_buf.len = m_slice.size();
101+
client->m_requests.insert(reinterpret_cast<uintptr_t>(&m_req), this);
102+
uv_write(&m_req, reinterpret_cast<uv_stream_t*>(&client->m_tcp), &m_buf, 1, writeCB);
103+
}
104+
105+
void PCSX::SIO1Client::WriteRequest::writeCB(uv_write_t* request, int status) {
106+
SIO1Client* client = static_cast<SIO1Client*>(request->handle->data);
107+
auto self = client->m_requests.find(reinterpret_cast<uintptr_t>(request));
108+
delete &*self;
109+
if (status != 0) client->close();
110+
}
111+
77112
PCSX::SIO1Server::SIO1Server() : m_listener(g_system->m_eventBus) {
78113
m_listener.listen<Events::SettingsLoaded>([this](const auto& event) {
79114
if (g_emulator->settings.get<Emulator::SettingDebugSettings>().get<Emulator::DebugSettings::SIO1Server>() &&

src/core/sio1-server.h

Lines changed: 32 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -36,82 +36,60 @@ class SIO1Server;
3636

3737
class SIO1Client : public Intrusive::List<SIO1Client>::Node {
3838
public:
39-
SIO1Client(uv_tcp_t* server);
4039
typedef Intrusive::List<SIO1Client> ListType;
4140

41+
SIO1Client(uv_tcp_t* server);
42+
4243
bool accept(uv_tcp_t* server);
4344
void close();
4445

4546
private:
46-
uv_tcp_t m_tcp;
4747
enum class SIO1ClientStatus { CLOSED, OPEN, CLOSING };
48-
SIO1ClientStatus m_status = SIO1ClientStatus::CLOSED;
49-
50-
bool m_allocated = false;
5148

52-
EventBus::Listener m_listener;
53-
uv_loop_t* m_loop = 0;
54-
friend SIO1Server;
55-
static constexpr size_t BUFFER_SIZE = 4096;
49+
struct WriteRequest : public Intrusive::HashTable<uintptr_t, WriteRequest>::Node {
50+
uv_buf_t m_buf = {};
51+
Slice m_slice;
52+
uv_write_t m_req = {};
5653

57-
void alloc(size_t suggestedSize, uv_buf_t* buf);
54+
WriteRequest() {}
55+
WriteRequest(Slice&& slice) : m_slice(std::move(slice)) {}
56+
void enqueue(SIO1Client* client);
57+
static void writeCB(uv_write_t* request, int status);
58+
};
5859

59-
static void allocTrampoline(uv_handle_t* handle, size_t suggestedSize, uv_buf_t* buf) {
60-
SIO1Client* client = static_cast<SIO1Client*>(handle->data);
61-
client->alloc(suggestedSize, buf);
62-
}
60+
SIO1ClientStatus m_status = SIO1ClientStatus::CLOSED;
6361

64-
static void closeCB(uv_handle_t* handle) {
65-
SIO1Client* client = static_cast<SIO1Client*>(handle->data);
66-
delete client;
67-
}
62+
static constexpr size_t BUFFER_SIZE = 4096;
6863

64+
void alloc(size_t suggestedSize, uv_buf_t* buf);
65+
static void allocTrampoline(uv_handle_t* handle, size_t suggestedSize, uv_buf_t* buf);
66+
static void closeCB(uv_handle_t* handle);
6967
void processData(const Slice& slice);
70-
7168
void read(ssize_t nread, const uv_buf_t* buf);
72-
73-
static void readTrampoline(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
74-
SIO1Client* client = static_cast<SIO1Client*>(stream->data);
75-
client->read(nread, buf);
76-
}
77-
69+
static void readTrampoline(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);
7870
void write(unsigned char c);
7971

80-
struct WriteRequest : public Intrusive::HashTable<uintptr_t, WriteRequest>::Node {
81-
WriteRequest() {}
82-
WriteRequest(Slice&& slice) : m_slice(std::move(slice)) {}
83-
void enqueue(SIO1Client* client) {
84-
m_buf.base = static_cast<char*>(const_cast<void*>(m_slice.data()));
85-
m_buf.len = m_slice.size();
86-
client->m_requests.insert(reinterpret_cast<uintptr_t>(&m_req), this);
87-
uv_write(&m_req, reinterpret_cast<uv_stream_t*>(&client->m_tcp), &m_buf, 1, writeCB);
88-
}
89-
static void writeCB(uv_write_t* request, int status) {
90-
SIO1Client* client = static_cast<SIO1Client*>(request->handle->data);
91-
auto self = client->m_requests.find(reinterpret_cast<uintptr_t>(request));
92-
delete &*self;
93-
if (status != 0) client->close();
94-
}
95-
uv_buf_t m_buf;
96-
uv_write_t m_req;
97-
Slice m_slice;
98-
};
72+
bool m_allocated = false;
73+
char m_buffer[BUFFER_SIZE] = {};
74+
EventBus::Listener m_listener;
75+
uv_loop_t* m_loop = NULL;
9976
Intrusive::HashTable<uintptr_t, WriteRequest> m_requests;
77+
uv_tcp_t m_tcp;
10078

101-
char m_buffer[BUFFER_SIZE];
79+
friend SIO1Server;
10280
};
10381

10482
class SIO1Server {
10583
public:
106-
SIO1Server();
107-
//~SIO1Server() { }
10884
enum class SIO1ServerStatus {
10985
SERVER_STOPPED,
11086
SERVER_STOPPING,
11187
SERVER_STARTED,
11288
};
89+
11390
SIO1ServerStatus getServerStatus() { return m_serverStatus; }
11491

92+
SIO1Server();
11593
void startServer(uv_loop_t* loop, int port = 6699);
11694
void stopServer();
11795

@@ -120,16 +98,16 @@ class SIO1Server {
12098
}
12199

122100
private:
123-
static void onNewConnectionTrampoline(uv_stream_t* server, int status);
124-
void onNewConnection(int status);
125101
static void closeCB(uv_handle_t* handle);
126-
SIO1ServerStatus m_serverStatus = SIO1ServerStatus::SERVER_STOPPED;
127-
uv_tcp_t m_server;
128-
uv_loop_t* m_loop;
129-
SIO1Client::ListType m_clients;
130-
EventBus::Listener m_listener;
102+
void onNewConnection(int status);
103+
static void onNewConnectionTrampoline(uv_stream_t* server, int status);
131104

105+
SIO1Client::ListType m_clients;
132106
std::string m_gotError;
107+
EventBus::Listener m_listener;
108+
uv_loop_t* m_loop = NULL;
109+
uv_tcp_t m_server = {};
110+
SIO1ServerStatus m_serverStatus = SIO1ServerStatus::SERVER_STOPPED;
133111
};
134112

135113
} // namespace PCSX

src/core/sio1.cc

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,20 @@ uint8_t PCSX::SIO1::readData8() {
3939
}
4040

4141
uint8_t PCSX::SIO1::readStat8() {
42-
if (m_slices.m_sliceQueue.empty()) {
43-
m_statusReg &= ~SR_RXRDY;
44-
} else {
45-
m_statusReg |= SR_RXRDY;
46-
}
47-
psxHu32(0x1054) = m_statusReg;
48-
42+
updateStat();
4943
return m_statusReg & 0xFF;
5044
}
5145

46+
uint16_t PCSX::SIO1::readStat16() {
47+
updateStat();
48+
return m_statusReg & 0xFFFF;
49+
}
50+
51+
uint32_t PCSX::SIO1::readStat32() {
52+
updateStat();
53+
return m_statusReg;
54+
}
55+
5256
void PCSX::SIO1::receiveCallback() {
5357
if (m_ctrlReg & CR_RXIRQEN) {
5458
if (!(m_statusReg & SR_IRQ)) {
@@ -58,6 +62,15 @@ void PCSX::SIO1::receiveCallback() {
5862
}
5963
}
6064

65+
void PCSX::SIO1::updateStat() {
66+
if (m_slices.m_sliceQueue.empty()) {
67+
m_statusReg &= ~SR_RXRDY;
68+
} else {
69+
m_statusReg |= SR_RXRDY;
70+
}
71+
psxHu32(0x1054) = m_statusReg;
72+
}
73+
6174
void PCSX::SIO1::writeBaud16(uint16_t v) {
6275
m_baudReg = v;
6376
psxHu16(0x105E) = m_baudReg;

0 commit comments

Comments
 (0)