Search
lxdream.org :: lxdream/src/aica/armmem.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/armmem.c
changeset 811:7ff871670e58
prev736:a02d1475ccfd
next931:430048ea8b71
next953:f4a156508ad1
author nkeynes
date Sun Aug 24 02:57:15 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Adjust the hclip when the horizontal scaler is active
file annotate diff log raw
nkeynes@31
     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@811
    23
#include "armcore.h"
nkeynes@7
    24
nkeynes@502
    25
unsigned char *arm_mem = NULL;
nkeynes@502
    26
unsigned char *arm_mem_scratch = NULL;
nkeynes@11
    27
nkeynes@7
    28
void arm_mem_init() {
nkeynes@11
    29
    arm_mem = mem_get_region_by_name( MEM_REGION_AUDIO );
nkeynes@40
    30
    arm_mem_scratch = mem_get_region_by_name( MEM_REGION_AUDIO_SCRATCH );
nkeynes@7
    31
}
nkeynes@7
    32
nkeynes@14
    33
int arm_has_page( uint32_t addr ) {
nkeynes@14
    34
    return ( addr < 0x00200000 ||
nkeynes@736
    35
            (addr >= 0x00800000 && addr <= 0x00805000 ) );
nkeynes@14
    36
}
nkeynes@14
    37
nkeynes@37
    38
uint32_t arm_read_long( uint32_t addr ) {
nkeynes@11
    39
    if( addr < 0x00200000 ) {
nkeynes@736
    40
        return *(int32_t *)(arm_mem + addr);
nkeynes@736
    41
        /* Main sound ram */
nkeynes@11
    42
    } else {
nkeynes@736
    43
        uint32_t val;
nkeynes@736
    44
        switch( addr & 0xFFFFF000 ) {
nkeynes@736
    45
        case 0x00800000:
nkeynes@736
    46
            val = mmio_region_AICA0_read(addr&0x0FFF);
nkeynes@736
    47
            //	    DEBUG( "ARM long read from %08X => %08X", addr, val );
nkeynes@736
    48
            return val;
nkeynes@736
    49
        case 0x00801000:
nkeynes@736
    50
            val = mmio_region_AICA1_read(addr&0x0FFF);
nkeynes@736
    51
            //	    DEBUG( "ARM long read from %08X => %08X", addr, val );
nkeynes@736
    52
            return val;
nkeynes@736
    53
        case 0x00802000:
nkeynes@736
    54
            val = mmio_region_AICA2_read(addr&0x0FFF);
nkeynes@736
    55
            // DEBUG( "ARM long read from %08X => %08X", addr, val );
nkeynes@736
    56
            return val;
nkeynes@736
    57
        case 0x00803000:
nkeynes@736
    58
        case 0x00804000:
nkeynes@736
    59
            return *(int32_t *)(arm_mem_scratch + addr - 0x00803000);
nkeynes@736
    60
        }
nkeynes@11
    61
    }
nkeynes@811
    62
    ERROR( "Attempted long read to undefined page: %08X at %08X",
nkeynes@811
    63
           addr, armr.r[15] );
nkeynes@37
    64
    /* Undefined memory */
nkeynes@37
    65
    return 0;
nkeynes@7
    66
}
nkeynes@7
    67
nkeynes@37
    68
uint32_t arm_read_word( uint32_t addr ) {
nkeynes@40
    69
    return (uint32_t)(uint16_t)arm_read_long( addr );
nkeynes@7
    70
}
nkeynes@7
    71
nkeynes@37
    72
uint32_t arm_read_byte( uint32_t addr ) {
nkeynes@40
    73
    return (uint32_t)(uint8_t)arm_read_long( addr );
nkeynes@7
    74
}
nkeynes@7
    75
nkeynes@37
    76
void arm_write_long( uint32_t addr, uint32_t value )
nkeynes@37
    77
{
nkeynes@37
    78
    if( addr < 0x00200000 ) {
nkeynes@736
    79
        /* Main sound ram */
nkeynes@736
    80
        *(uint32_t *)(arm_mem + addr) = value;
nkeynes@37
    81
    } else {
nkeynes@736
    82
        switch( addr & 0xFFFFF000 ) {
nkeynes@736
    83
        case 0x00800000:
nkeynes@736
    84
            // DEBUG( "ARM long write to %08X <= %08X", addr, value );
nkeynes@736
    85
            mmio_region_AICA0_write(addr&0x0FFF, value);
nkeynes@736
    86
            break;
nkeynes@736
    87
        case 0x00801000:
nkeynes@736
    88
            // DEBUG( "ARM long write to %08X <= %08X", addr, value );
nkeynes@736
    89
            mmio_region_AICA1_write(addr&0x0FFF, value);
nkeynes@736
    90
            break;
nkeynes@736
    91
        case 0x00802000:
nkeynes@736
    92
            // DEBUG( "ARM long write to %08X <= %08X", addr, value );
nkeynes@736
    93
            mmio_region_AICA2_write(addr&0x0FFF, value);
nkeynes@736
    94
            break;
nkeynes@736
    95
        case 0x00803000:
nkeynes@736
    96
        case 0x00804000:
nkeynes@736
    97
            *(uint32_t *)(arm_mem_scratch + addr - 0x00803000) = value;
nkeynes@736
    98
            break;
nkeynes@736
    99
        default:
nkeynes@736
   100
            ERROR( "Attempted long write to undefined address: %08X",
nkeynes@736
   101
                    addr );
nkeynes@736
   102
            /* Undefined memory */
nkeynes@736
   103
        } 
nkeynes@37
   104
    }
nkeynes@431
   105
    return;
nkeynes@37
   106
}
nkeynes@37
   107
