Search
lxdream.org :: lxdream/src/sh4/sh4mmio.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4mmio.c
changeset 1:eea311cfd33e
next10:c898b37506e0
author nkeynes
date Sat Oct 02 05:49:39 2004 +0000 (19 years ago)
permissions -rw-r--r--
last change compile fix
file annotate diff log raw
nkeynes@1
     1
#include "dream.h"
nkeynes@1
     2
#include "mem.h"
nkeynes@1
     3
#include "sh4core.h"
nkeynes@1
     4
#include "sh4mmio.h"
nkeynes@1
     5
#define MMIO_IMPL
nkeynes@1
     6
#include "sh4mmio.h"
nkeynes@1
     7
nkeynes@1
     8
/********************************* MMU *************************************/
nkeynes@1
     9
nkeynes@1
    10
MMIO_REGION_READ_STUBFN( MMU )
nkeynes@1
    11
nkeynes@1
    12
void mmio_region_MMU_write( uint32_t reg, uint32_t val )
nkeynes@1
    13
{
nkeynes@1
    14
    switch(reg) {
nkeynes@1
    15
        case CCR:
nkeynes@1
    16
            mem_set_cache_mode( val & (CCR_OIX|CCR_ORA) );
nkeynes@1
    17
            INFO( "Cache mode set to %08X", val );
nkeynes@1
    18
            break;
nkeynes@1
    19
        default:
nkeynes@1
    20
            break;
nkeynes@1
    21
    }
nkeynes@1
    22
    MMIO_WRITE( MMU, reg, val );
nkeynes@1
    23
}
nkeynes@1
    24
nkeynes@1
    25
nkeynes@1
    26
/********************************* BSC *************************************/
nkeynes@1
    27
nkeynes@1
    28
uint16_t bsc_output_mask_lo = 0, bsc_output_mask_hi = 0;
nkeynes@1
    29
uint16_t bsc_input_mask_lo = 0, bsc_input_mask_hi = 0;
nkeynes@1
    30
uint32_t bsc_output = 0, bsc_input = 0x0300;
nkeynes@1
    31
nkeynes@1
    32
void bsc_out( int output, int mask )
nkeynes@1
    33
{
nkeynes@1
    34
    /* Go figure... The BIOS won't start without this mess though */
nkeynes@1
    35
    if( ((output | (~mask)) & 0x03) == 3 ) {
nkeynes@1
    36
        bsc_output |= 0x03;
nkeynes@1
    37
    } else {
nkeynes@1
    38
        bsc_output &= ~0x03;
nkeynes@1
    39
    }
nkeynes@1
    40
}
nkeynes@1
    41
nkeynes@1
    42
void mmio_region_BSC_write( uint32_t reg, uint32_t val )
nkeynes@1
    43
{
nkeynes@1
    44
    int i;
nkeynes@1
    45
    switch( reg ) {
nkeynes@1
    46
        case PCTRA:
nkeynes@1
    47
            bsc_input_mask_lo = bsc_output_mask_lo = 0;
nkeynes@1
    48
            for( i=0; i<16; i++ ) {
nkeynes@1
    49
                int bits = (val >> (i<<1)) & 0x03;
nkeynes@1
    50
                if( bits == 2 ) bsc_input_mask_lo |= (1<<i);
nkeynes@1
    51
                else if( bits != 0 ) bsc_output_mask_lo |= (1<<i);
nkeynes@1
    52
            }
nkeynes@1
    53
            bsc_output = (bsc_output&0x000F0000) |
nkeynes@1
    54
                (MMIO_READ( BSC, PDTRA ) & bsc_output_mask_lo);
nkeynes@1
    55
            bsc_out( MMIO_READ( BSC, PDTRA ) | ((MMIO_READ(BSC,PDTRB)<<16)),
nkeynes@1
    56
                     bsc_output_mask_lo | (bsc_output_mask_hi<<16) );
nkeynes@1
    57
            break;
nkeynes@1
    58
        case PCTRB:
nkeynes@1
    59
            bsc_input_mask_hi = bsc_output_mask_hi = 0;
nkeynes@1
    60
            for( i=0; i<4; i++ ) {
nkeynes@1
    61
                int bits = (val >> (i>>1)) & 0x03;
nkeynes@1
    62
                if( bits == 2 ) bsc_input_mask_hi |= (1<<i);
nkeynes@1
    63
                else if( bits != 0 ) bsc_output_mask_hi |= (1<<i);
nkeynes@1
    64
            }
nkeynes@1
    65
            bsc_output = (bsc_output&0xFFFF) |
nkeynes@1
    66
                ((MMIO_READ( BSC, PDTRA ) & bsc_output_mask_hi)<<16);
nkeynes@1
    67
            break;
nkeynes@1
    68
        case PDTRA:
nkeynes@1
    69
            bsc_output = (bsc_output&0x000F0000) |
nkeynes@1
    70
                (val & bsc_output_mask_lo );
nkeynes@1
    71
            bsc_out( val | ((MMIO_READ(BSC,PDTRB)<<16)),
nkeynes@1
    72
                     bsc_output_mask_lo | (bsc_output_mask_hi<<16) );
nkeynes@1
    73
            break;
nkeynes@1
    74
        case PDTRB:
nkeynes@1
    75
            bsc_output = (bsc_output&0xFFFF) |
nkeynes@1
    76
                ( (val & bsc_output_mask_hi)<<16 );
nkeynes@1
    77
            break;
nkeynes@1
    78
    }
nkeynes@1
    79
    WARN( "Write to (mostly) unimplemented BSC (%03X <= %08X) [%s: %s]",
nkeynes@1
    80
          reg, val, MMIO_REGID(BSC,reg), MMIO_REGDESC(BSC,reg) );
nkeynes@1
    81
    MMIO_WRITE( BSC, reg, val );
nkeynes@1
    82
}
nkeynes@1
    83
