Search
lxdream.org :: lxdream/src/sh4/sh4mmio.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4mmio.c
changeset 1:eea311cfd33e
next10:c898b37506e0
author nkeynes
date Thu Dec 08 13:38:00 2005 +0000 (18 years ago)
permissions -rw-r--r--
last change Generalise the core debug window to allow multiple instances.
Add cpu description structure to define different cpus for use by the
debug window, in preparation for ARM implementation
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/sh4/sh4mmio.c Thu Dec 08 13:38:00 2005 +0000
1.3 @@ -0,0 +1,176 @@
1.4 +#include "dream.h"
1.5 +#include "mem.h"
1.6 +#include "sh4core.h"
1.7 +#include "sh4mmio.h"
1.8 +#define MMIO_IMPL
1.9 +#include "sh4mmio.h"
1.10 +
1.11 +/********************************* MMU *************************************/
1.12 +
1.13 +MMIO_REGION_READ_STUBFN( MMU )
1.14 +
1.15 +void mmio_region_MMU_write( uint32_t reg, uint32_t val )
1.16 +{
1.17 + switch(reg) {
1.18 + case CCR:
1.19 + mem_set_cache_mode( val & (CCR_OIX|CCR_ORA) );
1.20 + INFO( "Cache mode set to %08X", val );
1.21 + break;
1.22 + default:
1.23 + break;
1.24 + }
1.25 + MMIO_WRITE( MMU, reg, val );
1.26 +}
1.27 +
1.28 +
1.29 +/********************************* BSC *************************************/
1.30 +
1.31 +uint16_t bsc_output_mask_lo = 0, bsc_output_mask_hi = 0;
1.32 +uint16_t bsc_input_mask_lo = 0, bsc_input_mask_hi = 0;
1.33 +uint32_t bsc_output = 0, bsc_input = 0x0300;
1.34 +
1.35 +void bsc_out( int output, int mask )
1.36 +{
1.37 + /* Go figure... The BIOS won't start without this mess though */
1.38 + if( ((output | (~mask)) & 0x03) == 3 ) {
1.39 + bsc_output |= 0x03;
1.40 + } else {
1.41 + bsc_output &= ~0x03;
1.42 + }
1.43 +}
1.44 +
1.45 +void mmio_region_BSC_write( uint32_t reg, uint32_t val )
1.46 +{
1.47 + int i;
1.48 + switch( reg ) {
1.49 + case PCTRA:
1.50 + bsc_input_mask_lo = bsc_output_mask_lo = 0;
1.51 + for( i=0; i<16; i++ ) {
1.52 + int bits = (val >> (i<<1)) & 0x03;
1.53 + if( bits == 2 ) bsc_input_mask_lo |= (1<<i);
1.54 + else if( bits != 0 ) bsc_output_mask_lo |= (1<<i);
1.55 + }
1.56 + bsc_output = (bsc_output&0x000F0000) |
1.57 + (MMIO_READ( BSC, PDTRA ) & bsc_output_mask_lo);
1.58 + bsc_out( MMIO_READ( BSC, PDTRA ) | ((MMIO_READ(BSC,PDTRB)<<16)),
1.59 + bsc_output_mask_lo | (bsc_output_mask_hi<<16) );
1.60 + break;
1.61 + case PCTRB:
1.62 + bsc_input_mask_hi = bsc_output_mask_hi = 0;
1.63 + for( i=0; i<4; i++ ) {
1.64 + int bits = (val >> (i>>1)) & 0x03;
1.65 + if( bits == 2 ) bsc_input_mask_hi |= (1<<i);
1.66 + else if( bits != 0 ) bsc_output_mask_hi |= (1<<i);
1.67 + }
1.68 + bsc_output = (bsc_output&0xFFFF) |
1.69 + ((MMIO_READ( BSC, PDTRA ) & bsc_output_mask_hi)<<16);
1.70 + break;
1.71 + case PDTRA:
1.72 + bsc_output = (bsc_output&0x000F0000) |
1.73 + (val & bsc_output_mask_lo );
1.74 + bsc_out( val | ((MMIO_READ(BSC,PDTRB)<<16)),
1.75 + bsc_output_mask_lo | (bsc_output_mask_hi<<16) );
1.76 + break;
1.77 + case PDTRB:
1.78 + bsc_output = (bsc_output&0xFFFF) |
1.79 + ( (val & bsc_output_mask_hi)<<16 );
1.80 + break;
1.81 + }
1.82 + WARN( "Write to (mostly) unimplemented BSC (%03X <= %08X) [%s: %s]",
1.83 + reg, val, MMIO_REGID(BSC,reg), MMIO_REGDESC(BSC,reg) );
1.84 + MMIO_WRITE( BSC, reg, val );
1.85 +}
1.86 +
1.87 +int32_t mmio_region_BSC_read( uint32_t reg )
1.88 +{
1.89 + int32_t val;
1.90 + switch( reg ) {
1.91 + case PDTRA:
1.92 + val = (bsc_input & bsc_input_mask_lo) | (bsc_output&0xFFFF);
1.93 + break;
1.94 + case PDTRB:
1.95 + val = ((bsc_input>>16) & bsc_input_mask_hi) | (bsc_output>>16);
1.96 + break;
1.97 + default:
1.98 + val = MMIO_READ( BSC, reg );
1.99 + }
1.100 + WARN( "Read from (mostly) unimplemented BSC (%03X => %08X) [%s: %s]",
1.101 + reg, val, MMIO_REGID(BSC,reg), MMIO_REGDESC(BSC,reg) );
1.102 + return val;
1.103 +}
1.104 +
1.105 +/********************************* UBC *************************************/
1.106 +
1.107 +MMIO_REGION_STUBFNS( UBC )
1.108 +
1.109 +/********************************* CPG *************************************/
1.110 +
1.111 +MMIO_REGION_STUBFNS( CPG )
1.112 +
1.113 +/********************************* DMAC *************************************/
1.114 +
1.115 +MMIO_REGION_STUBFNS( DMAC )
1.116 +
1.117 +/********************************** RTC *************************************/
1.118 +
1.119 +MMIO_REGION_STUBFNS( RTC )
1.120 +
1.121 +/********************************** TMU *************************************/
1.122 +
1.123 +int timer_divider[3] = {16,16,16};
1.124 +MMIO_REGION_READ_DEFFN( TMU )
1.125 +
1.126 +int get_timer_div( int val )
1.127 +{
1.128 + switch( val & 0x07 ) {
1.129 + case 0: return 16; /* assume peripheral clock is IC/4 */
1.130 + case 1: return 64;
1.131 + case 2: return 256;
1.132 + case 3: return 1024;
1.133 + case 4: return 4096;
1.134 + }
1.135 + return 1;
1.136 +}
1.137 +
1.138 +void mmio_region_TMU_write( uint32_t reg, uint32_t val )
1.139 +{
1.140 + switch( reg ) {
1.141 + case TCR0:
1.142 + timer_divider[0] = get_timer_div(val);
1.143 + break;
1.144 + case TCR1:
1.145 + timer_divider[1] = get_timer_div(val);
1.146 + break;
1.147 + case TCR2:
1.148 + timer_divider[2] = get_timer_div(val);
1.149 + break;
1.150 + }
1.151 + MMIO_WRITE( TMU, reg, val );
1.152 +}
1.153 +
1.154 +void run_timers( int cycles )
1.155 +{
1.156 + int tcr = MMIO_READ( TMU, TSTR );
1.157 + cycles *= 16;
1.158 + if( tcr & 1 ) {
1.159 + int count = cycles / timer_divider[0];
1.160 + int *val = MMIO_REG( TMU, TCNT0 );
1.161 + if( *val < count ) {
1.162 + MMIO_READ( TMU, TCR0 ) |= 0x100;
1.163 + /* interrupt goes here */
1.164 + count -= *val;
1.165 + *val = MMIO_READ( TMU, TCOR0 ) - count;
1.166 + } else {
1.167 + *val -= count;
1.168 + }
1.169 + }
1.170 +}
1.171 +
1.172 +/********************************** SCI *************************************/
1.173 +
1.174 +MMIO_REGION_STUBFNS( SCI )
1.175 +
1.176 +/********************************* SCIF *************************************/
1.177 +
1.178 +MMIO_REGION_STUBFNS( SCIF )
1.179 +
.