filename | src/mem.h |
changeset | 1067:d3c00ffccfcd |
prev | 1065:bc1cc0c54917 |
prev | 946:d41ee7994db7 |
author | nkeynes |
date | Fri Aug 24 08:53:50 2012 +1000 (11 years ago) |
permissions | -rw-r--r-- |
last change | Move the generated prologue/epilogue code out into a common entry stub (reduces space requirements) and pre-save all saved registers. Change FASTCALL to use 3 regs instead of 2 since we can now keep everything in regs. |
file | annotate | diff | log | raw |
nkeynes@31 | 1 | /** |
nkeynes@586 | 2 | * $Id$ |
nkeynes@31 | 3 | * |
nkeynes@31 | 4 | * mem is responsible for creating and maintaining the overall system memory |
nkeynes@31 | 5 | * map, as visible from the SH4 processor. (Note the ARM has a different map) |
nkeynes@31 | 6 | * |
nkeynes@31 | 7 | * Copyright (c) 2005 Nathan Keynes. |
nkeynes@31 | 8 | * |
nkeynes@31 | 9 | * This program is free software; you can redistribute it and/or modify |
nkeynes@31 | 10 | * it under the terms of the GNU General Public License as published by |
nkeynes@31 | 11 | * the Free Software Foundation; either version 2 of the License, or |
nkeynes@31 | 12 | * (at your option) any later version. |
nkeynes@31 | 13 | * |
nkeynes@31 | 14 | * This program is distributed in the hope that it will be useful, |
nkeynes@31 | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
nkeynes@31 | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
nkeynes@31 | 17 | * GNU General Public License for more details. |
nkeynes@31 | 18 | */ |
nkeynes@31 | 19 | |
nkeynes@736 | 20 | #ifndef lxdream_mem_H |
nkeynes@736 | 21 | #define lxdream_mem_H 1 |
nkeynes@10 | 22 | |
nkeynes@10 | 23 | #include <stdint.h> |
nkeynes@477 | 24 | #include "lxdream.h" |
nkeynes@931 | 25 | #include "hook.h" |
nkeynes@10 | 26 | |
nkeynes@10 | 27 | #ifdef __cplusplus |
nkeynes@10 | 28 | extern "C" { |
nkeynes@10 | 29 | #endif |
nkeynes@10 | 30 | |
nkeynes@939 | 31 | |
nkeynes@939 | 32 | typedef FASTCALL int32_t (*mem_read_fn_t)(sh4addr_t); |
nkeynes@939 | 33 | typedef FASTCALL void (*mem_write_fn_t)(sh4addr_t, uint32_t); |
nkeynes@939 | 34 | typedef FASTCALL void (*mem_read_burst_fn_t)(unsigned char *,sh4addr_t); |
nkeynes@939 | 35 | typedef FASTCALL void (*mem_write_burst_fn_t)(sh4addr_t,unsigned char *); |
nkeynes@946 | 36 | typedef FASTCALL void (*mem_prefetch_fn_t)(sh4addr_t); |
nkeynes@939 | 37 | |
nkeynes@939 | 38 | typedef FASTCALL int32_t (*mem_read_exc_fn_t)(sh4addr_t, void *); |
nkeynes@939 | 39 | typedef FASTCALL void (*mem_write_exc_fn_t)(sh4addr_t, uint32_t, void *); |
nkeynes@939 | 40 | typedef FASTCALL void (*mem_read_burst_exc_fn_t)(unsigned char *,sh4addr_t, void *); |
nkeynes@939 | 41 | typedef FASTCALL void (*mem_write_burst_exc_fn_t)(sh4addr_t,unsigned char *, void *); |
nkeynes@946 | 42 | typedef FASTCALL void (*mem_prefetch_exc_fn_t)(sh4addr_t, void *); |
nkeynes@939 | 43 | |
nkeynes@931 | 44 | /** |
nkeynes@931 | 45 | * Basic memory region vtable - read/write at byte, word, long, and burst |
nkeynes@931 | 46 | * (32-byte) sizes. |
nkeynes@931 | 47 | */ |
nkeynes@929 | 48 | typedef struct mem_region_fn { |
nkeynes@946 | 49 | mem_read_fn_t read_long; |
nkeynes@946 | 50 | mem_write_fn_t write_long; |
nkeynes@946 | 51 | mem_read_fn_t read_word; |
nkeynes@946 | 52 | mem_write_fn_t write_word; |
nkeynes@946 | 53 | mem_read_fn_t read_byte; |
nkeynes@946 | 54 | mem_write_fn_t write_byte; |
nkeynes@946 | 55 | mem_read_burst_fn_t read_burst; |
nkeynes@946 | 56 | mem_write_burst_fn_t write_burst; |
nkeynes@946 | 57 | /* Prefetch is provided as a convenience for the SH4 - external memory |
nkeynes@946 | 58 | * spaces are automatically forced to unmapped_prefetch by mem.c |
nkeynes@946 | 59 | */ |
nkeynes@946 | 60 | mem_prefetch_fn_t prefetch; |
nkeynes@975 | 61 | /* Convenience for SH4 byte read/modify/write instructions */ |
nkeynes@975 | 62 | mem_read_fn_t read_byte_for_write; |
nkeynes@929 | 63 | } *mem_region_fn_t; |
nkeynes@931 | 64 | |
nkeynes@931 | 65 | int32_t FASTCALL unmapped_read_long( sh4addr_t addr ); |
nkeynes@931 | 66 | void FASTCALL unmapped_write_long( sh4addr_t addr, uint32_t val ); |
nkeynes@931 | 67 | void FASTCALL unmapped_read_burst( unsigned char *dest, sh4addr_t addr ); |
nkeynes@931 | 68 | void FASTCALL unmapped_write_burst( sh4addr_t addr, unsigned char *src ); |
nkeynes@946 | 69 | void FASTCALL unmapped_prefetch( sh4addr_t addr ); |
nkeynes@931 | 70 | extern struct mem_region_fn mem_region_unmapped; |
nkeynes@931 | 71 | |
nkeynes@10 | 72 | typedef struct mem_region { |
nkeynes@10 | 73 | uint32_t base; |
nkeynes@10 | 74 | uint32_t size; |
nkeynes@422 | 75 | const char *name; |
nkeynes@502 | 76 | sh4ptr_t mem; |
nkeynes@510 | 77 | uint32_t flags; |
nkeynes@929 | 78 | mem_region_fn_t fn; |
nkeynes@10 | 79 | } *mem_region_t; |
nkeynes@10 | 80 | |
nkeynes@10 | 81 | #define MAX_IO_REGIONS 24 |
nkeynes@931 | 82 | #define MAX_MEM_REGIONS 16 |
nkeynes@10 | 83 | |
nkeynes@180 | 84 | #define MEM_REGION_BIOS "Bios ROM" |
nkeynes@10 | 85 | #define MEM_REGION_MAIN "System RAM" |
nkeynes@10 | 86 | #define MEM_REGION_VIDEO "Video RAM" |
nkeynes@931 | 87 | #define MEM_REGION_VIDEO64 "Video RAM 64-bit" |
nkeynes@10 | 88 | #define MEM_REGION_AUDIO "Audio RAM" |
nkeynes@10 | 89 | #define MEM_REGION_AUDIO_SCRATCH "Audio Scratch RAM" |
nkeynes@146 | 90 | #define MEM_REGION_FLASH "System Flash" |
nkeynes@934 | 91 | #define MEM_REGION_PVR2TA "PVR2 TA Command" |
nkeynes@934 | 92 | #define MEM_REGION_PVR2YUV "PVR2 YUV Decode" |
nkeynes@934 | 93 | #define MEM_REGION_PVR2VDMA1 "PVR2 VRAM DMA 1" |
nkeynes@934 | 94 | #define MEM_REGION_PVR2VDMA2 "PVR2 VRAM DMA 2" |
nkeynes@10 | 95 | |
nkeynes@931 | 96 | typedef gboolean (*mem_page_remapped_hook_t)(sh4addr_t page, mem_region_fn_t newfn, void *user_data); |
nkeynes@931 | 97 | DECLARE_HOOK( mem_page_remapped_hook, mem_page_remapped_hook_t ); |
nkeynes@931 | 98 | |
nkeynes@934 | 99 | struct mem_region *mem_map_region( void *mem, uint32_t base, uint32_t size, |
nkeynes@934 | 100 | const char *name, mem_region_fn_t fn, int flags, uint32_t repeat_offset, |
nkeynes@934 | 101 | uint32_t repeat_until ); |
nkeynes@931 | 102 | |
nkeynes@543 | 103 | /** |
nkeynes@543 | 104 | * Load a ROM image from the specified filename. If the memory region has not |
nkeynes@543 | 105 | * been allocated, it is created now, otherwise the existing region is reused. |
nkeynes@543 | 106 | * If the CRC check fails, a warning will be printed. |
nkeynes@543 | 107 | * @return TRUE if the image was loaded successfully (irrespective of CRC failure). |
nkeynes@543 | 108 | */ |
nkeynes@934 | 109 | gboolean mem_load_rom( void *output, const gchar *filename, uint32_t size, uint32_t crc ); |
nkeynes@19 | 110 | void *mem_alloc_pages( int n ); |
nkeynes@502 | 111 | sh4ptr_t mem_get_region( uint32_t addr ); |
nkeynes@502 | 112 | sh4ptr_t mem_get_region_by_name( const char *name ); |
nkeynes@934 | 113 | gboolean mem_has_page( uint32_t addr ); |
nkeynes@146 | 114 | int mem_load_block( const gchar *filename, uint32_t base, uint32_t size ); |
nkeynes@146 | 115 | int mem_save_block( const gchar *filename, uint32_t base, uint32_t size ); |
nkeynes@586 | 116 | void mem_set_trace( const gchar *tracelist, int flag ); |
nkeynes@10 | 117 | void mem_init( void ); |
nkeynes@10 | 118 | void mem_reset( void ); |
nkeynes@912 | 119 | void mem_copy_from_sh4( sh4ptr_t dest, sh4addr_t src, size_t count ); |
nkeynes@912 | 120 | void mem_copy_to_sh4( sh4addr_t dest, sh4ptr_t src, size_t count ); |
nkeynes@10 | 121 | |
nkeynes@669 | 122 | /** |
nkeynes@669 | 123 | * Write a long value directly to SH4-addressable memory. |
nkeynes@669 | 124 | * @param dest a valid, writable physical memory address, relative to the SH4 |
nkeynes@669 | 125 | * @param value the value to write. |
nkeynes@669 | 126 | */ |
nkeynes@669 | 127 | void mem_write_long( sh4addr_t dest, uint32_t value ); |
nkeynes@669 | 128 | |
nkeynes@43 | 129 | #define ENABLE_DEBUG_MODE 1 |
nkeynes@43 | 130 | |
nkeynes@586 | 131 | typedef enum { BREAK_NONE=0, BREAK_ONESHOT=1, BREAK_KEEP=2 } breakpoint_type_t; |
nkeynes@586 | 132 | |
nkeynes@43 | 133 | struct breakpoint_struct { |
nkeynes@43 | 134 | uint32_t address; |
nkeynes@586 | 135 | breakpoint_type_t type; |
nkeynes@43 | 136 | }; |
nkeynes@43 | 137 | |
nkeynes@43 | 138 | #define MAX_BREAKPOINTS 32 |
nkeynes@43 | 139 | |
nkeynes@586 | 140 | |
nkeynes@586 | 141 | #define MEM_FLAG_ROM 4 /* Mem region is ROM-based */ |
nkeynes@586 | 142 | #define MEM_FLAG_RAM 6 |
nkeynes@10 | 143 | |
nkeynes@10 | 144 | #define WATCH_WRITE 1 |
nkeynes@10 | 145 | #define WATCH_READ 2 |
nkeynes@10 | 146 | #define WATCH_EXEC 3 /* AKA Breakpoint :) */ |
nkeynes@10 | 147 | |
nkeynes@10 | 148 | typedef struct watch_point *watch_point_t; |
nkeynes@10 | 149 | |
nkeynes@10 | 150 | watch_point_t mem_new_watch( uint32_t start, uint32_t end, int flags ); |
nkeynes@10 | 151 | void mem_delete_watch( watch_point_t watch ); |
nkeynes@10 | 152 | watch_point_t mem_is_watched( uint32_t addr, int size, int op ); |
nkeynes@10 | 153 | |
nkeynes@931 | 154 | extern mem_region_fn_t *ext_address_space; |
nkeynes@931 | 155 | |
nkeynes@931 | 156 | #define SIGNEXT4(n) ((((int32_t)(n))<<28)>>28) |
nkeynes@931 | 157 | #define SIGNEXT8(n) ((int32_t)((int8_t)(n))) |
nkeynes@931 | 158 | #define SIGNEXT12(n) ((((int32_t)(n))<<20)>>20) |
nkeynes@931 | 159 | #define SIGNEXT16(n) ((int32_t)((int16_t)(n))) |
nkeynes@931 | 160 | #define SIGNEXT32(n) ((int64_t)((int32_t)(n))) |
nkeynes@931 | 161 | #define SIGNEXT48(n) ((((int64_t)(n))<<16)>>16) |
nkeynes@931 | 162 | #define ZEROEXT32(n) ((int64_t)((uint64_t)((uint32_t)(n)))) |
nkeynes@736 | 163 | |
nkeynes@939 | 164 | /* Ensure the given region allows all of read/write/execute. If not |
nkeynes@939 | 165 | * page-aligned, some surrounding regions will similarly be unprotected. |
nkeynes@939 | 166 | */ |
nkeynes@939 | 167 | void mem_unprotect( void *ptr, uint32_t size ); |
nkeynes@939 | 168 | |
nkeynes@10 | 169 | #ifdef __cplusplus |
nkeynes@10 | 170 | } |
nkeynes@10 | 171 | #endif |
nkeynes@736 | 172 | |
nkeynes@736 | 173 | #endif /* !lxdream_mem_H */ |
.