nkeynes@1
    84
int32_t mmio_region_BSC_read( uint32_t reg )
nkeynes@1
    85
{
nkeynes@1
    86
    int32_t val;
nkeynes@1
    87
    switch( reg ) {
nkeynes@1
    88
        case PDTRA:
nkeynes@1
    89
            val = (bsc_input & bsc_input_mask_lo) | (bsc_output&0xFFFF);
nkeynes@1
    90
            break;
nkeynes@1
    91
        case PDTRB:
nkeynes@1
    92
            val = ((bsc_input>>16) & bsc_input_mask_hi) | (bsc_output>>16);
nkeynes@1
    93
            break;
nkeynes@1
    94
        default:
nkeynes@1
    95
            val = MMIO_READ( BSC, reg );
nkeynes@1
    96
    }
nkeynes@1
    97
    WARN( "Read from (mostly) unimplemented BSC (%03X => %08X) [%s: %s]",
nkeynes@1
    98
          reg, val, MMIO_REGID(BSC,reg), MMIO_REGDESC(BSC,reg) );
nkeynes@1
    99
    return val;
nkeynes@1
   100
}
nkeynes@1
   101
nkeynes@1
   102
/********************************* UBC *************************************/
nkeynes@1
   103
nkeynes@1
   104
MMIO_REGION_STUBFNS( UBC )
nkeynes@1
   105
nkeynes@1
   106
/********************************* CPG *************************************/
nkeynes@1
   107
nkeynes@1
   108
MMIO_REGION_STUBFNS( CPG )
nkeynes@1
   109
nkeynes@1
   110
/********************************* DMAC *************************************/
nkeynes@1
   111
nkeynes@1
   112
MMIO_REGION_STUBFNS( DMAC )
nkeynes@1
   113
nkeynes@1
   114
/********************************** RTC *************************************/
nkeynes@1
   115
nkeynes@1
   116
MMIO_REGION_STUBFNS( RTC )
nkeynes@1
   117
nkeynes@1
   118
/********************************** TMU *************************************/
nkeynes@1
   119
nkeynes@1
   120
int timer_divider[3] = {16,16,16};
nkeynes@1
   121
MMIO_REGION_READ_DEFFN( TMU )
nkeynes@1
   122
nkeynes@1
   123
int get_timer_div( int val )
nkeynes@1
   124
{
nkeynes@1
   125
    switch( val & 0x07 ) {
nkeynes@1
   126
        case 0: return 16; /* assume peripheral clock is IC/4 */
nkeynes@1
   127
        case 1: return 64;
nkeynes@1
   128
        case 2: return 256;
nkeynes@1
   129
        case 3: return 1024;
nkeynes@1
   130
        case 4: return 4096;
nkeynes@1
   131
    }
nkeynes@1
   132
    return 1;
nkeynes@1
   133
}
nkeynes@1
   134
nkeynes@1
   135
void mmio_region_TMU_write( uint32_t reg, uint32_t val )
nkeynes@1
   136
{
nkeynes@1
   137
    switch( reg ) {
nkeynes@1
   138
        case TCR0:
nkeynes@1
   139
            timer_divider[0] = get_timer_div(val);
nkeynes@1
   140
            break;
nkeynes@1
   141
        case TCR1:
nkeynes@1
   142
            timer_divider[1] = get_timer_div(val);
nkeynes@1
   143
            break;
nkeynes@1
   144
        case TCR2:
nkeynes@1
   145
            timer_divider[2] = get_timer_div(val);
nkeynes@1
   146
            break;
nkeynes@1
   147
    }
nkeynes@1
   148
    MMIO_WRITE( TMU, reg, val );
nkeynes@1
   149
}
nkeynes@1
   150
nkeynes@1
   151
void run_timers( int cycles )
nkeynes@1
   152
{
nkeynes@1
   153
    int tcr = MMIO_READ( TMU, TSTR );
nkeynes@1
   154
    cycles *= 16;
nkeynes@1
   155
    if( tcr & 1 ) {
nkeynes@1
   156
        int count = cycles / timer_divider[0];
nkeynes@1
   157
        int *val = MMIO_REG( TMU, TCNT0 );
nkeynes@1
   158
        if( *val < count ) {
nkeynes@1
   159
            MMIO_READ( TMU, TCR0 ) |= 0x100;
nkeynes@1
   160
            /* interrupt goes here */
nkeynes@1
   161
            count -= *val;
nkeynes@1
   162
            *val = MMIO_READ( TMU, TCOR0 ) - count;
nkeynes@1
   163
        } else {
nkeynes@1
   164
            *val -= count;
nkeynes@1
   165
        }
nkeynes@1
   166
    }
nkeynes@1
   167
}
nkeynes@1
   168
nkeynes@1
   169
/********************************** SCI *************************************/
nkeynes@1
   170
nkeynes@1
   171
MMIO_REGION_STUBFNS( SCI )
nkeynes@1
   172
nkeynes@1
   173
/********************************* SCIF *************************************/
nkeynes@1
   174
nkeynes@1
   175
MMIO_REGION_STUBFNS( SCIF )
nkeynes@1
   176
.