2 * $Id: armmem.c,v 1.7 2006-01-10 13:56:54 nkeynes Exp $
4 * Implements the ARM's memory map.
6 * Copyright (c) 2005 Nathan Keynes.
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.
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.
25 char *arm_mem_scratch = NULL;
28 arm_mem = mem_get_region_by_name( MEM_REGION_AUDIO );
29 arm_mem_scratch = mem_get_region_by_name( MEM_REGION_AUDIO_SCRATCH );
32 int arm_has_page( uint32_t addr ) {
33 return ( addr < 0x00200000 ||
34 (addr >= 0x00800000 && addr <= 0x00805000 ) );
37 uint32_t arm_read_long( uint32_t addr ) {
38 if( addr < 0x00200000 ) {
39 return *(int32_t *)(arm_mem + addr);
43 switch( addr & 0xFFFFF000 ) {
45 val = mmio_region_AICA0_read(addr&0x0FFF);
46 // DEBUG( "ARM long read from %08X => %08X", addr, val );
49 val = mmio_region_AICA1_read(addr&0x0FFF);
50 // DEBUG( "ARM long read from %08X => %08X", addr, val );
53 val = mmio_region_AICA2_read(addr&0x0FFF);
54 // DEBUG( "ARM long read from %08X => %08X", addr, val );
58 return *(int32_t *)(arm_mem_scratch + addr - 0x00803000);
61 ERROR( "Attempted long read to undefined page: %08X",
63 /* Undefined memory */
67 uint32_t arm_read_word( uint32_t addr ) {
68 return (uint32_t)(uint16_t)arm_read_long( addr );
71 uint32_t arm_read_byte( uint32_t addr ) {
72 return (uint32_t)(uint8_t)arm_read_long( addr );
75 void arm_write_long( uint32_t addr, uint32_t value )
77 if( addr < 0x00200000 ) {
79 *(uint32_t *)(arm_mem + addr) = value;
81 switch( addr & 0xFFFFF000 ) {
83 // DEBUG( "ARM long write to %08X <= %08X", addr, value );
84 mmio_region_AICA0_write(addr&0x0FFF, value);
87 // DEBUG( "ARM long write to %08X <= %08X", addr, value );
88 mmio_region_AICA1_write(addr&0x0FFF, value);
91 // DEBUG( "ARM long write to %08X <= %08X", addr, value );
92 mmio_region_AICA2_write(addr&0x0FFF, value);
96 *(uint32_t *)(arm_mem_scratch + addr - 0x00803000) = value;
99 ERROR( "Attempted long write to undefined address: %08X",
101 /* Undefined memory */
107 uint32_t arm_combine_byte( uint32_t addr, uint32_t val, uint8_t byte )
109 switch( addr & 0x03 ) {
111 return (val & 0xFFFFFF00) | byte;
113 return (val & 0xFFFF00FF) | (byte<<8);
115 return (val & 0xFF00FFFF) | (byte<<16);
117 return (val & 0x00FFFFFF) | (byte<<24);
121 void arm_write_byte( uint32_t addr, uint32_t value )
123 if( addr < 0x00200000 ) {
125 *(uint8_t *)(arm_mem + addr) = (uint8_t)value;
128 switch( addr & 0xFFFFF000 ) {
130 tmp = MMIO_READ( AICA0, addr & 0x0FFC );
131 value = arm_combine_byte( addr, tmp, value );
132 mmio_region_AICA0_write(addr&0x0FFC, value);
135 tmp = MMIO_READ( AICA1, addr & 0x0FFC );
136 value = arm_combine_byte( addr, tmp, value );
137 mmio_region_AICA1_write(addr&0x0FFC, value);
140 tmp = MMIO_READ( AICA2, addr & 0x0FFC );
141 value = arm_combine_byte( addr, tmp, value );
142 mmio_region_AICA2_write(addr&0x0FFC, value);
146 *(uint8_t *)(arm_mem_scratch + addr - 0x00803000) = (uint8_t)value;
149 ERROR( "Attempted byte write to undefined address: %08X",
151 /* Undefined memory */
157 /* User translations - TODO */
159 uint32_t arm_read_long_user( uint32_t addr ) {
160 return arm_read_long( addr );
163 uint32_t arm_read_byte_user( uint32_t addr ) {
164 return arm_read_byte( addr );
167 void arm_write_long_user( uint32_t addr, uint32_t val ) {
168 arm_write_long( addr, val );
171 void arm_write_byte_user( uint32_t addr, uint32_t val )
173 arm_write_byte( addr, val );
.