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