Search
lxdream.org :: lxdream/src/sh4/sh4mmio.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4mmio.c
changeset 166:8aa70cf503a2
prev92:108450d84ce8
next312:2c34bdc36cbd
author nkeynes
date Fri Dec 15 10:17:08 2006 +0000 (17 years ago)
permissions -rw-r--r--
last change Add UI for the trace flag
file annotate diff log raw
nkeynes@30
     1
/**
nkeynes@166
     2
 * $Id: sh4mmio.c,v 1.9 2006-06-18 12:01:53 nkeynes Exp $
nkeynes@30
     3
 * 
nkeynes@30
     4
 * Miscellaneous and not-really-implemented SH4 peripheral modules. Also
nkeynes@30
     5
 * responsible for including the IMPL side of the SH4 MMIO pages.
nkeynes@30
     6
 * Most of these will eventually be split off into their own files.
nkeynes@30
     7
 *
nkeynes@30
     8
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@30
     9
 *
nkeynes@30
    10
 * This program is free software; you can redistribute it and/or modify
nkeynes@30
    11
 * it under the terms of the GNU General Public License as published by
nkeynes@30
    12
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@30
    13
 * (at your option) any later version.
nkeynes@30
    14
 *
nkeynes@30
    15
 * This program is distributed in the hope that it will be useful,
nkeynes@30
    16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@30
    17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@30
    18
 * GNU General Public License for more details.
nkeynes@30
    19
 */
nkeynes@35
    20
#define MODULE sh4_module
nkeynes@30
    21
nkeynes@1
    22
#include "dream.h"
nkeynes@1
    23
#include "mem.h"
nkeynes@19
    24
#include "clock.h"
nkeynes@1
    25
#include "sh4core.h"
nkeynes@1
    26
#include "sh4mmio.h"
nkeynes@1
    27
#define MMIO_IMPL
nkeynes@1
    28
#include "sh4mmio.h"
nkeynes@1
    29
nkeynes@1
    30
/********************************* MMU *************************************/
nkeynes@1
    31
nkeynes@92
    32
MMIO_REGION_READ_DEFFN( MMU )
nkeynes@1
    33
nkeynes@10
    34
#define OCRAM_START (0x1C000000>>PAGE_BITS)
nkeynes@10
    35
#define OCRAM_END   (0x20000000>>PAGE_BITS)
nkeynes@10
    36
nkeynes@10
    37
static char *cache = NULL;
nkeynes@10
    38
nkeynes@1
    39
void mmio_region_MMU_write( uint32_t reg, uint32_t val )
nkeynes@1
    40
{
nkeynes@1
    41
    switch(reg) {
nkeynes@1
    42
        case CCR:
nkeynes@10
    43
            mmu_set_cache_mode( val & (CCR_OIX|CCR_ORA) );
nkeynes@1
    44
            break;
nkeynes@1
    45
        default:
nkeynes@1
    46
            break;
nkeynes@1
    47
    }
nkeynes@1
    48
    MMIO_WRITE( MMU, reg, val );
nkeynes@1
    49
}
nkeynes@1
    50
nkeynes@1
    51
nkeynes@10
    52
void mmu_init() 
nkeynes@10
    53
{
nkeynes@19
    54
    cache = mem_alloc_pages(2);
nkeynes@10
    55
}
nkeynes@10
    56
nkeynes@10
    57
void mmu_set_cache_mode( int mode )
nkeynes@10
    58
{
nkeynes@10
    59
    uint32_t i;
nkeynes@10
    60
    switch( mode ) {
nkeynes@10
    61
        case MEM_OC_INDEX0: /* OIX=0 */
nkeynes@10
    62
            for( i=OCRAM_START; i<OCRAM_END; i++ )
nkeynes@10
    63
                page_map[i] = cache + ((i&0x02)<<(PAGE_BITS-1));
nkeynes@10
    64
            break;
nkeynes@10
    65
        case MEM_OC_INDEX1: /* OIX=1 */
nkeynes@10
    66
            for( i=OCRAM_START; i<OCRAM_END; i++ )
nkeynes@10
    67
                page_map[i] = cache + ((i&0x02000000)>>(25-PAGE_BITS));
nkeynes@10
    68
            break;
nkeynes@10
    69
        default: /* disabled */
nkeynes@10
    70
            for( i=OCRAM_START; i<OCRAM_END; i++ )
nkeynes@10
    71
                page_map[i] = NULL;
nkeynes@10
    72
            break;
nkeynes@10
    73
    }
nkeynes@10
    74
}
nkeynes@10
    75
nkeynes@10
    76
nkeynes@1
    77
/********************************* BSC *************************************/
nkeynes@1
    78
nkeynes@1
    79
uint16_t bsc_output_mask_lo = 0, bsc_output_mask_hi = 0;
nkeynes@1
    80
uint16_t bsc_input_mask_lo = 0, bsc_input_mask_hi = 0;
nkeynes@1
    81
uint32_t bsc_output = 0, bsc_input = 0x0300;
nkeynes@1
    82
nkeynes@1
    83
