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 Mon Oct 06 01:05:12 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Move bundle/system paths into paths.c, install lxdreamrc into the bundle
(Fix OSX bundle missing default configuration)
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"
    23 #include "armcore.h"
    25 unsigned char *arm_mem = NULL;
    26 unsigned char *arm_mem_scratch = NULL;
    28 void arm_mem_init() {
    29     arm_mem = mem_get_region_by_name( MEM_REGION_AUDIO );
    30     arm_mem_scratch = mem_get_region_by_name( MEM_REGION_AUDIO_SCRATCH );
    31 }
    33 int arm_has_page( uint32_t addr ) {
    34     return ( addr < 0x00200000 ||
    35             (addr >= 0x00800000 && addr <= 0x00805000 ) );
    36 }
    38 uint32_t arm_read_long( uint32_t addr ) {
    39     if( addr < 0x00200000 ) {
    40         return *(int32_t *)(arm_mem + addr);
    41         /* Main sound ram */
    42     } else {
    43         uint32_t val;
    44         switch( addr & 0xFFFFF000 ) {
    45         case 0x00800000:
    46             val = mmio_region_AICA0_read(addr&0x0FFF);
    47             //	    DEBUG( "ARM long read from %08X => %08X", addr, val );
    48             return val;
    49         case 0x00801000:
    50             val = mmio_region_AICA1_read(addr&0x0FFF);
    51             //	    DEBUG( "ARM long read from %08X => %08X", addr, val );
    52             return val;
    53         case 0x00802000:
    54             val = mmio_region_AICA2_read(addr&0x0FFF);
    55             // DEBUG( "ARM long read from %08X => %08X", addr, val );
    56             return val;
    57         case 0x00803000:
    58         case 0x00804000:
    59             return *(int32_t *)(arm_mem_scratch + addr - 0x00803000);
    60         }
    61     }
    62     ERROR( "Attempted long read to undefined page: %08X at %08X",
    63            addr, armr.r[15] );
    64     /* Undefined memory */
    65     return 0;
    66 }
    68 uint32_t arm_read_word( uint32_t addr ) {
    69     return (uint32_t)(uint16_t)arm_read_long( addr );
    70 }
    72 uint32_t arm_read_byte( uint32_t addr ) {
    73     return (uint32_t)(uint8_t)arm_read_long( addr );
    74 }
    76 void arm_write_long( uint32_t addr, uint32_t value )
    77 {
    78     if( addr < 0x00200000 ) {
    79         /* Main sound ram */
    80         *(uint32_t *)(arm_mem + addr) = value;
    81     } else {
    82         switch( addr & 0xFFFFF000 ) {
    83         case 0x00800000:
    84             // DEBUG( "ARM long write to %08X <= %08X", addr, value );
    85             mmio_region_AICA0_write(addr&0x0FFF, value);
    86             break;
    87         case 0x00801000:
    88             // DEBUG( "ARM long write to %08X <= %08X", addr, value );
    89             mmio_region_AICA1_write(addr&0x0FFF, value);
    90             break;
    91         case 0x00802000:
    92             // DEBUG( "ARM long write to %08X <= %08X", addr, value );
    93             mmio_region_AICA2_write(addr&0x0FFF, value);
    94             break;
    95         case 0x00803000:
    96         case 0x00804000:
    97             *(uint32_t *)(arm_mem_scratch + addr - 0x00803000) = value;
    98             break;
    99         default:
   100             ERROR( "Attempted long write to undefined address: %08X",
   101                     addr );
   102             /* Undefined memory */
   103         } 
   104     }
   105     return;
   106 }
   108 uint32_t arm_combine_byte( uint32_t addr, uint32_t val, uint8_t byte )
   109 {
   110     switch( addr & 0x03 ) {
   111     case 0:
   112         return (val & 0xFFFFFF00) | byte;
   113     case 1:
   114         return (val & 0xFFFF00FF) | (byte<<8);
   115     case 2:
   116         return (val & 0xFF00FFFF) | (byte<<16);
   117     case 3:
   118         return (val & 0x00FFFFFF) | (byte<<24);
   119     default:
   120         return val; // Can't happen, but make gcc happy
   121     }
   122 }
   123 void arm_write_word( uint32_t addr, uint32_t value )
   124 {
   125 	if( addr < 0x00200000 ) {
   126         *(uint16_t *)(arm_mem + addr) = (uint16_t)value;
   127 	} else {
   129 	}
   130 }
   131 void arm_write_byte( uint32_t addr, uint32_t value )
   132 {
   133     if( addr < 0x00200000 ) {
   134         /* Main sound ram */
   135         *(uint8_t *)(arm_mem + addr) = (uint8_t)value;
   136     } else {
   137         uint32_t tmp;
   138         switch( addr & 0xFFFFF000 ) {
   139         case 0x00800000:
   140             tmp = MMIO_READ( AICA0, addr & 0x0FFC );
   141             value = arm_combine_byte( addr, tmp, value );
   142             mmio_region_AICA0_write(addr&0x0FFC, value);
   143             break;
   144         case 0x00801000:
   145             tmp = MMIO_READ( AICA1, addr & 0x0FFC );
   146             value = arm_combine_byte( addr, tmp, value );
   147             mmio_region_AICA1_write(addr&0x0FFC, value);
   148             break;
   149         case 0x00802000:
   150             tmp = MMIO_READ( AICA2, addr & 0x0FFC );
   151             value = arm_combine_byte( addr, tmp, value );
   152             mmio_region_AICA2_write(addr&0x0FFC, value);
   153             break;
   154         case 0x00803000:
   155         case 0x00804000:
   156             *(uint8_t *)(arm_mem_scratch + addr - 0x00803000) = (uint8_t)value;
   157             break;
   158         default:
   159             ERROR( "Attempted byte write to undefined address: %08X",
   160                     addr );
   161             /* Undefined memory */
   162         } 
   163     }
   164     return;
   165 }
   167 /* User translations - TODO */
   169 uint32_t arm_read_long_user( uint32_t addr ) {
   170     return arm_read_long( addr );
   171 }
   173 uint32_t arm_read_byte_user( uint32_t addr ) {
   174     return arm_read_byte( addr );
   175 }
   177 void arm_write_long_user( uint32_t addr, uint32_t val ) {
   178     arm_write_long( addr, val );
   179 }
   181 void arm_write_byte_user( uint32_t addr, uint32_t val )
   182 {
   183     arm_write_byte( addr, val );
   184 }
.