Search
lxdream.org :: lxdream/src/aica/armmem.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/armmem.c
changeset 1106:1879fd49ccf6
prev1067:d3c00ffccfcd
author nkeynes
date Fri Sep 17 20:08:50 2010 +1000 (13 years ago)
permissions -rw-r--r--
last change Refactor shader management to support multiple programs, which are all
defined in the shaders.glsl, rather than split up into one file per
fragment.
file annotate diff log raw
nkeynes@934
     1
/*`*
nkeynes@561
     2
 * $Id$
nkeynes@31
     3
 *
nkeynes@31
     4
 * Implements the ARM's memory map.
nkeynes@31
     5
 *
nkeynes@31
     6
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@31
     7
 *
nkeynes@31
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@31
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@31
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@31
    11
 * (at your option) any later version.
nkeynes@31
    12
 *
nkeynes@31
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@31
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@31
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@31
    16
 * GNU General Public License for more details.
nkeynes@31
    17
 */
nkeynes@31
    18
nkeynes@11
    19
#include <stdlib.h>
nkeynes@11
    20
#include "dream.h"
nkeynes@7
    21
#include "mem.h"
nkeynes@66
    22
#include "aica.h"
nkeynes@968
    23
#include "asic.h"
nkeynes@811
    24
#include "armcore.h"
nkeynes@7
    25
nkeynes@934
    26
unsigned char aica_main_ram[2 MB];
nkeynes@934
    27
unsigned char aica_scratch_ram[8 KB];
nkeynes@7
    28
nkeynes@931
    29
/*************** ARM memory access function blocks **************/
nkeynes@931
    30
nkeynes@931
    31
static int32_t FASTCALL ext_audioram_read_long( sh4addr_t addr )
nkeynes@931
    32
{
nkeynes@934
    33
    return *((int32_t *)(aica_main_ram + (addr&0x001FFFFF)));
nkeynes@931
    34
}
nkeynes@931
    35
static int32_t FASTCALL ext_audioram_read_word( sh4addr_t addr )
nkeynes@931
    36
{
nkeynes@934
    37
    return SIGNEXT16(*((int16_t *)(aica_main_ram + (addr&0x001FFFFF))));
nkeynes@931
    38
}
nkeynes@931
    39
static int32_t FASTCALL ext_audioram_read_byte( sh4addr_t addr )
nkeynes@931
    40
{
nkeynes@934
    41
    return SIGNEXT8(*((int16_t *)(aica_main_ram + (addr&0x001FFFFF))));
nkeynes@931
    42
}
nkeynes@931
    43
static void FASTCALL ext_audioram_write_long( sh4addr_t addr, uint32_t val )
nkeynes@931
    44
{
nkeynes@934
    45
    *(uint32_t *)(aica_main_ram + (addr&0x001FFFFF)) = val;
nkeynes@931
    46
    asic_g2_write_word();
nkeynes@931
    47
}
nkeynes@931
    48
static void FASTCALL ext_audioram_write_word( sh4addr_t addr, uint32_t val )
nkeynes@931
    49
{
nkeynes@934
    50
    *(uint16_t *)(aica_main_ram + (addr&0x001FFFFF)) = (uint16_t)val;
nkeynes@931
    51
    asic_g2_write_word();
nkeynes@931
    52
}
nkeynes@931
    53
static void FASTCALL ext_audioram_write_byte( sh4addr_t addr, uint32_t val )
nkeynes@931
    54
{
nkeynes@934
    55
    *(uint8_t *)(aica_main_ram + (addr&0x001FFFFF)) = (uint8_t)val;
nkeynes@931
    56
    asic_g2_write_word();
nkeynes@931
    57
}
nkeynes@931
    58
static void FASTCALL ext_audioram_read_burst( unsigned char *dest, sh4addr_t addr )
nkeynes@931
    59
{
nkeynes@934
    60
    memcpy( dest, aica_main_ram+(addr&0x001FFFFF), 32 );
nkeynes@931
    61
}
nkeynes@931
    62
static void FASTCALL ext_audioram_write_burst( sh4addr_t addr, unsigned char *src )
nkeynes@931
    63
{
nkeynes@934
    64
    memcpy( aica_main_ram+(addr&0x001FFFFF), src, 32 );
nkeynes@931
    65
}
nkeynes@931
    66
nkeynes@931
    67
struct mem_region_fn mem_region_audioram = { ext_audioram_read_long, ext_audioram_write_long, 
nkeynes@931
    68
        ext_audioram_read_word, ext_audioram_write_word, 
nkeynes@931
    69
        ext_audioram_read_byte, ext_audioram_write_byte, 
nkeynes@931
    70
        ext_audioram_read_burst, ext_audioram_write_burst }; 
