Search
lxdream.org :: lxdream/src/sh4/sh4mmio.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4mmio.c
changeset 428:338966c8aed0
prev413:bff683bc5228
next502:c4ecae2b1b5e
author nkeynes
date Wed Nov 07 11:45:53 2007 +0000 (16 years ago)
permissions -rw-r--r--
last change Add crash handler to get a backtrace via gdb
file annotate diff log raw
nkeynes@30
     1
/**
nkeynes@428
     2
 * $Id: sh4mmio.c,v 1.14 2007-10-07 06:27:12 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@428
    23
#include "dreamcast.h"
nkeynes@1
    24
#include "mem.h"
nkeynes@19
    25
#include "clock.h"
nkeynes@428
    26
#include "sh4/sh4core.h"
nkeynes@428
    27
#include "sh4/sh4mmio.h"
nkeynes@1
    28
#define MMIO_IMPL
nkeynes@428
    29
#include "sh4/sh4mmio.h"
nkeynes@1
    30
nkeynes@1
    31
/********************************* MMU *************************************/
nkeynes@1
    32
nkeynes@92
    33
MMIO_REGION_READ_DEFFN( MMU )
nkeynes@1
    34
nkeynes@10
    35
#define OCRAM_START (0x1C000000>>PAGE_BITS)
nkeynes@10
    36
#define OCRAM_END   (0x20000000>>PAGE_BITS)
nkeynes@10
    37
nkeynes@10
    38
static char *cache = NULL;
nkeynes@10
    39
nkeynes@1
    40
void mmio_region_MMU_write( uint32_t reg, uint32_t val )
nkeynes@1
    41
{
nkeynes@1
    42
    switch(reg) {
nkeynes@413
    43
    case MMUCR:
nkeynes@413
    44
	if( val & MMUCR_AT ) {
nkeynes@413
    45
	    ERROR( "MMU Address translation not implemented!" );
nkeynes@413
    46
	    dreamcast_stop();
nkeynes@413
    47
	}
nkeynes@413
    48
	break;
nkeynes@413
    49
    case CCR:
nkeynes@413
    50
	mmu_set_cache_mode( val & (CCR_OIX|CCR_ORA) );
nkeynes@413
    51
	break;
nkeynes@413
    52
    default:
nkeynes@413
    53
	break;
nkeynes@1
    54
    }
nkeynes@1
    55
    MMIO_WRITE( MMU, reg, val );
nkeynes@1
    56
}
nkeynes@1
    57
nkeynes@1
    58
nkeynes@312
    59
void MMU_init() 
nkeynes@10
    60
{
nkeynes@19
    61
    cache = mem_alloc_pages(2);
nkeynes@10
    62
}
nkeynes@10
    63
nkeynes@312
    64
void MMU_reset()
nkeynes@312
    65
{
nkeynes@312
    66
    mmio_region_MMU_write( CCR, 0 );
nkeynes@312
    67
}
nkeynes@312
    68
nkeynes@312
    69
void MMU_save_state( FILE *f )
nkeynes@312
    70
{
nkeynes@312
    71
    fwrite( cache, 4096, 2, f );
nkeynes@312
    72
}
nkeynes@312
    73
nkeynes@312
    74
int MMU_load_state( FILE *f )
nkeynes@312
    75
{
nkeynes@312
    76
    /* Setup the cache mode according to the saved register value
nkeynes@312
    77
     * (mem_load runs before this point to load all MMIO data)
nkeynes@312
    78
     */
nkeynes@312
    79
    mmio_region_MMU_write( CCR, MMIO_READ(MMU, CCR) );
nkeynes@312
    80
    if( fread( cache, 4096, 2, f ) != 2 ) {
nkeynes@312
    81
	return 1;
nkeynes@312
    82
    }
nkeynes@312
    83
    return 0;
nkeynes@312
    84
}
nkeynes@312
    85
nkeynes@10
    86
void mmu_set_cache_mode( int mode )
nkeynes@10
    87
{
nkeynes@10
    88
    uint32_t i;
nkeynes@10
    89
    switch( mode ) {
nkeynes@10
    90
        case MEM_OC_INDEX0: /* OIX=0 */
nkeynes@10
    91
            for( i=OCRAM_START; i<OCRAM_END; i++ )
nkeynes@10
    92
                page_map[i] = cache + ((i&0x02)<<(PAGE_BITS-1));
nkeynes@10
    93
            break;
nkeynes@10
    94
        case MEM_OC_INDEX1: /* OIX=1 */
nkeynes@10
    95
            for( i=OCRAM_START; i<OCRAM_END; i++ )
nkeynes@10
    96
                page_map[i] = cache + ((i&0x02000000)>>(25-PAGE_BITS));
nkeynes@10
    97
            break;
nkeynes@10
    98
        default: /* disabled */
nkeynes@10
    99
            for( i=OCRAM_START; i<OCRAM_END; i++ )
nkeynes@10
   100
                page_map[i] = NULL;
nkeynes@10
   101
            break;
nkeynes@10
   102
    }
nkeynes@10
   103
}
nkeynes@10
   104
