Skip to content

Commit df8d669

Browse files
committed
Tidy up SIO1
1 parent 03db02d commit df8d669

4 files changed

Lines changed: 203 additions & 137 deletions

File tree

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ void PCSX::SIO1Server::startServer(uv_loop_t* loop, int port) {
6767
m_serverStatus = SERVER_STARTED;
6868
}
6969

70-
7170
void PCSX::SIO1Server::closeCB(uv_handle_t* handle) {
7271
SIO1Server* self = static_cast<SIO1Server*>(handle->data);
7372
self->m_serverStatus = SERVER_STOPPED;
@@ -95,6 +94,6 @@ PCSX::SIO1Client::SIO1Client(uv_tcp_t* server) : m_listener(g_system->m_eventBus
9594
}
9695

9796
void PCSX::SIO1Client::processData(const Slice& slice) {
98-
PCSX::g_emulator->m_sio1->m_slices.pushSlice(slice);
97+
PCSX::g_emulator->m_sio1->pushSlice(slice);
9998
PCSX::g_emulator->m_sio1->receiveCallback();
10099
}

src/core/sio1.cc

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/***************************************************************************
2+
/***************************************************************************
3+
* Copyright (C) 2022 PCSX-Redux authors *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify *
6+
* it under the terms of the GNU General Public License as published by *
7+
* the Free Software Foundation; either version 2 of the License, or *
8+
* (at your option) any later version. *
9+
* *
10+
* This program is distributed in the hope that it will be useful, *
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13+
* GNU General Public License for more details. *
14+
* *
15+
* You should have received a copy of the GNU General Public License *
16+
* along with this program; if not, write to the *
17+
* Free Software Foundation, Inc., *
18+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
19+
***************************************************************************/
20+
21+
#include "core/sio1.h"
22+
23+
void PCSX::SIO1::interrupt() {
24+
SIO1_LOG("SIO1 Interrupt (CP0.Status = %x)\n", PCSX::g_emulator->m_psxCpu->m_psxRegs.CP0.n.Status);
25+
m_statusReg |= SR_IRQ;
26+
psxHu32ref(0x1070) |= SWAP_LEu32(0x100);
27+
}
28+
29+
uint8_t PCSX::SIO1::readData8() {
30+
uint8_t ret = 0;
31+
32+
if (m_statusReg & SR_RXRDY) {
33+
ret = m_slices.getByte();
34+
readStat8();
35+
psxHu8(0x1050) = ret;
36+
}
37+
38+
return ret;
39+
}
40+
41+
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+
49+
return m_statusReg & 0xFF;
50+
}
51+
52+
void PCSX::SIO1::receiveCallback() {
53+
if (m_ctrlReg & CR_RXIRQEN) {
54+
if (!(m_statusReg & SR_IRQ)) {
55+
scheduleInterrupt(SIO1_CYCLES);
56+
m_statusReg |= SR_IRQ;
57+
}
58+
}
59+
}
60+
61+
void PCSX::SIO1::writeBaud16(uint16_t v) {
62+
m_baudReg = v;
63+
psxHu16(0x105E) = m_baudReg;
64+
}
65+
66+
void PCSX::SIO1::writeCtrl16(uint16_t v) {
67+
m_ctrlReg = v;
68+
if (m_ctrlReg & CR_ACK) {
69+
m_ctrlReg &= ~CR_ACK;
70+
psxHu16(0x105A) = m_ctrlReg;
71+
72+
m_statusReg &= ~(SR_PARITYERR | SR_RXOVERRUN | SR_FRAMINGERR | SR_IRQ);
73+
psxHu32(0x1054) = m_statusReg;
74+
}
75+
76+
if (m_ctrlReg & CR_ACK) {
77+
m_ctrlReg &= ~CR_ACK;
78+
m_statusReg &= ~(SR_PARITYERR | SR_RXOVERRUN | SR_FRAMINGERR | SR_IRQ);
79+
}
80+
81+
if (m_ctrlReg & CR_RESET) {
82+
m_statusReg &= ~SR_IRQ;
83+
m_statusReg |= SR_TXRDY | SR_TXEMPTY;
84+
psxHu32(0x1054) = m_statusReg;
85+
86+
m_modeReg = 0;
87+
psxHu16(0x1058) = m_modeReg;
88+
89+
m_ctrlReg = 0;
90+
psxHu16(0x105A) = m_ctrlReg;
91+
92+
m_baudReg = 0;
93+
psxHu16(0x105E) = m_baudReg;
94+
95+
PCSX::g_emulator->m_psxCpu->m_psxRegs.interrupt &= ~(1 << PCSX::PSXINT_SIO1);
96+
}
97+
}
98+
99+
void PCSX::SIO1::writeData8(uint8_t v) {
100+
psxHu8(0x1050) = v;
101+
PCSX::g_emulator->m_sio1Server->write(v);
102+
103+
if (m_ctrlReg & CR_TXIRQEN) {
104+
if (!(m_statusReg & SR_IRQ)) {
105+
scheduleInterrupt(SIO1_CYCLES);
106+
m_statusReg |= SR_IRQ;
107+
}
108+
}
109+
110+
m_statusReg |= SR_TXRDY | SR_TXEMPTY;
111+
psxHu32(0x1054) = m_statusReg;
112+
}
113+
114+
void PCSX::SIO1::writeMode8(uint8_t v) {
115+
m_modeReg = v;
116+
psxHu16(0x1058) = v;
117+
}
118+
119+
void PCSX::SIO1::writeMode16(uint16_t v) {
120+
m_modeReg = v;
121+
psxHu16(0x1058) = v;
122+
}
123+
124+
void PCSX::SIO1::writeStat8(uint8_t v) {
125+
m_statusReg = v;
126+
psxHu32(0x1054) = m_statusReg;
127+
}
128+
129+
void PCSX::SIO1::writeStat16(uint16_t v) {
130+
m_statusReg = v;
131+
psxHu32(0x1054) = m_statusReg;
132+
}
133+
134+
void PCSX::SIO1::writeStat32(uint32_t v) {
135+
m_statusReg = v;
136+
psxHu32(0x1054) = m_statusReg;
137+
}

