filename | src/aica/armmem.c |
changeset | 811:7ff871670e58 |
prev | 736:a02d1475ccfd |
next | 931:430048ea8b71 |
next | 953:f4a156508ad1 |
author | nkeynes |
date | Mon Oct 06 01:05:12 2008 +0000 (15 years ago) |
permissions | -rw-r--r-- |
last change | Move bundle/system paths into paths.c, install lxdreamrc into the bundle (Fix OSX bundle missing default configuration) |
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 *arm_mem = NULL;
26 unsigned char *arm_mem_scratch = NULL;
28 void arm_mem_init() {
29 arm_mem = mem_get_region_by_name( MEM_REGION_AUDIO );
30 arm_mem_scratch = mem_get_region_by_name( MEM_REGION_AUDIO_SCRATCH );
31 }
33 int arm_has_page( uint32_t addr ) {
34 return ( addr < 0x00200000 ||
35 (addr >= 0x00800000 && addr <= 0x00805000 ) );
36 }
38 uint32_t arm_read_long( uint32_t addr ) {
39 if( addr < 0x00200000 ) {
40 return *(int32_t *)(arm_mem + addr);
41 /* Main sound ram */
42 } else {
43 uint32_t val;
44 switch( addr & 0xFFFFF000 ) {
45 case 0x00800000:
46 val = mmio_region_AICA0_read(addr&0x0FFF);
47 // DEBUG( "ARM long read from %08X => %08X", addr, val );
48 return val;
49 case 0x00801000:
50 val = mmio_region_AICA1_read(addr&0x0FFF);
51 // DEBUG( "ARM long read from %08X => %08X", addr, val );
52 return val;
53 case 0x00802000:
54 val = mmio_region_AICA2_read(addr&0x0FFF);
55 // DEBUG( "ARM long read from %08X => %08X", addr, val );
56 return val;
57 case 0x00803000:
58 case 0x00804000:
59 return *(int32_t *)(arm_mem_scratch + addr - 0x00803000);
60 }
61 }
62 ERROR( "Attempted long read to undefined page: %08X at %08X",
63 addr, armr.r[15] );
64 /* Undefined memory */
65 return 0;
66 }
68 uint32_t arm_read_word( uint32_t addr ) {
69 return (uint32_t)(uint16_t)arm_read_long( addr );
70 }
72 uint32_t arm_read_byte( uint32_t addr ) {
73 return (uint32_t)(uint8_t)arm_read_long( addr );
74 }
76 void arm_write_long( uint32_t addr, uint32_t value )
77 {
78 if( addr < 0x00200000 ) {
79 /* Main sound ram */
80 *(uint32_t *)(arm_mem + addr) = value;
81 } else {
82 switch( addr & 0xFFFFF000 ) {
83 case 0x00800000:
84 // DEBUG( "ARM long write to %08X <= %08X", addr, value );
85 mmio_region_AICA0_write(addr&0x0FFF, value);
86 break;
87 case 0x00801000:
88 // DEBUG( "ARM long write to %08X <= %08X", addr, value );
89 mmio_region_AICA1_write(addr&0x0FFF, value);
90 break;
91 case 0x00802000:
92 // DEBUG( "ARM long write to %08X <= %08X", addr, value );
93 mmio_region_AICA2_write(addr&0x0FFF, value);
94 break;
95 case 0x00803000:
96 case 0x00804000:
97 *(uint32_t *)(arm_mem_scratch + addr - 0x00803000) = value;
98 break;
99 default:
100 ERROR( "Attempted long write to undefined address: %08X",
101 addr );
102 /* Undefined memory */
103 }
104 }
105 return;
106 }
108 uint32_t arm_combine_byte( uint32_t addr, uint32_t val, uint8_t byte )
109 {
110 switch( addr & 0x03 ) {
111 case 0:
112 return (val & 0xFFFFFF00) | byte;
113 case 1:
114 return (val & 0xFFFF00FF) | (byte<<8);
115 case 2:
116 return (val & 0xFF00FFFF) | (byte<<16);
117 case 3:
118 return (val & 0x00FFFFFF) | (byte<<24);
119 default:
120 return val; // Can't happen, but make gcc happy
121 }
122 }
123 void arm_write_word( uint32_t addr, uint32_t value )
124 {
125 if( addr < 0x00200000 ) {
126 *(uint16_t *)(arm_mem + addr) = (uint16_t)value;
127 } else {
129 }
130 }
131 void arm_write_byte( uint32_t addr, uint32_t value )
132 {
133 if( addr < 0x00200000 ) {
134 /* Main sound ram */
135 *(uint8_t *)(arm_mem + addr) = (uint8_t)value;
136 } else {
137 uint32_t tmp;
138 switch( addr & 0xFFFFF000 ) {
139 case 0x00800000:
140 tmp = MMIO_READ( AICA0, addr & 0x0FFC );
141 value = arm_combine_byte( addr, tmp, value );
142 mmio_region_AICA0_write(addr&0x0FFC, value);
143 break;
144 case 0x00801000:
145 tmp = MMIO_READ( AICA1, addr & 0x0FFC );
146 value = arm_combine_byte( addr, tmp, value );
147 mmio_region_AICA1_write(addr&0x0FFC, value);
148 break;
149 case 0x00802000:
150 tmp = MMIO_READ( AICA2, addr & 0x0FFC );
151 value = arm_combine_byte( addr, tmp, value );
152 mmio_region_AICA2_write(addr&0x0FFC, value);
153 break;
154 case 0x00803000:
155 case 0x00804000:
156 *(uint8_t *)(arm_mem_scratch + addr - 0x00803000) = (uint8_t)value;
157 break;
158 default:
159 ERROR( "Attempted byte write to undefined address: %08X",
160 addr );
161 /* Undefined memory */
162 }
163 }
164 return;
165 }
167 /* User translations - TODO */
169 uint32_t arm_read_long_user( uint32_t addr ) {
170 return arm_read_long( addr );
171 }
173 uint32_t arm_read_byte_user( uint32_t addr ) {
174 return arm_read_byte( addr );
175 }
177 void arm_write_long_user( uint32_t addr, uint32_t val ) {
178 arm_write_long( addr, val );
179 }
181 void arm_write_byte_user( uint32_t addr, uint32_t val )
182 {
183 arm_write_byte( addr, val );
184 }
.