nkeynes@66
   108
uint32_t arm_combine_byte( uint32_t addr, uint32_t val, uint8_t byte )
nkeynes@66
   109
{
nkeynes@66
   110
    switch( addr & 0x03 ) {
nkeynes@66
   111
    case 0:
nkeynes@736
   112
        return (val & 0xFFFFFF00) | byte;
nkeynes@66
   113
    case 1:
nkeynes@736
   114
        return (val & 0xFFFF00FF) | (byte<<8);
nkeynes@66
   115
    case 2:
nkeynes@736
   116
        return (val & 0xFF00FFFF) | (byte<<16);
nkeynes@66
   117
    case 3:
nkeynes@736
   118
        return (val & 0x00FFFFFF) | (byte<<24);
nkeynes@431
   119
    default:
nkeynes@736
   120
        return val; // Can't happen, but make gcc happy
nkeynes@66
   121
    }
nkeynes@66
   122
}
nkeynes@811
   123
void arm_write_word( uint32_t addr, uint32_t value )
nkeynes@811
   124
{
nkeynes@811
   125
	if( addr < 0x00200000 ) {
nkeynes@811
   126
        *(uint16_t *)(arm_mem + addr) = (uint16_t)value;
nkeynes@811
   127
	} else {
nkeynes@811
   128
		
nkeynes@811
   129
	}
nkeynes@811
   130
}
nkeynes@37
   131
void arm_write_byte( uint32_t addr, uint32_t value )
nkeynes@37
   132
{
nkeynes@37
   133
    if( addr < 0x00200000 ) {
nkeynes@736
   134
        /* Main sound ram */
nkeynes@736
   135
        *(uint8_t *)(arm_mem + addr) = (uint8_t)value;
nkeynes@37
   136
    } else {
nkeynes@736
   137
        uint32_t tmp;
nkeynes@736
   138
        switch( addr & 0xFFFFF000 ) {
nkeynes@736
   139
        case 0x00800000:
nkeynes@736
   140
            tmp = MMIO_READ( AICA0, addr & 0x0FFC );
nkeynes@736
   141
            value = arm_combine_byte( addr, tmp, value );
nkeynes@736
   142
            mmio_region_AICA0_write(addr&0x0FFC, value);
nkeynes@736
   143
            break;
nkeynes@736
   144
        case 0x00801000:
nkeynes@736
   145
            tmp = MMIO_READ( AICA1, addr & 0x0FFC );
nkeynes@736
   146
            value = arm_combine_byte( addr, tmp, value );
nkeynes@736
   147
            mmio_region_AICA1_write(addr&0x0FFC, value);
nkeynes@736
   148
            break;
nkeynes@736
   149
        case 0x00802000:
nkeynes@736
   150
            tmp = MMIO_READ( AICA2, addr & 0x0FFC );
nkeynes@736
   151
            value = arm_combine_byte( addr, tmp, value );
nkeynes@736
   152
            mmio_region_AICA2_write(addr&0x0FFC, value);
nkeynes@736
   153
            break;
nkeynes@736
   154
        case 0x00803000:
nkeynes@736
   155
        case 0x00804000:
nkeynes@736
   156
            *(uint8_t *)(arm_mem_scratch + addr - 0x00803000) = (uint8_t)value;
nkeynes@736
   157
            break;
nkeynes@736
   158
        default:
nkeynes@736
   159
            ERROR( "Attempted byte write to undefined address: %08X",
nkeynes@736
   160
                    addr );
nkeynes@736
   161
            /* Undefined memory */
nkeynes@736
   162
        } 
nkeynes@37
   163
    }
nkeynes@431
   164
    return;
nkeynes@37
   165
}
nkeynes@37
   166
nkeynes@37
   167
/* User translations - TODO */
nkeynes@37
   168
nkeynes@11
   169
uint32_t arm_read_long_user( uint32_t addr ) {
nkeynes@37
   170
    return arm_read_long( addr );
nkeynes@11
   171
}
nkeynes@11
   172
nkeynes@11
   173
uint32_t arm_read_byte_user( uint32_t addr ) {
nkeynes@37
   174
    return arm_read_byte( addr );
nkeynes@37
   175
}
nkeynes@11
   176
nkeynes@37
   177
void arm_write_long_user( uint32_t addr, uint32_t val ) {
nkeynes@37
   178
    arm_write_long( addr, val );
nkeynes@11
   179
}
nkeynes@37
   180
nkeynes@37
   181
void arm_write_byte_user( uint32_t addr, uint32_t val )
nkeynes@37
   182
{
nkeynes@37
   183
    arm_write_byte( addr, val );
nkeynes@37
   184
}
.