@@ -101,26 +101,24 @@ constexpr void write_io(Device& periph, uint32_t addr, T data) {
101
101
#define TIMING (BITS, CYCLES ) timing<T, (BITS)>(CYCLES)
102
102
103
103
#define READ_IO (begin, end, periph, bits, cycles ) \
104
- if (addr >= (begin) && addr < (end)) { \
104
+ { \
105
105
TIMING (bits, cycles); \
106
106
auto data = read_io<T>((periph), addr - (begin)); \
107
107
\
108
108
LOG_IO (IO_LOG_ENTRY::MODE::READ, sizeof (T) * 8 , address, data, cpu->PC ); \
109
109
return data; \
110
110
}
111
111
112
- #define READ_IO32 (begin, end, periph, cycles ) \
113
- if (addr >= (begin) && addr < (end)) { \
114
- T data = 0 ; \
115
- if (sizeof (T) == 4 ) { \
116
- TIMING (32 , cycles); \
117
- data = (periph)->read (addr - (begin)); \
118
- } else { \
119
- fmt::print (" [SYS] R Unsupported access to " #periph " with bit size {}\n " , static_cast <int >(sizeof (T) * 8 )); \
120
- } \
121
- \
122
- LOG_IO (IO_LOG_ENTRY::MODE::READ, sizeof (T) * 8 , address, data, cpu->PC ); \
123
- return data; \
112
+ #define READ_IO32 (begin, end, periph, cycles ) \
113
+ { \
114
+ if constexpr (sizeof (T) == 4 ) { \
115
+ TIMING (32 , cycles); \
116
+ auto data = (periph)->read (addr - (begin)); \
117
+ LOG_IO (IO_LOG_ENTRY::MODE::READ, sizeof (T) * 8 , address, data, cpu->PC ); \
118
+ return data; \
119
+ } else { \
120
+ return 0 ; \
121
+ } \
124
122
}
125
123
126
124
#define WRITE_IO (begin, end, periph, bits, cycles ) \
@@ -132,60 +130,79 @@ constexpr void write_io(Device& periph, uint32_t addr, T data) {
132
130
return ; \
133
131
}
134
132
135
- #define WRITE_IO32 (begin, end, periph, cycles ) \
136
- if (addr >= (begin) && addr < (end)) { \
137
- if (sizeof (T) == 4 ) { \
138
- TIMING (32 , cycles); \
139
- (periph)->write (addr - (begin), data); \
140
- } else { \
141
- fmt::print (" [SYS] W Unsupported access to " #periph " with bit size {}\n " , static_cast <int >(sizeof (T) * 8 )); \
142
- } \
143
- \
144
- LOG_IO (IO_LOG_ENTRY::MODE::WRITE, sizeof (T) * 8 , address, data, cpu->PC ); \
145
- return ; \
133
+ #define WRITE_IO32 (begin, end, periph, cycles ) \
134
+ if (addr >= (begin) && addr < (end)) { \
135
+ if (sizeof (T) == 4 ) { \
136
+ TIMING (32 , cycles); \
137
+ (periph)->write (addr - (begin), data); \
138
+ } else { \
139
+ } \
140
+ \
141
+ LOG_IO (IO_LOG_ENTRY::MODE::WRITE, sizeof (T) * 8 , address, data, cpu->PC ); \
142
+ return ; \
146
143
}
147
144
145
+ #define BIOS_BASE (0x1fc00000 )
146
+ #define RAM_BASE (0x00000000 )
147
+ #define SCRATCHPAD_BASE (0x1f800000 )
148
+ #define EXPANSION_BASE (0x1f000000 )
149
+ #define IO_BASE (0x1f801000 )
150
+
151
+ #define BIOS_SIZE (512 * 1024 )
152
+ #define RAM_SIZE (2 * 1024 * 1024 )
153
+ #define SCRATCHPAD_SIZE (1024 )
154
+ #define EXPANSION_SIZE (1 * 1024 * 1024 )
155
+ #define IO_SIZE (0x2000 )
148
156
template <typename T>
149
157
INLINE T System::readMemory (uint32_t address) {
150
158
static_assert (std::is_same<T, uint8_t >() || std::is_same<T, uint16_t >() || std::is_same<T, uint32_t >(), " Invalid type used" );
151
159
152
- uint32_t addr = align_mips<T>(address);
153
- uint16_t part = (address & 0x0fe00000 ) >> 20 ;
154
- uint8_t segment = (address & 0xf0000000 ) >> 28 ;
155
-
156
- if (segment < 0xf ) {
160
+ uint8_t segment = (address & 0xf000'0000 ) >> 28 ;
161
+ if (segment < 0xc ) {
162
+ uint8_t part = (address & 0x0fc0'0000 ) >> 22 ;
163
+ uint32_t addr = align_mips<T>(address);
157
164
switch (part) {
158
- case 0 : TIMING (32 , 4 ); return read_fast<T>(ram.data (), (addr - RAM_BASE) & (RAM_SIZE - 1 ));
159
-
160
- case 0xf0 : TIMING (8 , 6 ); return read_fast<T>(expansion.data (), addr - EXPANSION_BASE);
161
-
162
- case 0xf8 : // scratch/ io / exp
165
+ case (0x00 >> 2 ): TIMING (32 , 4 ); return read_fast<T>(ram.data (), (addr - RAM_BASE) & (RAM_SIZE - 1 ));
166
+ case (0xf0 >> 2 ): TIMING (8 , 6 ); return read_fast<T>(expansion.data (), addr - EXPANSION_BASE);
167
+ case (0xf8 >> 2 ): { // scratch/ io / exp
163
168
if (in_range<SCRATCHPAD_BASE, SCRATCHPAD_SIZE>(addr)) {
164
169
TIMING (32 , 0 );
165
170
return read_fast<T>(scratchpad.data (), addr - SCRATCHPAD_BASE);
171
+ } else {
172
+ uint8_t dev = (addr & 0xff0 ) >> 4 ;
173
+ switch (dev) {
174
+ case 0x0 ... 0x3 : READ_IO (0x1f801000 , 0x1f801024 , memoryControl, 32 , 2 );
175
+ case 0x4 : READ_IO (0x1f801040 , 0x1f801050 , controller, 32 , 2 );
176
+ case 0x5 : READ_IO (0x1f801050 , 0x1f801060 , serial, 32 , 2 );
177
+ case 0x6 : READ_IO (0x1f801060 , 0x1f801064 , memoryControl, 32 , 2 );
178
+ case 0x7 : READ_IO (0x1f801070 , 0x1f801078 , interrupt, 32 , 2 );
179
+ case 0x8 ... 0xf : READ_IO (0x1f801080 , 0x1f801100 , dma, 32 , 2 );
180
+ case 0x10 : READ_IO (0x1f801100 , 0x1f801110 , timer[0 ], 32 , 2 );
181
+ case 0x11 : READ_IO (0x1f801110 , 0x1f801120 , timer[1 ], 32 , 2 );
182
+ case 0x12 : READ_IO (0x1f801120 , 0x1f801130 , timer[2 ], 32 , 2 );
183
+ case 0x80 : READ_IO (0x1f801800 , 0x1f801804 , cdrom, 8 , 8 );
184
+ case 0x81 : READ_IO32 (0x1f801810 , 0x1f801818 , gpu, 2 );
185
+ case 0x82 : READ_IO32 (0x1f801820 , 0x1f801828 , mdec, 3 );
186
+ case 0xc0 ... 0xff : READ_IO (0x1f801C00 , 0x1f802000 , spu, 16 , 16 );
187
+ default :
188
+ fmt::print (" [SYS] R Unhandled address at 0x{:08x}\n " , address);
189
+ cpu->busError ();
190
+ break ;
191
+ // case 0x13 - 0x7f - unmapped
192
+ // case 0x83 - 0xbf - unmapped
193
+ }
166
194
}
195
+ // READ_IO(0x1f802000, 0x1f802067, expansion2, 8, 10);
196
+ }
167
197
168
- READ_IO (0x1f801000 , 0x1f801024 , memoryControl, 32 , 2 );
169
- READ_IO (0x1f801040 , 0x1f801050 , controller, 32 , 2 );
170
- READ_IO (0x1f801050 , 0x1f801060 , serial, 32 , 2 );
171
- READ_IO (0x1f801060 , 0x1f801064 , memoryControl, 32 , 2 );
172
- READ_IO (0x1f801070 , 0x1f801078 , interrupt, 32 , 2 );
173
- READ_IO (0x1f801080 , 0x1f801100 , dma, 32 , 2 );
174
- READ_IO (0x1f801100 , 0x1f801110 , timer[0 ], 32 , 2 );
175
- READ_IO (0x1f801110 , 0x1f801120 , timer[1 ], 32 , 2 );
176
- READ_IO (0x1f801120 , 0x1f801130 , timer[2 ], 32 , 2 );
177
- READ_IO (0x1f801800 , 0x1f801804 , cdrom, 8 , 8 );
178
- READ_IO32 (0x1f801810 , 0x1f801818 , gpu, 2 );
179
- READ_IO32 (0x1f801820 , 0x1f801828 , mdec, 3 );
180
- READ_IO (0x1f801C00 , 0x1f802000 , spu, 16 , 16 );
181
- READ_IO (0x1f802000 , 0x1f802067 , expansion2, 8 , 10 );
198
+ case (0xfc >> 2 ): TIMING (8 , 6 ); return read_fast<T>(bios.data (), addr - BIOS_BASE);
199
+ default :
200
+ fmt::print (" [SYS] R Unhandled address at 0x{:08x}\n " , address);
201
+ cpu->busError ();
182
202
break ;
183
-
184
- case 0xfc : TIMING (8 , 6 ); return read_fast<T>(bios.data (), addr - BIOS_BASE);
185
203
}
186
-
187
204
} else {
188
- if (in_range< 0xfffe0130 , 4 >(address) && sizeof (T) == 4 ) {
205
+ if (sizeof (T) == 4 && address == 0xfffe0130 ) {
189
206
TIMING (32 , 1 );
190
207
auto data = cacheControl->read (0 );
191
208
LOG_IO (IO_LOG_ENTRY::MODE::READ, sizeof (T) * 8 , address, data, cpu->PC );
@@ -368,15 +385,13 @@ void System::emulateFrame() {
368
385
gpu->gpuLogList .clear ();
369
386
370
387
// gpu->prevVram = gpu->vram;
371
- int cpuCyclesConsumed = 0 ;
372
388
for (;;) {
373
- int systemCycles = 0x1000 ;
389
+ int systemCycles = 0x100 ;
374
390
cpuStalledCycles = 0 ;
375
391
if (!cpu->executeInstructions (systemCycles)) {
376
392
return ;
377
393
}
378
394
systemCycles += cpuStalledCycles;
379
- cpuCyclesConsumed += systemCycles;
380
395
381
396
dma->step ();
382
397
cdrom->step (systemCycles);
@@ -393,7 +408,6 @@ void System::emulateFrame() {
393
408
controller->step (systemCycles);
394
409
395
410
if (gpu->emulateGpuCycles (systemCycles)) {
396
- // fmt::print("cpuCyclesConsumed: {} (*60 == {})\n",cpuCyclesConsumed, cpuCyclesConsumed*60);
397
411
interrupt->trigger (interrupt::VBLANK);
398
412
return ; // frame emulated
399
413
}
0 commit comments