File: memory.h

package info (click to toggle)
fuse-emulator 1.1.1%2Bdfsg1-2
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 11,120 kB
  • ctags: 8,968
  • sloc: ansic: 78,960; sh: 11,228; perl: 3,742; makefile: 1,104; yacc: 236; lex: 140
file content (175 lines) | stat: -rw-r--r-- 6,205 bytes parent folder | download
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
/* memory.h: memory access routines
   Copyright (c) 2003-2011 Philip Kendall

   $Id: memory.h 4724 2012-07-08 13:38:21Z fredm $

   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_H
#define FUSE_MEMORY_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
 */
#define MEMORY_PAGE_SIZE_LOGARITHM 12

/* 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 ) )

/* 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_init( void );
void memory_end( 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 8K of memory */
void memory_map_8k( libspectrum_word address, memory_page source[],
  int page_num );

/* Map one page of memory */
void memory_map_page( memory_page *source[], int page_num );

/* Page in from /ROMCS */
void memory_map_romcs( 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[] );

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 );

#endif				/* #ifndef FUSE_MEMORY_H */