filename | src/aica/armmem.c |
changeset | 66:2ec5b6eb75e5 |
prev | 40:852ee31ace0d |
next | 431:248dd77a9e44 |
author | nkeynes |
date | Wed Mar 22 14:29:02 2006 +0000 (18 years ago) |
permissions | -rw-r--r-- |
last change | Rename IDE DMA registers appropriately Remove forced irq hack Add correct irq handling for IDE Miscellaneous WIP for the GD-rom drive |
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 }
.