filename | src/aica/armmem.c |
changeset | 1067:d3c00ffccfcd |
prev | 998:1754a8c6a9cf |
prev | 934:3acd3b3ee6d1 |
next | 1106:1879fd49ccf6 |
author | nkeynes |
date | Wed Oct 07 17:53:56 2009 +1000 (14 years ago) |
permissions | -rw-r--r-- |
last change | Create a host attachment for the SCIF serial port. By default, uses /dev/console Add general fd listening to netutil, and rename to ioutil Add SCIF update on port read/write - fixes KOS timing problems but needs to be redone properly. |
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 }
290 }
.