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, &regs);
2882    ywrite(&check, (void *)&regs, 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 *)&regs, sizeof(sh2regs_struct), 1, fp);
2925    SH2SetRegisters(context, &regs);
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