Search
lxdream.org :: lxdream/src/aica/armmem.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/armmem.c
changeset 431:248dd77a9e44
prev66:2ec5b6eb75e5
next502:c4ecae2b1b5e
author nkeynes
date Wed Oct 24 21:24:09 2007 +0000 (16 years ago)
permissions -rw-r--r--
last change Implement channel position readback
view annotate diff log raw
     1 /**
     2  * $Id: armmem.c,v 1.8 2007-10-09 08:11:51 nkeynes Exp $
     3  *
     4  * Implements the ARM's memory map.
     5  *
     6  * Copyright (c) 2005 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    19 #include <stdlib.h>
    20 #include "dream.h"
    21 #include "mem.h"
    22 #include "aica.h"
    24 char *arm_mem = NULL;
    25 char *arm_mem_scratch = NULL;
    27 void arm_mem_init() {
    28     arm_mem = mem_get_region_by_name( MEM_REGION_AUDIO );
    29     arm_mem_scratch = mem_get_region_by_name( MEM_REGION_AUDIO_SCRATCH );
    30 }
    32 int arm_has_page( uint32_t addr ) {
    33     return ( addr < 0x00200000 ||
    34 	     (addr >= 0x00800000 && addr <= 0x00805000 ) );
    35 }
    37 uint32_t arm_read_long( uint32_t addr ) {
    38     if( addr < 0x00200000 ) {
    39 	return *(int32_t *)(arm_mem + addr);
    40 	/* Main sound ram */
    41     } else {
    42 	uint32_t val;
    43 	switch( addr & 0xFFFFF000 ) {
    44 	case 0x00800000:
    45 	    val = mmio_region_AICA0_read(addr&0x0FFF);
    46 	    //	    DEBUG( "ARM long read from %08X => %08X", addr, val );
    47 	    return val;
    48 	case 0x00801000:
    49 	    val = mmio_region_AICA1_read(addr&0x0FFF);
    50 	    //	    DEBUG( "ARM long read from %08X => %08X", addr, val );
    51 	    return val;
    52 	case 0x00802000:
    53 	    val = mmio_region_AICA2_read(addr&0x0FFF);
    54 	    // DEBUG( "ARM long read from %08X => %08X", addr, val );
    55 	    return val;
    56 	case 0x00803000:
    57 	case 0x00804000:
    58 	    return *(int32_t *)(arm_mem_scratch + addr - 0x00803000);
    59 	}
    60     }
    61     ERROR( "Attempted long read to undefined page: %08X",
    62 	   addr );
    63     /* Undefined memory */
    64     return 0;
    65 }
    67 uint32_t arm_read_word( uint32_t addr ) {
    68     return (uint32_t)(uint16_t)arm_read_long( addr );
    69 }
    71 uint32_t arm_read_byte( uint32_t addr ) {
    72     return (uint32_t)(uint8_t)arm_read_long( addr );
    73 }
    75 void arm_write_long( uint32_t addr, uint32_t value )
    76 {
    77     if( addr < 0x00200000 ) {
    78 	/* Main sound ram */
    79 	*(uint32_t *)(arm_mem + addr) = value;
    80     } else {
    81 	switch( addr & 0xFFFFF000 ) {
    82 	case 0x00800000:
    83 	    // DEBUG( "ARM long write to %08X <= %08X", addr, value );
    84 	    mmio_region_AICA0_write(addr&0x0FFF, value);
    85 	    break;
    86 	case 0x00801000:
    87 	    // DEBUG( "ARM long write to %08X <= %08X", addr, value );
    88 	    mmio_region_AICA1_write(addr&0x0FFF, value);
    89 	    break;
    90 	case 0x00802000:
    91 	    // DEBUG( "ARM long write to %08X <= %08X", addr, value );
    92 	    mmio_region_AICA2_write(addr&0x0FFF, value);
    93 	    break;
    94 	case 0x00803000:
    95 	case 0x00804000:
    96 	    *(uint32_t *)(arm_mem_scratch + addr - 0x00803000) = value;
    97 	    break;
    98 	default:
    99 	    ERROR( "Attempted long write to undefined address: %08X",
   100 		   addr );
   101 	    /* Undefined memory */
   102 	} 
   103     }
   104     return;
   105 }
   107 uint32_t arm_combine_byte( uint32_t addr, uint32_t val, uint8_t byte )
   108 {
   109     switch( addr & 0x03 ) {
   110     case 0:
   111 	return (val & 0xFFFFFF00) | byte;
   112     case 1:
   113 	return (val & 0xFFFF00FF) | (byte<<8);
   114     case 2:
   115 	return (val & 0xFF00FFFF) | (byte<<16);
   116     case 3:
   117 	return (val & 0x00FFFFFF) | (byte<<24);
   118     default:
   119 	return val; // Can't happen, but make gcc happy
   120     }
   121 }
   123 void arm_write_byte( uint32_t addr, uint32_t value )
   124 {
   125     if( addr < 0x00200000 ) {
   126 	/* Main sound ram */
   127 	*(uint8_t *)(arm_mem + addr) = (uint8_t)value;
   128     } else {
   129 	uint32_t tmp;
   130 	switch( addr & 0xFFFFF000 ) {
   131 	case 0x00800000:
   132 	    tmp = MMIO_READ( AICA0, addr & 0x0FFC );
   133 	    value = arm_combine_byte( addr, tmp, value );
   134 	    mmio_region_AICA0_write(addr&0x0FFC, value);
   135 	    break;
   136 	case 0x00801000:
   137 	    tmp = MMIO_READ( AICA1, addr & 0x0FFC );
   138 	    value = arm_combine_byte( addr, tmp, value );
   139 	    mmio_region_AICA1_write(addr&0x0FFC, value);
   140 	    break;
   141 	case 0x00802000:
   142 	    tmp = MMIO_READ( AICA2, addr & 0x0FFC );
   143 	    value = arm_combine_byte( addr, tmp, value );
   144 	    mmio_region_AICA2_write(addr&0x0FFC, value);
   145 	    break;
   146 	case 0x00803000:
   147 	case 0x00804000:
   148 	    *(uint8_t *)(arm_mem_scratch + addr - 0x00803000) = (uint8_t)value;
   149 	    break;
   150 	default:
   151 	    ERROR( "Attempted byte write to undefined address: %08X",
   152 		   addr );
   153 	    /* Undefined memory */
   154 	} 
   155     }
   156     return;
   157 }
   159 /* User translations - TODO */
   161 uint32_t arm_read_long_user( uint32_t addr ) {
   162     return arm_read_long( addr );
   163 }
   165 uint32_t arm_read_byte_user( uint32_t addr ) {
   166     return arm_read_byte( addr );
   167 }
   169 void arm_write_long_user( uint32_t addr, uint32_t val ) {
   170     arm_write_long( addr, val );
   171 }
   173 void arm_write_byte_user( uint32_t addr, uint32_t val )
   174 {
   175     arm_write_byte( addr, val );
   176 }
.