/[gxemul]/trunk/src/devices/dev_sh4.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/devices/dev_sh4.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC revision 36 by dpavlin, Mon Oct 8 16:21:34 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2006  Anders Gavare.  All rights reserved.   *  Copyright (C) 2006-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_sh4.c,v 1.21 2006/11/02 05:43:44 debug Exp $   *  $Id: dev_sh4.c,v 1.32 2007/03/16 18:47:26 debug Exp $
29   *     *  
30   *  SH4 processor specific memory mapped registers (0xf0000000 - 0xffffffff).   *  SH4 processor specific memory mapped registers (0xf0000000 - 0xffffffff).
31     *
32     *  TODO: Lots and lots of stuff.
33   */   */
34    
35  #include <stdio.h>  #include <stdio.h>
# Line 38  Line 40 
40  #include "cpu.h"  #include "cpu.h"
41  #include "device.h"  #include "device.h"
42  #include "devices.h"  #include "devices.h"
43    #include "interrupt.h"
44  #include "machine.h"  #include "machine.h"
45  #include "memory.h"  #include "memory.h"
46  #include "misc.h"  #include "misc.h"
# Line 45  Line 48 
48    
49  #include "sh4_bscreg.h"  #include "sh4_bscreg.h"
50  #include "sh4_cache.h"  #include "sh4_cache.h"
51    #include "sh4_dmacreg.h"
52  #include "sh4_exception.h"  #include "sh4_exception.h"
53  #include "sh4_intcreg.h"  #include "sh4_intcreg.h"
54  #include "sh4_mmu.h"  #include "sh4_mmu.h"
55    #include "sh4_rtcreg.h"
56  #include "sh4_scifreg.h"  #include "sh4_scifreg.h"
57  #include "sh4_tmureg.h"  #include "sh4_tmureg.h"
58    
# Line 56  Line 61 
61  #define SH4_TICK_SHIFT          14  #define SH4_TICK_SHIFT          14
62  #define N_SH4_TIMERS            3  #define N_SH4_TIMERS            3
63    
64    /*  General-purpose I/O stuff:  */
65    #define SH4_PCTRA               0xff80002c
66    #define SH4_PDTRA               0xff800030
67    #define SH4_PCTRB               0xff800040
68    #define SH4_PDTRB               0xff800044
69    #define SH4_GPIOIC              0xff800048
70    
71    #ifdef UNSTABLE_DEVEL
72    #define SH4_DEGUG
73  /*  #define debug fatal  */  /*  #define debug fatal  */
74    #endif
75    
76  struct sh4_data {  struct sh4_data {
77            /*  SCIF (Serial controller):  */
78            uint16_t        scif_smr;
79            uint8_t         scif_brr;
80            uint16_t        scif_scr;
81            uint16_t        scif_ssr;
82            uint16_t        scif_fcr;
83            int             scif_delayed_tx;
84          int             scif_console_handle;          int             scif_console_handle;
85            struct interrupt scif_tx_irq;
86            struct interrupt scif_rx_irq;
87    
88          /*  Bus State Controller:  */          /*  Bus State Controller:  */
89          uint32_t        unknown_2c;          uint32_t        bsc_bcr1;
90          uint32_t        unknown_30;          uint16_t        bsc_bcr2;
91            uint32_t        bsc_wcr1;
92            uint32_t        bsc_wcr2;
93            uint32_t        bsc_mcr;
94            uint16_t        bsc_rtcsr;
95            uint16_t        bsc_rtcor;
96            uint16_t        bsc_rfcr;
97    
98            /*  GPIO:  */
99            uint32_t        pctra;          /*  Port Control Register A  */
100            uint32_t        pdtra;          /*  Port Data Register A  */
101            uint32_t        pctrb;          /*  Port Control Register B  */
102            uint32_t        pdtrb;          /*  Port Data Register B  */
103    
104            /*  SD-RAM:  */
105            uint16_t        sdmr2;
106            uint16_t        sdmr3;
107    
108          /*  Timer Management Unit:  */          /*  Timer Management Unit:  */
109          struct timer    *sh4_timer;          struct timer    *sh4_timer;
110            struct interrupt timer_irq[4];
111          uint32_t        tocr;          uint32_t        tocr;
112          uint32_t        tstr;          uint32_t        tstr;
113          uint32_t        tcnt[N_SH4_TIMERS];          uint32_t        tcnt[N_SH4_TIMERS];
# Line 74  struct sh4_data { Line 115  struct sh4_data {
115          uint32_t        tcr[N_SH4_TIMERS];          uint32_t        tcr[N_SH4_TIMERS];
116          int             timer_interrupts_pending[N_SH4_TIMERS];          int             timer_interrupts_pending[N_SH4_TIMERS];
117          double          timer_hz[N_SH4_TIMERS];          double          timer_hz[N_SH4_TIMERS];
118    
119            /*  RTC:  */
120            uint32_t        rtc_reg[14];    /*  Excluding rcr1 and 2  */
121            uint8_t         rtc_rcr1;
122  };  };
123    
124    
# Line 86  struct sh4_data { Line 131  struct sh4_data {
131   *  This function is called SH4_PSEUDO_TIMER_HZ times per real-world second.   *  This function is called SH4_PSEUDO_TIMER_HZ times per real-world second.
132   *  Its job is to update the SH4 timer counters, and if necessary, increase   *  Its job is to update the SH4 timer counters, and if necessary, increase
133   *  the number of pending interrupts.   *  the number of pending interrupts.
134     *
135     *  Also, RAM Refresh is also faked here.
136   */   */
137  static void sh4_timer_tick(struct timer *t, void *extra)  static void sh4_timer_tick(struct timer *t, void *extra)
138  {  {
139          struct sh4_data *d = (struct sh4_data *) extra;          struct sh4_data *d = (struct sh4_data *) extra;
140          int i;          int i;
141    
142            /*  Fake RAM refresh:  */
143            d->bsc_rfcr ++;
144            if (d->bsc_rtcsr & (RTCSR_CMIE | RTCSR_OVIE)) {
145                    fatal("sh4: RTCSR_CMIE | RTCSR_OVIE: TODO\n");
146                    /*  TODO: Implement refresh interrupts etc.  */
147                    exit(1);
148            }
149    
150            /*  Timer interrupts:  */
151          for (i=0; i<N_SH4_TIMERS; i++) {          for (i=0; i<N_SH4_TIMERS; i++) {
152                  int32_t old = d->tcnt[i];                  int32_t old = d->tcnt[i];
153    
# Line 128  static void sh4_timer_tick(struct timer Line 184  static void sh4_timer_tick(struct timer
184  }  }
185    
186    
187    static void scif_reassert_interrupts(struct sh4_data *d)
188    {
189            if (d->scif_scr & SCSCR2_RIE) {
190                    if (d->scif_ssr & SCSSR2_DR)
191                            INTERRUPT_ASSERT(d->scif_rx_irq);
192            } else {
193                    INTERRUPT_DEASSERT(d->scif_rx_irq);
194            }
195            if (d->scif_scr & SCSCR2_TIE) {
196                    if (d->scif_ssr & (SCSSR2_TDFE | SCSSR2_TEND))
197                            INTERRUPT_ASSERT(d->scif_tx_irq);
198            } else {
199                    INTERRUPT_DEASSERT(d->scif_tx_irq);
200            }
201    }
202    
203    
204  DEVICE_TICK(sh4)  DEVICE_TICK(sh4)
205  {  {
206          struct sh4_data *d = (struct sh4_data *) extra;          struct sh4_data *d = (struct sh4_data *) extra;
207          int i;          int i;
208    
209            /*  Serial controller interrupts:  */
210            /*  TODO: Which bits go to which interrupt?  */
211            if (console_charavail(d->scif_console_handle))
212                    d->scif_ssr |= SCSSR2_DR;
213            else
214                    d->scif_ssr &= SCSSR2_DR;
215            if (d->scif_delayed_tx) {
216                    if (--d->scif_delayed_tx == 0)
217                            d->scif_ssr |= SCSSR2_TDFE | SCSSR2_TEND;
218            }
219    
220            scif_reassert_interrupts(d);
221    
222            /*  Timer interrupts:  */
223          for (i=0; i<N_SH4_TIMERS; i++)          for (i=0; i<N_SH4_TIMERS; i++)
224                  if (d->timer_interrupts_pending[i] > 0) {                  if (d->timer_interrupts_pending[i] > 0) {
225                          cpu_interrupt(cpu, SH_INTEVT_TMU0_TUNI0 + 0x20 * i);                          INTERRUPT_ASSERT(d->timer_irq[i]);
226                          d->tcr[i] |= TCR_UNF;                          d->tcr[i] |= TCR_UNF;
227                  }                  }
228  }  }
# Line 161  DEVICE_ACCESS(sh4_itlb_aa) Line 248  DEVICE_ACCESS(sh4_itlb_aa)
248                  if (idata & SH4_ITLB_AA_V)                  if (idata & SH4_ITLB_AA_V)
249                          cpu->cd.sh.itlb_lo[e] |= SH4_PTEL_V;                          cpu->cd.sh.itlb_lo[e] |= SH4_PTEL_V;
250    
251                  if (safe_to_invalidate)                  /*  Invalidate if this ITLB entry previously belonged to the
252                          cpu->invalidate_translation_caches(cpu,                      currently running process, or if it was shared:  */
253                              old_hi & ~0xfff, INVALIDATE_VADDR);                  if (cpu->cd.sh.ptel & SH4_PTEL_SH ||
254                  else                      (old_hi & SH4_ITLB_AA_ASID_MASK) ==
255                          cpu->invalidate_translation_caches(cpu,                      (cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK)) {
256                              0, INVALIDATE_ALL);                          if (safe_to_invalidate)
257                                    cpu->invalidate_translation_caches(cpu,
258                                        old_hi & ~0xfff, INVALIDATE_VADDR);
259                            else
260                                    cpu->invalidate_translation_caches(cpu,
261                                        0, INVALIDATE_ALL);
262                    }
263          } else {          } else {
264                  odata = cpu->cd.sh.itlb_hi[e] &                  odata = cpu->cd.sh.itlb_hi[e] &
265                      (SH4_ITLB_AA_VPN_MASK | SH4_ITLB_AA_ASID_MASK);                      (SH4_ITLB_AA_VPN_MASK | SH4_ITLB_AA_ASID_MASK);
# Line 192  DEVICE_ACCESS(sh4_itlb_da1) Line 285  DEVICE_ACCESS(sh4_itlb_da1)
285          }          }
286    
287          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {
288                    uint32_t old_lo = cpu->cd.sh.itlb_lo[e];
289                  int safe_to_invalidate = 0;                  int safe_to_invalidate = 0;
290                  if ((cpu->cd.sh.itlb_lo[e] & SH4_PTEL_SZ_MASK)==SH4_PTEL_SZ_4K)                  if ((cpu->cd.sh.itlb_lo[e] & SH4_PTEL_SZ_MASK)==SH4_PTEL_SZ_4K)
291                          safe_to_invalidate = 1;                          safe_to_invalidate = 1;
# Line 200  DEVICE_ACCESS(sh4_itlb_da1) Line 294  DEVICE_ACCESS(sh4_itlb_da1)
294                  cpu->cd.sh.itlb_lo[e] &= ~mask;                  cpu->cd.sh.itlb_lo[e] &= ~mask;
295                  cpu->cd.sh.itlb_lo[e] |= (idata & mask);                  cpu->cd.sh.itlb_lo[e] |= (idata & mask);
296    
297                  if (safe_to_invalidate)                  /*  Invalidate if this ITLB entry belongs to the
298                          cpu->invalidate_translation_caches(cpu,                      currently running process, or if it was shared:  */
299                              cpu->cd.sh.itlb_hi[e] & ~0xfff, INVALIDATE_VADDR);                  if (old_lo & SH4_PTEL_SH ||
300                  else                      (cpu->cd.sh.itlb_hi[e] & SH4_ITLB_AA_ASID_MASK) ==
301                          cpu->invalidate_translation_caches(cpu,                      (cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK)) {
302                              0, INVALIDATE_ALL);                          if (safe_to_invalidate)
303                                    cpu->invalidate_translation_caches(cpu,
304                                        cpu->cd.sh.itlb_hi[e] & ~0xfff,
305                                        INVALIDATE_VADDR);
306                            else
307                                    cpu->invalidate_translation_caches(cpu,
308                                        0, INVALIDATE_ALL);
309                    }
310          } else {          } else {
311                  odata = cpu->cd.sh.itlb_lo[e] & mask;                  odata = cpu->cd.sh.itlb_lo[e] & mask;
312                  memory_writemax64(cpu, data, len, odata);                  memory_writemax64(cpu, data, len, odata);
# Line 313  DEVICE_ACCESS(sh4_utlb_aa) Line 414  DEVICE_ACCESS(sh4_utlb_aa)
414                          cpu->invalidate_translation_caches(cpu,                          cpu->invalidate_translation_caches(cpu,
415                              vaddr_to_invalidate, INVALIDATE_VADDR);                              vaddr_to_invalidate, INVALIDATE_VADDR);
416                  else                  else
417                          cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);                          cpu->invalidate_translation_caches(cpu, 0,
418                                INVALIDATE_ALL);
419          } else {          } else {
420                  odata = cpu->cd.sh.utlb_hi[e] &                  odata = cpu->cd.sh.utlb_hi[e] &
421                      (SH4_UTLB_AA_VPN_MASK | SH4_UTLB_AA_ASID_MASK);                      (SH4_UTLB_AA_VPN_MASK | SH4_UTLB_AA_ASID_MASK);
# Line 341  DEVICE_ACCESS(sh4_utlb_da1) Line 443  DEVICE_ACCESS(sh4_utlb_da1)
443          }          }
444    
445          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {
446                    uint32_t old_lo = cpu->cd.sh.utlb_lo[e];
447                  int safe_to_invalidate = 0;                  int safe_to_invalidate = 0;
448                  if ((cpu->cd.sh.utlb_lo[e] & SH4_PTEL_SZ_MASK)==SH4_PTEL_SZ_4K)                  if ((cpu->cd.sh.utlb_lo[e] & SH4_PTEL_SZ_MASK)==SH4_PTEL_SZ_4K)
449                          safe_to_invalidate = 1;                          safe_to_invalidate = 1;
# Line 349  DEVICE_ACCESS(sh4_utlb_da1) Line 452  DEVICE_ACCESS(sh4_utlb_da1)
452                  cpu->cd.sh.utlb_lo[e] &= ~mask;                  cpu->cd.sh.utlb_lo[e] &= ~mask;
453                  cpu->cd.sh.utlb_lo[e] |= (idata & mask);                  cpu->cd.sh.utlb_lo[e] |= (idata & mask);
454    
455                  if (safe_to_invalidate)                  /*  Invalidate if this UTLB entry belongs to the
456                          cpu->invalidate_translation_caches(cpu,                      currently running process, or if it was shared:  */
457                              cpu->cd.sh.utlb_hi[e] & ~0xfff, INVALIDATE_VADDR);                  if (old_lo & SH4_PTEL_SH ||
458                  else                      (cpu->cd.sh.utlb_hi[e] & SH4_ITLB_AA_ASID_MASK) ==
459                          cpu->invalidate_translation_caches(cpu,                      (cpu->cd.sh.pteh & SH4_PTEH_ASID_MASK)) {
460                              0, INVALIDATE_ALL);                          if (safe_to_invalidate)
461                                    cpu->invalidate_translation_caches(cpu,
462                                        cpu->cd.sh.utlb_hi[e] & ~0xfff,
463                                        INVALIDATE_VADDR);
464                            else
465                                    cpu->invalidate_translation_caches(cpu,
466                                        0, INVALIDATE_ALL);
467                    }
468          } else {          } else {
469                  odata = cpu->cd.sh.utlb_lo[e] & mask;                  odata = cpu->cd.sh.utlb_lo[e] & mask;
470                  memory_writemax64(cpu, data, len, odata);                  memory_writemax64(cpu, data, len, odata);
# Line 368  DEVICE_ACCESS(sh4) Line 478  DEVICE_ACCESS(sh4)
478  {  {
479          struct sh4_data *d = (struct sh4_data *) extra;          struct sh4_data *d = (struct sh4_data *) extra;
480          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
481          int timer_nr = 0;          int timer_nr = 0, dma_channel = 0;
482    
483          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
484                  idata = memory_readmax64(cpu, data, len);                  idata = memory_readmax64(cpu, data, len);
485    
486          relative_addr += SH4_REG_BASE;          relative_addr += SH4_REG_BASE;
487    
488            /*  SD-RAM access uses address only:  */
489            if (relative_addr >= 0xff900000 && relative_addr <= 0xff97ffff) {
490                    /*  Possibly not 100% correct... TODO  */
491                    int v = (relative_addr >> 2) & 0xffff;
492                    if (relative_addr & 0x00040000)
493                            d->sdmr3 = v;
494                    else
495                            d->sdmr2 = v;
496                    debug("[ sh4: sdmr%i set to 0x%04"PRIx16" ]\n",
497                        relative_addr & 0x00040000? 3 : 2, v);
498                    return 1;
499            }
500    
501    
502          switch (relative_addr) {          switch (relative_addr) {
503    
504          /*************************************************/          /*************************************************/
# Line 395  DEVICE_ACCESS(sh4) Line 519  DEVICE_ACCESS(sh4)
519                          cpu->cd.sh.pteh = idata;                          cpu->cd.sh.pteh = idata;
520    
521                          if ((idata & SH4_PTEH_ASID_MASK) != old_asid) {                          if ((idata & SH4_PTEH_ASID_MASK) != old_asid) {
522                                  /*  TODO: Don't invalidate everything?  */                                  /*
523                                     *  TODO: Don't invalidate everything,
524                                     *  only those pages that belonged to the
525                                     *  old asid.
526                                     */
527                                  cpu->invalidate_translation_caches(                                  cpu->invalidate_translation_caches(
528                                      cpu, 0, INVALIDATE_ALL);                                      cpu, 0, INVALIDATE_ALL);
529                          }                          }
# Line 436  DEVICE_ACCESS(sh4) Line 564  DEVICE_ACCESS(sh4)
564                  } else {                  } else {
565                          if (idata & SH4_MMUCR_TI) {                          if (idata & SH4_MMUCR_TI) {
566                                  /*  TLB invalidate.  */                                  /*  TLB invalidate.  */
567                                    int i;
568                                    for (i = 0; i < SH_N_ITLB_ENTRIES; i++)
569                                            cpu->cd.sh.itlb_lo[i] &=
570                                                ~SH4_PTEL_V;
571    
572                                    for (i = 0; i < SH_N_UTLB_ENTRIES; i++)
573                                            cpu->cd.sh.utlb_lo[i] &=
574                                                ~SH4_PTEL_V;
575    
                                 /*  TODO: Only invalidate something specific?  
                                     And not everything?  */  
576                                  cpu->invalidate_translation_caches(cpu,                                  cpu->invalidate_translation_caches(cpu,
577                                      0, INVALIDATE_ALL);                                      0, INVALIDATE_ALL);
578    
# Line 606  DEVICE_ACCESS(sh4) Line 740  DEVICE_ACCESS(sh4)
740                          }                          }
741    
742                          if (d->tcr[timer_nr] & TCR_UNF && !(idata & TCR_UNF)) {                          if (d->tcr[timer_nr] & TCR_UNF && !(idata & TCR_UNF)) {
743                                  cpu_interrupt_ack(cpu, SH_INTEVT_TMU0_TUNI0                                  INTERRUPT_DEASSERT(d->timer_irq[timer_nr]);
                                     + 0x20 * timer_nr);  
744                                  if (d->timer_interrupts_pending[timer_nr] > 0)                                  if (d->timer_interrupts_pending[timer_nr] > 0)
745                                          d->timer_interrupts_pending[timer_nr]--;                                          d->timer_interrupts_pending[timer_nr]--;
746                          }                          }
# Line 618  DEVICE_ACCESS(sh4) Line 751  DEVICE_ACCESS(sh4)
751    
752    
753          /*************************************************/          /*************************************************/
754            /*  DMAC: DMA Controller                         */
755    
756            case SH4_SAR3:
757                    dma_channel ++;
758            case SH4_SAR2:
759                    dma_channel ++;
760            case SH4_SAR1:
761                    dma_channel ++;
762            case SH4_SAR0:
763                    dma_channel ++;
764                    if (writeflag == MEM_READ)
765                            odata = cpu->cd.sh.dmac_sar[dma_channel];
766                    else
767                            cpu->cd.sh.dmac_sar[dma_channel] = idata;
768                    break;
769    
770            case SH4_DAR3:
771                    dma_channel ++;
772            case SH4_DAR2:
773                    dma_channel ++;
774            case SH4_DAR1:
775                    dma_channel ++;
776            case SH4_DAR0:
777                    dma_channel ++;
778                    if (writeflag == MEM_READ)
779                            odata = cpu->cd.sh.dmac_dar[dma_channel];
780                    else
781                            cpu->cd.sh.dmac_dar[dma_channel] = idata;
782                    break;
783    
784            case SH4_DMATCR3:
785                    dma_channel ++;
786            case SH4_DMATCR2:
787                    dma_channel ++;
788            case SH4_DMATCR1:
789                    dma_channel ++;
790            case SH4_DMATCR0:
791                    dma_channel ++;
792                    if (writeflag == MEM_READ)
793                            odata = cpu->cd.sh.dmac_tcr[dma_channel] & 0x00ffffff;
794                    else {
795                            if (idata & ~0x00ffffff) {
796                                    fatal("[ SH4 DMA: Attempt to set top 8 "
797                                        "bits of the count register? 0x%08"
798                                        PRIx32" ]\n", (uint32_t) idata);
799                                    exit(1);
800                            }
801    
802                            /*  Special case: writing 0 to the count register
803                                means 16777216:  */
804                            if (idata == 0)
805                                    idata = 0x01000000;
806                            cpu->cd.sh.dmac_tcr[dma_channel] = idata;
807                    }
808                    break;
809    
810            case SH4_CHCR3:
811                    dma_channel ++;
812            case SH4_CHCR2:
813                    dma_channel ++;
814            case SH4_CHCR1:
815                    dma_channel ++;
816            case SH4_CHCR0:
817                    dma_channel ++;
818                    if (writeflag == MEM_READ)
819                            odata = cpu->cd.sh.dmac_chcr[dma_channel];
820                    else {
821                            /*  IP.BIN sets this to 0x12c0, and I want to know if
822                                some other guest OS uses other values.  */
823                            if (idata != 0x12c0) {
824                                    fatal("[ SH4 DMA: Attempt to set chcr "
825                                        "to 0x%08"PRIx32" ]\n", (uint32_t) idata);
826                                    exit(1);
827                            }
828    
829                            cpu->cd.sh.dmac_chcr[dma_channel] = idata;
830                    }
831                    break;
832    
833    
834            /*************************************************/
835          /*  BSC: Bus State Controller                    */          /*  BSC: Bus State Controller                    */
836    
837          case SH4_RFCR:          case SH4_BCR1:
838                  /*  TODO  */                  if (writeflag == MEM_WRITE)
839                  fatal("[ SH4_RFCR: TODO ]\n");                          d->bsc_bcr1 = idata & 0x033efffd;
840                  odata = 0x11;                  else {
841                            odata = d->bsc_bcr1;
842                            if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
843                                    odata |= BCR1_LITTLE_ENDIAN;
844                    }
845                    break;
846    
847            case SH4_BCR2:
848                    if (len != sizeof(uint16_t)) {
849                            fatal("Non-16-bit SH4_BCR2 access?\n");
850                            exit(1);
851                    }
852                    if (writeflag == MEM_WRITE)
853                            d->bsc_bcr2 = idata & 0x3ffd;
854                    else
855                            odata = d->bsc_bcr2;
856                    break;
857    
858            case SH4_WCR1:
859                    if (writeflag == MEM_WRITE)
860                            d->bsc_wcr1 = idata & 0x77777777;
861                    else
862                            odata = d->bsc_wcr1;
863                    break;
864    
865            case SH4_WCR2:
866                    if (writeflag == MEM_WRITE)
867                            d->bsc_wcr2 = idata & 0xfffeefff;
868                    else
869                            odata = d->bsc_wcr2;
870                    break;
871    
872            case SH4_MCR:
873                    if (writeflag == MEM_WRITE)
874                            d->bsc_mcr = idata & 0xf8bbffff;
875                    else
876                            odata = d->bsc_mcr;
877                  break;                  break;
878    
879  #if 0          case SH4_RTCSR:
         case SH4_UNKNOWN_2C:  
                 /*  Not really part of the BSC? The 2C and 30 registers  
                     have to do with I/O pins... TODO  */  
880                  /*                  /*
881                   *  TODO:  Perhaps this isn't actually part of the Bus State                   *  Refresh Time Control/Status Register. Called RTCSR in
882                   *         controller?  Marcus Comstedt's video.s tutorial on                   *  NetBSD, but RTSCR in the SH7750 manual?
                  *         how to output video on the Dreamcast indicates that  
                  *         this is a way to sense which video cable is  
                  *         connected.  
883                   */                   */
884                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
885                          d->unknown_2c = idata;                          idata &= 0x00ff;
886                          d->unknown_30 = idata;                          if (idata & RTCSR_CMF) {
887                                    idata = (idata & ~RTCSR_CMF)
888                                        | (d->bsc_rtcsr & RTCSR_CMF);
889                            }
890                            d->bsc_rtcsr = idata & 0x00ff;
891                  } else                  } else
892                          odata = d->unknown_2c;                          odata = d->bsc_rtcsr;
893                  break;                  break;
 #endif  
894    
895  #if 1          case SH4_RTCOR:
896          case SH4_UNKNOWN_30:                  /*  Refresh Time Constant Register (8 bits):  */
897                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
898                          d->unknown_30 = idata;                          d->bsc_rtcor = idata & 0x00ff;
899                  else {                  else
900                          odata = d->unknown_30;                          odata = d->bsc_rtcor & 0x00ff;
901                    break;
902    
903            case SH4_RFCR:
904                    /*  Refresh Count Register (10 bits):  */
905                    if (writeflag == MEM_WRITE)
906                            d->bsc_rfcr = idata & 0x03ff;
907                    else
908                            odata = d->bsc_rfcr & 0x03ff;
909                    break;
910    
911    
912            /*******************************************/
913            /*  GPIO:  General-purpose I/O controller  */
914    
915            case SH4_PCTRA:
916                    if (writeflag == MEM_WRITE)
917                            d->pctra = idata;
918                    else
919                            odata = d->pctra;
920                    break;
921    
922                          /*  SUPER-UGLY HACK!  TODO  */          case SH4_PDTRA:
923                          d->unknown_30 ++;                  if (writeflag == MEM_WRITE) {
924                            debug("[ sh4: pdtra: write: TODO ]\n");
925                            d->pdtra = idata;
926                    } else {
927                            debug("[ sh4: pdtra: read: TODO ]\n");
928                            odata = d->pdtra;
929                    }
930                    break;
931    
932            case SH4_PCTRB:
933                    if (writeflag == MEM_WRITE)
934                            d->pctrb = idata;
935                    else
936                            odata = d->pctrb;
937                    break;
938    
939            case SH4_PDTRB:
940                    if (writeflag == MEM_WRITE) {
941                            debug("[ sh4: pdtrb: write: TODO ]\n");
942                            d->pdtrb = idata;
943                    } else {
944                            debug("[ sh4: pdtrb: read: TODO ]\n");
945                            odata = d->pdtrb;
946                  }                  }
947                  break;                  break;
 #endif  
948    
949    
950          /*********************************/          /*********************************/
# Line 693  DEVICE_ACCESS(sh4) Line 981  DEVICE_ACCESS(sh4)
981                          cpu->cd.sh.intc_iprc = idata;                          cpu->cd.sh.intc_iprc = idata;
982                  break;                  break;
983    
984            case SH4_IPRD:
985                    if (writeflag == MEM_READ)
986                            odata = cpu->cd.sh.intc_iprd;
987                    else
988                            cpu->cd.sh.intc_iprd = idata;
989                    break;
990    
991    
992          /*************************************************/          /*************************************************/
993          /*  SCIF: Serial Controller Interface with FIFO  */          /*  SCIF: Serial Controller Interface with FIFO  */
994    
995            case SH4_SCIF_BASE + SCIF_SMR:
996                    if (writeflag == MEM_WRITE) {
997                            d->scif_smr = idata;
998                    } else {
999                            odata = d->scif_smr;
1000                    }
1001                    break;
1002    
1003            case SH4_SCIF_BASE + SCIF_BRR:
1004                    if (writeflag == MEM_WRITE) {
1005                            d->scif_brr = idata;
1006                    } else {
1007                            odata = d->scif_brr;
1008                    }
1009                    break;
1010    
1011            case SH4_SCIF_BASE + SCIF_SCR:
1012                    if (writeflag == MEM_WRITE) {
1013                            d->scif_scr = idata;
1014                            scif_reassert_interrupts(d);
1015                    } else {
1016                            odata = d->scif_scr;
1017                    }
1018                    break;
1019    
1020          case SH4_SCIF_BASE + SCIF_FTDR:          case SH4_SCIF_BASE + SCIF_FTDR:
1021                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE) {
1022                          console_putchar(d->scif_console_handle, idata);                          console_putchar(d->scif_console_handle, idata);
1023                            d->scif_delayed_tx = 1;
1024                    }
1025                  break;                  break;
1026    
1027          case SH4_SCIF_BASE + SCIF_SSR:          case SH4_SCIF_BASE + SCIF_SSR:
1028                  /*  TODO: Implement more of this.  */                  if (writeflag == MEM_READ) {
1029                  odata = SCSSR2_TDFE | SCSSR2_TEND;                          odata = d->scif_ssr;
1030                  if (console_charavail(d->scif_console_handle))                  } else {
1031                          odata |= SCSSR2_DR;                          d->scif_ssr &= ~idata;
1032                            scif_reassert_interrupts(d);
1033                    }
1034                  break;                  break;
1035    
1036          case SH4_SCIF_BASE + SCIF_FRDR:          case SH4_SCIF_BASE + SCIF_FRDR:
# Line 715  DEVICE_ACCESS(sh4) Line 1039  DEVICE_ACCESS(sh4)
1039                          if (x == 13)                          if (x == 13)
1040                                  x = 10;                                  x = 10;
1041                          odata = x < 0? 0 : x;                          odata = x < 0? 0 : x;
1042                            d->scif_ssr &= ~SCSSR2_DR;
1043                    }
1044                    break;
1045    
1046            case SH4_SCIF_BASE + SCIF_FCR:
1047                    if (writeflag == MEM_WRITE) {
1048                            d->scif_fcr = idata;
1049                    } else {
1050                            odata = d->scif_fcr;
1051                  }                  }
1052                  break;                  break;
1053    
# Line 722  DEVICE_ACCESS(sh4) Line 1055  DEVICE_ACCESS(sh4)
1055                  odata = console_charavail(d->scif_console_handle);                  odata = console_charavail(d->scif_console_handle);
1056                  break;                  break;
1057    
1058    
1059            /*************************************************/
1060    
1061            case SH4_RSECCNT:
1062            case SH4_RMINCNT:
1063            case SH4_RHRCNT:
1064            case SH4_RWKCNT:
1065            case SH4_RDAYCNT:
1066            case SH4_RMONCNT:
1067            case SH4_RYRCNT:
1068            case SH4_RSECAR:
1069            case SH4_RMINAR:
1070            case SH4_RHRAR:
1071            case SH4_RWKAR:
1072            case SH4_RDAYAR:
1073            case SH4_RMONAR:
1074                    if (writeflag == MEM_WRITE) {
1075                            d->rtc_reg[(relative_addr - 0xffc80000) / 4] = idata;
1076                    } else {
1077                            /*  TODO: Update rtc_reg based on host's date/time.  */
1078                            odata = d->rtc_reg[(relative_addr - 0xffc80000) / 4];
1079                    }
1080                    break;
1081    
1082            case SH4_RCR1:
1083                    if (writeflag == MEM_READ)
1084                            odata = d->rtc_rcr1;
1085                    else {
1086                            d->rtc_rcr1 = idata;
1087                            if (idata & 0x18) {
1088                                    fatal("SH4: TODO: RTC interrupt enable\n");
1089                                    exit(1);
1090                            }
1091                    }
1092                    break;
1093    
1094    
1095          /*************************************************/          /*************************************************/
1096    
1097          default:if (writeflag == MEM_READ) {          default:if (writeflag == MEM_READ) {
# Line 731  DEVICE_ACCESS(sh4) Line 1101  DEVICE_ACCESS(sh4)
1101                          fatal("[ sh4: write to addr 0x%x: 0x%x ]\n",                          fatal("[ sh4: write to addr 0x%x: 0x%x ]\n",
1102                              (int)relative_addr, (int)idata);                              (int)relative_addr, (int)idata);
1103                  }                  }
1104    #ifdef SH4_DEGUG
1105    //              exit(1);
1106    #endif
1107          }          }
1108    
1109          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)
# Line 742  DEVICE_ACCESS(sh4) Line 1115  DEVICE_ACCESS(sh4)
1115    
1116  DEVINIT(sh4)  DEVINIT(sh4)
1117  {  {
1118            char tmp[200];
1119          struct machine *machine = devinit->machine;          struct machine *machine = devinit->machine;
1120          struct sh4_data *d = malloc(sizeof(struct sh4_data));          struct sh4_data *d = malloc(sizeof(struct sh4_data));
1121          if (d == NULL) {          if (d == NULL) {
# Line 753  DEVINIT(sh4) Line 1127  DEVINIT(sh4)
1127          d->scif_console_handle = console_start_slave(devinit->machine,          d->scif_console_handle = console_start_slave(devinit->machine,
1128              "SH4 SCIF", 1);              "SH4 SCIF", 1);
1129    
1130            snprintf(tmp, sizeof(tmp), "%s.irq[0x%x]",
1131                devinit->interrupt_path, SH4_INTEVT_SCIF_RXI);
1132            INTERRUPT_CONNECT(tmp, d->scif_rx_irq);
1133            snprintf(tmp, sizeof(tmp), "%s.irq[0x%x]",
1134                devinit->interrupt_path, SH4_INTEVT_SCIF_TXI);
1135            INTERRUPT_CONNECT(tmp, d->scif_tx_irq);
1136    
1137          memory_device_register(machine->memory, devinit->name,          memory_device_register(machine->memory, devinit->name,
1138              SH4_REG_BASE, 0x01000000, dev_sh4_access, d, DM_DEFAULT, NULL);              SH4_REG_BASE, 0x01000000, dev_sh4_access, d, DM_DEFAULT, NULL);
1139    
# Line 770  DEVINIT(sh4) Line 1151  DEVINIT(sh4)
1151           *           *
1152           *  TODO: Implement more correct cache behaviour?           *  TODO: Implement more correct cache behaviour?
1153           */           */
1154          dev_ram_init(machine, SH4_CCIA, SH4_ICACHE_SIZE, DEV_RAM_RAM, 0x0);          dev_ram_init(machine, SH4_CCIA, SH4_ICACHE_SIZE * 2, DEV_RAM_RAM, 0x0);
1155          dev_ram_init(machine, SH4_CCID, SH4_ICACHE_SIZE, DEV_RAM_RAM, 0x0);          dev_ram_init(machine, SH4_CCID, SH4_ICACHE_SIZE,     DEV_RAM_RAM, 0x0);
1156          dev_ram_init(machine, SH4_CCDA, SH4_DCACHE_SIZE, DEV_RAM_RAM, 0x0);          dev_ram_init(machine, SH4_CCDA, SH4_DCACHE_SIZE * 2, DEV_RAM_RAM, 0x0);
1157          dev_ram_init(machine, SH4_CCDD, SH4_DCACHE_SIZE, DEV_RAM_RAM, 0x0);          dev_ram_init(machine, SH4_CCDD, SH4_DCACHE_SIZE,     DEV_RAM_RAM, 0x0);
1158    
1159          /*  0xf2000000  SH4_ITLB_AA  */          /*  0xf2000000  SH4_ITLB_AA  */
1160          memory_device_register(machine->memory, devinit->name, SH4_ITLB_AA,          memory_device_register(machine->memory, devinit->name, SH4_ITLB_AA,
# Line 800  DEVINIT(sh4) Line 1181  DEVINIT(sh4)
1181          d->tcor[1] = 0xffffffff; d->tcnt[1] = 0xffffffff;          d->tcor[1] = 0xffffffff; d->tcnt[1] = 0xffffffff;
1182          d->tcor[2] = 0xffffffff; d->tcnt[2] = 0xffffffff;          d->tcor[2] = 0xffffffff; d->tcnt[2] = 0xffffffff;
1183    
1184            snprintf(tmp, sizeof(tmp), "emul[0].machine[0].cpu[0].irq[0x%x]",
1185                SH_INTEVT_TMU0_TUNI0);
1186            if (!interrupt_handler_lookup(tmp, &d->timer_irq[0])) {
1187                    fatal("Could not find interrupt '%s'.\n", tmp);
1188                    exit(1);
1189            }
1190            snprintf(tmp, sizeof(tmp), "emul[0].machine[0].cpu[0].irq[0x%x]",
1191                SH_INTEVT_TMU1_TUNI1);
1192            if (!interrupt_handler_lookup(tmp, &d->timer_irq[1])) {
1193                    fatal("Could not find interrupt '%s'.\n", tmp);
1194                    exit(1);
1195            }
1196            snprintf(tmp, sizeof(tmp), "emul[0].machine[0].cpu[0].irq[0x%x]",
1197                SH_INTEVT_TMU2_TUNI2);
1198            if (!interrupt_handler_lookup(tmp, &d->timer_irq[2])) {
1199                    fatal("Could not find interrupt '%s'.\n", tmp);
1200                    exit(1);
1201            }
1202    
1203            /*  Bus State Controller initial values:  */
1204            d->bsc_bcr2 = 0x3ffc;
1205            d->bsc_wcr1 = 0x77777777;
1206            d->bsc_wcr2 = 0xfffeefff;
1207    
1208          return 1;          return 1;
1209  }  }
1210    

Legend:
Removed from v.32  
changed lines
  Added in v.36

  ViewVC Help
Powered by ViewVC 1.1.26