nkeynes@31: /** nkeynes@40: * $Id: armmem.c,v 1.6 2005-12-26 10:48:20 nkeynes Exp $ nkeynes@31: * nkeynes@31: * Implements the ARM's memory map. nkeynes@31: * nkeynes@31: * Copyright (c) 2005 Nathan Keynes. nkeynes@31: * nkeynes@31: * This program is free software; you can redistribute it and/or modify nkeynes@31: * it under the terms of the GNU General Public License as published by nkeynes@31: * the Free Software Foundation; either version 2 of the License, or nkeynes@31: * (at your option) any later version. nkeynes@31: * nkeynes@31: * This program is distributed in the hope that it will be useful, nkeynes@31: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@31: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@31: * GNU General Public License for more details. nkeynes@31: */ nkeynes@31: nkeynes@11: #include nkeynes@11: #include "dream.h" nkeynes@7: #include "mem.h" nkeynes@7: nkeynes@11: char *arm_mem = NULL; nkeynes@40: char *arm_mem_scratch = NULL; nkeynes@11: nkeynes@7: void arm_mem_init() { nkeynes@11: arm_mem = mem_get_region_by_name( MEM_REGION_AUDIO ); nkeynes@40: arm_mem_scratch = mem_get_region_by_name( MEM_REGION_AUDIO_SCRATCH ); nkeynes@7: } nkeynes@7: nkeynes@14: int arm_has_page( uint32_t addr ) { nkeynes@14: return ( addr < 0x00200000 || nkeynes@14: (addr >= 0x00800000 && addr <= 0x00805000 ) ); nkeynes@14: } nkeynes@14: nkeynes@37: uint32_t arm_read_long( uint32_t addr ) { nkeynes@11: if( addr < 0x00200000 ) { nkeynes@11: return *(int32_t *)(arm_mem + addr); nkeynes@11: /* Main sound ram */ nkeynes@11: } else { nkeynes@37: switch( addr & 0xFFFFF000 ) { nkeynes@37: case 0x00800000: nkeynes@37: return mmio_region_AICA0_read(addr); nkeynes@37: case 0x00801000: nkeynes@37: return mmio_region_AICA1_read(addr); nkeynes@37: case 0x00802000: nkeynes@37: return mmio_region_AICA2_read(addr); nkeynes@37: case 0x00803000: nkeynes@37: case 0x00804000: nkeynes@40: return *(int32_t *)(arm_mem_scratch + addr - 0x00803000); nkeynes@37: } nkeynes@11: } nkeynes@37: ERROR( "Attempted long read to undefined page: %08X", nkeynes@37: addr ); nkeynes@37: /* Undefined memory */ nkeynes@37: return 0; nkeynes@7: } nkeynes@7: nkeynes@37: uint32_t arm_read_word( uint32_t addr ) { nkeynes@40: return (uint32_t)(uint16_t)arm_read_long( addr ); nkeynes@7: } nkeynes@7: nkeynes@37: uint32_t arm_read_byte( uint32_t addr ) { nkeynes@40: return (uint32_t)(uint8_t)arm_read_long( addr ); nkeynes@7: } nkeynes@7: nkeynes@37: void arm_write_long( uint32_t addr, uint32_t value ) nkeynes@37: { nkeynes@37: if( addr < 0x00200000 ) { nkeynes@40: /* Main sound ram */ nkeynes@37: *(uint32_t *)(arm_mem + addr) = value; nkeynes@37: } else { nkeynes@40: switch( addr & 0xFFFFF000 ) { nkeynes@40: case 0x00800000: nkeynes@40: mmio_region_AICA0_write(addr, value); nkeynes@40: break; nkeynes@40: case 0x00801000: nkeynes@40: mmio_region_AICA1_write(addr, value); nkeynes@40: break; nkeynes@40: case 0x00802000: nkeynes@40: mmio_region_AICA2_write(addr, value); nkeynes@40: break; nkeynes@40: case 0x00803000: nkeynes@40: case 0x00804000: nkeynes@40: *(uint32_t *)(arm_mem_scratch + addr - 0x00803000) = value; nkeynes@40: break; nkeynes@40: default: nkeynes@40: ERROR( "Attempted long write to undefined address: %08X", nkeynes@40: addr ); nkeynes@40: /* Undefined memory */ nkeynes@40: } nkeynes@37: } nkeynes@40: return 0; nkeynes@37: } nkeynes@37: nkeynes@37: void arm_write_byte( uint32_t addr, uint32_t value ) nkeynes@37: { nkeynes@37: if( addr < 0x00200000 ) { nkeynes@40: /* Main sound ram */ nkeynes@40: *(uint8_t *)(arm_mem + addr) = (uint8_t)value; nkeynes@37: } else { nkeynes@40: switch( addr & 0xFFFFF000 ) { nkeynes@40: case 0x00800000: nkeynes@40: mmio_region_AICA0_write(addr, value); nkeynes@40: break; nkeynes@40: case 0x00801000: nkeynes@40: mmio_region_AICA1_write(addr, value); nkeynes@40: break; nkeynes@40: case 0x00802000: nkeynes@40: mmio_region_AICA2_write(addr, value); nkeynes@40: break; nkeynes@40: case 0x00803000: nkeynes@40: case 0x00804000: nkeynes@40: *(uint8_t *)(arm_mem_scratch + addr - 0x00803000) = (uint8_t)value; nkeynes@40: break; nkeynes@40: default: nkeynes@40: ERROR( "Attempted byte write to undefined address: %08X", nkeynes@40: addr ); nkeynes@40: /* Undefined memory */ nkeynes@40: } nkeynes@37: } nkeynes@40: return 0; nkeynes@37: } nkeynes@37: nkeynes@37: /* User translations - TODO */ nkeynes@37: nkeynes@11: uint32_t arm_read_long_user( uint32_t addr ) { nkeynes@37: return arm_read_long( addr ); nkeynes@11: } nkeynes@11: nkeynes@11: uint32_t arm_read_byte_user( uint32_t addr ) { nkeynes@37: return arm_read_byte( addr ); nkeynes@37: } nkeynes@11: nkeynes@37: void arm_write_long_user( uint32_t addr, uint32_t val ) { nkeynes@37: arm_write_long( addr, val ); nkeynes@11: } nkeynes@37: nkeynes@37: void arm_write_byte_user( uint32_t addr, uint32_t val ) nkeynes@37: { nkeynes@37: arm_write_byte( addr, val ); nkeynes@37: }