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@931 | 31 | /**
|
nkeynes@931 | 32 | * Basic memory region vtable - read/write at byte, word, long, and burst
|
nkeynes@931 | 33 | * (32-byte) sizes.
|
nkeynes@931 | 34 | */
|
nkeynes@929 | 35 | typedef struct mem_region_fn {
|
nkeynes@929 | 36 | FASTCALL int32_t (*read_long)(sh4addr_t addr);
|
nkeynes@929 | 37 | FASTCALL void (*write_long)(sh4addr_t addr, uint32_t val);
|
nkeynes@929 | 38 | FASTCALL int32_t (*read_word)(sh4addr_t addr);
|
nkeynes@929 | 39 | FASTCALL void (*write_word)(sh4addr_t addr, uint32_t val);
|
nkeynes@929 | 40 | FASTCALL int32_t (*read_byte)(sh4addr_t addr);
|
nkeynes@929 | 41 | FASTCALL void (*write_byte)(sh4addr_t addr, uint32_t val);
|
nkeynes@929 | 42 | FASTCALL void (*read_burst)(unsigned char *dest, sh4addr_t addr);
|
nkeynes@929 | 43 | FASTCALL void (*write_burst)(sh4addr_t addr, unsigned char *src);
|
nkeynes@929 | 44 | } *mem_region_fn_t;
|
nkeynes@931 | 45 |
|
nkeynes@931 | 46 | int32_t FASTCALL unmapped_read_long( sh4addr_t addr );
|
nkeynes@931 | 47 | void FASTCALL unmapped_write_long( sh4addr_t addr, uint32_t val );
|
nkeynes@931 | 48 | void FASTCALL unmapped_read_burst( unsigned char *dest, sh4addr_t addr );
|
nkeynes@931 | 49 | void FASTCALL unmapped_write_burst( sh4addr_t addr, unsigned char *src );
|
nkeynes@931 | 50 | extern struct mem_region_fn mem_region_unmapped;
|
nkeynes@931 | 51 |
|
nkeynes@10 | 52 | typedef struct mem_region {
|
nkeynes@10 | 53 | uint32_t base;
|
nkeynes@10 | 54 | uint32_t size;
|
nkeynes@422 | 55 | const char *name;
|
nkeynes@502 | 56 | sh4ptr_t mem;
|
nkeynes@510 | 57 | uint32_t flags;
|
nkeynes@929 | 58 | mem_region_fn_t fn;
|
nkeynes@10 | 59 | } *mem_region_t;
|
nkeynes@10 | 60 |
|
nkeynes@10 | 61 | #define MAX_IO_REGIONS 24
|
nkeynes@931 | 62 | #define MAX_MEM_REGIONS 16
|
nkeynes@10 | 63 |
|
nkeynes@180 | 64 | #define MEM_REGION_BIOS "Bios ROM"
|
nkeynes@10 | 65 | #define MEM_REGION_MAIN "System RAM"
|
nkeynes@10 | 66 | #define MEM_REGION_VIDEO "Video RAM"
|
nkeynes@931 | 67 | #define MEM_REGION_VIDEO64 "Video RAM 64-bit"
|
nkeynes@10 | 68 | #define MEM_REGION_AUDIO "Audio RAM"
|
nkeynes@10 | 69 | #define MEM_REGION_AUDIO_SCRATCH "Audio Scratch RAM"
|
nkeynes@146 | 70 | #define MEM_REGION_FLASH "System Flash"
|
nkeynes@10 | 71 |
|
nkeynes@931 | 72 | typedef gboolean (*mem_page_remapped_hook_t)(sh4addr_t page, mem_region_fn_t newfn, void *user_data);
|
nkeynes@931 | 73 | DECLARE_HOOK( mem_page_remapped_hook, mem_page_remapped_hook_t );
|
nkeynes@931 | 74 |
|
nkeynes@929 | 75 | void *mem_create_ram_region( uint32_t base, uint32_t size, const char *name, mem_region_fn_t fn );
|
nkeynes@929 | 76 | void *mem_create_repeating_ram_region( uint32_t base, uint32_t size, const char *name, mem_region_fn_t fn,
|
nkeynes@146 | 77 | uint32_t repeat_offset, uint32_t last_repeat );
|
nkeynes@931 | 78 | void register_misc_region( uint32_t base, uint32_t size, const char *name, mem_region_fn_t fn );
|
nkeynes@931 | 79 |
|
nkeynes@543 | 80 | /**
|
nkeynes@543 | 81 | * Load a ROM image from the specified filename. If the memory region has not
|
nkeynes@543 | 82 | * been allocated, it is created now, otherwise the existing region is reused.
|
nkeynes@543 | 83 | * If the CRC check fails, a warning will be printed.
|
nkeynes@543 | 84 | * @return TRUE if the image was loaded successfully (irrespective of CRC failure).
|
nkeynes@543 | 85 | */
|
nkeynes@543 | 86 | gboolean mem_load_rom( const gchar *filename, uint32_t base, uint32_t size,
|
nkeynes@929 | 87 | uint32_t crc, const gchar *region_name, mem_region_fn_t fn );
|
nkeynes@19 | 88 | void *mem_alloc_pages( int n );
|
nkeynes@502 | 89 | sh4ptr_t mem_get_region( uint32_t addr );
|
nkeynes@502 | 90 | sh4ptr_t mem_get_region_by_name( const char *name );
|
nkeynes@10 | 91 | int mem_has_page( uint32_t addr );
|
nkeynes@502 | 92 | sh4ptr_t mem_get_page( uint32_t addr );
|
nkeynes@146 | 93 | int mem_load_block( const gchar *filename, uint32_t base, uint32_t size );
|
nkeynes@146 | 94 | int mem_save_block( const gchar *filename, uint32_t base, uint32_t size );
|
nkeynes@586 | 95 | void mem_set_trace( const gchar *tracelist, int flag );
|
nkeynes@10 | 96 | void mem_init( void );
|
nkeynes@10 | 97 | void mem_reset( void );
|
nkeynes@912 | 98 | void mem_copy_from_sh4( sh4ptr_t dest, sh4addr_t src, size_t count );
|
nkeynes@912 | 99 | void mem_copy_to_sh4( sh4addr_t dest, sh4ptr_t src, size_t count );
|
nkeynes@10 | 100 |
|
nkeynes@669 | 101 | /**
|
nkeynes@669 | 102 | * Write a long value directly to SH4-addressable memory.
|
nkeynes@669 | 103 | * @param dest a valid, writable physical memory address, relative to the SH4
|
nkeynes@669 | 104 | * @param value the value to write.
|
nkeynes@669 | 105 | */
|
nkeynes@669 | 106 | void mem_write_long( sh4addr_t dest, uint32_t value );
|
nkeynes@669 | 107 |
|
nkeynes@43 | 108 | #define ENABLE_DEBUG_MODE 1
|
nkeynes@43 | 109 |
|
nkeynes@586 | 110 | typedef enum { BREAK_NONE=0, BREAK_ONESHOT=1, BREAK_KEEP=2 } breakpoint_type_t;
|
nkeynes@586 | 111 |
|
nkeynes@43 | 112 | struct breakpoint_struct {
|
nkeynes@43 | 113 | uint32_t address;
|
nkeynes@586 | 114 | breakpoint_type_t type;
|
nkeynes@43 | 115 | };
|
nkeynes@43 | 116 |
|
nkeynes@43 | 117 | #define MAX_BREAKPOINTS 32
|
nkeynes@43 | 118 |
|
nkeynes@586 | 119 |
|
nkeynes@586 | 120 | #define MEM_FLAG_ROM 4 /* Mem region is ROM-based */
|
nkeynes@586 | 121 | #define MEM_FLAG_RAM 6
|
nkeynes@10 | 122 |
|
nkeynes@10 | 123 | #define WATCH_WRITE 1
|
nkeynes@10 | 124 | #define WATCH_READ 2
|
nkeynes@10 | 125 | #define WATCH_EXEC 3 /* AKA Breakpoint :) */
|
nkeynes@10 | 126 |
|
nkeynes@10 | 127 | typedef struct watch_point *watch_point_t;
|
nkeynes@10 | 128 |
|
nkeynes@10 | 129 | watch_point_t mem_new_watch( uint32_t start, uint32_t end, int flags );
|
nkeynes@10 | 130 | void mem_delete_watch( watch_point_t watch );
|
nkeynes@10 | 131 | watch_point_t mem_is_watched( uint32_t addr, int size, int op );
|
nkeynes@10 | 132 |
|
nkeynes@502 | 133 | extern sh4ptr_t *page_map;
|
nkeynes@931 | 134 | extern mem_region_fn_t *ext_address_space;
|
nkeynes@931 | 135 |
|
nkeynes@931 | 136 | #define SIGNEXT4(n) ((((int32_t)(n))<<28)>>28)
|
nkeynes@931 | 137 | #define SIGNEXT8(n) ((int32_t)((int8_t)(n)))
|
nkeynes@931 | 138 | #define SIGNEXT12(n) ((((int32_t)(n))<<20)>>20)
|
nkeynes@931 | 139 | #define SIGNEXT16(n) ((int32_t)((int16_t)(n)))
|
nkeynes@931 | 140 | #define SIGNEXT32(n) ((int64_t)((int32_t)(n)))
|
nkeynes@931 | 141 | #define SIGNEXT48(n) ((((int64_t)(n))<<16)>>16)
|
nkeynes@931 | 142 | #define ZEROEXT32(n) ((int64_t)((uint64_t)((uint32_t)(n))))
|
nkeynes@736 | 143 |
|
nkeynes@10 | 144 | #ifdef __cplusplus
|
nkeynes@10 | 145 | }
|
nkeynes@10 | 146 | #endif
|
nkeynes@736 | 147 |
|
nkeynes@736 | 148 | #endif /* !lxdream_mem_H */
|