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 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
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
.