nkeynes@10
   105
nkeynes@1
   106
/********************************* BSC *************************************/
nkeynes@1
   107
nkeynes@323
   108
uint32_t bsc_input = 0x0300;
nkeynes@1
   109
nkeynes@323
   110
uint16_t bsc_read_pdtra()
nkeynes@1
   111
{
nkeynes@323
   112
    int i;
nkeynes@323
   113
    uint32_t pctra = MMIO_READ( BSC, PCTRA );
nkeynes@323
   114
    uint16_t output = MMIO_READ( BSC, PDTRA );
nkeynes@323
   115
    uint16_t input_mask = 0, output_mask = 0;
nkeynes@323
   116
    for( i=0; i<16; i++ ) {
nkeynes@323
   117
	int bits = (pctra >> (i<<1)) & 0x03;
nkeynes@323
   118
	if( bits == 2 ) input_mask |= (1<<i);
nkeynes@323
   119
	else if( bits != 0 ) output_mask |= (1<<i);
nkeynes@323
   120
    }
nkeynes@323
   121
nkeynes@323
   122
    /* ??? */
nkeynes@323
   123
    if( ((output | (~output_mask)) & 0x03) == 3 ) {
nkeynes@323
   124
        output |= 0x03;
nkeynes@1
   125
    } else {
nkeynes@323
   126
        output &= ~0x03;
nkeynes@1
   127
    }
nkeynes@323
   128
nkeynes@323
   129
    return (bsc_input & input_mask) | output;
nkeynes@1
   130
}
nkeynes@1
   131
nkeynes@323
   132
uint32_t bsc_read_pdtrb()
nkeynes@1
   133
{
nkeynes@1
   134
    int i;
nkeynes@323
   135
    uint32_t pctrb = MMIO_READ( BSC, PCTRB );
nkeynes@323
   136
    uint16_t output = MMIO_READ( BSC, PDTRB );
nkeynes@323
   137
    uint16_t input_mask = 0, output_mask = 0;
nkeynes@323
   138
    for( i=0; i<4; i++ ) {
nkeynes@323
   139
	int bits = (pctrb >> (i<<1)) & 0x03;
nkeynes@323
   140
	if( bits == 2 ) input_mask |= (1<<i);
nkeynes@323
   141
	else if( bits != 0 ) output_mask |= (1<<i);
nkeynes@1
   142
    }
nkeynes@323
   143
nkeynes@323
   144
    return ((bsc_input>>16) & input_mask) | output;
nkeynes@323
   145
nkeynes@1
   146
}
nkeynes@1
   147
nkeynes@336
   148
MMIO_REGION_WRITE_DEFFN(BSC)
nkeynes@323
   149
nkeynes@1
   150
int32_t mmio_region_BSC_read( uint32_t reg )
nkeynes@1
   151
{
nkeynes@1
   152
    int32_t val;
nkeynes@1
   153
    switch( reg ) {
nkeynes@1
   154
        case PDTRA:
nkeynes@323
   155
	    val = bsc_read_pdtra();
nkeynes@323
   156
	    break;
nkeynes@1
   157
        case PDTRB:
nkeynes@323
   158
	    val = bsc_read_pdtrb();
nkeynes@323
   159
	    break;
nkeynes@1
   160
        default:
nkeynes@1
   161
            val = MMIO_READ( BSC, reg );
nkeynes@1
   162
    }
nkeynes@1
   163
    return val;
nkeynes@1
   164
}
nkeynes@1
   165
nkeynes@1
   166
/********************************* UBC *************************************/
nkeynes@1
   167
nkeynes@1
   168
MMIO_REGION_STUBFNS( UBC )
nkeynes@1
   169
nkeynes@1
   170
nkeynes@1
   171
/********************************** SCI *************************************/
nkeynes@1
   172
nkeynes@1
   173
MMIO_REGION_STUBFNS( SCI )
nkeynes@1
   174
.