void bsc_out( int output, int mask )
nkeynes@1
    84
{
nkeynes@1
    85
    /* Go figure... The BIOS won't start without this mess though */
nkeynes@1
    86
    if( ((output | (~mask)) & 0x03) == 3 ) {
nkeynes@1
    87
        bsc_output |= 0x03;
nkeynes@1
    88
    } else {
nkeynes@1
    89
        bsc_output &= ~0x03;
nkeynes@1
    90
    }
nkeynes@1
    91
}
nkeynes@1
    92
nkeynes@1
    93
void mmio_region_BSC_write( uint32_t reg, uint32_t val )
nkeynes@1
    94
{
nkeynes@1
    95
    int i;
nkeynes@1
    96
    switch( reg ) {
nkeynes@1
    97
        case PCTRA:
nkeynes@1
    98
            bsc_input_mask_lo = bsc_output_mask_lo = 0;
nkeynes@1
    99
            for( i=0; i<16; i++ ) {
nkeynes@1
   100
                int bits = (val >> (i<<1)) & 0x03;
nkeynes@1
   101
                if( bits == 2 ) bsc_input_mask_lo |= (1<<i);
nkeynes@1
   102
                else if( bits != 0 ) bsc_output_mask_lo |= (1<<i);
nkeynes@1
   103
            }
nkeynes@1
   104
            bsc_output = (bsc_output&0x000F0000) |
nkeynes@1
   105
                (MMIO_READ( BSC, PDTRA ) & bsc_output_mask_lo);
nkeynes@1
   106
            bsc_out( MMIO_READ( BSC, PDTRA ) | ((MMIO_READ(BSC,PDTRB)<<16)),
nkeynes@1
   107
                     bsc_output_mask_lo | (bsc_output_mask_hi<<16) );
nkeynes@1
   108
            break;
nkeynes@1
   109
        case PCTRB:
nkeynes@1
   110
            bsc_input_mask_hi = bsc_output_mask_hi = 0;
nkeynes@1
   111
            for( i=0; i<4; i++ ) {
nkeynes@1
   112
                int bits = (val >> (i>>1)) & 0x03;
nkeynes@1
   113
                if( bits == 2 ) bsc_input_mask_hi |= (1<<i);
nkeynes@1
   114
                else if( bits != 0 ) bsc_output_mask_hi |= (1<<i);
nkeynes@1
   115
            }
nkeynes@1
   116
            bsc_output = (bsc_output&0xFFFF) |
nkeynes@1
   117
                ((MMIO_READ( BSC, PDTRA ) & bsc_output_mask_hi)<<16);
nkeynes@1
   118
            break;
nkeynes@1
   119
        case PDTRA:
nkeynes@1
   120
            bsc_output = (bsc_output&0x000F0000) |
nkeynes@1
   121
                (val & bsc_output_mask_lo );
nkeynes@1
   122
            bsc_out( val | ((MMIO_READ(BSC,PDTRB)<<16)),
nkeynes@1
   123
                     bsc_output_mask_lo | (bsc_output_mask_hi<<16) );
nkeynes@1
   124
            break;
nkeynes@1
   125
        case PDTRB:
nkeynes@1
   126
            bsc_output = (bsc_output&0xFFFF) |
nkeynes@1
   127
                ( (val & bsc_output_mask_hi)<<16 );
nkeynes@1
   128
            break;
nkeynes@1
   129
    }
nkeynes@1
   130
    WARN( "Write to (mostly) unimplemented BSC (%03X <= %08X) [%s: %s]",
nkeynes@1
   131
          reg, val, MMIO_REGID(BSC,reg), MMIO_REGDESC(BSC,reg) );
nkeynes@1
   132
    MMIO_WRITE( BSC, reg, val );
nkeynes@1
   133
}
nkeynes@1
   134
nkeynes@1
   135
int32_t mmio_region_BSC_read( uint32_t reg )
nkeynes@1
   136
{
nkeynes@1
   137
    int32_t val;
nkeynes@1
   138
    switch( reg ) {
nkeynes@1
   139
        case PDTRA:
nkeynes@1
   140
            val = (bsc_input & bsc_input_mask_lo) | (bsc_output&0xFFFF);
nkeynes@1
   141
            break;
nkeynes@1
   142
        case PDTRB:
nkeynes@1
   143
            val = ((bsc_input>>16) & bsc_input_mask_hi) | (bsc_output>>16);
nkeynes@1
   144
            break;
nkeynes@1
   145
        default:
nkeynes@1
   146
            val = MMIO_READ( BSC, reg );
nkeynes@1
   147
    }
nkeynes@1
   148
    WARN( "Read from (mostly) unimplemented BSC (%03X => %08X) [%s: %s]",
nkeynes@1
   149
          reg, val, MMIO_REGID(BSC,reg), MMIO_REGDESC(BSC,reg) );
nkeynes@1
   150
    return val;
nkeynes@1
   151
}
nkeynes@1
   152
nkeynes@1
   153
/********************************* UBC *************************************/
nkeynes@1
   154
nkeynes@1
   155
MMIO_REGION_STUBFNS( UBC )
nkeynes@1
   156
nkeynes@1
   157
nkeynes@1
   158
/********************************** SCI *************************************/
nkeynes@1
   159
nkeynes@1
   160
MMIO_REGION_STUBFNS( SCI )
nkeynes@1
   161
.