1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
/* memory_pages.h: memory access routines
Copyright (c) 2003-2016 Philip Kendall
Copyright (c) 2015 Stuart Brady
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Author contact information:
E-mail: philip-fuse@shadowmagic.org.uk
*/
#ifndef FUSE_MEMORY_PAGES_H
#define FUSE_MEMORY_PAGES_H
#include <libspectrum.h>
/* Register a new memory source */
int memory_source_register( const char *description );
/* Get the description for a given source */
const char *memory_source_description( int source );
/* Get the source for a given description */
int memory_source_find( const char *description );
/* Pre-created memory sources */
extern int memory_source_rom; /* System ROM */
extern int memory_source_ram; /* System RAM */
extern int memory_source_dock; /* Timex DOCK */
extern int memory_source_exrom; /* Timex EXROM */
extern int memory_source_any; /* Used by the debugger to signify an absolute address */
extern int memory_source_none; /* No memory attached here */
typedef struct memory_page {
libspectrum_byte *page; /* The data for this page */
int writable; /* Can we write to this data? */
int contended; /* Are reads/writes to this page contended? */
int source; /* Where did this page come from? */
int save_to_snapshot; /* Set if this page should be saved snapshots
(set only if this page would not normally be
saved; things like RAM are always saved) */
int page_num; /* Which page from the source */
libspectrum_word offset; /* How far into the page this chunk starts */
} memory_page;
/* A memory page will be 1 << (this many) bytes in size
ie 12 => 4 KB, 13 => 8 KB, 14 => 16 KB
Note: we now rely on 2KB page size so this should no longer be changed
without a full review of all relevant code and changes will be required to
match
*/
#define MEMORY_PAGE_SIZE_LOGARITHM 11
/* The actual size of a memory page */
#define MEMORY_PAGE_SIZE ( 1 << MEMORY_PAGE_SIZE_LOGARITHM )
/* The mask to use to select the bits within a page */
#define MEMORY_PAGE_SIZE_MASK ( MEMORY_PAGE_SIZE - 1 )
/* The number of memory pages in 64K
This calculation is equivalent to 2^16 / MEMORY_PAGE_SIZE */
#define MEMORY_PAGES_IN_64K ( 1 << ( 16 - MEMORY_PAGE_SIZE_LOGARITHM ) )
/* The number of memory pages in 16K */
#define MEMORY_PAGES_IN_16K ( 1 << ( 14 - MEMORY_PAGE_SIZE_LOGARITHM ) )
/* The number of memory pages in 8K */
#define MEMORY_PAGES_IN_8K ( 1 << ( 13 - MEMORY_PAGE_SIZE_LOGARITHM ) )
/* The number of memory pages in 4K */
#define MEMORY_PAGES_IN_4K ( 1 << ( 12 - MEMORY_PAGE_SIZE_LOGARITHM ) )
/* The number of memory pages in 2K */
#define MEMORY_PAGES_IN_2K ( 1 << ( 11 - MEMORY_PAGE_SIZE_LOGARITHM ) )
/* The number of memory pages in 14K */
#define MEMORY_PAGES_IN_14K ( MEMORY_PAGES_IN_16K - MEMORY_PAGES_IN_2K )
/* The number of memory pages in 12K */
#define MEMORY_PAGES_IN_12K ( MEMORY_PAGES_IN_16K - MEMORY_PAGES_IN_4K )
/* Each RAM chunk accessible by the Z80 */
extern memory_page memory_map_read[MEMORY_PAGES_IN_64K];
extern memory_page memory_map_write[MEMORY_PAGES_IN_64K];
/* The number of 16Kb RAM pages we support: 1040 Kb needed for the Pentagon 1024 */
#define SPECTRUM_RAM_PAGES 65
/* The maximum number of 16Kb ROMs we support */
#define SPECTRUM_ROM_PAGES 4
extern memory_page memory_map_ram[SPECTRUM_RAM_PAGES * MEMORY_PAGES_IN_16K];
extern memory_page memory_map_rom[SPECTRUM_ROM_PAGES * MEMORY_PAGES_IN_16K];
/* Which RAM page contains the current screen */
extern int memory_current_screen;
/* Which bits to look at when working out where the screen is */
extern libspectrum_word memory_screen_mask;
void memory_register_startup( void );
libspectrum_byte *memory_pool_allocate( size_t length );
libspectrum_byte *memory_pool_allocate_persistent( size_t length,
int persistent );
void memory_pool_free( void );
/* Map in alternate bank if ROMCS is set */
void memory_romcs_map( void );
/* Have we loaded any custom ROMs? */
int memory_custom_rom( void );
/* Reset any memory configuration that may have changed in the machine
configuration */
void memory_reset( void );
/* Set contention for 16K of RAM */
void memory_ram_set_16k_contention( int page_num, int contended );
/* Map 16K of memory */
void memory_map_16k( libspectrum_word address, memory_page source[],
int page_num );
/* Map 16K of memory for either reading, writing or both */
void memory_map_16k_read_write( libspectrum_word address, memory_page source[],
int page_num, int map_read, int map_write );
/* Map 8K of memory */
void memory_map_8k( libspectrum_word address, memory_page source[],
int page_num );
/* Map 8K of memory for either reading, writing or both */
void memory_map_8k_read_write( libspectrum_word address, memory_page source[],
int page_num, int map_read, int map_write );
/* Map 4K of memory for either reading, writing or both */
void memory_map_4k_read_write( libspectrum_word address, memory_page source[],
int page_num, int map_read, int map_write );
/* Map 2K of memory for either reading, writing or both */
void memory_map_2k_read_write( libspectrum_word address, memory_page source[],
int page_num, int map_read, int map_write );
/* Map one page of memory */
void memory_map_page( memory_page *source[], int page_num );
/* Page in all 16K from /ROMCS */
void memory_map_romcs_full( memory_page source[] );
/* Page in 8K from /ROMCS */
void memory_map_romcs_8k( libspectrum_word address, memory_page source[] );
/* Page in 4K from /ROMCS */
void memory_map_romcs_4k( libspectrum_word address, memory_page source[] );
/* Page in 2K from /ROMCS */
void memory_map_romcs_2k( libspectrum_word address, memory_page source[] );
libspectrum_byte readbyte( libspectrum_word address );
/* Use a macro for performance in the main core, but a function for
flexibility in the core tester */
#ifndef CORETEST
#define readbyte_internal( address ) \
memory_map_read[ (libspectrum_word)(address) >> MEMORY_PAGE_SIZE_LOGARITHM ].page[ (address) & MEMORY_PAGE_SIZE_MASK ]
#else /* #ifndef CORETEST */
libspectrum_byte readbyte_internal( libspectrum_word address );
#endif /* #ifndef CORETEST */
void writebyte( libspectrum_word address, libspectrum_byte b );
void writebyte_internal( libspectrum_word address, libspectrum_byte b );
typedef void (*memory_display_dirty_fn)( libspectrum_word address,
libspectrum_byte b );
extern memory_display_dirty_fn memory_display_dirty;
void memory_display_dirty_sinclair( libspectrum_word address,
libspectrum_byte b );
void memory_display_dirty_pentagon_16_col( libspectrum_word address,
libspectrum_byte b );
typedef enum trap_type {
CHECK_TAPE_ROM,
CHECK_48K_ROM
} trap_type;
/* Check whether we're actually in the right ROM when a tape or other traps hit */
extern int trap_check_rom( trap_type type );
#endif /* #ifndef FUSE_MEMORY_PAGES_H */
|