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 Sat Mar 13 00:03:32 2004 +0000 (16 years ago)
permissions -rw-r--r--
last change This commit was generated by cvs2svn to compensate for changes in r2,
which included commits to RCS files with non-trunk default branches.
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/sh4/sh4mmio.c Sat Mar 13 00:03:32 2004 +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 +
.