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 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 )
32 return *((int32_t *)(aica_main_ram + (addr&0x001FFFFF)));
34 static int32_t FASTCALL ext_audioram_read_word( sh4addr_t addr )
36 return SIGNEXT16(*((int16_t *)(aica_main_ram + (addr&0x001FFFFF))));
38 static int32_t FASTCALL ext_audioram_read_byte( sh4addr_t addr )
40 return SIGNEXT8(*((int16_t *)(aica_main_ram + (addr&0x001FFFFF))));
42 static void FASTCALL ext_audioram_write_long( sh4addr_t addr, uint32_t val )
44 *(uint32_t *)(aica_main_ram + (addr&0x001FFFFF)) = val;
47 static void FASTCALL ext_audioram_write_word( sh4addr_t addr, uint32_t val )
49 *(uint16_t *)(aica_main_ram + (addr&0x001FFFFF)) = (uint16_t)val;
52 static void FASTCALL ext_audioram_write_byte( sh4addr_t addr, uint32_t val )
54 *(uint8_t *)(aica_main_ram + (addr&0x001FFFFF)) = (uint8_t)val;
57 static void FASTCALL ext_audioram_read_burst( unsigned char *dest, sh4addr_t addr )
59 memcpy( dest, aica_main_ram+(addr&0x001FFFFF), 32 );
61 static void FASTCALL ext_audioram_write_burst( sh4addr_t addr, unsigned char *src )
63 memcpy( aica_main_ram+(addr&0x001FFFFF), src, 32 );
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 )
74 return *((int32_t *)(aica_scratch_ram + (addr&0x00001FFF)));
76 static int32_t FASTCALL ext_audioscratch_read_word( sh4addr_t addr )
78 return SIGNEXT16(*((int16_t *)(aica_scratch_ram + (addr&0x00001FFF))));
80 static int32_t FASTCALL ext_audioscratch_read_byte( sh4addr_t addr )
82 return SIGNEXT8(*((int16_t *)(aica_scratch_ram + (addr&0x00001FFF))));
84 static void FASTCALL ext_audioscratch_write_long( sh4addr_t addr, uint32_t val )
86 *(uint32_t *)(aica_scratch_ram + (addr&0x00001FFF)) = val;
89 static void FASTCALL ext_audioscratch_write_word( sh4addr_t addr, uint32_t val )
91 *(uint16_t *)(aica_scratch_ram + (addr&0x00001FFF)) = (uint16_t)val;
94 static void FASTCALL ext_audioscratch_write_byte( sh4addr_t addr, uint32_t val )
96 *(uint8_t *)(aica_scratch_ram + (addr&0x00001FFF)) = (uint8_t)val;
99 static void FASTCALL ext_audioscratch_read_burst( unsigned char *dest, sh4addr_t addr )
101 memcpy( dest, aica_scratch_ram+(addr&0x00001FFF), 32 );
103 static void FASTCALL ext_audioscratch_write_burst( sh4addr_t addr, unsigned char *src )
105 memcpy( aica_scratch_ram+(addr&0x00001FFF), src, 32 );
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 ) );
119 uint32_t arm_read_long( uint32_t addr ) {
120 if( addr < 0x00200000 ) {
121 return *(int32_t *)(aica_main_ram + addr);
125 switch( addr & 0xFFFFF000 ) {
127 val = mmio_region_AICA0_read(addr&0x0FFF);
128 // DEBUG( "ARM long read from %08X => %08X", addr, val );
131 val = mmio_region_AICA1_read(addr&0x0FFF);
132 // DEBUG( "ARM long read from %08X => %08X", addr, val );
135 val = mmio_region_AICA2_read(addr&0x0FFF);
136 // DEBUG( "ARM long read from %08X => %08X", addr, val );
140 return *(int32_t *)(aica_scratch_ram + addr - 0x00803000);
143 ERROR( "Attempted long read to undefined page: %08X at %08X",
145 /* Undefined memory */
149 uint32_t arm_read_word( uint32_t addr ) {
150 return (uint32_t)(uint16_t)arm_read_long( addr );
153 uint32_t arm_read_byte( uint32_t addr ) {
154 return (uint32_t)(uint8_t)arm_read_long( addr );
157 void arm_write_long( uint32_t addr, uint32_t value )
159 if( addr < 0x00200000 ) {
161 *(uint32_t *)(aica_main_ram + addr) = value;
163 switch( addr & 0xFFFFF000 ) {
165 // DEBUG( "ARM long write to %08X <= %08X", addr, value );
166 mmio_region_AICA0_write(addr&0x0FFF, value);
169 // DEBUG( "ARM long write to %08X <= %08X", addr, value );
170 mmio_region_AICA1_write(addr&0x0FFF, value);
173 // DEBUG( "ARM long write to %08X <= %08X", addr, value );
174 mmio_region_AICA2_write(addr&0x0FFF, value);
178 *(uint32_t *)(aica_scratch_ram + addr - 0x00803000) = value;
181 ERROR( "Attempted long write to undefined address: %08X",
183 /* Undefined memory */
189 uint32_t arm_combine_byte( uint32_t addr, uint32_t val, uint8_t byte )
191 switch( addr & 0x03 ) {
193 return (val & 0xFFFFFF00) | byte;
195 return (val & 0xFFFF00FF) | (byte<<8);
197 return (val & 0xFF00FFFF) | (byte<<16);
199 return (val & 0x00FFFFFF) | (byte<<24);
201 return val; // Can't happen, but make gcc happy
204 void arm_write_word( uint32_t addr, uint32_t value )
206 if( addr < 0x00200000 ) {
207 *(uint16_t *)(aica_main_ram + addr) = (uint16_t)value;
212 void arm_write_byte( uint32_t addr, uint32_t value )
214 if( addr < 0x00200000 ) {
216 *(uint8_t *)(aica_main_ram + addr) = (uint8_t)value;
219 switch( addr & 0xFFFFF000 ) {
221 tmp = MMIO_READ( AICA0, addr & 0x0FFC );
222 value = arm_combine_byte( addr, tmp, value );
223 mmio_region_AICA0_write(addr&0x0FFC, value);
226 tmp = MMIO_READ( AICA1, addr & 0x0FFC );
227 value = arm_combine_byte( addr, tmp, value );
228 mmio_region_AICA1_write(addr&0x0FFC, value);
231 tmp = MMIO_READ( AICA2, addr & 0x0FFC );
232 value = arm_combine_byte( addr, tmp, value );
233 mmio_region_AICA2_write(addr&0x0FFC, value);
237 *(uint8_t *)(aica_scratch_ram + addr - 0x00803000) = (uint8_t)value;
240 ERROR( "Attempted byte write to undefined address: %08X",
242 /* Undefined memory */
248 /* User translations - TODO */
250 uint32_t arm_read_long_user( uint32_t addr ) {
251 return arm_read_long( addr );
254 uint32_t arm_read_byte_user( uint32_t addr ) {
255 return arm_read_byte( addr );
258 void arm_write_long_user( uint32_t addr, uint32_t val ) {
259 arm_write_long( addr, val );
262 void arm_write_byte_user( uint32_t addr, uint32_t val )
264 arm_write_byte( addr, val );
.