nkeynes@931
    71
nkeynes@931
    72
nkeynes@931
    73
static int32_t FASTCALL ext_audioscratch_read_long( sh4addr_t addr )
nkeynes@931
    74
{
nkeynes@934
    75
    return *((int32_t *)(aica_scratch_ram + (addr&0x00001FFF)));
nkeynes@931
    76
}
nkeynes@931
    77
static int32_t FASTCALL ext_audioscratch_read_word( sh4addr_t addr )
nkeynes@931
    78
{
nkeynes@934
    79
    return SIGNEXT16(*((int16_t *)(aica_scratch_ram + (addr&0x00001FFF))));
nkeynes@931
    80
}
nkeynes@931
    81
static int32_t FASTCALL ext_audioscratch_read_byte( sh4addr_t addr )
nkeynes@931
    82
{
nkeynes@934
    83
    return SIGNEXT8(*((int16_t *)(aica_scratch_ram + (addr&0x00001FFF))));
nkeynes@931
    84
}
nkeynes@931
    85
static void FASTCALL ext_audioscratch_write_long( sh4addr_t addr, uint32_t val )
nkeynes@931
    86
{
nkeynes@934
    87
    *(uint32_t *)(aica_scratch_ram + (addr&0x00001FFF)) = val;
nkeynes@931
    88
    asic_g2_write_word();
nkeynes@931
    89
}
nkeynes@931
    90
static void FASTCALL ext_audioscratch_write_word( sh4addr_t addr, uint32_t val )
nkeynes@931
    91
{
nkeynes@934
    92
    *(uint16_t *)(aica_scratch_ram + (addr&0x00001FFF)) = (uint16_t)val;
nkeynes@931
    93
    asic_g2_write_word();
nkeynes@931
    94
}
nkeynes@931
    95
static void FASTCALL ext_audioscratch_write_byte( sh4addr_t addr, uint32_t val )
nkeynes@931
    96
{
nkeynes@934
    97
    *(uint8_t *)(aica_scratch_ram + (addr&0x00001FFF)) = (uint8_t)val;
nkeynes@931
    98
    asic_g2_write_word();
nkeynes@931
    99
}
nkeynes@931
   100
static void FASTCALL ext_audioscratch_read_burst( unsigned char *dest, sh4addr_t addr )
nkeynes@931
   101
{
nkeynes@934
   102
    memcpy( dest, aica_scratch_ram+(addr&0x00001FFF), 32 );
nkeynes@931
   103
}
nkeynes@931
   104
static void FASTCALL ext_audioscratch_write_burst( sh4addr_t addr, unsigned char *src )
nkeynes@931
   105
{
nkeynes@934
   106
    memcpy( aica_scratch_ram+(addr&0x00001FFF), src, 32 );
nkeynes@931
   107
}
nkeynes@931
   108
nkeynes@931
   109
struct mem_region_fn mem_region_audioscratch = { ext_audioscratch_read_long, ext_audioscratch_write_long, 
nkeynes@931
   110
        ext_audioscratch_read_word, ext_audioscratch_write_word, 
nkeynes@931
   111
        ext_audioscratch_read_byte, ext_audioscratch_write_byte, 
nkeynes@931
   112
        ext_audioscratch_read_burst, ext_audioscratch_write_burst }; 
nkeynes@931
   113
nkeynes@931
   114
/************************** Local ARM support **************************/
nkeynes@14
   115
int arm_has_page( uint32_t addr ) {
nkeynes@14
   116
    return ( addr < 0x00200000 ||
nkeynes@736
   117
            (addr >= 0x00800000 && addr <= 0x00805000 ) );
nkeynes@14
   118
}
nkeynes@14
   119
nkeynes@37
   120
uint32_t arm_read_long( uint32_t addr ) {
nkeynes@11
   121
    if( addr < 0x00200000 ) {
nkeynes@934
   122
        return *(int32_t *)(aica_main_ram + addr);
nkeynes@736
   123
        /* Main sound ram */
nkeynes@11
   124
    } else {
nkeynes@736
   125
        uint32_t val;
nkeynes@736
   126
        switch( addr & 0xFFFFF000 ) {
nkeynes@736
   127
        case 0x00800000:
nkeynes@736
   128
            val = mmio_region_AICA0_read(addr&0x0FFF);
nkeynes@736
   129
            //	    DEBUG( "ARM long read from %08X => %08X", addr, val );
nkeynes@736
   130
            return val;
nkeynes@736
   131
        case 0x00801000:
nkeynes@736
   132
            val = mmio_region_AICA1_read(addr&0x0FFF);
nkeynes@736
   133
            //	    DEBUG( "ARM long read from %08X => %08X", addr, val );
nkeynes@736
   134
            return val;
nkeynes@736
   135
        case 0x00802000:
nkeynes@736
   136
            val = mmio_region_AICA2_read(addr&0x0FFF);
nkeynes@736
   137
            // DEBUG( "ARM long read from %08X => %08X", addr, val );
nkeynes@736
   138
            return val;
nkeynes@736
   139
        case 0x00803000:
nkeynes@736
   140
        case 0x00804000:
nkeynes@934
   141
            return *(int32_t *)(aica_scratch_ram + addr - 0x00803000);
nkeynes@736
   142
        }
nkeynes@11
   143
    }
nkeynes@1106
   144
    WARN( "Attempted long read to undefined page: %08X at %08X",
nkeynes@811
   145
           addr, armr.r[15] );
nkeynes@37
   146
    /* Undefined memory */
nkeynes@37
   147
    return 0;
nkeynes@7
   148
}
nkeynes@7
   149
