3030// #define SIO1_CYCLES (m_baudReg * 8)
3131#define SIO1_CYCLES (1 )
3232
33- namespace PCSX {
33+ namespace PCSX {
3434class 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
0 commit comments