-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmemory_pages.h
212 lines (150 loc) · 7.58 KB
/
memory_pages.h
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 */