1 /* Copyright 2003-2005 Guillaume Duhamel
2 Copyright 2004-2005, 2013 Theo Berkau
3
4 This file is part of Yabause.
5
6 Yabause is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 Yabause is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Yabause; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /*! \file sh2core.c
22 \brief SH2 shared emulation functions.
23 */
24
25 #include <stdlib.h>
26 #include "sh2core.h"
27 #include "debug.h"
28 #include "memory.h"
29 #include "yabause.h"
30 #include "sh7034.h"
31 #include "cs0.h"
32 #include "cs1.h"
33 #include "cs2.h"
34 #include "scsp.h"
35 #include "vdp1.h"
36 #include "vdp2.h"
37 #include "ygr.h"
38 #include "assert.h"
39 #include "smpc.h"
40 #include "scu.h"
41
42 // SH1/SH2 differences
43 // SH1's mac.w operates at a smaller precision. 16x16+42 instead of 16x16+64
44 // SH1 is missing the following instructions: bf/s, braf, bsrf, bt/s, dmuls.l, dmulu.l, dt, mac.l, mul.l
45
46 #if defined(SH2_DYNAREC)
47 #include "sh2_dynarec/sh2_dynarec.h"
48 #endif
49
50 SH2_struct *SH1=NULL;
51 SH2_struct *MSH2=NULL;
52 SH2_struct *SSH2=NULL;
53 SH2Interface_struct *SH1Core=NULL;
54 SH2Interface_struct *SH2Core=NULL;
55 extern SH2Interface_struct *SH2CoreList[];
56
57 void OnchipReset(SH2_struct *context);
58 void FRTExec(SH2_struct *sh, u32 cycles);
59 void WDTExec(SH2_struct *sh, u32 cycles);
60 u8 SCIReceiveByte(void);
61 void SCITransmitByte(u8);
62
63 //////////////////////////////////////////////////////////////////////////////
64
SH1Init(int coreid)65 int SH1Init(int coreid)
66 {
67 int i;
68
69 if ((SH1 = (SH2_struct *)calloc(1, sizeof(SH2_struct))) == NULL)
70 return -1;
71
72 if (SH2TrackInfLoopInit(SH1) != 0)
73 return -1;
74
75 SH1->onchip.BCR1 = 0x0000;
76 SH1->isslave = 0;
77 SH1->model = SHMT_SH1;
78
79 SH1->MappedMemoryReadByte = Sh1MemoryReadByte;
80 SH1->MappedMemoryReadWord = Sh1MemoryReadWord;
81 SH1->MappedMemoryReadLong = Sh1MemoryReadLong;
82 SH1->MappedMemoryWriteByte = Sh1MemoryWriteByte;
83 SH1->MappedMemoryWriteWord = Sh1MemoryWriteWord;
84 SH1->MappedMemoryWriteLong = Sh1MemoryWriteLong;
85
86 // So which core do we want?
87 if (coreid == SH2CORE_DEFAULT)
88 coreid = 0; // Assume we want the first one
89
90 // Go through core list and find the id
91 for (i = 0; SH2CoreList[i] != NULL; i++)
92 {
93 if (SH2CoreList[i]->id == coreid)
94 {
95 // Set to current core
96 SH1Core = SH2CoreList[i];
97 break;
98 }
99 }
100
101 if ((SH1Core == NULL) || (SH1Core->Init(SHMT_SH1, SH1, NULL) != 0)) {
102 free(SH1);
103 SH1 = NULL;
104 return -1;
105 }
106
107 SH1->core = SH1Core;
108
109 sh1_init_func();
110
111 return 0;
112 }
113
114 //////////////////////////////////////////////////////////////////////////////
115
sh2_set_read_write_funcs(SH2_struct * sh)116 void sh2_set_read_write_funcs(SH2_struct * sh)
117 {
118 if (yabsys.sh2_cache_enabled)
119 {
120 sh->MappedMemoryReadByte = MappedMemoryReadByteCacheEnabled;
121 sh->MappedMemoryReadWord = MappedMemoryReadWordCacheEnabled;
122 sh->MappedMemoryReadLong = MappedMemoryReadLongCacheEnabled;
123 sh->MappedMemoryWriteByte = MappedMemoryWriteByteCacheEnabled;
124 sh->MappedMemoryWriteWord = MappedMemoryWriteWordCacheEnabled;
125 sh->MappedMemoryWriteLong = MappedMemoryWriteLongCacheEnabled;
126 }
127 else
128 {
129 sh->MappedMemoryReadByte = MappedMemoryReadByteNocache;
130 sh->MappedMemoryReadWord = MappedMemoryReadWordNocache;
131 sh->MappedMemoryReadLong = MappedMemoryReadLongNocache;
132 sh->MappedMemoryWriteByte = MappedMemoryWriteByteNocache;
133 sh->MappedMemoryWriteWord = MappedMemoryWriteWordNocache;
134 sh->MappedMemoryWriteLong = MappedMemoryWriteLongNocache;
135 }
136 }
137
SH2Init(int coreid)138 int SH2Init(int coreid)
139 {
140 int i;
141
142 // MSH2
143 if ((MSH2 = (SH2_struct *)calloc(1, sizeof(SH2_struct))) == NULL)
144 return -1;
145
146 if (SH2TrackInfLoopInit(MSH2) != 0)
147 return -1;
148
149 MSH2->onchip.BCR1 = 0x0000;
150 MSH2->isslave = 0;
151 MSH2->model = SHMT_SH2;
152
153 sh2_set_read_write_funcs(MSH2);
154
155 // SSH2
156 if ((SSH2 = (SH2_struct *)calloc(1, sizeof(SH2_struct))) == NULL)
157 return -1;
158
159 if (SH2TrackInfLoopInit(SSH2) != 0)
160 return -1;
161
162 SSH2->onchip.BCR1 = 0x8000;
163 SSH2->isslave = 1;
164 SSH2->model = SHMT_SH2;
165
166 sh2_set_read_write_funcs(SSH2);
167
168 // So which core do we want?
169 if (coreid == SH2CORE_DEFAULT)
170 coreid = 0; // Assume we want the first one
171
172 // Go through core list and find the id
173 for (i = 0; SH2CoreList[i] != NULL; i++)
174 {
175 if (SH2CoreList[i]->id == coreid)
176 {
177 // Set to current core
178 SH2Core = SH2CoreList[i];
179 break;
180 }
181 }
182
183 if ((SH2Core == NULL) || (SH2Core->Init(SHMT_SH2, MSH2, SSH2) != 0)) {
184 free(MSH2);
185 free(SSH2);
186 MSH2 = SSH2 = NULL;
187 return -1;
188 }
189
190 MSH2->core = SSH2->core = SH2Core;
191 return 0;
192 }
193
194 //////////////////////////////////////////////////////////////////////////////
195
SH1DeInit()196 void SH1DeInit()
197 {
198 if (SH1Core)
199 SH1Core->DeInit();
200 SH1Core = NULL;
201
202 if (SH1)
203 {
204 SH2TrackInfLoopDeInit(SH1);
205 free(SH1);
206 }
207 SH1 = NULL;
208 }
209
210 //////////////////////////////////////////////////////////////////////////////
211
SH2DeInit()212 void SH2DeInit()
213 {
214 if (SH2Core)
215 SH2Core->DeInit();
216 SH2Core = NULL;
217
218 if (MSH2)
219 {
220 SH2TrackInfLoopDeInit(MSH2);
221 free(MSH2);
222 }
223 MSH2 = NULL;
224
225 if (SSH2)
226 {
227 SH2TrackInfLoopDeInit(SSH2);
228 free(SSH2);
229 }
230 SSH2 = NULL;
231 }
232
233 //////////////////////////////////////////////////////////////////////////////
234
SH2Reset(SH2_struct * context)235 void SH2Reset(SH2_struct *context)
236 {
237 int i;
238 SH2Interface_struct *core=context->core;
239
240 // Reset general registers
241 for (i = 0; i < 15; i++)
242 core->SetGPR(context, i, 0x00000000);
243
244 core->SetSR(context, 0x000000F0);
245 core->SetGBR(context, 0x00000000);
246 core->SetVBR(context, 0x00000000);
247 core->SetMACH(context, 0x00000000);
248 core->SetMACL(context, 0x00000000);
249 core->SetPR(context, 0x00000000);
250
251 // Internal variables
252 context->delay = 0x00000000;
253 context->cycles = 0;
254 context->isIdle = 0;
255
256 context->frc.leftover = 0;
257 context->frc.shift = 3;
258
259 context->wdt.isenable = 0;
260 context->wdt.isinterval = 1;
261 context->wdt.shift = 1;
262 context->wdt.leftover = 0;
263
264 // Reset Interrupts
265 memset((void *)context->interrupts, 0, sizeof(interrupt_struct) * MAX_INTERRUPTS);
266 core->SetInterrupts(context, 0, context->interrupts);
267
268 // Core specific reset
269 core->Reset(context);
270
271 // Reset Onchip modules
272 OnchipReset(context);
273 cache_clear(&context->onchip.cache);
274
275 // Reset backtrace
276 context->bt.numbacktrace = 0;
277 }
278
279 //////////////////////////////////////////////////////////////////////////////
280
SH2PowerOn(SH2_struct * context)281 void SH2PowerOn(SH2_struct *context) {
282 SH2Interface_struct *core=context->core;
283 u32 VBR = core->GetVBR(context);
284 core->SetPC(context, context->MappedMemoryReadLong(context, VBR));
285 core->SetGPR(context, 15, context->MappedMemoryReadLong(context, VBR+4));
286 }
287
288 //////////////////////////////////////////////////////////////////////////////
289
SH2Exec(SH2_struct * context,u32 cycles)290 void FASTCALL SH2Exec(SH2_struct *context, u32 cycles)
291 {
292 context->core->Exec(context, cycles);
293
294 if(context->model == SHMT_SH1)
295 sh1_onchip_run_cycles(cycles);
296 else
297 FRTExec(context, cycles);
298
299 WDTExec(context, cycles);
300
301 if (context->model == SHMT_SH2 && yabsys.use_sh2_dma_timing)
302 sh2_dma_exec(context, cycles);
303
304 if (UNLIKELY(context->cycles < cycles))
305 context->cycles = 0;
306 else
307 context->cycles -= cycles;
308 }
309
310 //////////////////////////////////////////////////////////////////////////////
311
SH2SendInterrupt(SH2_struct * context,u8 vector,u8 level)312 void SH2SendInterrupt(SH2_struct *context, u8 vector, u8 level)
313 {
314 context->core->SendInterrupt(context, vector, level);
315 }
316
317 //////////////////////////////////////////////////////////////////////////////
318
SH2NMI(SH2_struct * context)319 void SH2NMI(SH2_struct *context)
320 {
321 context->onchip.ICR |= 0x8000;
322 SH2SendInterrupt(context, 0xB, 0x10);
323 }
324
325 //////////////////////////////////////////////////////////////////////////////
326
SH2Step(SH2_struct * context)327 void SH2Step(SH2_struct *context)
328 {
329 SH2Interface_struct *core=context->core;
330 if (core)
331 {
332 u32 tmp = core->GetPC(context);
333
334 // Execute 1 instruction
335 SH2Exec(context, context->cycles+1);
336
337 // Sometimes it doesn't always execute one instruction,
338 // let's make sure it did
339 if (tmp == core->GetPC(context))
340 SH2Exec(context, context->cycles+1);
341 }
342 }
343
344 //////////////////////////////////////////////////////////////////////////////
345
SH2StepOver(SH2_struct * context,void (* func)(void *,u32,void *))346 int SH2StepOver(SH2_struct *context, void (*func)(void *, u32, void *))
347 {
348 SH2Interface_struct *core=context->core;
349 if (core)
350 {
351 u32 tmp = core->GetPC(context);
352 u16 inst= context->MappedMemoryReadWord(context, context->regs.PC);
353
354 // If instruction is jsr, bsr, or bsrf, step over it
355 if ((inst & 0xF000) == 0xB000 || // BSR
356 (inst & 0xF0FF) == 0x0003 || // BSRF
357 (inst & 0xF0FF) == 0x400B) // JSR
358 {
359 // Set breakpoint after at PC + 4
360 context->stepOverOut.callBack = func;
361 context->stepOverOut.type = SH2ST_STEPOVER;
362 context->stepOverOut.enabled = 1;
363 context->stepOverOut.address = context->regs.PC+4;
364 return 1;
365 }
366 else
367 {
368 // Execute 1 instruction instead
369 SH2Exec(context, context->cycles+1);
370
371 // Sometimes it doesn't always execute one instruction,
372 // let's make sure it did
373 if (tmp == SH2Core->GetPC(context))
374 SH2Exec(context, context->cycles+1);
375 }
376 }
377 return 0;
378 }
379
380 //////////////////////////////////////////////////////////////////////////////
381
SH2StepOut(SH2_struct * context,void (* func)(void *,u32,void *))382 void SH2StepOut(SH2_struct *context, void (*func)(void *, u32, void *))
383 {
384 if (SH2Core)
385 {
386 context->stepOverOut.callBack = func;
387 context->stepOverOut.type = SH2ST_STEPOUT;
388 context->stepOverOut.enabled = 1;
389 context->stepOverOut.address = 0;
390 }
391 }
392
393 //////////////////////////////////////////////////////////////////////////////
394
SH2TrackInfLoopInit(SH2_struct * context)395 int SH2TrackInfLoopInit(SH2_struct *context)
396 {
397 context->trackInfLoop.maxNum = 100;
398 if ((context->trackInfLoop.match = calloc(context->trackInfLoop.maxNum, sizeof(tilInfo_struct))) == NULL)
399 return -1;
400
401 return 0;
402 }
403
404 //////////////////////////////////////////////////////////////////////////////
405
SH2TrackInfLoopDeInit(SH2_struct * context)406 void SH2TrackInfLoopDeInit(SH2_struct *context)
407 {
408 if (context->trackInfLoop.match)
409 free(context->trackInfLoop.match);
410 }
411
412 //////////////////////////////////////////////////////////////////////////////
413
SH2TrackInfLoopStart(SH2_struct * context)414 void SH2TrackInfLoopStart(SH2_struct *context)
415 {
416 context->trackInfLoop.enabled = 1;
417 }
418
419 //////////////////////////////////////////////////////////////////////////////
420
SH2TrackInfLoopStop(SH2_struct * context)421 void SH2TrackInfLoopStop(SH2_struct *context)
422 {
423 context->trackInfLoop.enabled = 0;
424 }
425
426 //////////////////////////////////////////////////////////////////////////////
427
SH2TrackInfLoopClear(SH2_struct * context)428 void SH2TrackInfLoopClear(SH2_struct *context)
429 {
430 memset(context->trackInfLoop.match, 0, sizeof(tilInfo_struct) * context->trackInfLoop.maxNum);
431 context->trackInfLoop.num = 0;
432 }
433
434 //////////////////////////////////////////////////////////////////////////////
435
SH2GetRegisters(SH2_struct * context,sh2regs_struct * r)436 void SH2GetRegisters(SH2_struct *context, sh2regs_struct * r)
437 {
438 if (r != NULL) {
439 SH2Core->GetRegisters(context, r);
440 }
441 }
442
443 //////////////////////////////////////////////////////////////////////////////
444
SH2SetRegisters(SH2_struct * context,sh2regs_struct * r)445 void SH2SetRegisters(SH2_struct *context, sh2regs_struct * r)
446 {
447 if (r != NULL) {
448 SH2Core->SetRegisters(context, r);
449 }
450 }
451
452 //////////////////////////////////////////////////////////////////////////////
453
SH2WriteNotify(u32 start,u32 length)454 void SH2WriteNotify(u32 start, u32 length) {
455 if (SH2Core->WriteNotify)
456 SH2Core->WriteNotify(start, length);
457 }
458
459 //////////////////////////////////////////////////////////////////////////////
460
SH2SetBreakpointCallBack(SH2_struct * context,void (* func)(void *,u32,void *),void * userdata)461 void SH2SetBreakpointCallBack(SH2_struct *context, void (*func)(void *, u32, void *), void *userdata) {
462 context->bp.BreakpointCallBack = func;
463 context->bp.BreakpointUserData = userdata;
464 }
465
466 //////////////////////////////////////////////////////////////////////////////
467
SH2AddCodeBreakpoint(SH2_struct * context,u32 addr)468 int SH2AddCodeBreakpoint(SH2_struct *context, u32 addr) {
469 int i;
470
471 if (context->bp.numcodebreakpoints < MAX_BREAKPOINTS) {
472 // Make sure it isn't already on the list
473 for (i = 0; i < context->bp.numcodebreakpoints; i++)
474 {
475 if (addr == context->bp.codebreakpoint[i].addr)
476 return -1;
477 }
478
479 context->bp.codebreakpoint[context->bp.numcodebreakpoints].addr = addr;
480 context->bp.numcodebreakpoints++;
481
482 return 0;
483 }
484
485 return -1;
486 }
487
488 //////////////////////////////////////////////////////////////////////////////
489
SH2SortCodeBreakpoints(SH2_struct * context)490 static void SH2SortCodeBreakpoints(SH2_struct *context) {
491 int i, i2;
492 u32 tmp;
493
494 for (i = 0; i < (MAX_BREAKPOINTS-1); i++)
495 {
496 for (i2 = i+1; i2 < MAX_BREAKPOINTS; i2++)
497 {
498 if (context->bp.codebreakpoint[i].addr == 0xFFFFFFFF &&
499 context->bp.codebreakpoint[i2].addr != 0xFFFFFFFF)
500 {
501 tmp = context->bp.codebreakpoint[i].addr;
502 context->bp.codebreakpoint[i].addr = context->bp.codebreakpoint[i2].addr;
503 context->bp.codebreakpoint[i2].addr = tmp;
504 }
505 }
506 }
507 }
508
509 //////////////////////////////////////////////////////////////////////////////
510
SH2DelCodeBreakpoint(SH2_struct * context,u32 addr)511 int SH2DelCodeBreakpoint(SH2_struct *context, u32 addr) {
512 int i, i2;
513
514 LOG("Deleting breakpoint %08X...\n", addr);
515
516 if (context->bp.numcodebreakpoints > 0) {
517 for (i = 0; i < context->bp.numcodebreakpoints; i++) {
518 if (context->bp.codebreakpoint[i].addr == addr)
519 {
520 context->bp.codebreakpoint[i].addr = 0xFFFFFFFF;
521 SH2SortCodeBreakpoints(context);
522 context->bp.numcodebreakpoints--;
523
524 LOG("Remaining breakpoints: \n");
525
526 for (i2 = 0; i2 < context->bp.numcodebreakpoints; i2++)
527 {
528 LOG("%08X", context->bp.codebreakpoint[i2].addr);
529 }
530
531 return 0;
532 }
533 }
534 }
535
536 LOG("Failed deleting breakpoint\n");
537
538 return -1;
539 }
540
541 //////////////////////////////////////////////////////////////////////////////
542
SH2GetBreakpointList(SH2_struct * context)543 codebreakpoint_struct *SH2GetBreakpointList(SH2_struct *context) {
544 return context->bp.codebreakpoint;
545 }
546
547 //////////////////////////////////////////////////////////////////////////////
548
SH2ClearCodeBreakpoints(SH2_struct * context)549 void SH2ClearCodeBreakpoints(SH2_struct *context) {
550 int i;
551 for (i = 0; i < MAX_BREAKPOINTS; i++) {
552 context->bp.codebreakpoint[i].addr = 0xFFFFFFFF;
553 }
554
555 context->bp.numcodebreakpoints = 0;
556 }
557
558 //////////////////////////////////////////////////////////////////////////////
559
SH2MemoryBreakpointReadByte(SH2_struct * sh,u32 addr)560 static u8 FASTCALL SH2MemoryBreakpointReadByte(SH2_struct *sh, u32 addr) {
561 int i;
562
563 for (i = 0; i < sh->bp.nummemorybreakpoints; i++)
564 {
565 if (sh->bp.memorybreakpoint[i].addr == (addr & 0x0FFFFFFF))
566 {
567 if (sh->bp.BreakpointCallBack && sh->bp.inbreakpoint == 0)
568 {
569 sh->bp.inbreakpoint = 1;
570 sh->bp.BreakpointCallBack(sh, 0, sh->bp.BreakpointUserData);
571 sh->bp.inbreakpoint = 0;
572 }
573
574 return sh->bp.memorybreakpoint[i].oldreadbyte(sh, addr);
575 }
576 }
577
578 // Use the closest match if address doesn't match
579 for (i = 0; i < sh->bp.nummemorybreakpoints; i++)
580 {
581 if (((sh->bp.memorybreakpoint[i].addr >> 16) & 0xFFF) == ((addr >> 16) & 0xFFF))
582 return sh->bp.memorybreakpoint[i].oldreadbyte(sh, addr);
583 }
584
585 return 0;
586 }
587
588 //////////////////////////////////////////////////////////////////////////////
589
SH2MemoryBreakpointReadWord(SH2_struct * sh,u32 addr)590 static u16 FASTCALL SH2MemoryBreakpointReadWord(SH2_struct *sh, u32 addr) {
591 int i;
592
593 for (i = 0; i < sh->bp.nummemorybreakpoints; i++)
594 {
595 if (sh->bp.memorybreakpoint[i].addr == (addr & 0x0FFFFFFF))
596 {
597 if (sh->bp.BreakpointCallBack && sh->bp.inbreakpoint == 0)
598 {
599 sh->bp.inbreakpoint = 1;
600 sh->bp.BreakpointCallBack(sh, 0, sh->bp.BreakpointUserData);
601 sh->bp.inbreakpoint = 0;
602 }
603
604 return sh->bp.memorybreakpoint[i].oldreadword(sh, addr);
605 }
606 }
607
608 // Use the closest match if address doesn't match
609 for (i = 0; i < sh->bp.nummemorybreakpoints; i++)
610 {
611 if (((sh->bp.memorybreakpoint[i].addr >> 16) & 0xFFF) == ((addr >> 16) & 0xFFF))
612 return sh->bp.memorybreakpoint[i].oldreadword(sh, addr);
613 }
614 return 0;
615 }
616
617 //////////////////////////////////////////////////////////////////////////////
618
SH2MemoryBreakpointReadLong(SH2_struct * sh,u32 addr)619 static u32 FASTCALL SH2MemoryBreakpointReadLong(SH2_struct *sh, u32 addr) {
620 int i;
621
622 for (i = 0; i < sh->bp.nummemorybreakpoints; i++)
623 {
624 if (sh->bp.memorybreakpoint[i].addr == (addr & 0x0FFFFFFF))
625 {
626 if (sh->bp.BreakpointCallBack && sh->bp.inbreakpoint == 0)
627 {
628 sh->bp.inbreakpoint = 1;
629 sh->bp.BreakpointCallBack(sh, 0, sh->bp.BreakpointUserData);
630 sh->bp.inbreakpoint = 0;
631 }
632
633 return sh->bp.memorybreakpoint[i].oldreadlong(sh, addr);
634 }
635 }
636
637 // Use the closest match if address doesn't match
638 for (i = 0; i < sh->bp.nummemorybreakpoints; i++)
639 {
640 if (((sh->bp.memorybreakpoint[i].addr >> 16) & 0xFFF) == ((addr >> 16) & 0xFFF))
641 return sh->bp.memorybreakpoint[i].oldreadlong(sh, addr);
642 }
643 return 0;
644 }
645
646 //////////////////////////////////////////////////////////////////////////////
647
SH2MemoryBreakpointWriteByte(SH2_struct * sh,u32 addr,u8 val)648 static void FASTCALL SH2MemoryBreakpointWriteByte(SH2_struct *sh, u32 addr, u8 val) {
649 int i;
650
651 for (i = 0; i < sh->bp.nummemorybreakpoints; i++)
652 {
653 if (sh->bp.memorybreakpoint[i].addr == (addr & 0x0FFFFFFF))
654 {
655 if (sh->bp.BreakpointCallBack && sh->bp.inbreakpoint == 0)
656 {
657 sh->bp.inbreakpoint = 1;
658 sh->bp.BreakpointCallBack(sh, 0, sh->bp.BreakpointUserData);
659 sh->bp.inbreakpoint = 0;
660 }
661
662 sh->bp.memorybreakpoint[i].oldwritebyte(sh, addr, val);
663 return;
664 }
665 }
666
667 // Use the closest match if address doesn't match
668 for (i = 0; i < sh->bp.nummemorybreakpoints; i++)
669 {
670 if (((sh->bp.memorybreakpoint[i].addr >> 16) & 0xFFF) == ((addr >> 16) & 0xFFF))
671 {
672 sh->bp.memorybreakpoint[i].oldwritebyte(sh, addr, val);
673 return;
674 }
675 }
676 }
677
678 //////////////////////////////////////////////////////////////////////////////
679
SH2MemoryBreakpointWriteWord(SH2_struct * sh,u32 addr,u16 val)680 static void FASTCALL SH2MemoryBreakpointWriteWord(SH2_struct *sh, u32 addr, u16 val) {
681 int i;
682
683 for (i = 0; i < sh->bp.nummemorybreakpoints; i++)
684 {
685 if (sh->bp.memorybreakpoint[i].addr == (addr & 0x0FFFFFFF))
686 {
687 if (sh->bp.BreakpointCallBack && sh->bp.inbreakpoint == 0)
688 {
689 sh->bp.inbreakpoint = 1;
690 sh->bp.BreakpointCallBack(sh, 0, sh->bp.BreakpointUserData);
691 sh->bp.inbreakpoint = 0;
692 }
693
694 sh->bp.memorybreakpoint[i].oldwriteword(sh, addr, val);
695 return;
696 }
697 }
698
699 // Use the closest match if address doesn't match
700 for (i = 0; i < sh->bp.nummemorybreakpoints; i++)
701 {
702 if (((sh->bp.memorybreakpoint[i].addr >> 16) & 0xFFF) == ((addr >> 16) & 0xFFF))
703 {
704 sh->bp.memorybreakpoint[i].oldwriteword(sh, addr, val);
705 return;
706 }
707 }
708 }
709
710 //////////////////////////////////////////////////////////////////////////////
711
SH2MemoryBreakpointWriteLong(SH2_struct * sh,u32 addr,u32 val)712 static void FASTCALL SH2MemoryBreakpointWriteLong(SH2_struct *sh, u32 addr, u32 val) {
713 int i;
714
715 for (i = 0; i < sh->bp.nummemorybreakpoints; i++)
716 {
717 if (sh->bp.memorybreakpoint[i].addr == (addr & 0x0FFFFFFF))
718 {
719 if (sh->bp.BreakpointCallBack && sh->bp.inbreakpoint == 0)
720 {
721 sh->bp.inbreakpoint = 1;
722 sh->bp.BreakpointCallBack(sh, 0, sh->bp.BreakpointUserData);
723 sh->bp.inbreakpoint = 0;
724 }
725
726 sh->bp.memorybreakpoint[i].oldwritelong(sh, addr, val);
727 return;
728 }
729 }
730
731 // Use the closest match if address doesn't match
732 for (i = 0; i < sh->bp.nummemorybreakpoints; i++)
733 {
734 if (((sh->bp.memorybreakpoint[i].addr >> 16) & 0xFFF) == ((addr >> 16) & 0xFFF))
735 {
736 sh->bp.memorybreakpoint[i].oldwritelong(sh, addr, val);
737 return;
738 }
739 }
740 }
741
742 //////////////////////////////////////////////////////////////////////////////
743
CheckForMemoryBreakpointDupes(SH2_struct * context,u32 addr,u32 flag,int * which)744 static int CheckForMemoryBreakpointDupes(SH2_struct *context, u32 addr, u32 flag, int *which)
745 {
746 int i;
747
748 for (i = 0; i < context->bp.nummemorybreakpoints; i++)
749 {
750 if (((context->bp.memorybreakpoint[i].addr >> 16) & 0xFFF) ==
751 ((addr >> 16) & 0xFFF))
752 {
753 // See it actually was using the same operation flag
754 if (context->bp.memorybreakpoint[i].flags & flag)
755 {
756 *which = i;
757 return 1;
758 }
759 }
760 }
761
762 return 0;
763 }
764
765 //////////////////////////////////////////////////////////////////////////////
766
SH2AddMemoryBreakpoint(SH2_struct * context,u32 addr,u32 flags)767 int SH2AddMemoryBreakpoint(SH2_struct *context, u32 addr, u32 flags) {
768 int which;
769 int i;
770
771 if (flags == 0)
772 return -1;
773
774 if (context->bp.nummemorybreakpoints < MAX_BREAKPOINTS) {
775 // Only regular addresses are supported at this point(Sorry, no onchip!)
776 switch (addr >> 29) {
777 case 0x0:
778 case 0x1:
779 case 0x5:
780 break;
781 default:
782 return -1;
783 }
784
785 addr &= 0x0FFFFFFF;
786
787 // Make sure it isn't already on the list
788 for (i = 0; i < context->bp.nummemorybreakpoints; i++)
789 {
790 if (addr == context->bp.memorybreakpoint[i].addr)
791 return -1;
792 }
793
794 context->bp.memorybreakpoint[context->bp.nummemorybreakpoints].addr = addr;
795 context->bp.memorybreakpoint[context->bp.nummemorybreakpoints].flags = flags;
796
797 context->bp.memorybreakpoint[context->bp.nummemorybreakpoints].oldreadbyte = context->ReadByteList[(addr >> 16) & 0xFFF];
798 context->bp.memorybreakpoint[context->bp.nummemorybreakpoints].oldreadword = context->ReadWordList[(addr >> 16) & 0xFFF];
799 context->bp.memorybreakpoint[context->bp.nummemorybreakpoints].oldreadlong = context->ReadLongList[(addr >> 16) & 0xFFF];
800 context->bp.memorybreakpoint[context->bp.nummemorybreakpoints].oldwritebyte = context->WriteByteList[(addr >> 16) & 0xFFF];
801 context->bp.memorybreakpoint[context->bp.nummemorybreakpoints].oldwriteword = context->WriteWordList[(addr >> 16) & 0xFFF];
802 context->bp.memorybreakpoint[context->bp.nummemorybreakpoints].oldwritelong = context->WriteLongList[(addr >> 16) & 0xFFF];
803
804 if (flags & BREAK_BYTEREAD)
805 {
806 // Make sure function isn't already being breakpointed by another breakpoint
807 if (!CheckForMemoryBreakpointDupes(context, addr, BREAK_BYTEREAD, &which))
808 context->ReadByteList[(addr >> 16) & 0xFFF] = &SH2MemoryBreakpointReadByte;
809 else
810 // fix old memory access function
811 context->bp.memorybreakpoint[context->bp.nummemorybreakpoints].oldreadbyte = context->bp.memorybreakpoint[which].oldreadbyte;
812 }
813
814 if (flags & BREAK_WORDREAD)
815 {
816 // Make sure function isn't already being breakpointed by another breakpoint
817 if (!CheckForMemoryBreakpointDupes(context, addr, BREAK_WORDREAD, &which))
818 context->ReadWordList[(addr >> 16) & 0xFFF] = &SH2MemoryBreakpointReadWord;
819 else
820 // fix old memory access function
821 context->bp.memorybreakpoint[context->bp.nummemorybreakpoints].oldreadword = context->bp.memorybreakpoint[which].oldreadword;
822 }
823
824 if (flags & BREAK_LONGREAD)
825 {
826 // Make sure function isn't already being breakpointed by another breakpoint
827 if (!CheckForMemoryBreakpointDupes(context, addr, BREAK_LONGREAD, &which))
828 context->ReadLongList[(addr >> 16) & 0xFFF] = &SH2MemoryBreakpointReadLong;
829 else
830 // fix old memory access function
831 context->bp.memorybreakpoint[context->bp.nummemorybreakpoints].oldreadword = context->bp.memorybreakpoint[which].oldreadword;
832 }
833
834 if (flags & BREAK_BYTEWRITE)
835 {
836 // Make sure function isn't already being breakpointed by another breakpoint
837 if (!CheckForMemoryBreakpointDupes(context, addr, BREAK_BYTEWRITE, &which))
838 context->WriteByteList[(addr >> 16) & 0xFFF] = &SH2MemoryBreakpointWriteByte;
839 else
840 // fix old memory access function
841 context->bp.memorybreakpoint[context->bp.nummemorybreakpoints].oldwritebyte = context->bp.memorybreakpoint[which].oldwritebyte;
842 }
843
844 if (flags & BREAK_WORDWRITE)
845 {
846 // Make sure function isn't already being breakpointed by another breakpoint
847 if (!CheckForMemoryBreakpointDupes(context, addr, BREAK_WORDWRITE, &which))
848 context->WriteWordList[(addr >> 16) & 0xFFF] = &SH2MemoryBreakpointWriteWord;
849 else
850 // fix old memory access function
851 context->bp.memorybreakpoint[context->bp.nummemorybreakpoints].oldwriteword = context->bp.memorybreakpoint[which].oldwriteword;
852 }
853
854 if (flags & BREAK_LONGWRITE)
855 {
856 // Make sure function isn't already being breakpointed by another breakpoint
857 if (!CheckForMemoryBreakpointDupes(context, addr, BREAK_LONGWRITE, &which))
858 context->WriteLongList[(addr >> 16) & 0xFFF] = &SH2MemoryBreakpointWriteLong;
859 else
860 // fix old memory access function
861 context->bp.memorybreakpoint[context->bp.nummemorybreakpoints].oldwritelong = context->bp.memorybreakpoint[which].oldwritelong;
862 }
863
864 context->bp.nummemorybreakpoints++;
865
866 return 0;
867 }
868
869 return -1;
870 }
871
872 //////////////////////////////////////////////////////////////////////////////
873
SH2SortMemoryBreakpoints(SH2_struct * context)874 static void SH2SortMemoryBreakpoints(SH2_struct *context) {
875 int i, i2;
876 memorybreakpoint_struct tmp;
877
878 for (i = 0; i < (MAX_BREAKPOINTS-1); i++)
879 {
880 for (i2 = i+1; i2 < MAX_BREAKPOINTS; i2++)
881 {
882 if (context->bp.memorybreakpoint[i].addr == 0xFFFFFFFF &&
883 context->bp.memorybreakpoint[i2].addr != 0xFFFFFFFF)
884 {
885 memcpy(&tmp, context->bp.memorybreakpoint+i, sizeof(memorybreakpoint_struct));
886 memcpy(context->bp.memorybreakpoint+i, context->bp.memorybreakpoint+i2, sizeof(memorybreakpoint_struct));
887 memcpy(context->bp.memorybreakpoint+i2, &tmp, sizeof(memorybreakpoint_struct));
888 }
889 }
890 }
891 }
892
893 //////////////////////////////////////////////////////////////////////////////
894
SH2DelMemoryBreakpoint(SH2_struct * context,u32 addr)895 int SH2DelMemoryBreakpoint(SH2_struct *context, u32 addr) {
896 int i, i2;
897
898 if (context->bp.nummemorybreakpoints > 0) {
899 for (i = 0; i < context->bp.nummemorybreakpoints; i++) {
900 if (context->bp.memorybreakpoint[i].addr == addr)
901 {
902 // Remove memory access piggyback function to memory access function table
903
904 // Make sure no other breakpoints need the breakpoint functions first
905 for (i2 = 0; i2 < context->bp.nummemorybreakpoints; i2++)
906 {
907 if (((context->bp.memorybreakpoint[i].addr >> 16) & 0xFFF) ==
908 ((context->bp.memorybreakpoint[i2].addr >> 16) & 0xFFF) &&
909 i != i2)
910 {
911 // Clear the flags
912 context->bp.memorybreakpoint[i].flags &= ~context->bp.memorybreakpoint[i2].flags;
913 }
914 }
915
916 if (context->bp.memorybreakpoint[i].flags & BREAK_BYTEREAD)
917 context->ReadByteList[(addr >> 16) & 0xFFF] = context->bp.memorybreakpoint[i].oldreadbyte;
918
919 if (context->bp.memorybreakpoint[i].flags & BREAK_WORDREAD)
920 context->ReadWordList[(addr >> 16) & 0xFFF] = context->bp.memorybreakpoint[i].oldreadword;
921
922 if (context->bp.memorybreakpoint[i].flags & BREAK_LONGREAD)
923 context->ReadLongList[(addr >> 16) & 0xFFF] = context->bp.memorybreakpoint[i].oldreadlong;
924
925 if (context->bp.memorybreakpoint[i].flags & BREAK_BYTEWRITE)
926 context->WriteByteList[(addr >> 16) & 0xFFF] = context->bp.memorybreakpoint[i].oldwritebyte;
927
928 if (context->bp.memorybreakpoint[i].flags & BREAK_WORDWRITE)
929 context->WriteWordList[(addr >> 16) & 0xFFF] = context->bp.memorybreakpoint[i].oldwriteword;
930
931 if (context->bp.memorybreakpoint[i].flags & BREAK_LONGWRITE)
932 context->WriteLongList[(addr >> 16) & 0xFFF] = context->bp.memorybreakpoint[i].oldwritelong;
933
934 context->bp.memorybreakpoint[i].addr = 0xFFFFFFFF;
935 SH2SortMemoryBreakpoints(context);
936 context->bp.nummemorybreakpoints--;
937 return 0;
938 }
939 }
940 }
941
942 return -1;
943 }
944
945 //////////////////////////////////////////////////////////////////////////////
946
SH2GetMemoryBreakpointList(SH2_struct * context)947 memorybreakpoint_struct *SH2GetMemoryBreakpointList(SH2_struct *context) {
948 return context->bp.memorybreakpoint;
949 }
950
951 //////////////////////////////////////////////////////////////////////////////
952
SH2ClearMemoryBreakpoints(SH2_struct * context)953 void SH2ClearMemoryBreakpoints(SH2_struct *context) {
954 int i;
955 for (i = 0; i < MAX_BREAKPOINTS; i++)
956 {
957 context->bp.memorybreakpoint[i].addr = 0xFFFFFFFF;
958 context->bp.memorybreakpoint[i].flags = 0;
959 context->bp.memorybreakpoint[i].oldreadbyte = NULL;
960 context->bp.memorybreakpoint[i].oldreadword = NULL;
961 context->bp.memorybreakpoint[i].oldreadlong = NULL;
962 context->bp.memorybreakpoint[i].oldwritebyte = NULL;
963 context->bp.memorybreakpoint[i].oldwriteword = NULL;
964 context->bp.memorybreakpoint[i].oldwritelong = NULL;
965 }
966 context->bp.nummemorybreakpoints = 0;
967 }
968
969 //////////////////////////////////////////////////////////////////////////////
970
SH2HandleBackTrace(SH2_struct * context)971 void SH2HandleBackTrace(SH2_struct *context)
972 {
973 u16 inst = context->instruction;
974 if ((inst & 0xF000) == 0xB000 || // BSR
975 (inst & 0xF0FF) == 0x0003 || // BSRF
976 (inst & 0xF0FF) == 0x400B) // JSR
977 {
978 if (context->bt.numbacktrace < sizeof(context->bt.addr)/sizeof(u32))
979 {
980 context->bt.addr[context->bt.numbacktrace] = context->regs.PC;
981 context->bt.numbacktrace++;
982 }
983 }
984 else if (inst == 0x000B) // RTS
985 {
986 if (context->bt.numbacktrace > 0)
987 context->bt.numbacktrace--;
988 }
989 }
990
991 //////////////////////////////////////////////////////////////////////////////
992
SH2GetBacktraceList(SH2_struct * context,int * size)993 u32 *SH2GetBacktraceList(SH2_struct *context, int *size)
994 {
995 *size = context->bt.numbacktrace;
996 return context->bt.addr;
997 }
998
999 //////////////////////////////////////////////////////////////////////////////
1000
SH2HandleStepOverOut(SH2_struct * context)1001 void SH2HandleStepOverOut(SH2_struct *context)
1002 {
1003 if (context->stepOverOut.enabled)
1004 {
1005 switch ((int)context->stepOverOut.type)
1006 {
1007 case SH2ST_STEPOVER: // Step Over
1008 if (context->regs.PC == context->stepOverOut.address)
1009 {
1010 context->stepOverOut.enabled = 0;
1011 context->stepOverOut.callBack(context, context->regs.PC, (void *)context->stepOverOut.type);
1012 }
1013 break;
1014 case SH2ST_STEPOUT: // Step Out
1015 {
1016 u16 inst;
1017
1018 if (context->stepOverOut.levels < 0 && context->regs.PC == context->regs.PR)
1019 {
1020 context->stepOverOut.enabled = 0;
1021 context->stepOverOut.callBack(context, context->regs.PC, (void *)context->stepOverOut.type);
1022 return;
1023 }
1024
1025 inst = context->instruction;;
1026
1027 if ((inst & 0xF000) == 0xB000 || // BSR
1028 (inst & 0xF0FF) == 0x0003 || // BSRF
1029 (inst & 0xF0FF) == 0x400B) // JSR
1030 context->stepOverOut.levels++;
1031 else if (inst == 0x000B || // RTS
1032 inst == 0x002B) // RTE
1033 context->stepOverOut.levels--;
1034
1035 break;
1036 }
1037 default: break;
1038 }
1039 }
1040 }
1041
1042 //////////////////////////////////////////////////////////////////////////////
1043
SH2HandleTrackInfLoop(SH2_struct * context)1044 void SH2HandleTrackInfLoop(SH2_struct *context)
1045 {
1046 if (context->trackInfLoop.enabled)
1047 {
1048 // Look for specific bf/bt/bra instructions that branch to address < PC
1049 if ((context->instruction & 0x8B80) == 0x8B80 || // bf
1050 (context->instruction & 0x8F80) == 0x8F80 || // bf/s
1051 (context->instruction & 0x8980) == 0x8980 || // bt
1052 (context->instruction & 0x8D80) == 0x8D80 || // bt/s
1053 (context->instruction & 0xA800) == 0xA800) // bra
1054 {
1055 int i;
1056
1057 // See if it's already on match list
1058 for (i = 0; i < context->trackInfLoop.num; i++)
1059 {
1060 if (context->regs.PC == context->trackInfLoop.match[i].addr)
1061 {
1062 context->trackInfLoop.match[i].count++;
1063 return;
1064 }
1065 }
1066
1067 if (context->trackInfLoop.num >= context->trackInfLoop.maxNum)
1068 {
1069 context->trackInfLoop.match = realloc(context->trackInfLoop.match, sizeof(tilInfo_struct) * (context->trackInfLoop.maxNum * 2));
1070 context->trackInfLoop.maxNum *= 2;
1071 }
1072
1073 // Add new
1074 i=context->trackInfLoop.num;
1075 context->trackInfLoop.match[i].addr = context->regs.PC;
1076 context->trackInfLoop.match[i].count = 1;
1077 context->trackInfLoop.num++;
1078 }
1079 }
1080 }
1081
1082 //////////////////////////////////////////////////////////////////////////////
1083 // Onchip specific
1084 //////////////////////////////////////////////////////////////////////////////
1085
OnchipReset(SH2_struct * context)1086 void OnchipReset(SH2_struct *context) {
1087 context->onchip.SMR = 0x00;
1088 context->onchip.BRR = 0xFF;
1089 context->onchip.SCR = 0x00;
1090 context->onchip.TDR = 0xFF;
1091 context->onchip.SSR = 0x84;
1092 context->onchip.RDR = 0x00;
1093 context->onchip.TIER = 0x01;
1094 context->onchip.FTCSR = 0x00;
1095 context->onchip.FRC.all = 0x0000;
1096 context->onchip.OCRA = 0xFFFF;
1097 context->onchip.OCRB = 0xFFFF;
1098 context->onchip.TCR = 0x00;
1099 context->onchip.TOCR = 0xE0;
1100 context->onchip.FICR = 0x0000;
1101 context->onchip.IPRB = 0x0000;
1102 context->onchip.VCRA = 0x0000;
1103 context->onchip.VCRB = 0x0000;
1104 context->onchip.VCRC = 0x0000;
1105 context->onchip.VCRD = 0x0000;
1106 context->onchip.DRCR0 = 0x00;
1107 context->onchip.DRCR1 = 0x00;
1108 context->onchip.WTCSR = 0x18;
1109 context->onchip.WTCNT = 0x00;
1110 context->onchip.RSTCSR = 0x1F;
1111 context->onchip.SBYCR = 0x60;
1112 context->onchip.CCR = 0x00;
1113 context->onchip.ICR = 0x0000;
1114 context->onchip.IPRA = 0x0000;
1115 context->onchip.VCRWDT = 0x0000;
1116 context->onchip.DVCR = 0x00000000;
1117 context->onchip.VCRDIV = 0x00000000;
1118 context->onchip.BARA.all = 0x00000000;
1119 context->onchip.BAMRA.all = 0x00000000;
1120 context->onchip.BBRA = 0x0000;
1121 context->onchip.BARB.all = 0x00000000;
1122 context->onchip.BAMRB.all = 0x00000000;
1123 context->onchip.BDRB.all = 0x00000000;
1124 context->onchip.BDMRB.all = 0x00000000;
1125 context->onchip.BBRB = 0x0000;
1126 context->onchip.BRCR = 0x0000;
1127 context->onchip.CHCR0 = 0x00000000;
1128 context->onchip.CHCR1 = 0x00000000;
1129 context->onchip.DMAOR = 0x00000000;
1130 context->onchip.BCR1 &= 0x8000; // preserve MASTER bit
1131 context->onchip.BCR1 |= 0x03F0;
1132 context->onchip.BCR2 = 0x00FC;
1133 context->onchip.WCR = 0xAAFF;
1134 context->onchip.MCR = 0x0000;
1135 context->onchip.RTCSR = 0x0000;
1136 context->onchip.RTCNT = 0x0000;
1137 context->onchip.RTCOR = 0x0000;
1138 }
1139
1140 //////////////////////////////////////////////////////////////////////////////
1141
OnchipReadByte(SH2_struct * sh,u32 addr)1142 u8 FASTCALL OnchipReadByte(SH2_struct *sh, u32 addr) {
1143 switch(addr)
1144 {
1145 case 0x000:
1146 // LOG("Serial Mode Register read: %02X\n", sh->onchip.SMR);
1147 return sh->onchip.SMR;
1148 case 0x001:
1149 // LOG("Bit Rate Register read: %02X\n", sh->onchip.BRR);
1150 return sh->onchip.BRR;
1151 case 0x002:
1152 // LOG("Serial Control Register read: %02X\n", sh->onchip.SCR);
1153 return sh->onchip.SCR;
1154 case 0x003:
1155 // LOG("Transmit Data Register read: %02X\n", sh->onchip.TDR);
1156 return sh->onchip.TDR;
1157 case 0x004:
1158 // LOG("Serial Status Register read: %02X\n", sh->onchip.SSR);
1159
1160 /*
1161 // if Receiver is enabled, clear SSR's TDRE bit, set SSR's RDRF and update RDR.
1162
1163 if (sh->onchip.SCR & 0x10)
1164 {
1165 sh->onchip.RDR = SCIReceiveByte();
1166 sh->onchip.SSR = (sh->onchip.SSR & 0x7F) | 0x40;
1167 }
1168 // if Transmitter is enabled, clear SSR's RDRF bit, and set SSR's TDRE bit.
1169 else if (sh->onchip.SCR & 0x20)
1170 {
1171 sh->onchip.SSR = (sh->onchip.SSR & 0xBF) | 0x80;
1172 }
1173 */
1174 return sh->onchip.SSR;
1175 case 0x005:
1176 // LOG("Receive Data Register read: %02X PC = %08X\n", sh->onchip.RDR, SH2Core->GetPC(sh));
1177 return sh->onchip.RDR;
1178 case 0x010:
1179 return sh->onchip.TIER;
1180 case 0x011:
1181 return sh->onchip.FTCSR;
1182 case 0x012:
1183 return sh->onchip.FRC.part.H;
1184 case 0x013:
1185 return sh->onchip.FRC.part.L;
1186 case 0x014:
1187 if (!(sh->onchip.TOCR & 0x10))
1188 return sh->onchip.OCRA >> 8;
1189 else
1190 return sh->onchip.OCRB >> 8;
1191 case 0x015:
1192 if (!(sh->onchip.TOCR & 0x10))
1193 return sh->onchip.OCRA & 0xFF;
1194 else
1195 return sh->onchip.OCRB & 0xFF;
1196 case 0x016:
1197 return sh->onchip.TCR;
1198 case 0x017:
1199 return sh->onchip.TOCR;
1200 case 0x018:
1201 return sh->onchip.FICR >> 8;
1202 case 0x019:
1203 return sh->onchip.FICR & 0xFF;
1204 case 0x060:
1205 return sh->onchip.IPRB >> 8;
1206 case 0x062:
1207 return sh->onchip.VCRA >> 8;
1208 case 0x063:
1209 return sh->onchip.VCRA & 0xFF;
1210 case 0x064:
1211 return sh->onchip.VCRB >> 8;
1212 case 0x065:
1213 return sh->onchip.VCRB & 0xFF;
1214 case 0x066:
1215 return sh->onchip.VCRC >> 8;
1216 case 0x067:
1217 return sh->onchip.VCRC & 0xFF;
1218 case 0x068:
1219 return sh->onchip.VCRD >> 8;
1220 case 0x080:
1221 return sh->onchip.WTCSR;
1222 case 0x081:
1223 return sh->onchip.WTCNT;
1224 case 0x092:
1225 return sh->onchip.CCR;
1226 case 0x0E0:
1227 return sh->onchip.ICR >> 8;
1228 case 0x0E1:
1229 return sh->onchip.ICR & 0xFF;
1230 case 0x0E2:
1231 return sh->onchip.IPRA >> 8;
1232 case 0x0E3:
1233 return sh->onchip.IPRA & 0xFF;
1234 case 0x0E4:
1235 return sh->onchip.VCRWDT >> 8;
1236 case 0x0E5:
1237 return sh->onchip.VCRWDT & 0xFF;
1238 default:
1239 LOG("Unhandled Onchip byte read %08X\n", (int)addr);
1240 break;
1241 }
1242
1243 return 0;
1244 }
1245
1246 //////////////////////////////////////////////////////////////////////////////
1247
OnchipReadWord(SH2_struct * sh,u32 addr)1248 u16 FASTCALL OnchipReadWord(SH2_struct *sh, u32 addr) {
1249 switch(addr)
1250 {
1251 case 0x060:
1252 return sh->onchip.IPRB;
1253 case 0x062:
1254 return sh->onchip.VCRA;
1255 case 0x064:
1256 return sh->onchip.VCRB;
1257 case 0x066:
1258 return sh->onchip.VCRC;
1259 case 0x068:
1260 return sh->onchip.VCRD;
1261 case 0x0E0:
1262 return sh->onchip.ICR;
1263 case 0x0E2:
1264 return sh->onchip.IPRA;
1265 case 0x0E4:
1266 return sh->onchip.VCRWDT;
1267 case 0x1E2: // real BCR1 register is located at 0x1E2-0x1E3; Sega Rally OK
1268 return sh->onchip.BCR1;
1269 case 0x1E6:
1270 return sh->onchip.BCR2;
1271 case 0x1EA:
1272 return sh->onchip.WCR;
1273 case 0x1EE:
1274 return sh->onchip.MCR;
1275 case 0x1F2:
1276 return sh->onchip.RTCSR;
1277 case 0x1F6:
1278 return sh->onchip.RTCNT;
1279 case 0x1FA:
1280 return sh->onchip.RTCOR;
1281 default:
1282 LOG("Unhandled Onchip word read %08X\n", (int)addr);
1283 return 0;
1284 }
1285
1286 return 0;
1287 }
1288
1289 //////////////////////////////////////////////////////////////////////////////
1290
OnchipReadLong(SH2_struct * sh,u32 addr)1291 u32 FASTCALL OnchipReadLong(SH2_struct *sh, u32 addr) {
1292 switch(addr)
1293 {
1294 case 0x100:
1295 case 0x120:
1296 return sh->onchip.DVSR;
1297 case 0x104: // DVDNT
1298 case 0x124:
1299 return sh->onchip.DVDNTL;
1300 case 0x108:
1301 case 0x128:
1302 return sh->onchip.DVCR;
1303 case 0x10C:
1304 case 0x12C:
1305 return sh->onchip.VCRDIV;
1306 case 0x110:
1307 case 0x130:
1308 return sh->onchip.DVDNTH;
1309 case 0x114:
1310 case 0x134:
1311 return sh->onchip.DVDNTL;
1312 case 0x118: // Acts as a separate register, but is set to the same value
1313 case 0x138: // as DVDNTH after division
1314 return sh->onchip.DVDNTUH;
1315 case 0x11C: // Acts as a separate register, but is set to the same value
1316 case 0x13C: // as DVDNTL after division
1317 return sh->onchip.DVDNTUL;
1318 case 0x180:
1319 return sh->onchip.SAR0;
1320 case 0x184:
1321 return sh->onchip.DAR0;
1322 case 0x188:
1323 return sh->onchip.TCR0;
1324 case 0x18C:
1325 return sh->onchip.CHCR0;
1326 case 0x190:
1327 return sh->onchip.SAR1;
1328 case 0x194:
1329 return sh->onchip.DAR1;
1330 case 0x198:
1331 return sh->onchip.TCR1;
1332 case 0x19C:
1333 return sh->onchip.CHCR1;
1334 case 0x1A0:
1335 return sh->onchip.VCRDMA0;
1336 case 0x1A8:
1337 return sh->onchip.VCRDMA1;
1338 case 0x1B0:
1339 return sh->onchip.DMAOR;
1340 case 0x1E0:
1341 return sh->onchip.BCR1;
1342 case 0x1E4:
1343 return sh->onchip.BCR2;
1344 case 0x1E8:
1345 return sh->onchip.WCR;
1346 case 0x1EC:
1347 return sh->onchip.MCR;
1348 case 0x1F0:
1349 return sh->onchip.RTCSR;
1350 case 0x1F4:
1351 return sh->onchip.RTCNT;
1352 case 0x1F8:
1353 return sh->onchip.RTCOR;
1354 default:
1355 LOG("Unhandled Onchip long read %08X\n", (int)addr);
1356 return 0;
1357 }
1358
1359 return 0;
1360 }
1361
1362 //////////////////////////////////////////////////////////////////////////////
1363
OnchipWriteByte(SH2_struct * sh,u32 addr,u8 val)1364 void FASTCALL OnchipWriteByte(SH2_struct *sh, u32 addr, u8 val) {
1365 switch(addr) {
1366 case 0x000:
1367 // LOG("Serial Mode Register write: %02X\n", val);
1368 sh->onchip.SMR = val;
1369 return;
1370 case 0x001:
1371 // LOG("Bit Rate Register write: %02X\n", val);
1372 sh->onchip.BRR = val;
1373 return;
1374 case 0x002:
1375 // LOG("Serial Control Register write: %02X\n", val);
1376
1377 // If Transmitter is getting disabled, set TDRE
1378 if (!(val & 0x20))
1379 sh->onchip.SSR |= 0x80;
1380
1381 sh->onchip.SCR = val;
1382 return;
1383 case 0x003:
1384 // LOG("Transmit Data Register write: %02X. PC = %08X\n", val, SH2Core->GetPC(sh));
1385 sh->onchip.TDR = val;
1386 return;
1387 case 0x004:
1388 // LOG("Serial Status Register write: %02X\n", val);
1389
1390 if (sh->onchip.SCR & 0x20)
1391 {
1392 // Transmitter Mode
1393
1394 // If the TDRE bit cleared, let's do a transfer
1395 if (!(val & 0x80))
1396 SCITransmitByte(sh->onchip.TDR);
1397
1398 // Generate an interrupt if need be here
1399 }
1400 return;
1401 case 0x010:
1402 sh->onchip.TIER = (val & 0x8E) | 0x1;
1403 return;
1404 case 0x011:
1405 sh->onchip.FTCSR = (sh->onchip.FTCSR & (val & 0xFE)) | (val & 0x1);
1406 return;
1407 case 0x012:
1408 sh->onchip.FRC.part.H = val;
1409 return;
1410 case 0x013:
1411 sh->onchip.FRC.part.L = val;
1412 return;
1413 case 0x014:
1414 if (!(sh->onchip.TOCR & 0x10))
1415 sh->onchip.OCRA = (val << 8) | (sh->onchip.OCRA & 0xFF);
1416 else
1417 sh->onchip.OCRB = (val << 8) | (sh->onchip.OCRB & 0xFF);
1418 return;
1419 case 0x015:
1420 if (!(sh->onchip.TOCR & 0x10))
1421 sh->onchip.OCRA = (sh->onchip.OCRA & 0xFF00) | val;
1422 else
1423 sh->onchip.OCRB = (sh->onchip.OCRB & 0xFF00) | val;
1424 return;
1425 case 0x016:
1426 sh->onchip.TCR = val & 0x83;
1427
1428 switch (val & 3)
1429 {
1430 case 0:
1431 sh->frc.shift = 3;
1432 break;
1433 case 1:
1434 sh->frc.shift = 5;
1435 break;
1436 case 2:
1437 sh->frc.shift = 7;
1438 break;
1439 case 3:
1440 LOG("FRT external input clock not implemented.\n");
1441 break;
1442 }
1443 return;
1444 case 0x017:
1445 sh->onchip.TOCR = 0xE0 | (val & 0x13);
1446 return;
1447 case 0x060:
1448 sh->onchip.IPRB = (val << 8);
1449 return;
1450 case 0x061:
1451 return;
1452 case 0x062:
1453 sh->onchip.VCRA = ((val & 0x7F) << 8) | (sh->onchip.VCRA & 0x00FF);
1454 return;
1455 case 0x063:
1456 sh->onchip.VCRA = (sh->onchip.VCRA & 0xFF00) | (val & 0x7F);
1457 return;
1458 case 0x064:
1459 sh->onchip.VCRB = ((val & 0x7F) << 8) | (sh->onchip.VCRB & 0x00FF);
1460 return;
1461 case 0x065:
1462 sh->onchip.VCRB = (sh->onchip.VCRB & 0xFF00) | (val & 0x7F);
1463 return;
1464 case 0x066:
1465 sh->onchip.VCRC = ((val & 0x7F) << 8) | (sh->onchip.VCRC & 0x00FF);
1466 return;
1467 case 0x067:
1468 sh->onchip.VCRC = (sh->onchip.VCRC & 0xFF00) | (val & 0x7F);
1469 return;
1470 case 0x068:
1471 sh->onchip.VCRD = (val & 0x7F) << 8;
1472 return;
1473 case 0x069:
1474 return;
1475 case 0x071:
1476 sh->onchip.DRCR0 = val & 0x3;
1477 return;
1478 case 0x072:
1479 sh->onchip.DRCR1 = val & 0x3;
1480 return;
1481 case 0x091:
1482 sh->onchip.SBYCR = val & 0xDF;
1483 return;
1484 case 0x092:
1485 sh->onchip.CCR = val & 0xCF;
1486 if (val & 0x10){
1487 cache_clear(&sh->onchip.cache);
1488 }
1489 if ( (sh->onchip.CCR & 0x01) ){
1490 cache_enable(&sh->onchip.cache);
1491 }
1492 else{
1493 cache_disable(&sh->onchip.cache);
1494 }
1495 return;
1496 case 0x0E0:
1497 sh->onchip.ICR = ((val & 0x1) << 8) | (sh->onchip.ICR & 0xFEFF);
1498 return;
1499 case 0x0E1:
1500 sh->onchip.ICR = (sh->onchip.ICR & 0xFFFE) | (val & 0x1);
1501 return;
1502 case 0x0E2:
1503 sh->onchip.IPRA = (val << 8) | (sh->onchip.IPRA & 0x00FF);
1504 return;
1505 case 0x0E3:
1506 sh->onchip.IPRA = (sh->onchip.IPRA & 0xFF00) | (val & 0xF0);
1507 return;
1508 case 0x0E4:
1509 sh->onchip.VCRWDT = ((val & 0x7F) << 8) | (sh->onchip.VCRWDT & 0x00FF);
1510 return;
1511 case 0x0E5:
1512 sh->onchip.VCRWDT = (sh->onchip.VCRWDT & 0xFF00) | (val & 0x7F);
1513 return;
1514 default:
1515 LOG("Unhandled Onchip byte write %08X\n", (int)addr);
1516 }
1517 }
1518
1519 //////////////////////////////////////////////////////////////////////////////
1520
OnchipWriteWord(SH2_struct * sh,u32 addr,u16 val)1521 void FASTCALL OnchipWriteWord(SH2_struct *sh, u32 addr, u16 val) {
1522 switch(addr)
1523 {
1524 case 0x060:
1525 sh->onchip.IPRB = val & 0xFF00;
1526 return;
1527 case 0x062:
1528 sh->onchip.VCRA = val & 0x7F7F;
1529 return;
1530 case 0x064:
1531 sh->onchip.VCRB = val & 0x7F7F;
1532 return;
1533 case 0x066:
1534 sh->onchip.VCRC = val & 0x7F7F;
1535 return;
1536 case 0x068:
1537 sh->onchip.VCRD = val & 0x7F7F;
1538 return;
1539 case 0x080:
1540 // This and RSTCSR have got to be the most wackiest register
1541 // mappings I've ever seen
1542
1543 if (val >> 8 == 0xA5)
1544 {
1545 // WTCSR
1546 switch (val & 7)
1547 {
1548 case 0:
1549 sh->wdt.shift = 1;
1550 break;
1551 case 1:
1552 sh->wdt.shift = 6;
1553 break;
1554 case 2:
1555 sh->wdt.shift = 7;
1556 break;
1557 case 3:
1558 sh->wdt.shift = 8;
1559 break;
1560 case 4:
1561 sh->wdt.shift = 9;
1562 break;
1563 case 5:
1564 sh->wdt.shift = 10;
1565 break;
1566 case 6:
1567 sh->wdt.shift = 12;
1568 break;
1569 case 7:
1570 sh->wdt.shift = 13;
1571 break;
1572 }
1573
1574 sh->wdt.isenable = (val & 0x20);
1575 sh->wdt.isinterval = (~val & 0x40);
1576
1577 sh->onchip.WTCSR = (u8)val | 0x18;
1578 }
1579 else if (val >> 8 == 0x5A)
1580 {
1581 // WTCNT
1582 sh->onchip.WTCNT = (u8)val;
1583 }
1584 return;
1585 case 0x082:
1586 if (val == 0xA500)
1587 // clear WOVF bit
1588 sh->onchip.RSTCSR &= 0x7F;
1589 else if (val >> 8 == 0x5A)
1590 // RSTE and RSTS bits
1591 sh->onchip.RSTCSR = (sh->onchip.RSTCSR & 0x80) | (val & 0x60) | 0x1F;
1592 return;
1593 case 0x092:
1594 sh->onchip.CCR = val & 0xCF;
1595 if (val&0x10){
1596 cache_clear( &sh->onchip.cache );
1597 }
1598 if ((sh->onchip.CCR & 0x01)){
1599 cache_enable(&sh->onchip.cache);
1600 }
1601 else{
1602 cache_disable(&sh->onchip.cache);
1603 }
1604 return;
1605 case 0x0E0:
1606 sh->onchip.ICR = val & 0x0101;
1607 return;
1608 case 0x0E2:
1609 sh->onchip.IPRA = val & 0xFFF0;
1610 return;
1611 case 0x0E4:
1612 sh->onchip.VCRWDT = val & 0x7F7F;
1613 return;
1614 case 0x108:
1615 case 0x128:
1616 sh->onchip.DVCR = val & 0x3;
1617 return;
1618 case 0x148:
1619 sh->onchip.BBRA = val & 0xFF;
1620 return;
1621 case 0x178:
1622 sh->onchip.BRCR = val & 0xF4DC;
1623 return;
1624 default:
1625 LOG("Unhandled Onchip word write %08X(%04X)\n", (int)addr, val);
1626 return;
1627 }
1628 }
1629
1630 //////////////////////////////////////////////////////////////////////////////
1631
OnchipWriteLong(SH2_struct * sh,u32 addr,u32 val)1632 void FASTCALL OnchipWriteLong(SH2_struct *sh, u32 addr, u32 val) {
1633 switch (addr)
1634 {
1635 case 0x100:
1636 case 0x120:
1637 sh->onchip.DVSR = val;
1638 return;
1639 case 0x104: // 32-bit / 32-bit divide operation
1640 case 0x124:
1641 {
1642 s32 divisor = (s32) sh->onchip.DVSR;
1643 if (divisor == 0)
1644 {
1645 // Regardless of what DVDNTL is set to, the top 3 bits
1646 // are used to create the new DVDNTH value
1647 if (val & 0x80000000)
1648 {
1649 sh->onchip.DVDNTL = 0x80000000;
1650 sh->onchip.DVDNTH = 0xFFFFFFFC | ((val >> 29) & 0x3);
1651 }
1652 else
1653 {
1654 sh->onchip.DVDNTL = 0x7FFFFFFF;
1655 sh->onchip.DVDNTH = 0 | (val >> 29);
1656 }
1657 sh->onchip.DVDNTUL = sh->onchip.DVDNTL;
1658 sh->onchip.DVDNTUH = sh->onchip.DVDNTH;
1659 sh->onchip.DVCR |= 1;
1660
1661 if (sh->onchip.DVCR & 0x2)
1662 SH2SendInterrupt(sh, sh->onchip.VCRDIV & 0x7F, (MSH2->onchip.IPRA >> 12) & 0xF);
1663 }
1664 else
1665 {
1666 s32 quotient = ((s32) val) / divisor;
1667 s32 remainder = ((s32) val) % divisor;
1668 sh->onchip.DVDNTL = quotient;
1669 sh->onchip.DVDNTUL = quotient;
1670 sh->onchip.DVDNTH = remainder;
1671 sh->onchip.DVDNTUH = remainder;
1672 }
1673 return;
1674 }
1675 case 0x108:
1676 case 0x128:
1677 sh->onchip.DVCR = val & 0x3;
1678 return;
1679 case 0x10C:
1680 case 0x12C:
1681 sh->onchip.VCRDIV = val & 0xFFFF;
1682 return;
1683 case 0x110:
1684 case 0x130:
1685 sh->onchip.DVDNTH = val;
1686 return;
1687 case 0x114:
1688 case 0x134: { // 64-bit / 32-bit divide operation
1689 s32 divisor = (s32) sh->onchip.DVSR;
1690 s64 dividend = sh->onchip.DVDNTH;
1691 dividend <<= 32;
1692 dividend |= val;
1693
1694 if (divisor == 0)
1695 {
1696 if (sh->onchip.DVDNTH & 0x80000000)
1697 {
1698 sh->onchip.DVDNTL = 0x80000000;
1699 sh->onchip.DVDNTH = sh->onchip.DVDNTH << 3; // fix me
1700 }
1701 else
1702 {
1703 sh->onchip.DVDNTL = 0x7FFFFFFF;
1704 sh->onchip.DVDNTH = sh->onchip.DVDNTH << 3; // fix me
1705 }
1706
1707 sh->onchip.DVDNTUL = sh->onchip.DVDNTL;
1708 sh->onchip.DVDNTUH = sh->onchip.DVDNTH;
1709 sh->onchip.DVCR |= 1;
1710
1711 if (sh->onchip.DVCR & 0x2)
1712 SH2SendInterrupt(sh, sh->onchip.VCRDIV & 0x7F, (MSH2->onchip.IPRA >> 12) & 0xF);
1713 }
1714 else
1715 {
1716 s64 quotient = dividend / divisor;
1717 s32 remainder = dividend % divisor;
1718
1719 if (quotient > 0x7FFFFFFF)
1720 {
1721 sh->onchip.DVCR |= 1;
1722 sh->onchip.DVDNTL = 0x7FFFFFFF;
1723 sh->onchip.DVDNTH = 0xFFFFFFFE; // fix me
1724
1725 if (sh->onchip.DVCR & 0x2)
1726 SH2SendInterrupt(sh, sh->onchip.VCRDIV & 0x7F, (MSH2->onchip.IPRA >> 12) & 0xF);
1727 }
1728 else if ((s32)(quotient >> 32) < -1)
1729 {
1730 sh->onchip.DVCR |= 1;
1731 sh->onchip.DVDNTL = 0x80000000;
1732 sh->onchip.DVDNTH = 0xFFFFFFFE; // fix me
1733
1734 if (sh->onchip.DVCR & 0x2)
1735 SH2SendInterrupt(sh, sh->onchip.VCRDIV & 0x7F, (MSH2->onchip.IPRA >> 12) & 0xF);
1736 }
1737 else
1738 {
1739 sh->onchip.DVDNTL = quotient;
1740 sh->onchip.DVDNTH = remainder;
1741 }
1742
1743 sh->onchip.DVDNTUL = sh->onchip.DVDNTL;
1744 sh->onchip.DVDNTUH = sh->onchip.DVDNTH;
1745 }
1746 return;
1747 }
1748 case 0x118:
1749 case 0x138:
1750 sh->onchip.DVDNTUH = val;
1751 return;
1752 case 0x11C:
1753 case 0x13C:
1754 sh->onchip.DVDNTUL = val;
1755 return;
1756 case 0x140:
1757 sh->onchip.BARA.all = val;
1758 return;
1759 case 0x144:
1760 sh->onchip.BAMRA.all = val;
1761 return;
1762 case 0x180:
1763 sh->onchip.SAR0 = val;
1764 return;
1765 case 0x184:
1766 sh->onchip.DAR0 = val;
1767 return;
1768 case 0x188:
1769 sh->onchip.TCR0 = val & 0xFFFFFF;
1770 return;
1771 case 0x18C:
1772 sh->onchip.CHCR0 = val & 0xFFFF;
1773
1774 // If the DMAOR DME bit is set and AE and NMIF bits are cleared,
1775 // and CHCR's DE bit is set and TE bit is cleared,
1776 // do a dma transfer
1777 if ((sh->onchip.DMAOR & 7) == 1 && (val & 0x3) == 1)
1778 {
1779 if(yabsys.use_sh2_dma_timing)
1780 sh->onchip.dma0_active = 1;
1781 else
1782 DMAExec(sh);
1783 }
1784 return;
1785 case 0x190:
1786 sh->onchip.SAR1 = val;
1787 return;
1788 case 0x194:
1789 sh->onchip.DAR1 = val;
1790 return;
1791 case 0x198:
1792 sh->onchip.TCR1 = val & 0xFFFFFF;
1793 return;
1794 case 0x19C:
1795 sh->onchip.CHCR1 = val & 0xFFFF;
1796
1797 // If the DMAOR DME bit is set and AE and NMIF bits are cleared,
1798 // and CHCR's DE bit is set and TE bit is cleared,
1799 // do a dma transfer
1800 if ((sh->onchip.DMAOR & 7) == 1 && (val & 0x3) == 1)
1801 {
1802 if(yabsys.use_sh2_dma_timing)
1803 sh->onchip.dma1_active = 1;
1804 else
1805 DMAExec(sh);
1806 }
1807 return;
1808 case 0x1A0:
1809 sh->onchip.VCRDMA0 = val & 0xFFFF;
1810 return;
1811 case 0x1A8:
1812 sh->onchip.VCRDMA1 = val & 0xFFFF;
1813 return;
1814 case 0x1B0:
1815 sh->onchip.DMAOR = val & 0xF;
1816
1817 // If the DMAOR DME bit is set and AE and NMIF bits are cleared,
1818 // and CHCR's DE bit is set and TE bit is cleared,
1819 // do a dma transfer
1820 if ((val & 7) == 1)
1821 {
1822 if(yabsys.use_sh2_dma_timing)
1823 {
1824 if((sh->onchip.CHCR0 & 0x3) == 1)
1825 sh->onchip.dma0_active = 1;
1826 if ((sh->onchip.CHCR1 & 0x3) == 1)
1827 sh->onchip.dma1_active = 1;
1828 }
1829 else
1830 {
1831 DMAExec(sh);
1832 }
1833 }
1834 return;
1835 case 0x1E0:
1836 sh->onchip.BCR1 &= 0x8000;
1837 sh->onchip.BCR1 |= val & 0x1FF7;
1838 return;
1839 case 0x1E4:
1840 sh->onchip.BCR2 = val & 0xFC;
1841 return;
1842 case 0x1E8:
1843 sh->onchip.WCR = val;
1844 return;
1845 case 0x1EC:
1846 sh->onchip.MCR = val & 0xFEFC;
1847 return;
1848 case 0x1F0:
1849 sh->onchip.RTCSR = val & 0xF8;
1850 return;
1851 case 0x1F8:
1852 sh->onchip.RTCOR = val & 0xFF;
1853 return;
1854 default:
1855 LOG("Unhandled Onchip long write %08X\n", (int)addr);
1856 break;
1857 }
1858 }
1859
1860 //////////////////////////////////////////////////////////////////////////////
1861
AddressArrayReadLong(SH2_struct * sh,u32 addr)1862 u32 FASTCALL AddressArrayReadLong(SH2_struct *sh, u32 addr) {
1863 if (yabsys.sh2_cache_enabled)
1864 {
1865 int way = (sh->onchip.CCR >> 6) & 3;
1866 int entry = (addr & 0x3FC) >> 4;
1867 u32 data = sh->onchip.cache.way[way][entry].tag;
1868 data |= sh->onchip.cache.lru[entry] << 4;
1869 data |= sh->onchip.cache.way[way][entry].v << 2;
1870 return data;
1871 }
1872 else
1873 return sh->AddressArray[(addr & 0x3FC) >> 2];
1874 }
1875
1876 //////////////////////////////////////////////////////////////////////////////
1877
AddressArrayWriteLong(SH2_struct * sh,u32 addr,u32 val)1878 void FASTCALL AddressArrayWriteLong(SH2_struct *sh, u32 addr, u32 val) {
1879 if (yabsys.sh2_cache_enabled)
1880 {
1881 int way = (sh->onchip.CCR >> 6) & 3;
1882 int entry = (addr & 0x3FC) >> 4;
1883 sh->onchip.cache.way[way][entry].tag = addr & 0x1FFFFC00;
1884 sh->onchip.cache.way[way][entry].v = (addr >> 2) & 1;
1885 sh->onchip.cache.lru[entry] = (val >> 4) & 0x3f;
1886 }
1887 else
1888 sh->AddressArray[(addr & 0x3FC) >> 2] = val;
1889 }
1890
1891 //////////////////////////////////////////////////////////////////////////////
1892
DataArrayReadByte(SH2_struct * sh,u32 addr)1893 u8 FASTCALL DataArrayReadByte(SH2_struct *sh, u32 addr) {
1894 if (yabsys.sh2_cache_enabled)
1895 {
1896 int way = (addr >> 10) & 3;
1897 int entry = (addr >> 4) & 0x3f;
1898 return sh->onchip.cache.way[way][entry].data[addr & 0xf];
1899 }
1900 else
1901 return T2ReadByte(sh->DataArray, addr & 0xFFF);
1902 }
1903
1904 //////////////////////////////////////////////////////////////////////////////
1905
DataArrayReadWord(SH2_struct * sh,u32 addr)1906 u16 FASTCALL DataArrayReadWord(SH2_struct *sh, u32 addr) {
1907 if (yabsys.sh2_cache_enabled)
1908 {
1909 int way = (addr >> 10) & 3;
1910 int entry = (addr >> 4) & 0x3f;
1911 return ((u16)(sh->onchip.cache.way[way][entry].data[addr & 0xf]) << 8) | sh->onchip.cache.way[way][entry].data[(addr & 0xf) + 1];
1912 }
1913 else
1914 return T2ReadWord(sh->DataArray, addr & 0xFFF);
1915 }
1916
1917 //////////////////////////////////////////////////////////////////////////////
1918
DataArrayReadLong(SH2_struct * sh,u32 addr)1919 u32 FASTCALL DataArrayReadLong(SH2_struct *sh, u32 addr) {
1920 if (yabsys.sh2_cache_enabled)
1921 {
1922 int way = (addr >> 10) & 3;
1923 int entry = (addr >> 4) & 0x3f;
1924 u32 data = ((u32)(sh->onchip.cache.way[way][entry].data[addr & 0xf]) << 24) |
1925 ((u32)(sh->onchip.cache.way[way][entry].data[(addr & 0xf) + 1]) << 16) |
1926 ((u32)(sh->onchip.cache.way[way][entry].data[(addr & 0xf) + 2]) << 8) |
1927 ((u32)(sh->onchip.cache.way[way][entry].data[(addr & 0xf) + 3]) << 0);
1928 return data;
1929 }
1930 else
1931 return T2ReadLong(sh->DataArray, addr & 0xFFF);
1932 }
1933
1934 //////////////////////////////////////////////////////////////////////////////
1935
DataArrayWriteByte(SH2_struct * sh,u32 addr,u8 val)1936 void FASTCALL DataArrayWriteByte(SH2_struct *sh, u32 addr, u8 val) {
1937 if (yabsys.sh2_cache_enabled)
1938 {
1939 int way = (addr >> 10) & 3;
1940 int entry = (addr >> 4) & 0x3f;
1941 sh->onchip.cache.way[way][entry].data[addr & 0xf] = val;
1942 }
1943 else
1944 T2WriteByte(sh->DataArray, addr & 0xFFF, val);
1945 }
1946
1947 //////////////////////////////////////////////////////////////////////////////
1948
DataArrayWriteWord(SH2_struct * sh,u32 addr,u16 val)1949 void FASTCALL DataArrayWriteWord(SH2_struct *sh, u32 addr, u16 val) {
1950 if (yabsys.sh2_cache_enabled)
1951 {
1952 int way = (addr >> 10) & 3;
1953 int entry = (addr >> 4) & 0x3f;
1954 sh->onchip.cache.way[way][entry].data[addr & 0xf] = val >> 8;
1955 sh->onchip.cache.way[way][entry].data[(addr & 0xf) + 1] = val;
1956 }
1957 else
1958 T2WriteWord(sh->DataArray, addr & 0xFFF, val);
1959 }
1960
1961 //////////////////////////////////////////////////////////////////////////////
1962
DataArrayWriteLong(SH2_struct * sh,u32 addr,u32 val)1963 void FASTCALL DataArrayWriteLong(SH2_struct *sh, u32 addr, u32 val) {
1964 if (yabsys.sh2_cache_enabled)
1965 {
1966 int way = (addr >> 10) & 3;
1967 int entry = (addr >> 4) & 0x3f;
1968 sh->onchip.cache.way[way][entry].data[(addr & 0xf)] = ((val >> 24) & 0xFF);
1969 sh->onchip.cache.way[way][entry].data[(addr & 0xf) + 1] = ((val >> 16) & 0xFF);
1970 sh->onchip.cache.way[way][entry].data[(addr & 0xf) + 2] = ((val >> 8) & 0xFF);
1971 sh->onchip.cache.way[way][entry].data[(addr & 0xf) + 3] = ((val >> 0) & 0xFF);
1972 }
1973 else
1974 T2WriteLong(sh->DataArray, addr & 0xFFF, val);
1975 }
1976
1977 //////////////////////////////////////////////////////////////////////////////
1978
FRTExec(SH2_struct * sh,u32 cycles)1979 void FRTExec(SH2_struct *sh, u32 cycles)
1980 {
1981 u32 frcold;
1982 u32 frctemp;
1983 u32 mask;
1984
1985 frcold = frctemp = (u32)sh->onchip.FRC.all;
1986 mask = (1 << sh->frc.shift) - 1;
1987
1988 // Increment FRC
1989 frctemp += ((cycles + sh->frc.leftover) >> sh->frc.shift);
1990 sh->frc.leftover = (cycles + sh->frc.leftover) & mask;
1991
1992 // Check to see if there is or was a Output Compare A match
1993 if (frctemp >= sh->onchip.OCRA && frcold < sh->onchip.OCRA)
1994 {
1995 // Do we need to trigger an interrupt?
1996 if (sh->onchip.TIER & 0x8)
1997 SH2SendInterrupt(sh, sh->onchip.VCRC & 0x7F, (sh->onchip.IPRB & 0xF00) >> 8);
1998
1999 // Do we need to clear the FRC?
2000 if (sh->onchip.FTCSR & 0x1)
2001 {
2002 frctemp = 0;
2003 sh->frc.leftover = 0;
2004 }
2005
2006 // Set OCFA flag
2007 sh->onchip.FTCSR |= 0x8;
2008 }
2009
2010 // Check to see if there is or was a Output Compare B match
2011 if (frctemp >= sh->onchip.OCRB && frcold < sh->onchip.OCRB)
2012 {
2013 // Do we need to trigger an interrupt?
2014 if (sh->onchip.TIER & 0x4)
2015 SH2SendInterrupt(sh, sh->onchip.VCRC & 0x7F, (sh->onchip.IPRB & 0xF00) >> 8);
2016
2017 // Set OCFB flag
2018 sh->onchip.FTCSR |= 0x4;
2019 }
2020
2021 // If FRC overflows, set overflow flag
2022 if (frctemp > 0xFFFF)
2023 {
2024 // Do we need to trigger an interrupt?
2025 if (sh->onchip.TIER & 0x2)
2026 SH2SendInterrupt(sh, (sh->onchip.VCRD >> 8) & 0x7F, (sh->onchip.IPRB & 0xF00) >> 8);
2027
2028 sh->onchip.FTCSR |= 2;
2029 }
2030
2031 // Write new FRC value
2032 sh->onchip.FRC.all = frctemp;
2033 }
2034
2035 //////////////////////////////////////////////////////////////////////////////
2036
WDTExec(SH2_struct * sh,u32 cycles)2037 void WDTExec(SH2_struct *sh, u32 cycles) {
2038 u32 wdttemp;
2039 u32 mask;
2040
2041 if (!sh->wdt.isenable || sh->onchip.WTCSR & 0x80 || sh->onchip.RSTCSR & 0x80)
2042 return;
2043
2044 wdttemp = (u32)sh->onchip.WTCNT;
2045 mask = (1 << sh->wdt.shift) - 1;
2046 wdttemp += ((cycles + sh->wdt.leftover) >> sh->wdt.shift);
2047 sh->wdt.leftover = (cycles + sh->wdt.leftover) & mask;
2048
2049 // Are we overflowing?
2050 if (wdttemp > 0xFF)
2051 {
2052 // Obviously depending on whether or not we're in Watchdog or Interval
2053 // Modes, they'll handle an overflow differently.
2054
2055 if (sh->wdt.isinterval)
2056 {
2057 // Interval Timer Mode
2058
2059 // Set OVF flag
2060 sh->onchip.WTCSR |= 0x80;
2061
2062 // Trigger interrupt
2063 SH2SendInterrupt(sh, (sh->onchip.VCRWDT >> 8) & 0x7F, (sh->onchip.IPRA >> 4) & 0xF);
2064 }
2065 else
2066 {
2067 // Watchdog Timer Mode(untested)
2068 LOG("Watchdog timer(WDT mode) overflow not implemented\n");
2069 }
2070 }
2071
2072 // Write new WTCNT value
2073 sh->onchip.WTCNT = (u8)wdttemp;
2074 }
2075
2076 //////////////////////////////////////////////////////////////////////////////
2077
sh2_dma_access(u32 addr,u32 data,int is_read,int size)2078 u32 sh2_dma_access(u32 addr, u32 data, int is_read, int size)
2079 {
2080 addr &= 0xfffffff;
2081
2082 if (addr <= 0x00fffff)
2083 {
2084 //bios
2085 if (is_read)
2086 {
2087 if (size == 0)
2088 return BiosRomMemoryReadByte(addr);
2089 else if (size == 1)
2090 return BiosRomMemoryReadWord(addr);
2091 else
2092 return BiosRomMemoryReadLong(addr);
2093 }
2094 else
2095 {
2096 if (size == 0)
2097 BiosRomMemoryWriteByte(addr, data);
2098 else if (size == 1)
2099 BiosRomMemoryWriteWord(addr, data);
2100 else
2101 BiosRomMemoryWriteLong(addr, data);
2102 return 0;
2103 }
2104 }
2105 else if (addr >= 0x0100000 && addr <= 0x017ffff)
2106 {
2107 //smpc
2108 if (is_read)
2109 {
2110 if (size == 0)
2111 return SmpcReadByte(MSH2, addr);
2112 else if (size == 1)
2113 return SmpcReadWord(MSH2, addr);
2114 else
2115 return SmpcReadLong(MSH2, addr);
2116 }
2117 else
2118 {
2119 if (size == 0)
2120 SmpcWriteByte(MSH2, addr, data);
2121 else if (size == 1)
2122 SmpcWriteWord(MSH2, addr, data);
2123 else
2124 SmpcWriteLong(MSH2, addr, data);
2125 return 0;
2126 }
2127 }
2128 else if (addr >= 0x0180000 && addr <= 0x01fffff)
2129 {
2130 //backup ram
2131 if (is_read)
2132 {
2133 if (size == 0)
2134 return BupRamMemoryReadByte(addr);
2135 else if (size == 1)
2136 return BupRamMemoryReadWord(addr);
2137 else
2138 return BupRamMemoryReadLong(addr);
2139 }
2140 else
2141 {
2142 if (size == 0)
2143 BupRamMemoryWriteByte(addr, data);
2144 else if (size == 1)
2145 BupRamMemoryWriteWord(addr, data);
2146 else
2147 BupRamMemoryWriteLong(addr, data);
2148 return 0;
2149 }
2150 }
2151 else if (addr >= 0x0200000 && addr <= 0x02fffff)
2152 {
2153 //low wram
2154 if (is_read)
2155 {
2156 if (size == 0)
2157 return LowWramMemoryReadByte(addr);
2158 else if (size == 1)
2159 return LowWramMemoryReadWord(addr);
2160 else
2161 return LowWramMemoryReadLong(addr);
2162 }
2163 else
2164 {
2165 if (size == 0)
2166 LowWramMemoryWriteByte(addr, data);
2167 else if (size == 1)
2168 LowWramMemoryWriteWord(addr, data);
2169 else
2170 LowWramMemoryWriteLong(addr, data);
2171 return 0;
2172 }
2173 }
2174 else if (addr >= 0x1000000 && addr <= 0x17fffff)
2175 {
2176 //ssh2 input capture
2177 if (is_read)
2178 {
2179 if (size == 0)
2180 return UnhandledMemoryReadByte(addr);
2181 else if (size == 1)
2182 return UnhandledMemoryReadWord(addr);
2183 else
2184 return UnhandledMemoryReadLong(addr);
2185 }
2186 else
2187 {
2188 if (size == 0)
2189 UnhandledMemoryWriteByte(addr, data);
2190 else if (size == 1)
2191 SSH2InputCaptureWriteWord(MSH2, addr, data);
2192 else
2193 UnhandledMemoryWriteLong(addr, data);
2194 return 0;
2195 }
2196 }
2197 else if (addr >= 0x1800000 && addr <= 0x1ffffff)
2198 {
2199 //msh2 input capture
2200 if (is_read)
2201 {
2202 if (size == 0)
2203 return UnhandledMemoryReadByte(addr);
2204 else if (size == 1)
2205 return UnhandledMemoryReadWord(addr);
2206 else
2207 return UnhandledMemoryReadLong(addr);
2208 }
2209 else
2210 {
2211 if (size == 0)
2212 UnhandledMemoryWriteByte(addr, data);
2213 else if (size == 1)
2214 MSH2InputCaptureWriteWord(MSH2, addr, data);
2215 else
2216 UnhandledMemoryWriteLong(addr, data);
2217 return 0;
2218 }
2219 }
2220 else if (addr >= 0x2000000 && addr <= 0x3ffffff)
2221 {
2222 //cs0
2223 if (is_read)
2224 {
2225 if(size == 0)
2226 return CartridgeArea->Cs0ReadByte(MSH2, addr);
2227 else if (size == 1)
2228 return CartridgeArea->Cs0ReadWord(MSH2, addr);
2229 else
2230 return CartridgeArea->Cs0ReadLong(MSH2, addr);
2231 }
2232 else
2233 {
2234 if(size == 0)
2235 CartridgeArea->Cs0WriteByte(MSH2, addr, data);
2236 else if (size == 1)
2237 CartridgeArea->Cs0WriteWord(MSH2, addr, data);
2238 else
2239 CartridgeArea->Cs0WriteLong(MSH2, addr, data);
2240 return 0;
2241 }
2242 }
2243 else if (addr >= 0x4000000 && addr <= 0x4ffffff)
2244 {
2245 if (is_read)
2246 {
2247 if (size == 0)
2248 return Cs1ReadByte(MSH2, addr);
2249 else if (size == 1)
2250 return Cs1ReadWord(MSH2, addr);
2251 else
2252 return Cs1ReadLong(MSH2, addr);
2253 }
2254 else
2255 {
2256 if (size == 0)
2257 Cs1WriteByte(MSH2, addr, data);
2258 else if (size == 1)
2259 Cs1WriteWord(MSH2, addr, data);
2260 else
2261 Cs1WriteLong(MSH2, addr, data);
2262 return 0;
2263 }
2264 }
2265 else if (addr >= 0x5000000 && addr <= 0x57fffff)
2266 {
2267 //dummy
2268 }
2269 else if (addr >= 0x5800000 && addr <= 0x58fffff)
2270 {
2271 //cs2
2272 if (yabsys.use_cd_block_lle)
2273 {
2274 if (is_read)
2275 {
2276 if (size == 0)
2277 return Cs2ReadByte(MSH2, addr);
2278 else if (size == 1)
2279 return ygr_a_bus_read_word(addr);
2280 else
2281 return ygr_a_bus_read_long(addr);
2282 }
2283 else
2284 {
2285 if (size == 0)
2286 Cs2WriteByte(MSH2, addr, data);
2287 else if (size == 1)
2288 ygr_a_bus_write_word(addr, data);
2289 else
2290 ygr_a_bus_write_long(addr, data);
2291 return 0;
2292 }
2293 }
2294 else
2295 {
2296 if (is_read)
2297 {
2298 if (size == 0)
2299 return Cs2ReadByte(MSH2, addr);
2300 else if (size == 1)
2301 return Cs2ReadWord(MSH2, addr);
2302 else
2303 return Cs2ReadLong(MSH2, addr);
2304 }
2305 else
2306 {
2307 if (size == 0)
2308 Cs2WriteByte(MSH2, addr, data);
2309 else if (size == 1)
2310 Cs2WriteWord(MSH2, addr, data);
2311 else
2312 Cs2WriteLong(MSH2, addr, data);
2313 return 0;
2314 }
2315 }
2316 }
2317 else if (addr >= 0x5a00000 && addr <= 0x5afffff)
2318 {
2319 //sound ram
2320 if (is_read)
2321 {
2322 if (size == 0)
2323 return SoundRamReadByte(addr);
2324 else if (size == 1)
2325 return SoundRamReadWord(addr);
2326 else
2327 return SoundRamReadLong(addr);
2328 }
2329 else
2330 {
2331 if (size == 0)
2332 SoundRamWriteByte(addr, data);
2333 else if (size == 1)
2334 SoundRamWriteWord(addr, data);
2335 else
2336 SoundRamWriteLong(addr, data);
2337 return 0;
2338 }
2339 }
2340 else if (addr >= 0x5b00000 && addr <= 0x5bfffff)
2341 {
2342 //scsp regs
2343 if (is_read)
2344 {
2345 if (size == 0)
2346 return ScspReadByte(addr);
2347 else if (size == 1)
2348 return ScspReadWord(addr);
2349 else
2350 return ScspReadLong(addr);
2351 }
2352 else
2353 {
2354 if (size == 0)
2355 ScspWriteByte(addr, data);
2356 else if (size == 1)
2357 ScspWriteWord(addr, data);
2358 else
2359 ScspWriteLong(addr, data);
2360 return 0;
2361 }
2362 }
2363 else if (addr >= 0x5c00000 && addr <= 0x5c7ffff)
2364 {
2365 //vdp1 ram
2366 if (is_read)
2367 {
2368 if (size == 0)
2369 return Vdp1RamReadByte(addr);
2370 else if (size == 1)
2371 return Vdp1RamReadWord(addr);
2372 else
2373 return Vdp1RamReadLong(addr);
2374 }
2375 else
2376 {
2377 if (size == 0)
2378 Vdp1RamWriteByte(addr, data);
2379 else if (size == 1)
2380 Vdp1RamWriteWord(addr, data);
2381 else
2382 Vdp1RamWriteLong(addr, data);
2383 return 0;
2384 }
2385 }
2386 else if (addr >= 0x5c80000 && addr <= 0x5cfffff)
2387 {
2388 //vdp1 framebuffer
2389 if (is_read)
2390 {
2391 if (size == 0)
2392 return Vdp1FrameBufferReadByte(addr);
2393 else if (size == 1)
2394 return Vdp1FrameBufferReadWord(addr);
2395 else
2396 return Vdp1FrameBufferReadLong(addr);
2397 }
2398 else
2399 {
2400 if (size == 0)
2401 Vdp1FrameBufferWriteByte(addr, data);
2402 else if (size == 1)
2403 Vdp1FrameBufferWriteWord(addr, data);
2404 else
2405 Vdp1FrameBufferWriteLong(addr, data);
2406 return 0;
2407 }
2408 }
2409 else if (addr >= 0x5d00000 && addr <= 0x5d7ffff)
2410 {
2411 //vdp1 registers
2412 if (is_read)
2413 {
2414 if (size == 0)
2415 return Vdp1ReadByte(addr);
2416 else if (size == 1)
2417 return Vdp1ReadWord(addr);
2418 else
2419 return Vdp1ReadLong(addr);
2420 }
2421 else
2422 {
2423 if (size == 0)
2424 Vdp1WriteByte(addr, data);
2425 else if (size == 1)
2426 Vdp1WriteWord(addr, data);
2427 else
2428 Vdp1WriteLong(addr, data);
2429 return 0;
2430 }
2431 }
2432 else if (addr >= 0x5e00000 && addr <= 0x5efffff)
2433 {
2434 //vdp2 ram
2435 if (is_read)
2436 {
2437 if (size == 0)
2438 return Vdp2RamReadByte(addr);
2439 else if (size == 1)
2440 return Vdp2RamReadWord(addr);
2441 else
2442 return Vdp2RamReadLong(addr);
2443 }
2444 else
2445 {
2446 if (size == 0)
2447 Vdp2RamWriteByte(addr, data);
2448 else if (size == 1)
2449 Vdp2RamWriteWord(addr, data);
2450 else
2451 Vdp2RamWriteLong(addr, data);
2452 return 0;
2453 }
2454 }
2455 else if (addr >= 0x5f00000 && addr <= 0x5f7ffff)
2456 {
2457 //vdp2 color ram
2458 if (is_read)
2459 {
2460 if (size == 0)
2461 return Vdp2ColorRamReadByte(addr);
2462 else if (size == 1)
2463 return Vdp2ColorRamReadWord(addr);
2464 else
2465 return Vdp2ColorRamReadLong(addr);
2466 }
2467 else
2468 {
2469 if (size == 0)
2470 Vdp2ColorRamWriteByte(addr, data);
2471 else if (size == 1)
2472 Vdp2ColorRamWriteWord(addr, data);
2473 else
2474 Vdp2ColorRamWriteLong(addr, data);
2475 return 0;
2476 }
2477 }
2478 else if (addr >= 0x5f80000 && addr <= 0x5fbffff)
2479 {
2480 //vdp2 registers
2481 if (is_read)
2482 {
2483 if (size == 0)
2484 return Vdp2ReadByte(addr);
2485 else if (size == 1)
2486 return Vdp2ReadWord(addr);
2487 else
2488 return Vdp2ReadLong(addr);
2489 }
2490 else
2491 {
2492 if (size == 0)
2493 Vdp2WriteByte(addr, data);
2494 else if (size == 1)
2495 Vdp2WriteWord(addr, data);
2496 else
2497 Vdp2WriteLong(addr, data);
2498 return 0;
2499 }
2500 }
2501 else if (addr >= 0x5fe0000 && addr <= 0x5feffff)
2502 {
2503 //scu registers
2504 if (is_read)
2505 {
2506 if (size == 0)
2507 return ScuReadByte(addr);
2508 else if (size == 1)
2509 return ScuReadWord(addr);
2510 else
2511 return ScuReadLong(addr);
2512 }
2513 else
2514 {
2515 if (size == 0)
2516 ScuWriteByte(addr, data);
2517 else if (size == 1)
2518 ScuWriteWord(addr, data);
2519 else
2520 ScuWriteLong(addr, data);
2521 return 0;
2522 }
2523 }
2524 else if (addr >= 0x6000000 && addr <= 0x7ffffff)
2525 {
2526 //scu registers
2527 if (is_read)
2528 {
2529 if (size == 0)
2530 return HighWramMemoryReadByte(addr);
2531 else if (size == 1)
2532 return HighWramMemoryReadWord(addr);
2533 else
2534 return HighWramMemoryReadLong(addr);
2535 }
2536 else
2537 {
2538 if (size == 0)
2539 HighWramMemoryWriteByte(addr, data);
2540 else if (size == 1)
2541 HighWramMemoryWriteWord(addr, data);
2542 else
2543 HighWramMemoryWriteLong(addr, data);
2544 return 0;
2545 }
2546 }
2547 assert(0);
2548 return 0;
2549 }
2550
2551 int sh2_check_wait(SH2_struct * sh, u32 addr, int size);
2552
dma_tick(SH2_struct * sh,u32 * CHCR,u32 * SAR,u32 * DAR,u32 * TCR,u32 * VCRDMA,int * active)2553 void dma_tick(SH2_struct *sh, u32 *CHCR, u32 *SAR, u32 *DAR, u32 *TCR, u32 *VCRDMA, int * active)
2554 {
2555 int src_increment = 0;
2556 int dst_increment = 0;
2557 u8 dest_inc_mode = (*CHCR >> 14) & 3;
2558 u8 src_inc_mode = (*CHCR >> 12) & 3;
2559 u8 size = (*CHCR >> 10) & 3;
2560 int check_size = size;
2561
2562 if (check_size > 2)
2563 check_size = 2;//size 3 is also long size writes
2564
2565 if (sh2_check_wait(sh, *SAR, check_size))
2566 return;
2567
2568 if (dest_inc_mode == 1)
2569 dst_increment = 1;
2570 else if (dest_inc_mode == 2)
2571 dst_increment = -1;
2572
2573 if (src_inc_mode == 1)
2574 src_increment = 1;
2575 else if (src_inc_mode == 2)
2576 src_increment = -1;
2577
2578 if (size == 0)
2579 {
2580 u8 source_val = sh2_dma_access(*SAR,0,1,0);
2581 sh2_dma_access(*DAR, source_val,0,0);
2582 }
2583 else if (size == 1)
2584 {
2585 u16 source_val = sh2_dma_access(*SAR, 0, 1, 1);
2586 sh2_dma_access(*DAR, source_val, 0, 1);
2587 src_increment *= 2;
2588 dst_increment *= 2;
2589 }
2590 else if (size == 2 || size == 3)
2591 {
2592 u32 source_val = sh2_dma_access(*SAR, 0, 1, 2);
2593 sh2_dma_access(*DAR, source_val, 0, 2);
2594 src_increment *= 4;
2595 dst_increment *= 4;
2596 }
2597
2598 if(dst_increment > 0)
2599 SH2WriteNotify(*DAR, *DAR + dst_increment);
2600 else
2601 SH2WriteNotify(*DAR + dst_increment, *DAR);
2602
2603 *TCR = *TCR - 1;
2604 *SAR = *SAR + src_increment;
2605 *DAR = *DAR + dst_increment;
2606
2607 if (*TCR == 0)
2608 {
2609 *active = 0;
2610
2611 if ((*CHCR >> 2) & 1)
2612 SH2SendInterrupt(sh, *VCRDMA, (sh->onchip.IPRA & 0xF00) >> 8);
2613
2614 *CHCR |= 0x2;
2615 }
2616 }
2617
tick_dma0(SH2_struct * sh)2618 void tick_dma0(SH2_struct *sh)
2619 {
2620 dma_tick(
2621 sh,
2622 &sh->onchip.CHCR0,
2623 &sh->onchip.SAR0,
2624 &sh->onchip.DAR0,
2625 &sh->onchip.TCR0,
2626 &sh->onchip.VCRDMA0,
2627 &sh->onchip.dma0_active);
2628 }
2629
tick_dma1(SH2_struct * sh)2630 void tick_dma1(SH2_struct *sh)
2631 {
2632 dma_tick(
2633 sh,
2634 &sh->onchip.CHCR1,
2635 &sh->onchip.SAR1,
2636 &sh->onchip.DAR1,
2637 &sh->onchip.TCR1,
2638 &sh->onchip.VCRDMA1,
2639 &sh->onchip.dma1_active);//channel 0
2640 }
2641
sh2_dma_exec(SH2_struct * sh,u32 cycles)2642 void sh2_dma_exec(SH2_struct *sh, u32 cycles) {
2643 int i;
2644
2645 if (!sh->onchip.dma0_active && !sh->onchip.dma1_active)
2646 return;
2647
2648 for (i = 0; i < cycles; i++)
2649 {
2650 if ((sh->onchip.DMAOR >> 3) & 1)//round robin priority
2651 {
2652 //both channels are active, round robin
2653 if (sh->onchip.dma0_active && sh->onchip.dma1_active)
2654 {
2655 if (sh->onchip.dma_robin)
2656 {
2657 sh->onchip.dma_robin = 0;
2658 tick_dma0(sh);
2659 }
2660 else
2661 {
2662 tick_dma1(sh);//channel 1
2663 }
2664 }
2665 else
2666 {
2667 //only one channel is active
2668 if (sh->onchip.dma0_active)
2669 tick_dma0(sh);
2670 if (sh->onchip.dma1_active)
2671 tick_dma1(sh);
2672 }
2673 }
2674 else
2675 {
2676 //channel 0 > channel 1
2677
2678 if(sh->onchip.dma0_active)
2679 tick_dma0(sh);//channel 0
2680 else if (sh->onchip.dma1_active)
2681 tick_dma1(sh);//channel 1
2682 }
2683 }
2684 }
2685
2686
DMAExec(SH2_struct * sh)2687 void DMAExec(SH2_struct *sh) {
2688 // If AE and NMIF bits are set, we can't continue
2689 if (sh->onchip.DMAOR & 0x6)
2690 return;
2691
2692 if ( ((sh->onchip.CHCR0 & 0x3)==0x01) && ((sh->onchip.CHCR1 & 0x3)==0x01) ) { // both channel wants DMA
2693 if (sh->onchip.DMAOR & 0x8) { // round robin priority
2694 LOG("dma\t: FIXME: two channel dma - round robin priority not properly implemented\n");
2695 DMATransfer(sh, &sh->onchip.CHCR0, &sh->onchip.SAR0,
2696 &sh->onchip.DAR0, &sh->onchip.TCR0,
2697 &sh->onchip.VCRDMA0);
2698 DMATransfer(sh, &sh->onchip.CHCR1, &sh->onchip.SAR1,
2699 &sh->onchip.DAR1, &sh->onchip.TCR1,
2700 &sh->onchip.VCRDMA1);
2701 }
2702 else { // channel 0 > channel 1 priority
2703 DMATransfer(sh, &sh->onchip.CHCR0, &sh->onchip.SAR0,
2704 &sh->onchip.DAR0, &sh->onchip.TCR0,
2705 &sh->onchip.VCRDMA0);
2706 DMATransfer(sh, &sh->onchip.CHCR1, &sh->onchip.SAR1,
2707 &sh->onchip.DAR1, &sh->onchip.TCR1,
2708 &sh->onchip.VCRDMA1);
2709 }
2710 }
2711 else { // only one channel wants DMA
2712 if (((sh->onchip.CHCR0 & 0x3) == 0x01)) { // DMA for channel 0
2713 DMATransfer(sh, &sh->onchip.CHCR0, &sh->onchip.SAR0,
2714 &sh->onchip.DAR0, &sh->onchip.TCR0,
2715 &sh->onchip.VCRDMA0);
2716 return;
2717 }
2718 if (((sh->onchip.CHCR1 & 0x3) == 0x01)) { // DMA for channel 1
2719 DMATransfer(sh, &sh->onchip.CHCR1, &sh->onchip.SAR1,
2720 &sh->onchip.DAR1, &sh->onchip.TCR1,
2721 &sh->onchip.VCRDMA1);
2722 return;
2723 }
2724 }
2725 }
2726
2727 //////////////////////////////////////////////////////////////////////////////
2728
DMATransfer(SH2_struct * sh,u32 * CHCR,u32 * SAR,u32 * DAR,u32 * TCR,u32 * VCRDMA)2729 void DMATransfer(SH2_struct *sh, u32 *CHCR, u32 *SAR, u32 *DAR, u32 *TCR, u32 *VCRDMA)
2730 {
2731 int size;
2732 u32 i, i2;
2733
2734 if (!(*CHCR & 0x2)) { // TE is not set
2735 int srcInc;
2736 int destInc;
2737
2738 switch(*CHCR & 0x3000) {
2739 case 0x0000: srcInc = 0; break;
2740 case 0x1000: srcInc = 1; break;
2741 case 0x2000: srcInc = -1; break;
2742 default: srcInc = 0; break;
2743 }
2744
2745 switch(*CHCR & 0xC000) {
2746 case 0x0000: destInc = 0; break;
2747 case 0x4000: destInc = 1; break;
2748 case 0x8000: destInc = -1; break;
2749 default: destInc = 0; break;
2750 }
2751
2752 switch (size = ((*CHCR & 0x0C00) >> 10)) {
2753 case 0:
2754 for (i = 0; i < *TCR; i++) {
2755 MappedMemoryWriteByteNocache(sh, *DAR, MappedMemoryReadByteNocache(sh, *SAR));
2756 *SAR += srcInc;
2757 *DAR += destInc;
2758 }
2759
2760 *TCR = 0;
2761 break;
2762 case 1:
2763 destInc *= 2;
2764 srcInc *= 2;
2765
2766 for (i = 0; i < *TCR; i++) {
2767 MappedMemoryWriteWordNocache(sh, *DAR, MappedMemoryReadWordNocache(sh, *SAR));
2768 *SAR += srcInc;
2769 *DAR += destInc;
2770 }
2771
2772 *TCR = 0;
2773 break;
2774 case 2:
2775 destInc *= 4;
2776 srcInc *= 4;
2777
2778 for (i = 0; i < *TCR; i++) {
2779 MappedMemoryWriteLongNocache(sh, *DAR, MappedMemoryReadLongNocache(sh, *SAR));
2780 *DAR += destInc;
2781 *SAR += srcInc;
2782 }
2783
2784 *TCR = 0;
2785 break;
2786 case 3:
2787 destInc *= 4;
2788 srcInc *= 4;
2789
2790 for (i = 0; i < *TCR; i+=4) {
2791 for(i2 = 0; i2 < 4; i2++) {
2792 MappedMemoryWriteLongNocache(sh, *DAR, MappedMemoryReadLongNocache(sh, *SAR));
2793 *DAR += destInc;
2794 *SAR += srcInc;
2795 }
2796 }
2797
2798 *TCR = 0;
2799 break;
2800 }
2801 SH2WriteNotify(destInc<0?*DAR:*DAR-i*destInc,i*abs(destInc));
2802 }
2803
2804 if (*CHCR & 0x4)
2805 SH2SendInterrupt(sh, *VCRDMA, (sh->onchip.IPRA & 0xF00) >> 8);
2806
2807 // Set Transfer End bit
2808 *CHCR |= 0x2;
2809 }
2810
2811 //////////////////////////////////////////////////////////////////////////////
2812 // Input Capture Specific
2813 //////////////////////////////////////////////////////////////////////////////
2814
MSH2InputCaptureWriteWord(SH2_struct * sh,UNUSED u32 addr,UNUSED u16 data)2815 void FASTCALL MSH2InputCaptureWriteWord(SH2_struct *sh, UNUSED u32 addr, UNUSED u16 data)
2816 {
2817 // Set Input Capture Flag
2818 MSH2->onchip.FTCSR |= 0x80;
2819
2820 // Copy FRC register to FICR
2821 MSH2->onchip.FICR = MSH2->onchip.FRC.all;
2822
2823 // Time for an Interrupt?
2824 if (MSH2->onchip.TIER & 0x80)
2825 SH2SendInterrupt(MSH2, (MSH2->onchip.VCRC >> 8) & 0x7F, (MSH2->onchip.IPRB >> 8) & 0xF);
2826 }
2827
2828 //////////////////////////////////////////////////////////////////////////////
2829
SSH2InputCaptureWriteWord(SH2_struct * sh,UNUSED u32 addr,UNUSED u16 data)2830 void FASTCALL SSH2InputCaptureWriteWord(SH2_struct *sh, UNUSED u32 addr, UNUSED u16 data)
2831 {
2832 // Set Input Capture Flag
2833 SSH2->onchip.FTCSR |= 0x80;
2834
2835 // Copy FRC register to FICR
2836 SSH2->onchip.FICR = SSH2->onchip.FRC.all;
2837
2838 // Time for an Interrupt?
2839 if (SSH2->onchip.TIER & 0x80)
2840 SH2SendInterrupt(SSH2, (SSH2->onchip.VCRC >> 8) & 0x7F, (SSH2->onchip.IPRB >> 8) & 0xF);
2841 }
2842
2843 //////////////////////////////////////////////////////////////////////////////
2844 // SCI Specific
2845 //////////////////////////////////////////////////////////////////////////////
2846
SCIReceiveByte(void)2847 u8 SCIReceiveByte(void) {
2848 return 0;
2849 }
2850
2851 //////////////////////////////////////////////////////////////////////////////
2852
SCITransmitByte(UNUSED u8 val)2853 void SCITransmitByte(UNUSED u8 val) {
2854 }
2855
2856 //////////////////////////////////////////////////////////////////////////////
2857
SH2SaveState(SH2_struct * context,FILE * fp)2858 int SH2SaveState(SH2_struct *context, FILE *fp)
2859 {
2860 int offset;
2861 IOCheck_struct check = { 0, 0 };
2862 sh2regs_struct regs;
2863
2864 if (context->model == SHMT_SH1)
2865 {
2866 offset = StateWriteHeader(fp, "SH1 ", 1);
2867 }
2868 else if (context->model == SHMT_SH2)
2869 {
2870 // Write header
2871 if (context->isslave == 0)
2872 offset = StateWriteHeader(fp, "MSH2", 1);
2873 else
2874 {
2875 offset = StateWriteHeader(fp, "SSH2", 1);
2876 ywrite(&check, (void *)&yabsys.IsSSH2Running, 1, 1, fp);
2877 }
2878 }
2879
2880 // Write registers
2881 SH2GetRegisters(context, ®s);
2882 ywrite(&check, (void *)®s, sizeof(sh2regs_struct), 1, fp);
2883
2884 // Write onchip registers
2885 ywrite(&check, (void *)&context->onchip, sizeof(Onchip_struct), 1, fp);
2886
2887 // Write internal variables
2888 // FIXME: write the clock divisor rather than the shift amount for
2889 // backward compatibility (fix this next time the save state version
2890 // is updated)
2891 context->frc.shift = 1 << context->frc.shift;
2892 ywrite(&check, (void *)&context->frc, sizeof(context->frc), 1, fp);
2893 {
2894 u32 div = context->frc.shift;
2895 context->frc.shift = 0;
2896 while ((div >>= 1) != 0)
2897 context->frc.shift++;
2898 }
2899 context->NumberOfInterrupts = SH2Core->GetInterrupts(context, context->interrupts);
2900 ywrite(&check, (void *)context->interrupts, sizeof(interrupt_struct), MAX_INTERRUPTS, fp);
2901 ywrite(&check, (void *)&context->NumberOfInterrupts, sizeof(u32), 1, fp);
2902 ywrite(&check, (void *)context->AddressArray, sizeof(u32), 0x100, fp);
2903 ywrite(&check, (void *)context->DataArray, sizeof(u8), 0x1000, fp);
2904 ywrite(&check, (void *)&context->delay, sizeof(u32), 1, fp);
2905 ywrite(&check, (void *)&context->cycles, sizeof(u32), 1, fp);
2906 ywrite(&check, (void *)&context->isslave, sizeof(u8), 1, fp);
2907 ywrite(&check, (void *)&context->isIdle, sizeof(u8), 1, fp);
2908 ywrite(&check, (void *)&context->instruction, sizeof(u16), 1, fp);
2909
2910 return StateFinishHeader(fp, offset);
2911 }
2912
2913 //////////////////////////////////////////////////////////////////////////////
2914
SH2LoadState(SH2_struct * context,FILE * fp,UNUSED int version,int size)2915 int SH2LoadState(SH2_struct *context, FILE *fp, UNUSED int version, int size)
2916 {
2917 IOCheck_struct check = { 0, 0 };
2918 sh2regs_struct regs;
2919
2920 if (context->isslave == 1)
2921 yread(&check, (void *)&yabsys.IsSSH2Running, 1, 1, fp);
2922
2923 // Read registers
2924 yread(&check, (void *)®s, sizeof(sh2regs_struct), 1, fp);
2925 SH2SetRegisters(context, ®s);
2926
2927 // Read onchip registers
2928 yread(&check, (void *)&context->onchip, sizeof(Onchip_struct), 1, fp);
2929
2930 // Read internal variables
2931 yread(&check, (void *)&context->frc, sizeof(context->frc), 1, fp);
2932 { // FIXME: backward compatibility hack (see SH2SaveState() comment)
2933 u32 div = context->frc.shift;
2934 context->frc.shift = 0;
2935 while ((div >>= 1) != 0)
2936 context->frc.shift++;
2937 }
2938 yread(&check, (void *)context->interrupts, sizeof(interrupt_struct), MAX_INTERRUPTS, fp);
2939 yread(&check, (void *)&context->NumberOfInterrupts, sizeof(u32), 1, fp);
2940 SH2Core->SetInterrupts(context, context->NumberOfInterrupts, context->interrupts);
2941 yread(&check, (void *)context->AddressArray, sizeof(u32), 0x100, fp);
2942 yread(&check, (void *)context->DataArray, sizeof(u8), 0x1000, fp);
2943 yread(&check, (void *)&context->delay, sizeof(u32), 1, fp);
2944 yread(&check, (void *)&context->cycles, sizeof(u32), 1, fp);
2945 yread(&check, (void *)&context->isslave, sizeof(u8), 1, fp);
2946 yread(&check, (void *)&context->isIdle, sizeof(u8), 1, fp);
2947 yread(&check, (void *)&context->instruction, sizeof(u16), 1, fp);
2948
2949 #if defined(SH2_DYNAREC)
2950 if(SH2Core->id==2) {
2951 invalidate_all_pages();
2952 if (context->isslave == 1) {
2953 // If the slave SH2 isn't running, make sure the dynarec stops it
2954 if(!yabsys.IsSSH2Running) SH2Core->Reset(SSH2);
2955 }
2956 }
2957 #endif
2958
2959 return size;
2960 }
2961
2962 //////////////////////////////////////////////////////////////////////////////
2963