Search
lxdream.org :: lxdream/src/aica/armmem.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/armmem.c
changeset 934:3acd3b3ee6d1
prev931:430048ea8b71
next1067:d3c00ffccfcd
author nkeynes
date Sat Jan 03 07:30:26 2009 +0000 (15 years ago)
branchlxdream-mem
permissions -rw-r--r--
last change Add svn:keywords props on new files
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 aica_main_ram[2 MB];
    26 unsigned char aica_scratch_ram[8 KB];
    28 /*************** ARM memory access function blocks **************/
    30 static int32_t FASTCALL ext_audioram_read_long( sh4addr_t addr )
    31 {
    32     return *((int32_t *)(aica_main_ram + (addr&0x001FFFFF)));
    33 }
    34 static int32_t FASTCALL ext_audioram_read_word( sh4addr_t addr )
    35 {
    36     return SIGNEXT16(*((int16_t *)(aica_main_ram + (addr&0x001FFFFF))));
    37 }
    38 static int32_t FASTCALL ext_audioram_read_byte( sh4addr_t addr )
    39 {
    40     return SIGNEXT8(*((int16_t *)(aica_main_ram + (addr&0x001FFFFF))));
    41 }
    42 static void FASTCALL ext_audioram_write_long( sh4addr_t addr, uint32_t val )
    43 {
    44     *(uint32_t *)(aica_main_ram + (addr&0x001FFFFF)) = val;
    45     asic_g2_write_word();
    46 }
    47 static void FASTCALL ext_audioram_write_word( sh4addr_t addr, uint32_t val )
    48 {
    49     *(uint16_t *)(aica_main_ram + (addr&0x001FFFFF)) = (uint16_t)val;
    50     asic_g2_write_word();
    51 }
    52 static void FASTCALL ext_audioram_write_byte( sh4addr_t addr, uint32_t val )
    53 {
    54     *(uint8_t *)(aica_main_ram + (addr&0x001FFFFF)) = (uint8_t)val;
    55     asic_g2_write_word();
    56 }
    57 static void FASTCALL ext_audioram_read_burst( unsigned char *dest, sh4addr_t addr )
    58 {
    59     memcpy( dest, aica_main_ram+(addr&0x001FFFFF), 32 );
    60 }
    61 static void FASTCALL ext_audioram_write_burst( sh4addr_t addr, unsigned char *src )
    62 {
    63     memcpy( aica_main_ram+(addr&0x001FFFFF), src, 32 );
    64 }
    66 struct mem_region_fn mem_region_audioram = { ext_audioram_read_long, ext_audioram_write_long, 
    67         ext_audioram_read_word, ext_audioram_write_word, 
    68         ext_audioram_read_byte, ext_audioram_write_byte, 
    69         ext_audioram_read_burst, ext_audioram_write_burst }; 
    72 static int32_t FASTCALL ext_audioscratch_read_long( sh4addr_t addr )
    73 {
    74     return *((int32_t *)(aica_scratch_ram + (addr&0x00001FFF)));
    75 }
    76 static int32_t FASTCALL ext_audioscratch_read_word( sh4addr_t addr )
    77 {
    78     return SIGNEXT16(*((int16_t *)(aica_scratch_ram + (addr&0x00001FFF))));
    79 }
    80 static int32_t FASTCALL ext_audioscratch_read_byte( sh4addr_t addr )
    81 {
    82     return SIGNEXT8(*((int16_t *)(aica_scratch_ram + (addr&0x00001FFF))));
    83 }
    84 static void FASTCALL ext_audioscratch_write_long( sh4addr_t addr, uint32_t val )
    85 {
    86     *(uint32_t *)(aica_scratch_ram + (addr&0x00001FFF)) = val;
    87     asic_g2_write_word();
    88 }
    89 static void FASTCALL ext_audioscratch_write_word( sh4addr_t addr, uint32_t val )
    90 {
    91     *(uint16_t *)(aica_scratch_ram + (addr&0x00001FFF)) = (uint16_t)val;
    92     asic_g2_write_word();
    93 }
    94 static void FASTCALL ext_audioscratch_write_byte( sh4addr_t addr, uint32_t val )
    95 {
    96     *(uint8_t *)(aica_scratch_ram + (addr&0x00001FFF)) = (uint8_t)val;
    97     asic_g2_write_word();
    98 }
    99 static void FASTCALL ext_audioscratch_read_burst( unsigned char *dest, sh4addr_t addr )
   100 {
   101     memcpy( dest, aica_scratch_ram+(addr&0x00001FFF), 32 );
   102 }
   103 static void FASTCALL ext_audioscratch_write_burst( sh4addr_t addr, unsigned char *src )
   104 {
   105     memcpy( aica_scratch_ram+(addr&0x00001FFF), src, 32 );
   106 }
   108 struct mem_region_fn mem_region_audioscratch = { ext_audioscratch_read_long, ext_audioscratch_write_long, 
   109         ext_audioscratch_read_word, ext_audioscratch_write_word, 
   110         ext_audioscratch_read_byte, ext_audioscratch_write_byte, 
   111         ext_audioscratch_read_burst, ext_audioscratch_write_burst }; 
   113 /************************** Local ARM support **************************/
   114 int arm_has_page( uint32_t addr ) {
   115     return ( addr < 0x00200000 ||
   116             (addr >= 0x00800000 && addr <= 0x00805000 ) );
   117 }
   119 uint32_t arm_read_long( uint32_t addr ) {
   120     if( addr < 0x00200000 ) {
   121         return *(int32_t *)(aica_main_ram + addr);
   122         /* Main sound ram */
   123     } else {
   124         uint32_t val;
   125         switch( addr & 0xFFFFF000 ) {
   126         case 0x00800000:
   127             val = mmio_region_AICA0_read(addr&0x0FFF);
   128             //	    DEBUG( "ARM long read from %08X => %08X", addr, val );
   129             return val;
   130         case 0x00801000:
   131             val = mmio_region_AICA1_read(addr&0x0FFF);
   132             //	    DEBUG( "ARM long read from %08X => %08X", addr, val );
   133             return val;
   134         case 0x00802000:
   135             val = mmio_region_AICA2_read(addr&0x0FFF);
   136             // DEBUG( "ARM long read from %08X => %08X", addr, val );
   137             return val;
   138         case 0x00803000:
   139         case 0x00804000:
   140             return *(int32_t *)(aica_scratch_ram + addr - 0x00803000);
   141         }
   142     }
   143     ERROR( "Attempted long read to undefined page: %08X at %08X",
   144            addr, armr.r[15] );
   145     /* Undefined memory */
   146     return 0;
   147 }
   149 uint32_t arm_read_word( uint32_t addr ) {
   150     return (uint32_t)(uint16_t)arm_read_long( addr );
   151 }
   153 uint32_t arm_read_byte( uint32_t addr ) {
   154     return (uint32_t)(uint8_t)arm_read_long( addr );
   155 }
   157 void arm_write_long( uint32_t addr, uint32_t value )
   158 {
   159     if( addr < 0x00200000 ) {
   160         /* Main sound ram */
   161         *(uint32_t *)(aica_main_ram + addr) = value;
   162     } else {
   163         switch( addr & 0xFFFFF000 ) {
   164         case 0x00800000:
   165             // DEBUG( "ARM long write to %08X <= %08X", addr, value );
   166             mmio_region_AICA0_write(addr&0x0FFF, value);
   167             break;
   168         case 0x00801000:
   169             // DEBUG( "ARM long write to %08X <= %08X", addr, value );
   170             mmio_region_AICA1_write(addr&0x0FFF, value);
   171             break;
   172         case 0x00802000:
   173             // DEBUG( "ARM long write to %08X <= %08X", addr, value );
   174             mmio_region_AICA2_write(addr&0x0FFF, value);
   175             break;
   176         case 0x00803000:
   177         case 0x00804000:
   178             *(uint32_t *)(aica_scratch_ram + addr - 0x00803000) = value;
   179             break;
   180         default:
   181             ERROR( "Attempted long write to undefined address: %08X",
   182                     addr );
   183             /* Undefined memory */
   184         } 
   185     }
   186     return;
   187 }
   189 uint32_t arm_combine_byte( uint32_t addr, uint32_t val, uint8_t byte )
   190 {
   191     switch( addr & 0x03 ) {
   192     case 0:
   193         return (val & 0xFFFFFF00) | byte;
   194     case 1:
   195         return (val & 0xFFFF00FF) | (byte<<8);
   196     case 2:
   197         return (val & 0xFF00FFFF) | (byte<<16);
   198     case 3:
   199         return (val & 0x00FFFFFF) | (byte<<24);
   200     default:
   201         return val; // Can't happen, but make gcc happy
   202     }
   203 }
   204 void arm_write_word( uint32_t addr, uint32_t value )
   205 {
   206 	if( addr < 0x00200000 ) {
   207         *(uint16_t *)(aica_main_ram + addr) = (uint16_t)value;
   208 	} else {
   210 	}
   211 }
   212 void arm_write_byte( uint32_t addr, uint32_t value )
   213 {
   214     if( addr < 0x00200000 ) {
   215         /* Main sound ram */
   216         *(uint8_t *)(aica_main_ram + addr) = (uint8_t)value;
   217     } else {
   218         uint32_t tmp;
   219         switch( addr & 0xFFFFF000 ) {
   220         case 0x00800000:
   221             tmp = MMIO_READ( AICA0, addr & 0x0FFC );
   222             value = arm_combine_byte( addr, tmp, value );
   223             mmio_region_AICA0_write(addr&0x0FFC, value);
   224             break;
   225         case 0x00801000:
   226             tmp = MMIO_READ( AICA1, addr & 0x0FFC );
   227             value = arm_combine_byte( addr, tmp, value );
   228             mmio_region_AICA1_write(addr&0x0FFC, value);
   229             break;
   230         case 0x00802000:
   231             tmp = MMIO_READ( AICA2, addr & 0x0FFC );
   232             value = arm_combine_byte( addr, tmp, value );
   233             mmio_region_AICA2_write(addr&0x0FFC, value);
   234             break;
   235         case 0x00803000:
   236         case 0x00804000:
   237             *(uint8_t *)(aica_scratch_ram + addr - 0x00803000) = (uint8_t)value;
   238             break;
   239         default:
   240             ERROR( "Attempted byte write to undefined address: %08X",
   241                     addr );
   242             /* Undefined memory */
   243         } 
   244     }
   245     return;
   246 }
   248 /* User translations - TODO */
   250 uint32_t arm_read_long_user( uint32_t addr ) {
   251     return arm_read_long( addr );
   252 }
   254 uint32_t arm_read_byte_user( uint32_t addr ) {
   255     return arm_read_byte( addr );
   256 }
   258 void arm_write_long_user( uint32_t addr, uint32_t val ) {
   259     arm_write_long( addr, val );
   260 }
   262 void arm_write_byte_user( uint32_t addr, uint32_t val )
   263 {
   264     arm_write_byte( addr, val );
   265 }
.