nkeynes@37
   150
uint32_t arm_read_word( uint32_t addr ) {
nkeynes@40
   151
    return (uint32_t)(uint16_t)arm_read_long( addr );
nkeynes@7
   152
}
nkeynes@7
   153
nkeynes@37
   154
uint32_t arm_read_byte( uint32_t addr ) {
nkeynes@40
   155
    return (uint32_t)(uint8_t)arm_read_long( addr );
nkeynes@7
   156
}
nkeynes@7
   157
nkeynes@37
   158
void arm_write_long( uint32_t addr, uint32_t value )
nkeynes@37
   159
{
nkeynes@37
   160
    if( addr < 0x00200000 ) {
nkeynes@736
   161
        /* Main sound ram */
nkeynes@934
   162
        *(uint32_t *)(aica_main_ram + addr) = value;
nkeynes@37
   163
    } else {
nkeynes@736
   164
        switch( addr & 0xFFFFF000 ) {
nkeynes@736
   165
        case 0x00800000:
nkeynes@736
   166
            // DEBUG( "ARM long write to %08X <= %08X", addr, value );
nkeynes@736
   167
            mmio_region_AICA0_write(addr&0x0FFF, value);
nkeynes@736
   168
            break;
nkeynes@736
   169
        case 0x00801000:
nkeynes@736
   170
            // DEBUG( "ARM long write to %08X <= %08X", addr, value );
nkeynes@736
   171
            mmio_region_AICA1_write(addr&0x0FFF, value);
nkeynes@736
   172
            break;
nkeynes@736
   173
        case 0x00802000:
nkeynes@736
   174
            // DEBUG( "ARM long write to %08X <= %08X", addr, value );
nkeynes@736
   175
            mmio_region_AICA2_write(addr&0x0FFF, value);
nkeynes@736
   176
            break;
nkeynes@736
   177
        case 0x00803000:
nkeynes@736
   178
        case 0x00804000:
nkeynes@934
   179
            *(uint32_t *)(aica_scratch_ram + addr - 0x00803000) = value;
nkeynes@736
   180
            break;
nkeynes@736
   181
        default:
nkeynes@1106
   182
            WARN( "Attempted long write to undefined address: %08X",
nkeynes@736
   183
                    addr );
nkeynes@736
   184
            /* Undefined memory */
nkeynes@736
   185
        } 
nkeynes@37
   186
    }
nkeynes@431
   187
    return;
nkeynes@37
   188
}
nkeynes@37
   189
nkeynes@66
   190
uint32_t arm_combine_byte( uint32_t addr, uint32_t val, uint8_t byte )
nkeynes@66
   191
{
nkeynes@66
   192
    switch( addr & 0x03 ) {
nkeynes@66
   193
    case 0:
nkeynes@736
   194
        return (val & 0xFFFFFF00) | byte;
nkeynes@66
   195
    case 1:
nkeynes@736
   196
        return (val & 0xFFFF00FF) | (byte<<8);
nkeynes@66
   197
    case 2:
nkeynes@736
   198
        return (val & 0xFF00FFFF) | (byte<<16);
nkeynes@66
   199
    case 3:
nkeynes@736
   200
        return (val & 0x00FFFFFF) | (byte<<24);
nkeynes@431
   201
    default:
nkeynes@736
   202
        return val; // Can't happen, but make gcc happy
nkeynes@66
   203
    }
nkeynes@66
   204
}
nkeynes@811
   205
void arm_write_word( uint32_t addr, uint32_t value )
nkeynes@811
   206
{
nkeynes@811
   207
	if( addr < 0x00200000 ) {
nkeynes@934
   208
        *(uint16_t *)(aica_main_ram + addr) = (uint16_t)value;
nkeynes@811
   209
	} else {
nkeynes@811
   210
		
nkeynes@811
   211
	}
nkeynes@811
   212
}
nkeynes@37
   213
