Search
lxdream.org :: lxdream/src/aica/armmem.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/armmem.c
changeset 1067:d3c00ffccfcd
prev998:1754a8c6a9cf
prev934:3acd3b3ee6d1
next1106:1879fd49ccf6
author nkeynes
date Sun Jul 05 13:54:48 2009 +1000 (12 years ago)
permissions -rw-r--r--
last change No-op merge lxdream-mem to tip to remove head (Long since merged in
actuality)
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 "asic.h"
    24 #include "armcore.h"
    26 unsigned char aica_main_ram[2 MB];
    27 unsigned char aica_scratch_ram[8 KB];
    29 /*************** ARM memory access function blocks **************/
    31 static int32_t FASTCALL ext_audioram_read_long( sh4addr_t addr )
    32 {
    33     return *((int32_t *)(aica_main_ram + (addr&0x001FFFFF)));
    34 }
    35 static int32_t FASTCALL ext_audioram_read_word( sh4addr_t addr )
    36 {
    37     return SIGNEXT16(*((int16_t *)(aica_main_ram + (addr&0x001FFFFF))));
    38 }
    39 static int32_t FASTCALL ext_audioram_read_byte( sh4addr_t addr )
    40 {
    41     return SIGNEXT8(*((int16_t *)(aica_main_ram + (addr&0x001FFFFF))));
    42 }
    43 static void FASTCALL ext_audioram_write_long( sh4addr_t addr, uint32_t val )
    44 {
    45     *(uint32_t *)(aica_main_ram + (addr&0x001FFFFF)) = val;
    46     asic_g2_write_word();
    47 }
    48 static void FASTCALL ext_audioram_write_word( sh4addr_t addr, uint32_t val )
    49 {
    50     *(uint16_t *)(aica_main_ram + (addr&0x001FFFFF)) = (uint16_t)val;
    51     asic_g2_write_word();
    52 }
    53 static void FASTCALL ext_audioram_write_byte( sh4addr_t addr, uint32_t val )
    54 {
    55     *(uint8_t *)(aica_main_ram + (addr&0x001FFFFF)) = (uint8_t)val;
    56     asic_g2_write_word();
    57 }
    58 static void FASTCALL ext_audioram_read_burst( unsigned char *dest, sh4addr_t addr )
    59 {
    60     memcpy( dest, aica_main_ram+(addr&0x001FFFFF), 32 );
    61 }
    62 static void FASTCALL ext_audioram_write_burst( sh4addr_t addr, unsigned char *src )
    63 {
    64     memcpy( aica_main_ram+(addr&0x001FFFFF), src, 32 );
    65 }
    67 struct mem_region_fn mem_region_audioram = { ext_audioram_read_long, ext_audioram_write_long, 
    68         ext_audioram_read_word, ext_audioram_write_word, 
    69         ext_audioram_read_byte, ext_audioram_write_byte, 
    70         ext_audioram_read_burst, ext_audioram_write_burst }; 
    73 static int32_t FASTCALL ext_audioscratch_read_long( sh4addr_t addr )
    74 {
    75     return *((int32_t *)(aica_scratch_ram + (addr&0x00001FFF)));
    76 }
    77 static int32_t FASTCALL ext_audioscratch_read_word( sh4addr_t addr )
    78 {
    79     return SIGNEXT16(*((int16_t *)(aica_scratch_ram + (addr&0x00001FFF))));
    80 }
    81 static int32_t FASTCALL ext_audioscratch_read_byte( sh4addr_t addr )
    82 {
    83     return SIGNEXT8(*((int16_t *)(aica_scratch_ram + (addr&0x00001FFF))));
    84 }
    85 static void FASTCALL ext_audioscratch_write_long( sh4addr_t addr, uint32_t val )
    86 {
    87     *(uint32_t *)(aica_scratch_ram + (addr&0x00001FFF)) = val;
    88     asic_g2_write_word();
    89 }
    90 static void FASTCALL ext_audioscratch_write_word( sh4addr_t addr, uint32_t val )
    91 {
    92     *(uint16_t *)(aica_scratch_ram + (addr&0x00001FFF)) = (uint16_t)val;
    93     asic_g2_write_word();
    94 }
    95 static void FASTCALL ext_audioscratch_write_byte( sh4addr_t addr, uint32_t val )
    96 {
    97     *(uint8_t *)(aica_scratch_ram + (addr&0x00001FFF)) = (uint8_t)val;
    98     asic_g2_write_word();
    99 }
   100 static void FASTCALL ext_audioscratch_read_burst( unsigned char *dest, sh4addr_t addr )
   101 {
   102     memcpy( dest, aica_scratch_ram+(addr&0x00001FFF), 32 );
   103 }
   104 static void FASTCALL ext_audioscratch_write_burst( sh4addr_t addr, unsigned char *src )
   105 {
   106     memcpy( aica_scratch_ram+(addr&0x00001FFF), src, 32 );
   107 }
   109 struct mem_region_fn mem_region_audioscratch = { ext_audioscratch_read_long, ext_audioscratch_write_long, 
   110         ext_audioscratch_read_word, ext_audioscratch_write_word, 
   111         ext_audioscratch_read_byte, ext_audioscratch_write_byte, 
   112         ext_audioscratch_read_burst, ext_audioscratch_write_burst }; 
   114 /************************** Local ARM support **************************/
   115 int arm_has_page( uint32_t addr ) {
   116     return ( addr < 0x00200000 ||
   117             (addr >= 0x00800000 && addr <= 0x00805000 ) );
   118 }
   120 uint32_t arm_read_long( uint32_t addr ) {
   121     if( addr < 0x00200000 ) {
   122         return *(int32_t *)(aica_main_ram + addr);
   123         /* Main sound ram */
   124     } else {
   125         uint32_t val;
   126         switch( addr & 0xFFFFF000 ) {
   127         case 0x00800000:
   128             val = mmio_region_AICA0_read(addr&0x0FFF);
   129             //	    DEBUG( "ARM long read from %08X => %08X", addr, val );
   130             return val;
   131         case 0x00801000:
   132             val = mmio_region_AICA1_read(addr&0x0FFF);
   133             //	    DEBUG( "ARM long read from %08X => %08X", addr, val );
   134             return val;
   135         case 0x00802000:
   136             val = mmio_region_AICA2_read(addr&0x0FFF);
   137             // DEBUG( "ARM long read from %08X => %08X", addr, val );
   138             return val;
   139         case 0x00803000:
   140         case 0x00804000:
   141             return *(int32_t *)(aica_scratch_ram + addr - 0x00803000);
   142         }
   143     }
   144     ERROR( "Attempted long read to undefined page: %08X at %08X",
   145            addr, armr.r[15] );
   146     /* Undefined memory */
   147     return 0;
   148 }
   150 uint32_t arm_read_word( uint32_t addr ) {
   151     return (uint32_t)(uint16_t)arm_read_long( addr );
   152 }
   154 uint32_t arm_read_byte( uint32_t addr ) {
   155     return (uint32_t)(uint8_t)arm_read_long( addr );
   156 }
   158 void arm_write_long( uint32_t addr, uint32_t value )
   159 {
   160     if( addr < 0x00200000 ) {
   161         /* Main sound ram */
   162         *(uint32_t *)(aica_main_ram + addr) = value;
   163     } else {
   164         switch( addr & 0xFFFFF000 ) {
   165         case 0x00800000:
   166             // DEBUG( "ARM long write to %08X <= %08X", addr, value );
   167             mmio_region_AICA0_write(addr&0x0FFF, value);
   168             break;
   169         case 0x00801000:
   170             // DEBUG( "ARM long write to %08X <= %08X", addr, value );
   171             mmio_region_AICA1_write(addr&0x0FFF, value);
   172             break;
   173         case 0x00802000:
   174             // DEBUG( "ARM long write to %08X <= %08X", addr, value );
   175             mmio_region_AICA2_write(addr&0x0FFF, value);
   176             break;
   177         case 0x00803000:
   178         case 0x00804000:
   179             *(uint32_t *)(aica_scratch_ram + addr - 0x00803000) = value;
   180             break;
   181         default:
   182             ERROR( "Attempted long write to undefined address: %08X",
   183                     addr );
   184             /* Undefined memory */
   185         } 
   186     }
   187     return;
   188 }
   190 uint32_t arm_combine_byte( uint32_t addr, uint32_t val, uint8_t byte )
   191 {
   192     switch( addr & 0x03 ) {
   193     case 0:
   194         return (val & 0xFFFFFF00) | byte;
   195     case 1:
   196         return (val & 0xFFFF00FF) | (byte<<8);
   197     case 2:
   198         return (val & 0xFF00FFFF) | (byte<<16);
   199     case 3:
   200         return (val & 0x00FFFFFF) | (byte<<24);
   201     default:
   202         return val; // Can't happen, but make gcc happy
   203     }
   204 }
   205 void arm_write_word( uint32_t addr, uint32_t value )
   206 {
   207 	if( addr < 0x00200000 ) {
   208         *(uint16_t *)(aica_main_ram + addr) = (uint16_t)value;
   209 	} else {
   211 	}
   212 }
   213 void arm_write_byte( uint32_t addr, uint32_t value )
   214 {
   215     if( addr < 0x00200000 ) {
   216         /* Main sound ram */
   217         *(uint8_t *)(aica_main_ram + addr) = (uint8_t)value;
   218     } else {
   219         uint32_t tmp;
   220         switch( addr & 0xFFFFF000 ) {
   221         case 0x00800000:
   222             tmp = MMIO_READ( AICA0, addr & 0x0FFC );
   223             value = arm_combine_byte( addr, tmp, value );
   224             mmio_region_AICA0_write(addr&0x0FFC, value);
   225             break;
   226         case 0x00801000:
   227             tmp = MMIO_READ( AICA1, addr & 0x0FFC );
   228             value = arm_combine_byte( addr, tmp, value );
   229             mmio_region_AICA1_write(addr&0x0FFC, value);
   230             break;
   231         case 0x00802000:
   232             tmp = MMIO_READ( AICA2, addr & 0x0FFC );
   233             value = arm_combine_byte( addr, tmp, value );
   234             mmio_region_AICA2_write(addr&0x0FFC, value);
   235             break;
   236         case 0x00803000:
   237         case 0x00804000:
   238             *(uint8_t *)(aica_scratch_ram + addr - 0x00803000) = (uint8_t)value;
   239             break;
   240         default:
   241             ERROR( "Attempted byte write to undefined address: %08X",
   242                     addr );
   243             /* Undefined memory */
   244         } 
   245     }
   246     return;
   247 }
   249 /* User translations - TODO */
   251 uint32_t arm_read_long_user( uint32_t addr ) {
   252     return arm_read_long( addr );
   253 }
   255 uint32_t arm_read_byte_user( uint32_t addr ) {
   256     return arm_read_byte( addr );
   257 }
   259 void arm_write_long_user( uint32_t addr, uint32_t val ) {
   260     arm_write_long( addr, val );
   261 }
   263 void arm_write_byte_user( uint32_t addr, uint32_t val )
   264 {
   265     arm_write_byte( addr, val );
   266 }
   268 size_t arm_read_phys( unsigned char *buf, uint32_t addr, size_t length ) {
   269     if( addr < sizeof(aica_main_ram) ) {
   270         if( addr+length > sizeof(aica_main_ram) ) {
   271             length = sizeof(aica_main_ram) - addr;
   272         }
   273         memcpy( buf, &aica_main_ram[addr], length );
   274         return length;
   275     } else {
   276         return 0;
   277     }
   278 }
   280 size_t arm_write_phys( uint32_t addr, unsigned char *buf, size_t length ) {
   281     if( addr < sizeof(aica_main_ram) ) {
   282         if( addr+length > sizeof(aica_main_ram) ) {
   283             length = sizeof(aica_main_ram) - addr;
   284         }
   285         memcpy( &aica_main_ram[addr], buf, length );
   286         return length;
   287     } else {
   288         return 0;
   289     }
.