src/core/sio1.h

Lines changed: 63 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -30,146 +30,55 @@
3030
//#define SIO1_CYCLES (m_baudReg * 8)
3131
#define SIO1_CYCLES (1)
3232

33-
namespace PCSX {
33+
namespace PCSX {
3434
class SIO1 {
35+
/*
36+
* To-do:
37+
* STAT Baudrate timer + BAUD register
38+
*
39+
* FIFO buffer - not 100% how this will work, spx
40+
* unclear and the server receives large packets[2048+] at a time.
41+
*
42+
* Test and finish interrupts, only RX is tested
43+
*
44+
* Add/verify cases for all R/W functions exist in psxhw.cpp
45+
*/
46+
3547
public:
36-
unsigned char readData8() {
37-
uint8_t ret = 0;
38-
39-
if (m_statusReg & SR_RXRDY)
40-
{
41-
ret = m_slices.getByte();
42-
readStat8();
43-
psxHu8(0x1050) = ret;
44-
}
48+
void interrupt();
4549

46-
return ret;
47-
}
48-
unsigned char readStat8() {
49-
if (m_slices.m_sliceQueue.empty()) {
50-
m_statusReg &= ~SR_RXRDY;
51-
} else {
52-
m_statusReg |= SR_RXRDY;
53-
}
54-
psxHu32(0x1054) = m_statusReg;
55-
56-
return m_statusReg & 0xFF;
57-
}
58-
unsigned short readData16() {
59-
60-
return psxHu16(0x1050);
61-
}
62-
uint32_t readData32() {
63-
return psxHu32(0x1050);
64-
}
65-
66-
unsigned short readStat16() { return m_statusReg; }
67-
unsigned short readMode16() { return m_modeReg; }
68-
unsigned short readCtrl16() { return m_ctrlReg; }
69-
unsigned short readBaud16() { return m_baudReg; }
70-
71-
void writeData8(unsigned char v) {
72-
psxHu8(0x1050) = v;
73-
PCSX::g_emulator->m_sio1Server->write(v);
74-
75-
if (m_ctrlReg & CR_TXIRQEN) {
76-
if (!(m_statusReg & SR_IRQ)) {
77-
scheduleInterrupt(SIO1_CYCLES);
78-
m_statusReg |= SR_IRQ;
79-
}
80-
}
50+
uint8_t readBaud8() { return m_baudReg & 0xFF; }
51+
uint16_t readBaud16() { return m_baudReg; }
8152

82-
m_statusReg |= SR_TXRDY | SR_TXEMPTY;
83-
psxHu32(0x1054) = m_statusReg;
84-
}
53+
uint16_t readCtrl16() { return m_ctrlReg; }
8554

86-
void writeData16(unsigned short v) { psxHu16(0x1050) = v; }
87-
void writeData32(uint32_t v) { psxHu32(0x1050) = v; }
55+
uint8_t readData8();
56+
uint16_t readData16() { return psxHu16(0x1050); }
57+
uint32_t readData32() { return psxHu32(0x1050); }
8858

89-
void writeStat8(unsigned char v) { psxHu8(0x1054) = v; }
90-
91-
void writeStat16(uint16_t v) {
92-
m_statusReg = v;
93-
psxHu32(0x1054) = m_statusReg;
94-
}
95-
void writeMode16(uint16_t v) {
96-
m_modeReg = v;
97-
psxHu16(0x1058) = v;
98-
}
99-
void writeCtrl16(uint16_t v) {
100-
m_ctrlReg = v;
101-
if (m_ctrlReg & CR_ACK) {
102-
m_ctrlReg &= ~CR_ACK;
103-
psxHu16(0x105A) = m_ctrlReg;
104-
105-
m_statusReg &= ~(SR_PARITYERR | SR_RXOVERRUN | SR_FRAMINGERR | SR_IRQ);
106-
psxHu32(0x1054) = m_statusReg;
107-
}
59+
uint8_t readMode8() { return m_modeReg & 0xFF; }
60+
uint16_t readMode16() { return m_modeReg; }
10861

109-
if (m_ctrlReg & CR_ACK) {
110-
m_ctrlReg &= ~CR_ACK;
111-
m_statusReg &= ~(SR_PARITYERR | SR_RXOVERRUN | SR_FRAMINGERR | SR_IRQ);
112-
}
113-
114-
if (m_ctrlReg & CR_RESET) {
115-
m_statusReg &= ~SR_IRQ;
116-
m_statusReg |= SR_TXRDY | SR_TXEMPTY;
117-
psxHu32(0x1054) = m_statusReg;
62+
uint8_t readStat8();
63+
uint16_t readStat16() { return m_statusReg; }
11864

119-
m_modeReg = 0;
120-
psxHu16(0x1058) = m_modeReg;
65+
void writeBaud16(uint16_t v);
12166

122-
m_ctrlReg = 0;
123-
psxHu16(0x105A) = m_ctrlReg;
67+
void writeCtrl16(uint16_t v);
12468

125-
m_baudReg = 0;
126-
psxHu16(0x105E) = m_baudReg;
69+
void writeData8(uint8_t v);
70+
void writeData16(uint16_t v) { psxHu16(0x1050) = v; }
71+
void writeData32(uint32_t v) { psxHu32(0x1050) = v; }
12772

128-
PCSX::g_emulator->m_psxCpu->m_psxRegs.interrupt &= ~(1 << PCSX::PSXINT_SIO1);
129-
}
130-
}
131-
void writeBaud16(uint16_t v) {
132-
m_baudReg = v;
133-
psxHu16(0x105E) = m_baudReg;
134-
}
135-
136-
void interrupt() {
137-
SIO1_LOG("Sio1 Interrupt (CP0.Status = %x)\n", PCSX::g_emulator->m_psxCpu->m_psxRegs.CP0.n.Status);
138-
m_statusReg |= SR_IRQ;
139-
psxHu32ref(0x1070) |= SWAP_LEu32(0x100);
140-
}
141-
142-
void receiveCallback() {
143-
if (m_ctrlReg & CR_RXIRQEN) {
144-
if (!(m_statusReg & SR_IRQ)) {
145-
scheduleInterrupt(SIO1_CYCLES);
146-
m_statusReg |= SR_IRQ;
147-
}
148-
}
149-
}
73+
void writeMode8(uint8_t v);
74+
void writeMode16(uint16_t v);
15075

151-
struct Slices {
152-
void pushSlice(const Slice& slice) { m_sliceQueue.push(slice); }
153-
~Slices() {
154-
while (!m_sliceQueue.empty()) m_sliceQueue.pop();
155-
}
76+
void writeStat8(uint8_t v);
77+
void writeStat16(uint16_t v);
78+
void writeStat32(uint32_t v);
15679

157-
uint8_t getByte() {
158-
if (m_sliceQueue.empty()) return 0xff; // derp?
159-
Slice& slice = m_sliceQueue.front();
160-
uint8_t r = slice.getByte(m_cursor);
161-
if (++m_cursor >= slice.size()) {
162-
m_cursor = 0;
163-
m_sliceQueue.pop();
164-
}
165-
return r;
166-
}
167-
168-
std::queue<Slice> m_sliceQueue;
169-
uint32_t m_cursor = 0;
170-
};
171-
172-
Slices m_slices;
80+
void receiveCallback();
81+
void pushSlice(Slice slice) { m_slices.pushSlice(slice); }
17382

17483
private:
17584
enum {
@@ -194,23 +103,43 @@ class SIO1 {
194103
CR_TXOUTLVL = 0x0008,
195104
CR_ACK = 0x0010,
196105
CR_RTSOUTLVL = 0x0020,
197-
CR_RESET = 0x0040, // RESET INT?
106+
CR_RESET = 0x0040, // RESET INT?
198107
CR_UNKNOWN = 0x0080,
199-
CR_RXIRQMODE = 0x0100, // FIFO byte count, need to implement
108+
CR_RXIRQMODE = 0x0100, // FIFO byte count, need to implement
200109
CR_TXIRQEN = 0x0400,
201110
CR_RXIRQEN = 0x0800,
202111
CR_DSRIRQEN = 0x0400,
203112
};
204113

205-
//uint32_t m_dataReg = 0;
114+
struct Slices {
115+
void pushSlice(const Slice& slice) { m_sliceQueue.push(slice); }
116+
~Slices() {
117+
while (!m_sliceQueue.empty()) m_sliceQueue.pop();
118+
}
119+
120+
uint8_t getByte() {
121+
if (m_sliceQueue.empty()) return 0xff; // derp?
122+
Slice& slice = m_sliceQueue.front();
123+
uint8_t r = slice.getByte(m_cursor);
124+
if (++m_cursor >= slice.size()) {
125+
m_cursor = 0;
126+
m_sliceQueue.pop();
127+
}
128+
return r;
129+
}
130+
131+
std::queue<Slice> m_sliceQueue;
132+
uint32_t m_cursor = 0;
133+
};
134+
135+
// uint32_t m_dataReg = 0;
206136
uint32_t m_statusReg = SR_TXRDY | SR_TXEMPTY | SR_DSR | SR_CTS;
207137
uint16_t m_modeReg = 0;
208138
uint16_t m_ctrlReg = 0;
209-
//uint16_t m_miscReg = 0;
139+
// uint16_t m_miscReg = 0;
210140
uint16_t m_baudReg = 0;
141+
Slices m_slices;
211142

212-
inline void scheduleInterrupt(uint32_t eCycle) {
213-
g_emulator->m_psxCpu->scheduleInterrupt(PSXINT_SIO1, eCycle);
214-
}
143+
inline void scheduleInterrupt(uint32_t eCycle) { g_emulator->m_psxCpu->scheduleInterrupt(PSXINT_SIO1, eCycle); }
215144
};
216145
} // namespace PCSX

vsprojects/core/core.vcxproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,8 @@
216216
<ClCompile Include="..\..\src\core\psxmem.cc" />
217217
<ClCompile Include="..\..\src\core\r3000a.cc" />
218218
<ClCompile Include="..\..\src\core\sio.cc" />
219-
<ClCompile Include="..\..\src\core\sio1-server.cpp" />
219+
<ClCompile Include="..\..\src\core\sio1-server.cc" />
220+
<ClCompile Include="..\..\src\core\sio1.cc" />
220221
<ClCompile Include="..\..\src\core\spu.cc" />
221222
<ClCompile Include="..\..\src\core\sstate.cc" />
222223
<ClCompile Include="..\..\src\core\stacktrace.cc" />

0 commit comments

Comments
 (0)