void arm_write_byte( uint32_t addr, uint32_t value )
nkeynes@37
   214
{
nkeynes@37
   215
    if( addr < 0x00200000 ) {
nkeynes@736
   216
        /* Main sound ram */
nkeynes@934
   217
        *(uint8_t *)(aica_main_ram + addr) = (uint8_t)value;
nkeynes@37
   218
    } else {
nkeynes@736
   219
        uint32_t tmp;
nkeynes@736
   220
        switch( addr & 0xFFFFF000 ) {
nkeynes@736
   221
        case 0x00800000:
nkeynes@736
   222
            tmp = MMIO_READ( AICA0, addr & 0x0FFC );
nkeynes@736
   223
            value = arm_combine_byte( addr, tmp, value );
nkeynes@736
   224
            mmio_region_AICA0_write(addr&0x0FFC, value);
nkeynes@736
   225
            break;
nkeynes@736
   226
        case 0x00801000:
nkeynes@736
   227
            tmp = MMIO_READ( AICA1, addr & 0x0FFC );
nkeynes@736
   228
            value = arm_combine_byte( addr, tmp, value );
nkeynes@736
   229
            mmio_region_AICA1_write(addr&0x0FFC, value);
nkeynes@736
   230
            break;
nkeynes@736
   231
        case 0x00802000:
nkeynes@736
   232
            tmp = MMIO_READ( AICA2, addr & 0x0FFC );
nkeynes@736
   233
            value = arm_combine_byte( addr, tmp, value );
nkeynes@736
   234
            mmio_region_AICA2_write(addr&0x0FFC, value);
nkeynes@736
   235
            break;
nkeynes@736
   236
        case 0x00803000:
nkeynes@736
   237
        case 0x00804000:
nkeynes@934
   238
            *(uint8_t *)(aica_scratch_ram + addr - 0x00803000) = (uint8_t)value;
nkeynes@736
   239
            break;
nkeynes@736
   240
        default:
nkeynes@1106
   241
            WARN( "Attempted byte write to undefined address: %08X",
nkeynes@736
   242
                    addr );
nkeynes@736
   243
            /* Undefined memory */
nkeynes@736
   244
        } 
nkeynes@37
   245
    }
nkeynes@431
   246
    return;
nkeynes@37
   247
}
nkeynes@37
   248
nkeynes@37
   249
/* User translations - TODO */
nkeynes@37
   250
nkeynes@11
   251
uint32_t arm_read_long_user( uint32_t addr ) {
nkeynes@37
   252
    return arm_read_long( addr );
nkeynes@11
   253
}
nkeynes@11
   254
nkeynes@11
   255
uint32_t arm_read_byte_user( uint32_t addr ) {
nkeynes@37
   256
    return arm_read_byte( addr );
nkeynes@37
   257
}
nkeynes@11
   258
nkeynes@37
   259
void arm_write_long_user( uint32_t addr, uint32_t val ) {
nkeynes@37
   260
    arm_write_long( addr, val );
nkeynes@11
   261
}
nkeynes@37
   262
nkeynes@37
   263
void arm_write_byte_user( uint32_t addr, uint32_t val )
nkeynes@37
   264
{
nkeynes@37
   265
    arm_write_byte( addr, val );
nkeynes@37
   266
}
nkeynes@998
   267
nkeynes@998
   268
size_t arm_read_phys( unsigned char *buf, uint32_t addr, size_t length ) {
nkeynes@998
   269
    if( addr < sizeof(aica_main_ram) ) {
nkeynes@998
   270
        if( addr+length > sizeof(aica_main_ram) ) {
nkeynes@998
   271
            length = sizeof(aica_main_ram) - addr;
nkeynes@998
   272
        }
nkeynes@998
   273
        memcpy( buf, &aica_main_ram[addr], length );
nkeynes@998
   274
        return length;
nkeynes@998
   275
    } else {
nkeynes@998
   276
        return 0;
nkeynes@998
   277
    }
nkeynes@998
   278
}
nkeynes@998
   279
nkeynes@998
   280
size_t arm_write_phys( uint32_t addr, unsigned char *buf, size_t length ) {
nkeynes@998
   281
    if( addr < sizeof(aica_main_ram) ) {
nkeynes@998
   282
        if( addr+length > sizeof(aica_main_ram) ) {
nkeynes@998
   283
            length = sizeof(aica_main_ram) - addr;
nkeynes@998
   284
        }
nkeynes@998
   285
        memcpy( &aica_main_ram[addr], buf, length );
nkeynes@998
   286
        return length;
nkeynes@998
   287
    } else {
nkeynes@998
   288
        return 0;
nkeynes@998
   289
    }
nkeynes@998
   290
}
.