1 /*
2  * scpu64mem.c -- SCPU64 memory handling.
3  *
4  * Written by
5  *  Kajtar Zsolt <soci@c64.rulez.org>
6  *  Andreas Boose <viceteam@t-online.de>
7  *  Ettore Perazzoli <ettore@comm2000.it>
8  *
9  * This file is part of VICE, the Versatile Commodore Emulator.
10  * See README for copyright notice.
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25  *  02111-1307  USA.
26  *
27  */
28 
29 #include "vice.h"
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 
35 #include "scpu64.h"
36 #include "scpu64-resources.h"
37 #include "c64cart.h"
38 #include "c64cia.h"
39 #include "c64pla.h"
40 #include "scpu64mem.h"
41 #include "scpu64rom.h"
42 #include "scpu64meminit.h"
43 #include "c64cartmem.h"
44 #include "cartio.h"
45 #include "cartridge.h"
46 #include "cia.h"
47 #include "clkguard.h"
48 #include "machine.h"
49 #include "main65816cpu.h"
50 #include "mem.h"
51 #include "monitor.h"
52 #include "ram.h"
53 #include "reu.h"
54 #include "sid.h"
55 #include "vicii-mem.h"
56 #include "vicii-phi1.h"
57 #include "vicii.h"
58 #include "scpu64cpu.h"
59 #include "lib.h"
60 #include "wdc65816.h"
61 #include "vicii-cycle.h"
62 #include "traps.h"
63 
64 /* Machine class */
65 int machine_class = VICE_MACHINE_SCPU64;
66 
67 static int scpu64_version_v2 = 1; /* for future v1 emulation */
68 
69 /* Dummy processor port.  */
70 pport_t pport;
71 
72 /* C64 memory-related resources.  */
73 
74 /* ------------------------------------------------------------------------- */
75 
76 /* Number of possible memory configurations.  */
77 #define NUM_CONFIGS     256
78 
79 /* Number of possible mirroring configurations.  */
80 #define NUM_MIRRORS     16
81 
82 static const uint16_t mem_mirrors[NUM_MIRRORS] = {
83     0x80bf, 0x80bf, 0x003f, 0x023f,
84     0x407f, 0x407f, 0xc0ff, 0xc0ff,
85     0x0407, 0x0407,        0,    0,
86     0x00ff, 0x02ff, 0x00ff, 0x02ff
87 };
88 
89 /* The C64 memory.  */
90 uint8_t mem_ram[SCPU64_RAM_SIZE];
91 uint8_t mem_sram[SCPU64_SRAM_SIZE];
92 uint8_t mem_trap_ram[SCPU64_KERNAL_ROM_SIZE];
93 uint8_t *mem_simm_ram = NULL;
94 static int mem_simm_page_size;
95 static int mem_conf_page_size;
96 static int mem_conf_size;
97 unsigned int mem_simm_ram_mask = 0;
98 uint8_t mem_tooslow[1];
99 static int traps_pending;
100 
101 #ifdef USE_EMBEDDED
102 #define C64_CHARGEN_ROM_SIZE SCPU64_CHARGEN_ROM_SIZE
103 #include "c64chargen.h"
104 #else
105 uint8_t mem_chargen_rom[SCPU64_CHARGEN_ROM_SIZE];
106 #endif
107 
108 /* Internal color memory.  */
109 static uint8_t mem_color_ram[0x400];
110 uint8_t *mem_color_ram_cpu, *mem_color_ram_vicii;
111 
112 /* Pointer to the chargen ROM.  */
113 uint8_t *mem_chargen_rom_ptr;
114 
115 /* Pointers to the currently used memory read and write tables.  */
116 read_func_ptr_t *_mem_read_tab_ptr;
117 store_func_ptr_t *_mem_write_tab_ptr;
118 static uint8_t **_mem_read_base_tab_ptr;
119 static uint32_t *mem_read_limit_tab_ptr;
120 
121 /* Memory read and write tables.  */
122 static store_func_ptr_t mem_write_tab[NUM_MIRRORS][NUM_CONFIGS][0x101];
123 static read_func_ptr_t mem_read_tab[NUM_CONFIGS][0x101];
124 static uint8_t *mem_read_base_tab[NUM_CONFIGS][0x101];
125 static uint32_t mem_read_limit_tab[NUM_CONFIGS][0x101];
126 
127 static store_func_ptr_t mem_write_tab_watch[0x101];
128 static read_func_ptr_t mem_read_tab_watch[0x101];
129 
130 /* Current mirror config */
131 static int mirror;
132 
133 /* Current memory configuration.  */
134 static int mem_config;
135 
136 /* Current watchpoint state. 1 = watchpoints active, 0 = no watchpoints */
137 static int watchpoints_active;
138 
139 
140 static int mem_reg_sw_1mhz;     /* 1MHz physical switch */
141 static int mem_reg_sw_jiffy = 1;/* Jiffy physical switch */
142 int mem_reg_soft_1mhz;          /* 1MHz software enabled */
143 int mem_reg_sys_1mhz;           /* 1MHz system enabled */
144 int mem_reg_hwenable;           /* hardware enabled */
145 int mem_reg_dosext;             /* dos extension enable */
146 int mem_reg_ramlink;            /* ramlink registers enable */
147 int mem_reg_optim;              /* optimization mode */
148 int mem_reg_bootmap;            /* boot map */
149 int mem_reg_simm;               /* simm configuration */
150 int mem_pport;                  /* processor "port" */
151 
152 /* ------------------------------------------------------------------------- */
153 
check_ba_read(void)154 inline static void check_ba_read(void)
155 {
156     if (!scpu64_fastmode && maincpu_ba_low_flags) {
157         maincpu_steal_cycles();
158     }
159 }
160 
check_ba_write(void)161 inline static void check_ba_write(void)
162 {
163     if (!scpu64_fastmode && !scpu64_emulation_mode && maincpu_ba_low_flags) {
164         maincpu_steal_cycles();
165     }
166 }
167 /* ------------------------------------------------------------------------- */
168 
zero_read_watch(uint16_t addr)169 static uint8_t zero_read_watch(uint16_t addr)
170 {
171     addr &= 0xff;
172     monitor_watch_push_load_addr(addr, e_comp_space);
173     return mem_read_tab[mem_config][0](addr);
174 }
175 
zero_store_watch(uint16_t addr,uint8_t value)176 static void zero_store_watch(uint16_t addr, uint8_t value)
177 {
178     addr &= 0xff;
179     monitor_watch_push_store_addr(addr, e_comp_space);
180     mem_write_tab[mirror][mem_config][0](addr, value);
181 }
182 
read_watch(uint16_t addr)183 static uint8_t read_watch(uint16_t addr)
184 {
185     monitor_watch_push_load_addr(addr, e_comp_space);
186     return mem_read_tab[mem_config][addr >> 8](addr);
187 }
188 
store_watch(uint16_t addr,uint8_t value)189 static void store_watch(uint16_t addr, uint8_t value)
190 {
191     monitor_watch_push_store_addr(addr, e_comp_space);
192     mem_write_tab[mirror][mem_config][addr >> 8](addr, value);
193 }
194 
mem_toggle_watchpoints(int flag,void * context)195 void mem_toggle_watchpoints(int flag, void *context)
196 {
197     if (flag) {
198         _mem_read_tab_ptr = mem_read_tab_watch;
199         _mem_write_tab_ptr = mem_write_tab_watch;
200     } else {
201         _mem_read_tab_ptr = mem_read_tab[mem_config];
202         _mem_write_tab_ptr = mem_write_tab[mirror][mem_config];
203     }
204     watchpoints_active = flag;
205 }
206 
207 /* ------------------------------------------------------------------------- */
208 
scpu64_mem_init(void)209 void scpu64_mem_init(void)
210 {
211     /* Initialize REU BA low interface (FIXME find a better place for this) */
212     reu_ba_register(vicii_cycle, vicii_steal_cycles, &maincpu_ba_low_flags, MAINCPU_BA_LOW_REU);
213 }
214 
mem_pla_config_changed(void)215 void mem_pla_config_changed(void)
216 {
217     mem_config = ((mem_pport & 7) | (export.exrom << 3) | (export.game << 4)
218                 | (mem_reg_hwenable << 5) | (mem_reg_dosext << 6) | (mem_reg_bootmap << 7));
219 
220     if (watchpoints_active) {
221         _mem_read_tab_ptr = mem_read_tab_watch;
222         _mem_write_tab_ptr = mem_write_tab_watch;
223     } else {
224         _mem_read_tab_ptr = mem_read_tab[mem_config];
225         _mem_write_tab_ptr = mem_write_tab[mirror][mem_config];
226     }
227 
228     _mem_read_base_tab_ptr = mem_read_base_tab[mem_config];
229     mem_read_limit_tab_ptr = mem_read_limit_tab[mem_config];
230 
231     maincpu_resync_limits();
232 }
233 
pport_store(uint16_t addr,uint8_t value)234 static void pport_store(uint16_t addr, uint8_t value)
235 {
236     if (mem_pport != value) {
237         mem_pport = value;
238         mem_pla_config_changed();
239     }
240 }
241 
zero_read(uint16_t addr)242 uint8_t zero_read(uint16_t addr)
243 {
244     addr &= 0xff;
245 
246     switch ((uint8_t)addr) {
247         case 0:
248             return pport.dir_read;
249         case 1:
250             return pport.data_read;
251     }
252 
253     return mem_ram[addr & 0xff];
254 }
255 
zero_store(uint16_t addr,uint8_t value)256 void zero_store(uint16_t addr, uint8_t value)
257 {
258     mem_sram[addr] = value;
259 
260     if (addr == 1) {
261         pport_store(addr, (uint8_t)(value & 7));
262     }
263 }
264 
zero_store_mirrored(uint16_t addr,uint8_t value)265 static void zero_store_mirrored(uint16_t addr, uint8_t value)
266 {
267     scpu64_clock_write_stretch();
268     mem_sram[addr] = value;
269     if (addr == 1) {
270         pport_store(addr, (uint8_t)(value & 7));
271     }
272     mem_ram[addr] = value;
273 }
274 
zero_store_int(uint16_t addr,uint8_t value)275 static void zero_store_int(uint16_t addr, uint8_t value)
276 {
277     scpu64_clock_write_stretch();
278     if (addr == 1) {
279         pport_store(addr, (uint8_t)(value & 7));
280     }
281     mem_ram[addr] = value;
282 }
283 
284 /* ------------------------------------------------------------------------- */
285 
chargen_read(uint16_t addr)286 uint8_t chargen_read(uint16_t addr)
287 {
288     scpu64_clock_read_stretch_io();
289     return mem_chargen_rom[addr & 0xfff];
290 }
291 
ram_read(uint16_t addr)292 uint8_t ram_read(uint16_t addr)
293 {
294     check_ba_read();
295     return mem_sram[addr];
296 }
297 
ram_store(uint16_t addr,uint8_t value)298 void ram_store(uint16_t addr, uint8_t value)
299 {
300     check_ba_write();
301     mem_sram[addr] = value;
302 }
303 
ram_read_int(uint16_t addr)304 uint8_t ram_read_int(uint16_t addr)
305 {
306     scpu64_clock_read_stretch_io();
307     return mem_ram[addr];
308 }
309 
ram_store_int(uint16_t addr,uint8_t value)310 void ram_store_int(uint16_t addr, uint8_t value)
311 {
312     scpu64_clock_write_stretch();
313     mem_ram[addr] = value;
314 }
315 
ram_store_mirrored(uint16_t addr,uint8_t value)316 static void ram_store_mirrored(uint16_t addr, uint8_t value)
317 {
318     scpu64_clock_write_stretch();
319     mem_sram[addr] = value;
320     mem_ram[addr] = value;
321 }
322 /* ------------------------------------ */
ram_hi_store_mirrored(uint16_t addr,uint8_t value)323 static void ram_hi_store_mirrored(uint16_t addr, uint8_t value) /* mirrored, no vbank */
324 {
325     if (addr == 0xff00) {
326         scpu64_clock_write_stretch_io_start();
327         mem_sram[addr] = value;
328         mem_ram[addr] = value;
329         reu_dma(-1);
330         scpu64_clock_write_stretch_io_long();
331     } else {
332         scpu64_clock_write_stretch();
333         mem_sram[addr] = value;
334         mem_ram[addr] = value;
335     }
336 }
337 
ram_hi_store(uint16_t addr,uint8_t value)338 static void ram_hi_store(uint16_t addr, uint8_t value) /* not mirrored */
339 {
340     if (addr == 0xff00) {
341         scpu64_clock_write_stretch_io_start();
342         mem_sram[addr] = value;
343         reu_dma(-1);
344         scpu64_clock_write_stretch_io_long();
345     } else {
346         check_ba_write();
347         mem_sram[addr] = value;
348     }
349 }
350 
ram_hi_store_int(uint16_t addr,uint8_t value)351 static void ram_hi_store_int(uint16_t addr, uint8_t value) /* internal */
352 {
353     if (addr == 0xff00) {
354         scpu64_clock_write_stretch_io_start();
355         mem_ram[addr] = value;
356         reu_dma(-1);
357         scpu64_clock_write_stretch_io_long();
358     } else {
359         scpu64_clock_write_stretch();
360         mem_ram[addr] = value;
361     }
362 }
363 
364 /* ------------------------------------ */
365 
scpu64_kernalshadow_read(uint16_t addr)366 uint8_t scpu64_kernalshadow_read(uint16_t addr)
367 {
368     check_ba_read();
369     return mem_sram[0x8000 + addr];
370 }
371 
ram1_read(uint16_t addr)372 uint8_t ram1_read(uint16_t addr)
373 {
374     check_ba_read();
375     return mem_sram[0x10000 + addr];
376 }
377 
scpu64rom_scpu64_read(uint16_t addr)378 uint8_t scpu64rom_scpu64_read(uint16_t addr)
379 {
380     scpu64_clock_read_stretch_eprom();
381     return scpu64rom_scpu64_rom[addr];
382 }
383 
384 /* ------------------------------------------------------------------------- */
385 
386 /* Generic memory access.  */
387 
mem_store(uint16_t addr,uint8_t value)388 void mem_store(uint16_t addr, uint8_t value)
389 {
390     _mem_write_tab_ptr[addr >> 8](addr, value);
391 }
392 
mem_read(uint16_t addr)393 uint8_t mem_read(uint16_t addr)
394 {
395     return _mem_read_tab_ptr[addr >> 8](addr);
396 }
397 
mem_store2(uint32_t addr,uint8_t value)398 void mem_store2(uint32_t addr, uint8_t value)
399 {
400     switch (addr & 0xfe0000) {
401     case 0xf60000:
402         if (mem_simm_ram_mask) {
403             if (mem_simm_page_size != mem_conf_page_size) {
404                 addr = ((addr >> mem_conf_page_size) << mem_simm_page_size) | (addr & ((1 << mem_simm_page_size)-1));
405                 addr &= mem_simm_ram_mask;
406             }
407             if (mem_reg_hwenable) {
408                 mem_simm_ram[addr & 0x1ffff] = value;
409             }
410             scpu64_clock_write_stretch_simm(addr);
411         }
412         return;
413     case 0xf80000:
414     case 0xfa0000:
415     case 0xfc0000:
416     case 0xfe0000:
417         scpu64_clock_write_stretch_eprom();
418         return;
419     case 0x000000:
420         if (addr & 0xfffe) {
421             if (addr >= 0x1e000 && mem_trap_ram[addr & 0x1fff] != value) {
422                 traps_pending = 1;
423                 mem_trap_ram[addr & 0x1fff] = value;
424             }
425             mem_sram[addr] = value;
426         } else if (scpu64_version_v2) {
427             mem_sram[addr & 1] = value;
428         } else {
429             mem_sram[addr] = value;
430         }
431         return;
432     default:
433         if (mem_simm_ram_mask && addr < (unsigned int)mem_conf_size) {
434             if (mem_simm_page_size != mem_conf_page_size) {
435                 addr = ((addr >> mem_conf_page_size) << mem_simm_page_size) | (addr & ((1 << mem_simm_page_size)-1));
436             }
437             mem_simm_ram[addr & mem_simm_ram_mask] = value;
438             scpu64_clock_write_stretch_simm(addr);
439         }
440     }
441 }
442 
mem_read2(uint32_t addr)443 uint8_t mem_read2(uint32_t addr)
444 {
445     switch (addr & 0xfe0000) {
446     case 0xf60000:
447         if (mem_simm_ram_mask) {
448             if (mem_simm_page_size != mem_conf_page_size) {
449                 addr = ((addr >> mem_conf_page_size) << mem_simm_page_size) | (addr & ((1 << mem_simm_page_size)-1));
450                 addr &= mem_simm_ram_mask;
451             }
452             scpu64_clock_read_stretch_simm(addr);
453             return mem_simm_ram[addr & 0x1ffff];
454         }
455         break;
456     case 0xf80000:
457     case 0xfa0000:
458     case 0xfc0000:
459     case 0xfe0000:
460         scpu64_clock_read_stretch_eprom();
461         return scpu64rom_scpu64_rom[addr & (SCPU64_SCPU64_ROM_MAXSIZE-1) & 0x7ffff];
462     case 0x000000:
463         if (addr & 0xfffe) {
464             return mem_sram[addr];
465         }
466         return scpu64_version_v2 ? mem_sram[addr & 1] : mem_sram[addr];
467     default:
468         if (mem_simm_ram_mask && addr < (unsigned int)mem_conf_size) {
469             if (mem_simm_page_size != mem_conf_page_size) {
470                 addr = ((addr >> mem_conf_page_size) << mem_simm_page_size) | (addr & ((1 << mem_simm_page_size)-1));
471             }
472             scpu64_clock_read_stretch_simm(addr);
473             return mem_simm_ram[addr & mem_simm_ram_mask];
474         }
475         break;
476     }
477     return (uint8_t)(addr >> 16);
478 }
479 
mem_peek2(uint32_t addr)480 static uint8_t mem_peek2(uint32_t addr)
481 {
482     switch (addr & 0xfe0000) {
483     case 0xf60000:
484         if (mem_simm_ram_mask) {
485             if (mem_simm_page_size != mem_conf_page_size) {
486                 addr = ((addr >> mem_conf_page_size) << mem_simm_page_size) | (addr & ((1 << mem_simm_page_size)-1));
487                 addr &= mem_simm_ram_mask;
488             }
489             return mem_simm_ram[addr & 0x1ffff];
490         }
491         break;
492     case 0xf80000:
493     case 0xfa0000:
494     case 0xfc0000:
495     case 0xfe0000:
496         return scpu64rom_scpu64_rom[addr & (SCPU64_SCPU64_ROM_MAXSIZE-1) & 0x7ffff];
497     case 0x000000:
498         if (addr & 0xfffe) {
499             return mem_sram[addr];
500         }
501         return scpu64_version_v2 ? mem_sram[addr & 1] : mem_sram[addr];
502     default:
503         if (mem_simm_ram_mask && addr < (unsigned int)mem_conf_size) {
504             if (mem_simm_page_size != mem_conf_page_size) {
505                 addr = ((addr >> mem_conf_page_size) << mem_simm_page_size) | (addr & ((1 << mem_simm_page_size)-1));
506             }
507             return mem_simm_ram[addr & mem_simm_ram_mask];
508         }
509         break;
510     }
511     return (uint8_t)(addr >> 16);
512 }
513 
mem_store_without_ultimax(uint16_t addr,uint8_t value)514 void mem_store_without_ultimax(uint16_t addr, uint8_t value)
515 {
516     store_func_ptr_t *write_tab_ptr;
517 
518     write_tab_ptr = mem_write_tab[mirror][mem_config & 7];
519 
520     write_tab_ptr[addr >> 8](addr, value);
521 }
522 
mem_read_without_ultimax(uint16_t addr)523 uint8_t mem_read_without_ultimax(uint16_t addr)
524 {
525     read_func_ptr_t *read_tab_ptr;
526 
527     read_tab_ptr = mem_read_tab[mem_config & 7];
528 
529     return read_tab_ptr[addr >> 8](addr);
530 }
531 
mem_store_without_romlh(uint16_t addr,uint8_t value)532 void mem_store_without_romlh(uint16_t addr, uint8_t value)
533 {
534     store_func_ptr_t *write_tab_ptr;
535 
536     write_tab_ptr = mem_write_tab[mirror][0];
537 
538     write_tab_ptr[addr >> 8](addr, value);
539 }
540 
541 /* ------------------------------------------------------------------------- */
scpu64_hardware_read(uint16_t addr)542 static uint8_t scpu64_hardware_read(uint16_t addr)
543 {
544     uint8_t value = 0x00;
545 
546     switch (addr) {
547     case 0xd0b0:
548         value = scpu64_version_v2 ? 0x40 : 0xc0;
549         break;
550     case 0xd0b1:
551         break;
552     case 0xd0b2:       /* bit 7 - hwreg enabled (1)/disabled (0) */
553                        /* bit 6 - system 1 MHz enabled (1)/disabled (0) */
554         value = (mem_reg_hwenable ? 0x80 : 0x00) | (mem_reg_sys_1mhz ? 0x40 : 0x00);
555         break;
556     case 0xd0b3:
557         if (scpu64_version_v2) {
558             value = mem_reg_optim & 0xc0;
559         }
560         break;
561     case 0xd0b4:
562         value = mem_reg_optim & 0xc0;
563         break;
564     case 0xd0b5:      /* bit 7 - Jiffy (1)/No jiffy (0) switch */
565                       /* bit 6 - 1 MHz (1)/20 MHz (0) switch */
566         value = (mem_reg_sw_jiffy ? 0x80 : 0x00) | (mem_reg_sw_1mhz ? 0x40 : 0x00);
567         break;
568     case 0xd0b6:      /* bit 7 - Emulation mode (1)/Native (0) */
569         value = scpu64_emulation_mode ? 0x80 : 0x00;
570         break;
571     case 0xd0b7:
572         break;
573     case 0xd0b9:      /* same as 0xd0b8 */
574     case 0xd0b8:      /* bit 7 - software 1 MHz enabled (1)/disabled (0) */
575                       /* bit 6 - 1 MHz (1)/20 MHz (2) switch+software+system */
576         value = (mem_reg_soft_1mhz ? 0x80 : 0x00) | ((mem_reg_soft_1mhz
577                  || (mem_reg_sw_1mhz && !mem_reg_hwenable) || mem_reg_sys_1mhz) ? 0x40 : 0x00);
578         break;
579     case 0xd0ba:
580         break;
581     case 0xd0bb:
582         break;
583     case 0xd0bc:
584     case 0xd0bd:
585     case 0xd0be:
586     case 0xd0bf:
587         value = (mem_reg_dosext ? 0x80 : 0x00) | (mem_reg_ramlink ? 0x40 : 0x00);
588         break;
589     default:
590         value = 0xff;
591         break;
592     }
593     return value | (mem_reg_optim & 7);
594 }
595 
scpu64_hardware_store(uint16_t addr,uint8_t value)596 static void scpu64_hardware_store(uint16_t addr, uint8_t value)
597 {
598     switch (addr) {
599     case 0xd071:
600         break;
601     case 0xd072: /* System 1MHz enable */
602         if (!mem_reg_sys_1mhz) {
603             mem_reg_sys_1mhz = 1;
604             scpu64_set_fastmode(0);
605         }
606         break;
607     case 0xd073: /* System 1MHz disable */
608         if (mem_reg_sys_1mhz) {
609             mem_reg_sys_1mhz = 0;
610             scpu64_set_fastmode(!(mem_reg_soft_1mhz || (mem_reg_sw_1mhz && !mem_reg_hwenable)));
611         }
612         break;
613     case 0xd074: /* Optimization modes */
614     case 0xd075:
615     case 0xd076:
616     case 0xd077:
617         if (mem_reg_hwenable) {
618             mem_reg_optim = (addr << 6);
619             mem_set_mirroring(mem_reg_optim);
620         }
621         break;
622     case 0xd078: /* SIMM configuration */
623         if (mem_reg_hwenable && mem_reg_simm != value) {
624             mem_reg_simm = value;
625             mem_set_simm(mem_reg_simm);
626         }
627         break;
628     case 0xd07a: /* Software 1MHz enable */
629         if (!mem_reg_soft_1mhz) {
630             mem_reg_soft_1mhz = 1;
631             scpu64_set_fastmode(0);
632         }
633         break;
634     case 0xd079: /* same as 0xd07b */
635     case 0xd07b: /* Software 1MHz disable */
636         if (mem_reg_soft_1mhz) {
637             mem_reg_soft_1mhz = 0;
638             scpu64_set_fastmode(!(mem_reg_sys_1mhz || (mem_reg_sw_1mhz && !mem_reg_hwenable)));
639         }
640         break;
641     case 0xd07c:
642         break;
643     case 0xd07e: /* hwreg enable */
644         if (!mem_reg_hwenable) {
645             mem_reg_hwenable = 1;
646             scpu64_set_fastmode(!(mem_reg_sys_1mhz || mem_reg_soft_1mhz));
647             mem_pla_config_changed();
648         }
649         break;
650     case 0xd07d: /* same as 0xd07d */
651     case 0xd07f: /* hwreg disable */
652         if (mem_reg_hwenable) {
653             mem_reg_hwenable = 0;
654             scpu64_set_fastmode(!(mem_reg_sys_1mhz || mem_reg_soft_1mhz || mem_reg_sw_1mhz));
655             mem_pla_config_changed();
656         }
657         break;
658     case 0xd0b0:
659     case 0xd0b1:
660         break;
661     case 0xd0b2: /* hwenable and set system 1 MHz */
662         if (mem_reg_hwenable) {
663             mem_reg_sys_1mhz = !!(value & 0x40);
664             if (!(value & 0x80)) {
665                 mem_reg_hwenable = 0;
666                 mem_pla_config_changed();
667             }
668             scpu64_set_fastmode(!(mem_reg_sys_1mhz || mem_reg_soft_1mhz || (mem_reg_sw_1mhz && !mem_reg_hwenable)));
669         }
670         break;
671     case 0xd0b3: /* set optim mode */
672         if (mem_reg_hwenable && scpu64_version_v2) {
673             mem_reg_optim = (mem_reg_optim & 0x38) | (value & 0xc7);
674             mem_set_mirroring(mem_reg_optim);
675         }
676         break;
677     case 0xd0b4: /* set optim mode */
678         if (mem_reg_hwenable) {
679             mem_reg_optim = (mem_reg_optim & 0x3f) | (value & 0xc0);
680             mem_set_mirroring(mem_reg_optim);
681         }
682         break;
683     case 0xd0b5:
684         break;
685     case 0xd0b6: /* disable bootmap */
686         if (mem_reg_hwenable && mem_reg_bootmap) {
687             mem_reg_bootmap = 0;
688             mem_pla_config_changed();
689         }
690         break;
691     case 0xd0b7: /* enable bootmap */
692         if (mem_reg_hwenable && !mem_reg_bootmap) {
693             mem_reg_bootmap = 1;
694             mem_pla_config_changed();
695         }
696         break;
697     case 0xd0b8: /* set software 1 MHz */
698         if (mem_reg_hwenable) {
699             mem_reg_soft_1mhz = value >> 7;
700             scpu64_set_fastmode(!(mem_reg_sys_1mhz || mem_reg_soft_1mhz || (mem_reg_sw_1mhz && !mem_reg_hwenable)));
701         }
702         break;
703     case 0xd0b9:
704     case 0xd0ba:
705     case 0xd0bb:
706         break;
707     case 0xd0bc: /* set dos extension */
708         if (mem_reg_hwenable && (mem_reg_dosext != (value >> 7))) {
709             mem_reg_dosext = value >> 7;
710             mem_pla_config_changed();
711         }
712         break;
713     case 0xd0be: /* dos extension enable */
714         if (mem_reg_hwenable && !mem_reg_dosext) {
715             mem_reg_dosext = 1;
716             mem_pla_config_changed();
717         }
718         break;
719     case 0xd0bd: /* same as 0xd0bf */
720     case 0xd0bf: /* dos extension disable */
721         if (mem_reg_dosext) {
722             mem_reg_dosext = 0;
723             mem_pla_config_changed();
724         }
725         break;
726     default:
727         break;
728     }
729 }
730 
colorram_store(uint16_t addr,uint8_t value)731 static void colorram_store(uint16_t addr, uint8_t value)
732 {
733     if (scpu64_version_v2) mem_sram[0x10000 + addr] = value;
734     mem_color_ram[addr & 0x3ff] = value & 0xf;
735 }
736 
colorram_read(uint16_t addr)737 static uint8_t colorram_read(uint16_t addr)
738 {
739     if (scpu64_version_v2) {
740         return mem_sram[0x10000 + addr];
741     }
742     return mem_color_ram[addr & 0x3ff] | (vicii_read_phi1() & 0xf0);
743 }
744 
scpu64_d200_read(uint16_t addr)745 static uint8_t scpu64_d200_read(uint16_t addr)
746 {
747     return mem_sram[0x10000 + addr];
748 }
749 
scpu64_d200_store(uint16_t addr,uint8_t value)750 static void scpu64_d200_store(uint16_t addr, uint8_t value)
751 {
752     if (mem_reg_hwenable || addr == 0xd27e) {
753         mem_sram[0x10000 + addr] = value;
754     }
755 }
756 
scpu64_d300_read(uint16_t addr)757 static uint8_t scpu64_d300_read(uint16_t addr)
758 {
759     return mem_sram[0x10000 + addr];
760 }
761 
scpu64_d300_store(uint16_t addr,uint8_t value)762 static void scpu64_d300_store(uint16_t addr, uint8_t value)
763 {
764     if (mem_reg_hwenable) {
765         mem_sram[0x10000 + addr] = value;
766     }
767 }
768 /* ------------------------------------------------------------------------- */
769 
scpu64io_d000_read(uint16_t addr)770 uint8_t scpu64io_d000_read(uint16_t addr)
771 {
772     if ((addr & 0xfff0) == 0xd0b0) {
773         if (scpu64_version_v2) {
774             check_ba_read();
775             return scpu64_hardware_read(addr); /* not an i/o read! */
776         }
777         scpu64_clock_read_stretch_io();
778         return scpu64_hardware_read(addr); /* i/o read! */
779     }
780     scpu64_clock_read_stretch_io();
781     return c64io_d000_read(addr); /* i/o read */
782 }
783 
scpu64io_d000_peek(uint16_t addr)784 static uint8_t scpu64io_d000_peek(uint16_t addr)
785 {
786     if ((addr & 0xfff0) == 0xd0b0) {
787         return scpu64_hardware_read(addr);
788     } else {
789         return c64io_d000_peek(addr);
790     }
791 }
792 
scpu64io_d000_store(uint16_t addr,uint8_t value)793 void scpu64io_d000_store(uint16_t addr, uint8_t value)
794 {
795     int oldfastmode;
796     scpu64_clock_write_stretch_io_start();
797     if (scpu64_version_v2) mem_sram[0x10000 + addr] = value;
798     if ((addr >= 0xd071 && addr < 0xd080) || (addr >= 0xd0b0 && addr < 0xd0c0)) {
799         oldfastmode = scpu64_fastmode;
800         scpu64_hardware_store(addr, value);
801         if (!oldfastmode && scpu64_fastmode) {
802             return; /* stretch already handled */
803         }
804     } else {
805         c64io_d000_store(addr, value);
806     }
807     scpu64_clock_write_stretch_io();
808 }
809 
scpu64io_d100_read(uint16_t addr)810 uint8_t scpu64io_d100_read(uint16_t addr)
811 {
812     scpu64_clock_read_stretch_io();
813     return c64io_d100_read(addr); /* i/o read */
814 }
815 
scpu64io_d100_store(uint16_t addr,uint8_t value)816 void scpu64io_d100_store(uint16_t addr, uint8_t value)
817 {
818     scpu64_clock_write_stretch_io_start();
819     if (scpu64_version_v2) mem_sram[0x10000 + addr] = value;
820     c64io_d100_store(addr, value);
821     scpu64_clock_write_stretch_io();
822 }
823 
scpu64io_d200_read(uint16_t addr)824 uint8_t scpu64io_d200_read(uint16_t addr)
825 {
826     check_ba_read();
827     if (!scpu64_version_v2) {
828         scpu64_clock_read_ioram();
829     }
830     return scpu64_d200_read(addr); /* not an i/o read! */
831 }
832 
scpu64io_d200_store(uint16_t addr,uint8_t value)833 void scpu64io_d200_store(uint16_t addr, uint8_t value)
834 {
835     scpu64_clock_write_stretch();
836     scpu64_d200_store(addr, value);
837 }
838 
scpu64io_d300_read(uint16_t addr)839 uint8_t scpu64io_d300_read(uint16_t addr)
840 {
841     check_ba_read();
842     if (!scpu64_version_v2) {
843         scpu64_clock_read_ioram();
844     }
845     return scpu64_d300_read(addr); /* not an i/o read! */
846 }
847 
scpu64io_d300_store(uint16_t addr,uint8_t value)848 void scpu64io_d300_store(uint16_t addr, uint8_t value)
849 {
850     scpu64_clock_write_stretch();
851     scpu64_d300_store(addr, value);
852 }
853 
scpu64io_d400_read(uint16_t addr)854 uint8_t scpu64io_d400_read(uint16_t addr)
855 {
856     scpu64_clock_read_stretch_io();
857     return c64io_d400_read(addr); /* i/o read */
858 }
859 
scpu64io_d400_store(uint16_t addr,uint8_t value)860 void scpu64io_d400_store(uint16_t addr, uint8_t value)
861 {
862     scpu64_clock_write_stretch_io_start();
863     if (scpu64_version_v2) mem_sram[0x10000 + addr] = value;
864     c64io_d400_store(addr, value);
865     scpu64_clock_write_stretch_io();
866 }
867 
scpu64io_d500_read(uint16_t addr)868 uint8_t scpu64io_d500_read(uint16_t addr)
869 {
870     scpu64_clock_read_stretch_io();
871     return c64io_d500_read(addr); /* i/o read */
872 }
873 
scpu64io_d500_store(uint16_t addr,uint8_t value)874 void scpu64io_d500_store(uint16_t addr, uint8_t value)
875 {
876     scpu64_clock_write_stretch_io_start();
877     if (scpu64_version_v2) mem_sram[0x10000 + addr] = value;
878     c64io_d500_store(addr, value);
879     scpu64_clock_write_stretch_io();
880 }
881 
scpu64io_d600_read(uint16_t addr)882 uint8_t scpu64io_d600_read(uint16_t addr)
883 {
884     scpu64_clock_read_stretch_io();
885     return c64io_d600_read(addr); /* i/o read */
886 }
887 
scpu64io_d600_store(uint16_t addr,uint8_t value)888 void scpu64io_d600_store(uint16_t addr, uint8_t value)
889 {
890     scpu64_clock_write_stretch(); /* strange, but not i/o ! */
891     c64io_d600_store(addr, value);
892 }
893 
scpu64io_d700_read(uint16_t addr)894 uint8_t scpu64io_d700_read(uint16_t addr)
895 {
896     scpu64_clock_read_stretch_io();
897     return c64io_d700_read(addr); /* i/o read */
898 }
899 
scpu64io_d700_store(uint16_t addr,uint8_t value)900 void scpu64io_d700_store(uint16_t addr, uint8_t value)
901 {
902     scpu64_clock_write_stretch_io_start();
903     c64io_d700_store(addr, value);
904     scpu64_clock_write_stretch_io();
905 }
906 
scpu64io_colorram_read(uint16_t addr)907 uint8_t scpu64io_colorram_read(uint16_t addr)
908 {
909     if (scpu64_version_v2) {
910         check_ba_read();
911         return mem_sram[0x10000 + addr]; /* not an i/o read! */
912     }
913     scpu64_clock_read_stretch_io();
914     return mem_color_ram[addr & 0x3ff] | (vicii_read_phi1() & 0xf0); /* i/o read */
915 }
916 
scpu64io_colorram_store(uint16_t addr,uint8_t value)917 void scpu64io_colorram_store(uint16_t addr, uint8_t value)
918 {
919     scpu64_clock_write_stretch();
920     colorram_store(addr, value);
921 }
922 
scpu64io_colorram_read_int(uint16_t addr)923 uint8_t scpu64io_colorram_read_int(uint16_t addr)
924 {
925     scpu64_clock_read_stretch_io();
926     return vicii_read_phi1();
927 }
928 
scpu64io_colorram_store_int(uint16_t addr,uint8_t value)929 void scpu64io_colorram_store_int(uint16_t addr, uint8_t value)
930 {
931     scpu64_clock_write_stretch();
932     mem_color_ram[addr & 0x3ff] = value & 0xf;
933 }
934 
scpu64_cia1_read(uint16_t addr)935 uint8_t scpu64_cia1_read(uint16_t addr)
936 {
937     scpu64_clock_read_stretch_io();
938     return cia1_read(addr); /* i/o read */
939 }
940 
scpu64_cia1_store(uint16_t addr,uint8_t value)941 void scpu64_cia1_store(uint16_t addr, uint8_t value)
942 {
943     scpu64_clock_write_stretch_io_start_cia();
944     if (scpu64_version_v2) mem_sram[0x10000 + addr] = value;
945     cia1_store(addr, value);
946     scpu64_clock_write_stretch_io_cia();
947 }
948 
scpu64_cia2_read(uint16_t addr)949 uint8_t scpu64_cia2_read(uint16_t addr)
950 {
951     scpu64_clock_read_stretch_io();
952     return cia2_read(addr); /* i/o read */
953 }
954 
scpu64_cia2_store(uint16_t addr,uint8_t value)955 void scpu64_cia2_store(uint16_t addr, uint8_t value)
956 {
957     scpu64_clock_write_stretch_io_start_cia();
958     if (scpu64_version_v2) mem_sram[0x10000 + addr] = value;
959     cia2_store(addr, value);
960     scpu64_clock_write_stretch_io_cia();
961 }
962 
scpu64io_de00_read(uint16_t addr)963 uint8_t scpu64io_de00_read(uint16_t addr)
964 {
965     scpu64_clock_read_stretch_io();
966     return c64io_de00_read(addr); /* i/o read */
967 }
968 
scpu64io_de00_store(uint16_t addr,uint8_t value)969 void scpu64io_de00_store(uint16_t addr, uint8_t value)
970 {
971     scpu64_clock_write_stretch_io_start();
972     c64io_de00_store(addr, value);
973     scpu64_clock_write_stretch_io();
974 }
975 
scpu64io_df00_read(uint16_t addr)976 uint8_t scpu64io_df00_read(uint16_t addr)
977 {
978     scpu64_clock_read_stretch_io();
979     return c64io_df00_read(addr); /* i/o read */
980 }
981 
scpu64io_df00_store(uint16_t addr,uint8_t value)982 void scpu64io_df00_store(uint16_t addr, uint8_t value)
983 {
984     scpu64_clock_write_stretch_io_start();
985     c64io_df00_store(addr, value);
986     switch (addr) {
987     case 0xdf01:
988     case 0xdf21:
989         scpu64_clock_write_stretch_io_long();
990         break;
991     case 0xdf7e:
992         scpu64_clock_write_stretch_io(); /* TODO: verify */
993         mem_reg_ramlink = 1;
994         break;
995     case 0xdf7f:
996         scpu64_clock_write_stretch_io(); /* TODO: verify */
997         mem_reg_ramlink = 0;
998         break;
999     default:
1000         scpu64_clock_write_stretch_io();
1001         break;
1002     }
1003 }
1004 
scpu64_roml_read(uint16_t addr)1005 uint8_t scpu64_roml_read(uint16_t addr)
1006 {
1007     scpu64_clock_read_stretch_io();
1008     return roml_read(addr); /* i/o read */
1009 }
1010 
scpu64_roml_store(uint16_t addr,uint8_t value)1011 void scpu64_roml_store(uint16_t addr, uint8_t value)
1012 {
1013     scpu64_clock_write_stretch_io_start();
1014     roml_store(addr, value); /* i/o write */
1015     scpu64_clock_write_stretch_io();
1016 }
1017 
scpu64_romh_read(uint16_t addr)1018 uint8_t scpu64_romh_read(uint16_t addr)
1019 {
1020     scpu64_clock_read_stretch_io();
1021     return romh_read(addr); /* i/o read */
1022 }
1023 
scpu64_romh_store(uint16_t addr,uint8_t value)1024 void scpu64_romh_store(uint16_t addr, uint8_t value)
1025 {
1026     scpu64_clock_write_stretch_io_start();
1027     romh_store(addr, value); /* i/o write */
1028     scpu64_clock_write_stretch_io();
1029 }
1030 
scpu64_ultimax_1000_7fff_read(uint16_t addr)1031 uint8_t scpu64_ultimax_1000_7fff_read(uint16_t addr)
1032 {
1033     scpu64_clock_read_stretch_io();
1034     return ultimax_1000_7fff_read(addr); /* i/o read */
1035 }
1036 
scpu64_ultimax_1000_7fff_store(uint16_t addr,uint8_t value)1037 void scpu64_ultimax_1000_7fff_store(uint16_t addr, uint8_t value)
1038 {
1039     scpu64_clock_write_stretch_io_start();
1040     ultimax_1000_7fff_store(addr, value); /* i/o write */
1041     scpu64_clock_write_stretch_io();
1042 }
1043 
scpu64_ultimax_a000_bfff_read(uint16_t addr)1044 uint8_t scpu64_ultimax_a000_bfff_read(uint16_t addr)
1045 {
1046     scpu64_clock_read_stretch_io();
1047     return ultimax_a000_bfff_read(addr); /* i/o read */
1048 }
1049 
scpu64_ultimax_a000_bfff_store(uint16_t addr,uint8_t value)1050 void scpu64_ultimax_a000_bfff_store(uint16_t addr, uint8_t value)
1051 {
1052     scpu64_clock_write_stretch_io_start();
1053     ultimax_a000_bfff_store(addr, value); /* i/o write */
1054     scpu64_clock_write_stretch_io();
1055 }
1056 
scpu64_ultimax_c000_cfff_read(uint16_t addr)1057 uint8_t scpu64_ultimax_c000_cfff_read(uint16_t addr)
1058 {
1059     scpu64_clock_read_stretch_io();
1060     return ultimax_c000_cfff_read(addr); /* i/o read */
1061 }
1062 
scpu64_ultimax_c000_cfff_store(uint16_t addr,uint8_t value)1063 void scpu64_ultimax_c000_cfff_store(uint16_t addr, uint8_t value)
1064 {
1065     scpu64_clock_write_stretch_io_start();
1066     ultimax_c000_cfff_store(addr, value); /* i/o write */
1067     scpu64_clock_write_stretch_io();
1068 }
1069 
1070 /* ------------------------------------------------------------------------- */
1071 
mem_set_write_hook(int config,int page,store_func_t * f)1072 void mem_set_write_hook(int config, int page, store_func_t *f)
1073 {
1074     int j;
1075 
1076     for (j = 0; j < NUM_MIRRORS; j++) {
1077         mem_write_tab[j][config][page] = f;
1078     }
1079 }
1080 
mem_read_tab_set(unsigned int base,unsigned int index,read_func_ptr_t read_func)1081 void mem_read_tab_set(unsigned int base, unsigned int index, read_func_ptr_t read_func)
1082 {
1083     mem_read_tab[base][index] = read_func;
1084 }
1085 
mem_read_base_set(unsigned int base,unsigned int index,uint8_t * mem_ptr)1086 void mem_read_base_set(unsigned int base, unsigned int index, uint8_t *mem_ptr)
1087 {
1088     mem_read_base_tab[base][index] = mem_ptr;
1089 }
1090 
mem_initialize_memory(void)1091 void mem_initialize_memory(void)
1092 {
1093     int i, j, l;
1094 
1095     mem_chargen_rom_ptr = mem_chargen_rom;
1096     mem_color_ram_cpu = mem_color_ram;
1097     mem_color_ram_vicii = mem_color_ram;
1098 
1099     /* setup watchpoint tables */
1100     mem_read_tab_watch[0] = zero_read_watch;
1101     mem_write_tab_watch[0] = zero_store_watch;
1102     for (i = 1; i <= 0x100; i++) {
1103         mem_read_tab_watch[i] = read_watch;
1104         mem_write_tab_watch[i] = store_watch;
1105     }
1106 
1107     /* Default is RAM.  */
1108     /* normal RAM maps */
1109     for (i = 0; i < NUM_CONFIGS - 0x20; i++) {
1110         for (j = 0; j <= 0xff; j++) {
1111             mem_read_tab[i][j] = ram_read;
1112             mem_read_base_tab[i][j] = mem_sram;
1113             for (l = 0; l < NUM_MIRRORS; l++) {
1114                 if (mem_mirrors[l] && (mem_mirrors[l] >> 8) <= j && (mem_mirrors[l] & 0xff) >= j) {
1115                     /* mirrored */
1116                     if (j == 0) {
1117                         mem_write_tab[l][i][j] = zero_store_mirrored;
1118                     } else if (j == 0xff) {
1119                         mem_write_tab[l][i][j] = ram_hi_store_mirrored;
1120                     } else {
1121                         mem_write_tab[l][i][j] = ram_store_mirrored;
1122                     }
1123                 } else { /* nothing to see here */
1124                     if (j == 0) {
1125                         mem_write_tab[l][i][j] = zero_store;
1126                     } else if (j == 0xff) {
1127                         mem_write_tab[l][i][j] = ram_hi_store;
1128                     } else {
1129                         mem_write_tab[l][i][j] = ram_store;
1130                     }
1131                 }
1132             }
1133         }
1134     }
1135     /* internal RAM maps */
1136     for (i = NUM_CONFIGS - 0x20; i < NUM_CONFIGS; i++) {
1137         for (j = 0; j <= 0xff; j++) {
1138             mem_read_tab[i][j] = ram_read_int;
1139             mem_read_base_tab[i][j] = mem_ram;
1140             for (l = 0; l < NUM_MIRRORS; l++) {
1141                 if (j == 0) {
1142                     mem_write_tab[l][i][j] = zero_store_int;
1143                 } else if (j == 0xff) {
1144                     mem_write_tab[l][i][j] = ram_hi_store_int;
1145                 } else {
1146                     mem_write_tab[l][i][j] = ram_store_int;
1147                 }
1148             }
1149         }
1150     }
1151 
1152     scpu64meminit();
1153 
1154     for (i = 0; i < NUM_CONFIGS; i++) {
1155         mem_read_tab[i][0x100] = mem_read_tab[i][0];
1156             for (l = 0; l < NUM_MIRRORS; l++) {
1157                 mem_write_tab[l][i][0x100] = mem_write_tab[l][i][0];
1158             }
1159         mem_read_base_tab[i][0x100] = mem_read_base_tab[i][0];
1160     }
1161 
1162     /* A fully automatic limit filler ;) */
1163     for (i = 0; i < NUM_CONFIGS; i++) {
1164         for (j = 0, l = 1; j <= 0xff; l++) {
1165             uint8_t *p = mem_read_base_tab[i][j];
1166             read_func_ptr_t f = mem_read_tab[i][j];
1167             uint32_t range;
1168 
1169             while (l <= 0xff && p == mem_read_base_tab[i][l]) {
1170                 l++;
1171             }
1172             /* Some areas are I/O or cartridge (NULL) or too slow and need cycle stretching */
1173             range = (p == NULL || f == ram_read_int || f == scpu64rom_scpu64_read || f == chargen_read) ? 0 : ((j << 24) | ((l << 8)-3));
1174             while (j < l) {
1175                 mem_read_limit_tab[i][j] = range;
1176                 j++;
1177             }
1178         }
1179         mem_read_limit_tab[i][0x100] = 0;
1180     }
1181 
1182     vicii_set_chargen_addr_options(0x7000, 0x1000);
1183 
1184     mem_pport = 7;
1185     export.exrom = 0;
1186     export.game = 0;
1187     mem_reg_bootmap = 1;
1188 
1189     /* Setup initial memory configuration.  */
1190     mem_pla_config_changed();
1191     cartridge_init_config();
1192 }
1193 
mem_mmu_translate(unsigned int addr,uint8_t ** base,int * start,int * limit)1194 void mem_mmu_translate(unsigned int addr, uint8_t **base, int *start, int *limit)
1195 {
1196     uint8_t *p;
1197     uint32_t limits;
1198 
1199     if (addr >= 0x10000) {
1200         if (addr < 0x20000) {
1201             *base = mem_sram + 0x10000;
1202             *limit = 0xfffd;
1203             *start = 0x0000;
1204         } else if (!scpu64_fastmode) {
1205             if (addr >= 0xf80000) {
1206                 *base = scpu64rom_scpu64_rom + (addr & 0x70000 & (SCPU64_SCPU64_ROM_MAXSIZE-1));
1207                 *limit = 0xfffd;
1208                 *start = 0x0000;
1209             } else if (addr >= 0xf60000 && mem_simm_ram_mask && mem_simm_page_size == mem_conf_page_size) {
1210                 *base = mem_simm_ram + (addr & 0x10000);
1211                 *limit = 0xfffd;
1212                 *start = 0x0000;
1213             } else if (mem_simm_ram_mask && mem_simm_page_size == mem_conf_page_size && addr < (unsigned int)mem_conf_size) {
1214                 *base = mem_simm_ram + (addr & 0xff0000 & mem_simm_ram_mask);
1215                 *limit = 0xfffd;
1216                 *start = 0x0000;
1217             } else {
1218                 *base = NULL;
1219                 *limit = 0;
1220                 *start = 0;
1221             }
1222         } else {
1223             *base = NULL;
1224             *limit = 0;
1225             *start = 0;
1226         }
1227     } else {
1228         p = _mem_read_base_tab_ptr[addr >> 8];
1229         if (p != NULL) {
1230             *base = p;
1231             limits = mem_read_limit_tab_ptr[addr >> 8];
1232             *limit = limits & 0xffff;
1233             *start = limits >> 16;
1234             if (traps_pending) {
1235                 traps_refresh();
1236                 traps_pending = 0;
1237             }
1238         } else if (scpu64_fastmode) {
1239             *base = NULL;
1240             *limit = 0;
1241             *start = 0;
1242         } else {
1243             cartridge_mmu_translate(addr, base, start, limit);
1244         }
1245     }
1246 }
1247 
1248 /* ------------------------------------------------------------------------- */
1249 
1250 /* Initialize RAM for power-up.  */
mem_powerup(void)1251 void mem_powerup(void)
1252 {
1253     ram_init(mem_ram, SCPU64_RAM_SIZE);
1254     ram_init(mem_sram, SCPU64_SRAM_SIZE);
1255     ram_init(mem_trap_ram, SCPU64_KERNAL_ROM_SIZE);
1256     cartridge_ram_init();  /* Clean cartridge ram too */
1257 }
1258 
1259 /* ------------------------------------------------------------------------- */
1260 
1261 /* Change the current video bank.  Call this routine only when the vbank
1262    has really changed.  */
mem_set_vbank(int new_vbank)1263 void mem_set_vbank(int new_vbank)
1264 {
1265     vicii_set_vbank(new_vbank);
1266 }
1267 
mem_set_mirroring(int new_mirroring)1268 void mem_set_mirroring(int new_mirroring)
1269 {
1270     mirror = ((new_mirroring & 0x1) ? 1 : 0) | ((new_mirroring & 0x4) ? 2 : 0)
1271            | ((new_mirroring & 0x40) ? 4 : 0) | ((new_mirroring & 0x80) ? 8 : 0);
1272 
1273     /* Do not override watchpoints on vbank switches.  */
1274     if (_mem_write_tab_ptr != mem_write_tab_watch) {
1275         _mem_write_tab_ptr = mem_write_tab[mirror][mem_config];
1276     }
1277 }
1278 
mem_set_simm(int config)1279 void mem_set_simm(int config)
1280 {
1281     switch (config & 7) {
1282     case 0:
1283         mem_conf_page_size = 9 + 2;
1284         mem_conf_size = 1 * 1024 *1024;
1285         break;
1286     case 1:
1287         mem_conf_page_size = 10 + 2;
1288         mem_conf_size = 4 * 1024 *1024;
1289         break;
1290     case 2:
1291         mem_conf_page_size = 10 + 2;
1292         mem_conf_size = 8 * 1024 *1024;
1293         break;
1294     case 3:
1295         mem_conf_page_size = 10 + 2;
1296         mem_conf_size = 16 * 1024 *1024;
1297         break;
1298     default:
1299         mem_conf_page_size = 11 + 2;
1300         mem_conf_size = 16 * 1024 *1024;
1301         break;
1302     }
1303     scpu64_set_simm_row_size(mem_conf_page_size);
1304 }
1305 
scpu64_hardware_reset(void)1306 void scpu64_hardware_reset(void)
1307 {
1308     mem_reg_optim = 0xc7;
1309     mem_reg_soft_1mhz = 0;
1310     mem_reg_sys_1mhz = 0;
1311     mem_reg_hwenable = 0;
1312     mem_reg_dosext = 0;
1313     mem_reg_ramlink = 0;
1314     mem_reg_bootmap = 1;
1315     mem_reg_simm = 4;
1316     mem_pport = 7;
1317     mem_set_mirroring(mem_reg_optim);
1318     mem_set_simm(mem_reg_simm);
1319     mem_pla_config_changed();
1320 }
1321 
1322 /* Set the tape nonsense status.  */
mem_set_tape_sense(int sense)1323 void mem_set_tape_sense(int sense)
1324 {
1325 }
1326 
1327 /* ------------------------------------------------------------------------- */
1328 
1329 /* FIXME: this part needs to be checked.  */
1330 
mem_get_basic_text(uint16_t * start,uint16_t * end)1331 void mem_get_basic_text(uint16_t *start, uint16_t *end)
1332 {
1333     if (start != NULL) {
1334         *start = mem_sram[0x2b] | (mem_sram[0x2c] << 8);
1335     }
1336     if (end != NULL) {
1337         *end = mem_sram[0x2d] | (mem_sram[0x2e] << 8);
1338     }
1339 }
1340 
mem_set_basic_text(uint16_t start,uint16_t end)1341 void mem_set_basic_text(uint16_t start, uint16_t end)
1342 {
1343     mem_sram[0x2b] = mem_sram[0xac] = start & 0xff;
1344     mem_sram[0x2c] = mem_sram[0xad] = start >> 8;
1345     mem_sram[0x2d] = mem_sram[0x2f] = mem_sram[0x31] = mem_sram[0xae] = end & 0xff;
1346     mem_sram[0x2e] = mem_sram[0x30] = mem_sram[0x32] = mem_sram[0xaf] = end >> 8;
1347 }
1348 
mem_inject(uint32_t addr,uint8_t value)1349 void mem_inject(uint32_t addr, uint8_t value)
1350 {
1351     /* could be made to handle various internal expansions in some sane way */
1352     mem_ram[addr & 0xffff] = mem_sram[addr & 0xffff] = value;
1353 }
1354 
1355 /* ------------------------------------------------------------------------- */
1356 
mem_rom_trap_allowed(uint16_t addr)1357 int mem_rom_trap_allowed(uint16_t addr)
1358 {
1359     if (addr >= 0xe000) {
1360         switch (mem_config) {
1361             case 2:
1362             case 3:
1363             case 6:
1364             case 7:
1365             case 10:
1366             case 11:
1367             case 14:
1368             case 15:
1369             case 26:
1370             case 27:
1371             case 30:
1372             case 31:
1373                 return 1;
1374             default:
1375                 return 0;
1376         }
1377     }
1378 
1379     return 0;
1380 }
1381 
1382 /* ------------------------------------------------------------------------- */
1383 
1384 /* Banked memory access functions for the monitor.  */
1385 
store_bank_io(uint16_t addr,uint8_t byte)1386 void store_bank_io(uint16_t addr, uint8_t byte)
1387 {
1388     switch (addr & 0xff00) {
1389         case 0xd000:
1390             if ((addr >= 0xd071 && addr < 0xd080) || (addr >= 0xd0b0 && addr < 0xd0c0)) {
1391                 scpu64_hardware_store(addr, byte);
1392             } else {
1393                 c64io_d000_store(addr, byte);
1394             }
1395             break;
1396         case 0xd100:
1397             c64io_d100_store(addr, byte);
1398             break;
1399         case 0xd200:
1400             scpu64_d200_store(addr, byte);
1401             break;
1402         case 0xd300:
1403             scpu64_d300_store(addr, byte);
1404             break;
1405         case 0xd400:
1406             c64io_d400_store(addr, byte);
1407             break;
1408         case 0xd500:
1409             c64io_d500_store(addr, byte);
1410             break;
1411         case 0xd600:
1412             c64io_d600_store(addr, byte);
1413             break;
1414         case 0xd700:
1415             c64io_d700_store(addr, byte);
1416             break;
1417         case 0xd800:
1418         case 0xd900:
1419         case 0xda00:
1420         case 0xdb00:
1421             colorram_store(addr, byte);
1422             break;
1423         case 0xdc00:
1424             cia1_store(addr, byte);
1425             break;
1426         case 0xdd00:
1427             cia2_store(addr, byte);
1428             break;
1429         case 0xde00:
1430             c64io_de00_store(addr, byte);
1431             break;
1432         case 0xdf00:
1433             c64io_df00_store(addr, byte);
1434             break;
1435     }
1436     return;
1437 }
1438 
read_bank_io(uint16_t addr)1439 uint8_t read_bank_io(uint16_t addr)
1440 {
1441     switch (addr & 0xff00) {
1442         case 0xd000:
1443             if ((addr & 0xfff0) == 0xd0b0) {
1444                 return scpu64_hardware_read(addr);
1445             }
1446             return c64io_d000_read(addr);
1447         case 0xd100:
1448             return c64io_d100_read(addr);
1449         case 0xd200:
1450             return scpu64_d200_read(addr);
1451         case 0xd300:
1452             return scpu64_d300_read(addr);
1453         case 0xd400:
1454             return c64io_d400_read(addr);
1455         case 0xd500:
1456             return c64io_d500_read(addr);
1457         case 0xd600:
1458             return c64io_d600_read(addr);
1459         case 0xd700:
1460             return c64io_d700_read(addr);
1461         case 0xd800:
1462         case 0xd900:
1463         case 0xda00:
1464         case 0xdb00:
1465             return colorram_read(addr);
1466         case 0xdc00:
1467             return cia1_read(addr);
1468         case 0xdd00:
1469             return cia2_read(addr);
1470         case 0xde00:
1471             return c64io_de00_read(addr);
1472         case 0xdf00:
1473             return c64io_df00_read(addr);
1474     }
1475     return 0xff;
1476 }
1477 
peek_bank_io(uint16_t addr)1478 static uint8_t peek_bank_io(uint16_t addr)
1479 {
1480     switch (addr & 0xff00) {
1481         case 0xd000:
1482             return scpu64io_d000_peek(addr);
1483         case 0xd100:
1484             return c64io_d100_peek(addr);
1485         case 0xd200:
1486             return scpu64_d200_read(addr);
1487         case 0xd300:
1488             return scpu64_d300_read(addr);
1489         case 0xd400:
1490             return c64io_d400_peek(addr);
1491         case 0xd500:
1492             return c64io_d500_peek(addr);
1493         case 0xd600:
1494             return c64io_d600_peek(addr);
1495         case 0xd700:
1496             return c64io_d700_peek(addr);
1497         case 0xd800:
1498         case 0xd900:
1499         case 0xda00:
1500         case 0xdb00:
1501             return colorram_read(addr);
1502         case 0xdc00:
1503             return cia1_peek(addr);
1504         case 0xdd00:
1505             return cia2_peek(addr);
1506         case 0xde00:
1507             return c64io_de00_peek(addr);
1508         case 0xdf00:
1509             return c64io_df00_peek(addr);
1510     }
1511     return 0xff;
1512 }
1513 
1514 /* ------------------------------------------------------------------------- */
1515 
scpu64_interrupt_reroute(void)1516 int scpu64_interrupt_reroute(void)
1517 {
1518     return (_mem_read_tab_ptr[0xff] == scpu64_kernalshadow_read || _mem_read_tab_ptr[0xff] == ram1_read) && (!scpu64_emulation_mode || mem_reg_hwenable || mem_reg_sys_1mhz || mem_reg_dosext || mem_reg_ramlink);
1519 }
1520 
1521 /* ------------------------------------------------------------------------- */
1522 
1523 /* Exported banked memory access functions for the monitor.  */
1524 
1525 static const char *banknames[] = {
1526     "default",
1527     "cpu",
1528     "ram",
1529     "rom",
1530     "io",
1531     "cart",
1532     "ram00", "ram01", "ram02", "ram03", "ram04", "ram05", "ram06", "ram07",
1533     "ram08", "ram09", "ram0a", "ram0b", "ram0c", "ram0d", "ram0e", "ram0f",
1534     "ram10", "ram11", "ram12", "ram13", "ram14", "ram15", "ram16", "ram17",
1535     "ram18", "ram19", "ram1a", "ram1b", "ram1c", "ram1d", "ram1e", "ram1f",
1536     "ram20", "ram21", "ram22", "ram23", "ram24", "ram25", "ram26", "ram27",
1537     "ram28", "ram29", "ram2a", "ram2b", "ram2c", "ram2d", "ram2e", "ram2f",
1538     "ram30", "ram31", "ram32", "ram33", "ram34", "ram35", "ram36", "ram37",
1539     "ram38", "ram39", "ram3a", "ram3b", "ram3c", "ram3d", "ram3e", "ram3f",
1540     "ram40", "ram41", "ram42", "ram43", "ram44", "ram45", "ram46", "ram47",
1541     "ram48", "ram49", "ram4a", "ram4b", "ram4c", "ram4d", "ram4e", "ram4f",
1542     "ram50", "ram51", "ram52", "ram53", "ram54", "ram55", "ram56", "ram57",
1543     "ram58", "ram59", "ram5a", "ram5b", "ram5c", "ram5d", "ram5e", "ram5f",
1544     "ram60", "ram61", "ram62", "ram63", "ram64", "ram65", "ram66", "ram67",
1545     "ram68", "ram69", "ram6a", "ram6b", "ram6c", "ram6d", "ram6e", "ram6f",
1546     "ram70", "ram71", "ram72", "ram73", "ram74", "ram75", "ram76", "ram77",
1547     "ram78", "ram79", "ram7a", "ram7b", "ram7c", "ram7d", "ram7e", "ram7f",
1548     "ram80", "ram81", "ram82", "ram83", "ram84", "ram85", "ram86", "ram87",
1549     "ram88", "ram89", "ram8a", "ram8b", "ram8c", "ram8d", "ram8e", "ram8f",
1550     "ram90", "ram91", "ram92", "ram93", "ram94", "ram95", "ram96", "ram97",
1551     "ram98", "ram99", "ram9a", "ram9b", "ram9c", "ram9d", "ram9e", "ram9f",
1552     "rama0", "rama1", "rama2", "rama3", "rama4", "rama5", "rama6", "rama7",
1553     "rama8", "rama9", "ramaa", "ramab", "ramac", "ramad", "ramae", "ramaf",
1554     "ramb0", "ramb1", "ramb2", "ramb3", "ramb4", "ramb5", "ramb6", "ramb7",
1555     "ramb8", "ramb9", "ramba", "rambb", "rambc", "rambd", "rambe", "rambf",
1556     "ramc0", "ramc1", "ramc2", "ramc3", "ramc4", "ramc5", "ramc6", "ramc7",
1557     "ramc8", "ramc9", "ramca", "ramcb", "ramcc", "ramcd", "ramce", "ramcf",
1558     "ramd0", "ramd1", "ramd2", "ramd3", "ramd4", "ramd5", "ramd6", "ramd7",
1559     "ramd8", "ramd9", "ramda", "ramdb", "ramdc", "ramdd", "ramde", "ramdf",
1560     "rame0", "rame1", "rame2", "rame3", "rame4", "rame5", "rame6", "rame7",
1561     "rame8", "rame9", "ramea", "rameb", "ramec", "ramed", "ramee", "ramef",
1562     "ramf0", "ramf1", "ramf2", "ramf3", "ramf4", "ramf5", "ramf6", "ramf7",
1563     "romf8", "romf9", "romfa", "romfb", "romfc", "romfd", "romfe", "romff",
1564     NULL
1565 };
1566 
1567 static const int banknums[] =
1568 {
1569     1, 0, 1, 2, 3, 4,
1570     5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
1571     21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
1572     37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
1573     53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
1574     69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
1575     85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
1576     101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
1577     117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,
1578     133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
1579     149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
1580     165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
1581     181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
1582     197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,
1583     213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,
1584     229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,
1585     245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260
1586 };
1587 
mem_bank_list(void)1588 const char **mem_bank_list(void)
1589 {
1590     return banknames;
1591 }
1592 
mem_bank_from_name(const char * name)1593 int mem_bank_from_name(const char *name)
1594 {
1595     int i = 0;
1596 
1597     while (banknames[i]) {
1598         if (!strcmp(name, banknames[i])) {
1599             return banknums[i];
1600         }
1601         i++;
1602     }
1603     return -1;
1604 }
1605 
1606 /* read memory with side-effects */
mem_bank_read(int bank,uint16_t addr,void * context)1607 uint8_t mem_bank_read(int bank, uint16_t addr, void *context)
1608 {
1609     if ((bank >= 5) && (bank <= 6)) {
1610         return mem_sram[((bank - 5) << 16) + addr]; /* ram00..01 */
1611     }
1612     if ((bank >= 7) && (bank <= 252)) {
1613         int addr2 = addr + ((bank - ((bank >= 251) ? 251 : 5)) << 16);
1614         if (mem_simm_page_size != mem_conf_page_size) {
1615             addr2 = ((addr2 >> mem_conf_page_size) << mem_simm_page_size) | (addr2 & ((1 << mem_simm_page_size)-1));
1616         }
1617         if (mem_simm_ram_mask && addr2 < mem_conf_size) {
1618             return mem_simm_ram[addr2 & mem_simm_ram_mask]; /* ram02..f6 */
1619         }
1620         return bank - 5;
1621     }
1622     if ((bank >= 253) && (bank <= 260)) {
1623         return scpu64rom_scpu64_rom[(((bank - 253) << 16) + addr) & (SCPU64_SCPU64_ROM_MAXSIZE-1)]; /* romf8..ff */
1624     }
1625 
1626     switch (bank) {
1627         case 0:                   /* current */
1628             bank = WDC65816_REGS_GET_PBR(maincpu_monitor_interface->cpu_65816_regs);
1629             if (bank > 0) {
1630                 return mem_peek2(addr + (bank << 16));
1631             }
1632             return mem_read(addr);
1633         case 3:                   /* io */
1634             if (addr >= 0xd000 && addr < 0xe000) {
1635                 return read_bank_io(addr);
1636             }
1637             /* FALL THROUGH */
1638         case 4:                   /* cart */
1639             return cartridge_peek_mem(addr);
1640         case 2:                   /* rom */
1641             if (addr >= 0xa000 && addr <= 0xbfff) {
1642                 return ram1_read(addr);
1643             }
1644             if (addr >= 0xd000 && addr <= 0xdfff) {
1645                 return mem_chargen_rom[addr & 0x0fff];
1646             }
1647             if (addr >= 0xe000) {
1648 
1649                 return mem_reg_hwenable ? scpu64_kernalshadow_read(addr) : ram1_read(addr);
1650             }
1651             /* FALL THROUGH */
1652         case 1:                   /* ram */
1653             break;
1654     }
1655     return mem_sram[addr];
1656 }
1657 
1658 /* read memory without side-effects */
mem_bank_peek(int bank,uint16_t addr,void * context)1659 uint8_t mem_bank_peek(int bank, uint16_t addr, void *context)
1660 {
1661     if ((bank >= 5) && (bank <= 260)) {
1662         return mem_bank_read(bank, addr, context); /* ram00..ff */
1663     }
1664     switch (bank) {
1665         case 0:                   /* current */
1666             bank = WDC65816_REGS_GET_PBR(maincpu_monitor_interface->cpu_65816_regs);
1667             if (bank > 0) {
1668                 return mem_peek2(addr + (bank << 16));
1669             }
1670             /* we must check for which bank is currently active, and only use peek_bank_io
1671                when needed to avoid side effects */
1672             if ((addr >= 0xd000) && (addr < 0xe000)) {
1673                 if (_mem_read_base_tab_ptr[0xd2] == mem_sram + 0x10000) {
1674                     return peek_bank_io(addr);
1675                 }
1676             }
1677             return mem_read(addr);
1678             break;
1679         case 3:                   /* io */
1680             if ((addr >= 0xd000) && (addr < 0xe000)) {
1681                 return peek_bank_io(addr);
1682             }
1683             break;
1684         case 4:                   /* cart */
1685             return cartridge_peek_mem(addr);
1686     }
1687     return mem_bank_read(bank, addr, context);
1688 }
1689 
mem_bank_write(int bank,uint16_t addr,uint8_t byte,void * context)1690 void mem_bank_write(int bank, uint16_t addr, uint8_t byte, void *context)
1691 {
1692     if ((bank >= 5) && (bank <= 6)) {
1693         mem_sram[((bank - 5) << 16) + addr] = byte; /* ram00..01 */
1694         return;
1695     }
1696     if ((bank >= 7) && (bank <= 252)) {
1697         int addr2 = addr + ((bank - ((bank >= 251) ? 251 : 5)) << 16);
1698         if (mem_simm_page_size != mem_conf_page_size) {
1699             addr2 = ((addr2 >> mem_conf_page_size) << mem_simm_page_size) | (addr2 & ((1 << mem_simm_page_size)-1));
1700         }
1701         if (mem_simm_ram_mask && addr2 < mem_conf_size) {
1702             mem_simm_ram[addr2 & mem_simm_ram_mask] = byte; /* ram02..f6 */
1703         }
1704         return;
1705     }
1706     if ((bank >= 253) && (bank <= 260)) {
1707         scpu64rom_scpu64_rom[(((bank - 253) << 16) + addr) & (SCPU64_SCPU64_ROM_MAXSIZE-1)] = byte; /* romf8..ff */
1708         return;
1709     }
1710     switch (bank) {
1711         case 0:                   /* current */
1712             bank = WDC65816_REGS_GET_PBR(maincpu_monitor_interface->cpu_65816_regs);
1713             if (bank > 0) {
1714                 mem_store2(addr + (bank << 16), byte);
1715                 return;
1716             }
1717             mem_store(addr, byte);
1718             return;
1719         case 3:                   /* io */
1720             if (addr >= 0xd000 && addr < 0xe000) {
1721                 store_bank_io(addr, byte);
1722                 return;
1723             }
1724             /* FALL THROUGH */
1725         case 2:                   /* rom */
1726             if (addr >= 0xa000 && addr <= 0xbfff) {
1727                 return;
1728             }
1729             if (addr >= 0xd000 && addr <= 0xdfff) {
1730                 return;
1731             }
1732             if (addr >= 0xe000) {
1733                 return;
1734             }
1735             /* FALL THROUGH */
1736         case 1:                   /* ram */
1737             break;
1738     }
1739     mem_sram[addr] = byte;
1740 }
1741 
mem_dump_io(void * context,uint16_t addr)1742 static int mem_dump_io(void *context, uint16_t addr)
1743 {
1744     if ((addr >= 0xdc00) && (addr <= 0xdc3f)) {
1745         return ciacore_dump(machine_context.cia1);
1746     } else if ((addr >= 0xdd00) && (addr <= 0xdd3f)) {
1747         return ciacore_dump(machine_context.cia2);
1748     }
1749     return -1;
1750 }
1751 
mem_ioreg_list_get(void * context)1752 mem_ioreg_list_t *mem_ioreg_list_get(void *context)
1753 {
1754     mem_ioreg_list_t *mem_ioreg_list = NULL;
1755 
1756     mon_ioreg_add_list(&mem_ioreg_list, "CIA1", 0xdc00, 0xdc0f, mem_dump_io, NULL);
1757     mon_ioreg_add_list(&mem_ioreg_list, "CIA2", 0xdd00, 0xdd0f, mem_dump_io, NULL);
1758 
1759     io_source_ioreg_add_list(&mem_ioreg_list);
1760 
1761     return mem_ioreg_list;
1762 }
1763 
mem_get_screen_parameter(uint16_t * base,uint8_t * rows,uint8_t * columns,int * bank)1764 void mem_get_screen_parameter(uint16_t *base, uint8_t *rows, uint8_t *columns, int *bank)
1765 {
1766     *base = ((vicii_peek(0xd018) & 0xf0) << 6) | ((~cia2_peek(0xdd00) & 0x03) << 14);
1767     *rows = 25;
1768     *columns = 40;
1769     *bank = 0;
1770 }
1771 
1772 /* ------------------------------------------------------------------------- */
1773 
mem_set_simm_size(int val)1774 void mem_set_simm_size(int val)
1775 {
1776     size_t size = val << 20;
1777     if (!size) size = 1;
1778     mem_simm_ram_mask = size - 1;
1779     mem_simm_ram = lib_realloc(mem_simm_ram, size);
1780     ram_init(mem_simm_ram, size);
1781     switch (val) {
1782     case 1:
1783         mem_simm_page_size = 9 + 2; /* 0 */
1784         break;
1785     case 4:                             /* 1 */
1786     case 8:                             /* 2 */
1787         mem_simm_page_size = 10 + 2;  /* 3 */
1788         break;
1789     default:
1790         mem_simm_page_size = 11 + 2;  /* 4,3 */
1791         break;
1792     }
1793     maincpu_resync_limits();
1794 }
1795 
mem_set_jiffy_switch(int val)1796 void mem_set_jiffy_switch(int val)
1797 {
1798     mem_reg_sw_jiffy = !!val;
1799 }
1800 
mem_set_speed_switch(int val)1801 void mem_set_speed_switch(int val)
1802 {
1803     if (mem_reg_sw_1mhz == val) {
1804         mem_reg_sw_1mhz = !val;
1805         scpu64_set_fastmode_nosync(!(mem_reg_soft_1mhz || mem_reg_sys_1mhz || (mem_reg_sw_1mhz && !mem_reg_hwenable)));
1806     }
1807 }
1808 
1809 /* ------------------------------------------------------------------------- */
1810 
scpu64_trap_read(uint16_t addr)1811 uint8_t scpu64_trap_read(uint16_t addr)
1812 {
1813     return mem_trap_ram[addr & 0x1fff];
1814 }
1815 
scpu64_trap_store(uint16_t addr,uint8_t value)1816 void scpu64_trap_store(uint16_t addr, uint8_t value)
1817 {
1818     mem_trap_ram[addr & 0x1fff] = value;
1819 }
1820 
mem_color_ram_to_snapshot(uint8_t * color_ram)1821 void mem_color_ram_to_snapshot(uint8_t *color_ram)
1822 {
1823     memcpy(color_ram, mem_color_ram, 0x400);
1824 }
1825 
mem_color_ram_from_snapshot(uint8_t * color_ram)1826 void mem_color_ram_from_snapshot(uint8_t *color_ram)
1827 {
1828     memcpy(mem_color_ram, color_ram, 0x400);
1829 }
1830 
scpu64_mem_shutdown(void)1831 void scpu64_mem_shutdown(void)
1832 {
1833     lib_free(mem_simm_ram);
1834     mem_simm_ram = NULL;
1835 }
1836