filename | src/aica/armmem.c |
changeset | 561:533f6b478071 |
prev | 502:c4ecae2b1b5e |
next | 736:a02d1475ccfd |
author | nkeynes |
date | Mon Jul 14 00:09:51 2008 +0000 (15 years ago) |
permissions | -rw-r--r-- |
last change | Fix version number in configure.in Remove obsolete x86_64 AM conditional Add --disable-translator option for testing purposes |
file | annotate | diff | log | raw |
nkeynes@31 | 1 | /** |
nkeynes@561 | 2 | * $Id$ |
nkeynes@31 | 3 | * |
nkeynes@31 | 4 | * Implements the ARM's memory map. |
nkeynes@31 | 5 | * |
nkeynes@31 | 6 | * Copyright (c) 2005 Nathan Keynes. |
nkeynes@31 | 7 | * |
nkeynes@31 | 8 | * This program is free software; you can redistribute it and/or modify |
nkeynes@31 | 9 | * it under the terms of the GNU General Public License as published by |
nkeynes@31 | 10 | * the Free Software Foundation; either version 2 of the License, or |
nkeynes@31 | 11 | * (at your option) any later version. |
nkeynes@31 | 12 | * |
nkeynes@31 | 13 | * This program is distributed in the hope that it will be useful, |
nkeynes@31 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
nkeynes@31 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
nkeynes@31 | 16 | * GNU General Public License for more details. |
nkeynes@31 | 17 | */ |
nkeynes@31 | 18 | |
nkeynes@11 | 19 | #include <stdlib.h> |
nkeynes@11 | 20 | #include "dream.h" |
nkeynes@7 | 21 | #include "mem.h" |
nkeynes@66 | 22 | #include "aica.h" |
nkeynes@7 | 23 | |
nkeynes@502 | 24 | unsigned char *arm_mem = NULL; |
nkeynes@502 | 25 | unsigned char *arm_mem_scratch = NULL; |
nkeynes@11 | 26 | |
nkeynes@7 | 27 | void arm_mem_init() { |
nkeynes@11 | 28 | arm_mem = mem_get_region_by_name( MEM_REGION_AUDIO ); |
nkeynes@40 | 29 | arm_mem_scratch = mem_get_region_by_name( MEM_REGION_AUDIO_SCRATCH ); |
nkeynes@7 | 30 | } |
nkeynes@7 | 31 | |
nkeynes@14 | 32 | int arm_has_page( uint32_t addr ) { |
nkeynes@14 | 33 | return ( addr < 0x00200000 || |
nkeynes@14 | 34 | (addr >= 0x00800000 && addr <= 0x00805000 ) ); |
nkeynes@14 | 35 | } |
nkeynes@14 | 36 | |
nkeynes@37 | 37 | uint32_t arm_read_long( uint32_t addr ) { |
nkeynes@11 | 38 | if( addr < 0x00200000 ) { |
nkeynes@11 | 39 | return *(int32_t *)(arm_mem + addr); |
nkeynes@11 | 40 | /* Main sound ram */ |
nkeynes@11 | 41 | } else { |
nkeynes@66 | 42 | uint32_t val; |
nkeynes@37 | 43 | switch( addr & 0xFFFFF000 ) { |
nkeynes@37 | 44 | case 0x00800000: |
nkeynes@66 | 45 | val = mmio_region_AICA0_read(addr&0x0FFF); |
nkeynes@66 | 46 | // DEBUG( "ARM long read from %08X => %08X", addr, val ); |
nkeynes@66 | 47 | return val; |
nkeynes@37 | 48 | case 0x00801000: |
nkeynes@66 | 49 | val = mmio_region_AICA1_read(addr&0x0FFF); |
nkeynes@66 | 50 | // DEBUG( "ARM long read from %08X => %08X", addr, val ); |
nkeynes@66 | 51 | return val; |
nkeynes@37 | 52 | case 0x00802000: |
nkeynes@66 | 53 | val = mmio_region_AICA2_read(addr&0x0FFF); |
nkeynes@66 | 54 | // DEBUG( "ARM long read from %08X => %08X", addr, val ); |
nkeynes@66 | 55 | return val; |
nkeynes@37 | 56 | case 0x00803000: |
nkeynes@37 | 57 | case 0x00804000: |
nkeynes@40 | 58 | return *(int32_t *)(arm_mem_scratch + addr - 0x00803000); |
nkeynes@37 | 59 | } |
nkeynes@11 | 60 | } |
nkeynes@37 | 61 | ERROR( "Attempted long read to undefined page: %08X", |
nkeynes@37 | 62 | addr ); |
nkeynes@37 | 63 | /* Undefined memory */ |
nkeynes@37 | 64 | return 0; |
nkeynes@7 | 65 | } |
nkeynes@7 | 66 | |
nkeynes@37 | 67 | uint32_t arm_read_word( uint32_t addr ) { |
nkeynes@40 | 68 | return (uint32_t)(uint16_t)arm_read_long( addr ); |
nkeynes@7 | 69 | } |
nkeynes@7 | 70 | |
nkeynes@37 | 71 | uint32_t arm_read_byte( uint32_t addr ) { |
nkeynes@40 | 72 | return (uint32_t)(uint8_t)arm_read_long( addr ); |
nkeynes@7 | 73 | } |
nkeynes@7 | 74 | |
nkeynes@37 | 75 | void arm_write_long( uint32_t addr, uint32_t value ) |
nkeynes@37 | 76 | { |
nkeynes@37 | 77 | if( addr < 0x00200000 ) { |
nkeynes@40 | 78 | /* Main sound ram */ |
nkeynes@37 | 79 | *(uint32_t *)(arm_mem + addr) = value; |
nkeynes@37 | 80 | } else { |
nkeynes@40 | 81 | switch( addr & 0xFFFFF000 ) { |
nkeynes@40 | 82 | case 0x00800000: |
nkeynes@66 | 83 | // DEBUG( "ARM long write to %08X <= %08X", addr, value ); |
nkeynes@66 | 84 | mmio_region_AICA0_write(addr&0x0FFF, value); |
nkeynes@40 | 85 | break; |
nkeynes@40 | 86 | case 0x00801000: |
nkeynes@66 | 87 | // DEBUG( "ARM long write to %08X <= %08X", addr, value ); |
nkeynes@66 | 88 | mmio_region_AICA1_write(addr&0x0FFF, value); |
nkeynes@40 | 89 | break; |
nkeynes@40 | 90 | case 0x00802000: |
nkeynes@66 | 91 | // DEBUG( "ARM long write to %08X <= %08X", addr, value ); |
nkeynes@66 | 92 | mmio_region_AICA2_write(addr&0x0FFF, value); |
nkeynes@40 | 93 | break; |
nkeynes@40 | 94 | case 0x00803000: |
nkeynes@40 | 95 | case 0x00804000: |
nkeynes@40 | 96 | *(uint32_t *)(arm_mem_scratch + addr - 0x00803000) = value; |
nkeynes@40 | 97 | break; |
nkeynes@40 | 98 | default: |
nkeynes@40 | 99 | ERROR( "Attempted long write to undefined address: %08X", |
nkeynes@40 | 100 | addr ); |
nkeynes@40 | 101 | /* Undefined memory */ |
nkeynes@40 | 102 | } |
nkeynes@37 | 103 | } |
nkeynes@431 | 104 | return; |
nkeynes@37 | 105 | } |
nkeynes@37 | 106 | |
nkeynes@66 | 107 | uint32_t arm_combine_byte( uint32_t addr, uint32_t val, uint8_t byte ) |
nkeynes@66 | 108 | { |
nkeynes@66 | 109 | switch( addr & 0x03 ) { |
nkeynes@66 | 110 | case 0: |
nkeynes@66 | 111 | return (val & 0xFFFFFF00) | byte; |
nkeynes@66 | 112 | case 1: |
nkeynes@66 | 113 | return (val & 0xFFFF00FF) | (byte<<8); |
nkeynes@66 | 114 | case 2: |
nkeynes@66 | 115 | return (val & 0xFF00FFFF) | (byte<<16); |
nkeynes@66 | 116 | case 3: |
nkeynes@66 | 117 | return (val & 0x00FFFFFF) | (byte<<24); |
nkeynes@431 | 118 | default: |
nkeynes@431 | 119 | return val; // Can't happen, but make gcc happy |
nkeynes@66 | 120 | } |
nkeynes@66 | 121 | } |
nkeynes@66 | 122 | |
nkeynes@37 | 123 | void arm_write_byte( uint32_t addr, uint32_t value ) |
nkeynes@37 | 124 | { |
nkeynes@37 | 125 | if( addr < 0x00200000 ) { |
nkeynes@40 | 126 | /* Main sound ram */ |
nkeynes@40 | 127 | *(uint8_t *)(arm_mem + addr) = (uint8_t)value; |
nkeynes@37 | 128 | } else { |
nkeynes@66 | 129 | uint32_t tmp; |
nkeynes@40 | 130 | switch( addr & 0xFFFFF000 ) { |
nkeynes@40 | 131 | case 0x00800000: |
nkeynes@66 | 132 | tmp = MMIO_READ( AICA0, addr & 0x0FFC ); |
nkeynes@66 | 133 | value = arm_combine_byte( addr, tmp, value ); |
nkeynes@66 | 134 | mmio_region_AICA0_write(addr&0x0FFC, value); |
nkeynes@40 | 135 | break; |
nkeynes@40 | 136 | case 0x00801000: |
nkeynes@66 | 137 | tmp = MMIO_READ( AICA1, addr & 0x0FFC ); |
nkeynes@66 | 138 | value = arm_combine_byte( addr, tmp, value ); |
nkeynes@66 | 139 | mmio_region_AICA1_write(addr&0x0FFC, value); |
nkeynes@40 | 140 | break; |
nkeynes@40 | 141 | case 0x00802000: |
nkeynes@66 | 142 | tmp = MMIO_READ( AICA2, addr & 0x0FFC ); |
nkeynes@66 | 143 | value = arm_combine_byte( addr, tmp, value ); |
nkeynes@66 | 144 | mmio_region_AICA2_write(addr&0x0FFC, value); |
nkeynes@40 | 145 | break; |
nkeynes@40 | 146 | case 0x00803000: |
nkeynes@40 | 147 | case 0x00804000: |
nkeynes@40 | 148 | *(uint8_t *)(arm_mem_scratch + addr - 0x00803000) = (uint8_t)value; |
nkeynes@40 | 149 | break; |
nkeynes@40 | 150 | default: |
nkeynes@40 | 151 | ERROR( "Attempted byte write to undefined address: %08X", |
nkeynes@40 | 152 | addr ); |
nkeynes@40 | 153 | /* Undefined memory */ |
nkeynes@40 | 154 | } |
nkeynes@37 | 155 | } |
nkeynes@431 | 156 | return; |
nkeynes@37 | 157 | } |
nkeynes@37 | 158 | |
nkeynes@37 | 159 | /* User translations - TODO */ |
nkeynes@37 | 160 | |
nkeynes@11 | 161 | uint32_t arm_read_long_user( uint32_t addr ) { |
nkeynes@37 | 162 | return arm_read_long( addr ); |
nkeynes@11 | 163 | } |
nkeynes@11 | 164 | |
nkeynes@11 | 165 | uint32_t arm_read_byte_user( uint32_t addr ) { |
nkeynes@37 | 166 | return arm_read_byte( addr ); |
nkeynes@37 | 167 | } |
nkeynes@11 | 168 | |
nkeynes@37 | 169 | void arm_write_long_user( uint32_t addr, uint32_t val ) { |
nkeynes@37 | 170 | arm_write_long( addr, val ); |
nkeynes@11 | 171 | } |
nkeynes@37 | 172 | |
nkeynes@37 | 173 | void arm_write_byte_user( uint32_t addr, uint32_t val ) |
nkeynes@37 | 174 | { |
nkeynes@37 | 175 | arm_write_byte( addr, val ); |
nkeynes@37 | 176 | } |
.