Search
lxdream.org :: lxdream/src/aica/armmem.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/armmem.c
changeset 736:a02d1475ccfd
prev561:533f6b478071
next811:7ff871670e58
author nkeynes
date Mon Jul 21 00:08:34 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Add gettext.h and build sanely without libintl if it's not available
Remove x86dasm's config.h & opintl.h (no longer needed and actually wrong)
view annotate diff log raw
     1 /**
     2  * $Id$
     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 unsigned char *arm_mem = NULL;
    25 unsigned 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 }
.