Search
lxdream.org :: lxdream/src/aica/armmem.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/armmem.c
changeset 66:2ec5b6eb75e5
prev40:852ee31ace0d
next431:248dd77a9e44
author nkeynes
date Wed Jan 03 09:00:17 2007 +0000 (17 years ago)
permissions -rw-r--r--
last change Adjust timers when they're read rather than waiting until the next time
slice. Also temporarily cut the CPU time by 4.
Initialize the FRQCR register to 0x0E0A for convenience
view annotate diff log raw
     1 /**
     2  * $Id: armmem.c,v 1.7 2006-01-10 13:56:54 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 0;
   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     }
   119 }
   121 void arm_write_byte( uint32_t addr, uint32_t value )
   122 {
   123     if( addr < 0x00200000 ) {
   124 	/* Main sound ram */
   125 	*(uint8_t *)(arm_mem + addr) = (uint8_t)value;
   126     } else {
   127 	uint32_t tmp;
   128 	switch( addr & 0xFFFFF000 ) {
   129 	case 0x00800000:
   130 	    tmp = MMIO_READ( AICA0, addr & 0x0FFC );
   131 	    value = arm_combine_byte( addr, tmp, value );
   132 	    mmio_region_AICA0_write(addr&0x0FFC, value);
   133 	    break;
   134 	case 0x00801000:
   135 	    tmp = MMIO_READ( AICA1, addr & 0x0FFC );
   136 	    value = arm_combine_byte( addr, tmp, value );
   137 	    mmio_region_AICA1_write(addr&0x0FFC, value);
   138 	    break;
   139 	case 0x00802000:
   140 	    tmp = MMIO_READ( AICA2, addr & 0x0FFC );
   141 	    value = arm_combine_byte( addr, tmp, value );
   142 	    mmio_region_AICA2_write(addr&0x0FFC, value);
   143 	    break;
   144 	case 0x00803000:
   145 	case 0x00804000:
   146 	    *(uint8_t *)(arm_mem_scratch + addr - 0x00803000) = (uint8_t)value;
   147 	    break;
   148 	default:
   149 	    ERROR( "Attempted byte write to undefined address: %08X",
   150 		   addr );
   151 	    /* Undefined memory */
   152 	} 
   153     }
   154     return 0;
   155 }
   157 /* User translations - TODO */
   159 uint32_t arm_read_long_user( uint32_t addr ) {
   160     return arm_read_long( addr );
   161 }
   163 uint32_t arm_read_byte_user( uint32_t addr ) {
   164     return arm_read_byte( addr );
   165 }
   167 void arm_write_long_user( uint32_t addr, uint32_t val ) {
   168     arm_write_long( addr, val );
   169 }
   171 void arm_write_byte_user( uint32_t addr, uint32_t val )
   172 {
   173     arm_write_byte( addr, val );
   174 }
.