Search
lxdream.org :: lxdream/src/aica/armmem.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/armmem.c
changeset 40:852ee31ace0d
prev37:1d84f4c18816
next66:2ec5b6eb75e5
author nkeynes
date Mon Dec 26 10:48:20 2005 +0000 (14 years ago)
permissions -rw-r--r--
last change Fixup ARM memory to be a little more functional
file annotate diff log raw
nkeynes@31
     1
/**
nkeynes@40
     2
 * $Id: armmem.c,v 1.6 2005-12-26 10:48:20 nkeynes Exp $
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@7
    22
nkeynes@11
    23
char *arm_mem = NULL;
nkeynes@40
    24
char *arm_mem_scratch = NULL;
nkeynes@11
    25
nkeynes@7
    26
void arm_mem_init() {
nkeynes@11
    27
    arm_mem = mem_get_region_by_name( MEM_REGION_AUDIO );
nkeynes@40
    28
    arm_mem_scratch = mem_get_region_by_name( MEM_REGION_AUDIO_SCRATCH );
nkeynes@7
    29
}
nkeynes@7
    30
nkeynes@14
    31
int arm_has_page( uint32_t addr ) {
nkeynes@14
    32
    return ( addr < 0x00200000 ||
nkeynes@14
    33
	     (addr >= 0x00800000 && addr <= 0x00805000 ) );
nkeynes@14
    34
}
nkeynes@14
    35
nkeynes@37
    36
uint32_t arm_read_long( uint32_t addr ) {
nkeynes@11
    37
    if( addr < 0x00200000 ) {
nkeynes@11
    38
	return *(int32_t *)(arm_mem + addr);
nkeynes@11
    39
	/* Main sound ram */
nkeynes@11
    40
    } else {
nkeynes@37
    41
	switch( addr & 0xFFFFF000 ) {
nkeynes@37
    42
	case 0x00800000:
nkeynes@37
    43
	    return mmio_region_AICA0_read(addr);
nkeynes@37
    44
	case 0x00801000:
nkeynes@37
    45
	    return mmio_region_AICA1_read(addr);
nkeynes@37
    46
	case 0x00802000:
nkeynes@37
    47
	    return mmio_region_AICA2_read(addr);
nkeynes@37
    48
	case 0x00803000:
nkeynes@37
    49
	case 0x00804000:
nkeynes@40
    50
	    return *(int32_t *)(arm_mem_scratch + addr - 0x00803000);
nkeynes@37
    51
	}
nkeynes@11
    52
    }
nkeynes@37
    53
    ERROR( "Attempted long read to undefined page: %08X",
nkeynes@37
    54
	   addr );
nkeynes@37
    55
    /* Undefined memory */
nkeynes@37
    56
    return 0;
nkeynes@7
    57
}
nkeynes@7
    58
nkeynes@37
    59
uint32_t arm_read_word( uint32_t addr ) {
nkeynes@40
    60
    return (uint32_t)(uint16_t)arm_read_long( addr );
nkeynes@7
    61
}
nkeynes@7
    62
nkeynes@37
    63
uint32_t arm_read_byte( uint32_t addr ) {
nkeynes@40
    64
    return (uint32_t)(uint8_t)arm_read_long( addr );
nkeynes@7
    65
}
nkeynes@7
    66
nkeynes@37
    67
void arm_write_long( uint32_t addr, uint32_t value )
nkeynes@37
    68
{
nkeynes@37
    69
    if( addr < 0x00200000 ) {
nkeynes@40
    70
	/* Main sound ram */
nkeynes@37
    71
	*(uint32_t *)(arm_mem + addr) = value;
nkeynes@37
    72
    } else {
nkeynes@40
    73
	switch( addr & 0xFFFFF000 ) {
nkeynes@40
    74
	case 0x00800000:
nkeynes@40
    75
	    mmio_region_AICA0_write(addr, value);
nkeynes@40
    76
	    break;
nkeynes@40
    77
	case 0x00801000:
nkeynes@40
    78
	    mmio_region_AICA1_write(addr, value);
nkeynes@40
    79
	    break;
nkeynes@40
    80
	case 0x00802000:
nkeynes@40
    81
	    mmio_region_AICA2_write(addr, value);
nkeynes@40
    82
	    break;
nkeynes@40
    83
	case 0x00803000:
nkeynes@40
    84
	case 0x00804000:
nkeynes@40
    85
	    *(uint32_t *)(arm_mem_scratch + addr - 0x00803000) = value;
nkeynes@40
    86
	    break;
nkeynes@40
    87
	default:
nkeynes@40
    88
	    ERROR( "Attempted long write to undefined address: %08X",
nkeynes@40
    89
		   addr );
nkeynes@40
    90
	    /* Undefined memory */
nkeynes@40
    91
	} 
nkeynes@37
    92
    }
nkeynes@40
    93
    return 0;
nkeynes@37
    94
}
nkeynes@37
    95
nkeynes@37
    96
void arm_write_byte( uint32_t addr, uint32_t value )
nkeynes@37
    97
{
nkeynes@37
    98
    if( addr < 0x00200000 ) {
nkeynes@40
    99
	/* Main sound ram */
nkeynes@40
   100
	*(uint8_t *)(arm_mem + addr) = (uint8_t)value;
nkeynes@37
   101
    } else {
nkeynes@40
   102
	switch( addr & 0xFFFFF000 ) {
nkeynes@40
   103
	case 0x00800000:
nkeynes@40
   104
	    mmio_region_AICA0_write(addr, value);
nkeynes@40
   105
	    break;
nkeynes@40
   106
	case 0x00801000:
nkeynes@40
   107
	    mmio_region_AICA1_write(addr, value);
nkeynes@40
   108
	    break;
nkeynes@40
   109
	case 0x00802000:
nkeynes@40
   110
	    mmio_region_AICA2_write(addr, value);
nkeynes@40
   111
	    break;
nkeynes@40
   112
	case 0x00803000:
nkeynes@40
   113
	case 0x00804000:
nkeynes@40
   114
	    *(uint8_t *)(arm_mem_scratch + addr - 0x00803000) = (uint8_t)value;
nkeynes@40
   115
	    break;
nkeynes@40
   116
	default:
nkeynes@40
   117
	    ERROR( "Attempted byte write to undefined address: %08X",
nkeynes@40
   118
		   addr );
nkeynes@40
   119
	    /* Undefined memory */
nkeynes@40
   120
	} 
nkeynes@37
   121
    }
nkeynes@40
   122
    return 0;
nkeynes@37
   123
}
nkeynes@37
   124
nkeynes@37
   125
/* User translations - TODO */
nkeynes@37
   126
nkeynes@11
   127
uint32_t arm_read_long_user( uint32_t addr ) {
nkeynes@37
   128
    return arm_read_long( addr );
nkeynes@11
   129
}
nkeynes@11
   130
nkeynes@11
   131
uint32_t arm_read_byte_user( uint32_t addr ) {
nkeynes@37
   132
    return arm_read_byte( addr );
nkeynes@37
   133
}
nkeynes@11
   134
nkeynes@37
   135
void arm_write_long_user( uint32_t addr, uint32_t val ) {
nkeynes@37
   136
    arm_write_long( addr, val );
nkeynes@11
   137
}
nkeynes@37
   138
nkeynes@37
   139
void arm_write_byte_user( uint32_t addr, uint32_t val )
nkeynes@37
   140
{
nkeynes@37
   141
    arm_write_byte( addr, val );
nkeynes@37
   142
}
.