1 /*
2  * c128mem.c -- Memory handling for the C128 emulator.
3  *
4  * Written by
5  *  Andreas Boose <viceteam@t-online.de>
6  *  Ettore Perazzoli <ettore@comm2000.it>
7  *  Marco van den Heuvel <blackystardust68@yahoo.com>
8  *
9  * Based on the original work in VICE 0.11.0 by
10  *  Jouko Valta <jopi@stekt.oulu.fi>
11  *
12  * This file is part of VICE, the Versatile Commodore Emulator.
13  * See README for copyright notice.
14  *
15  *  This program is free software; you can redistribute it and/or modify
16  *  it under the terms of the GNU General Public License as published by
17  *  the Free Software Foundation; either version 2 of the License, or
18  *  (at your option) any later version.
19  *
20  *  This program is distributed in the hope that it will be useful,
21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  *  GNU General Public License for more details.
24  *
25  *  You should have received a copy of the GNU General Public License
26  *  along with this program; if not, write to the Free Software
27  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28  *  02111-1307  USA.
29  *
30  */
31 
32 #include "vice.h"
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 
38 #include "c128-resources.h"
39 #include "c128.h"
40 #include "c128mem.h"
41 #include "c128meminit.h"
42 #include "c128memlimit.h"
43 #include "c128memrom.h"
44 #include "c128mmu.h"
45 #include "c64cart.h"
46 #include "c64cia.h"
47 #include "c64meminit.h"
48 #include "c64memrom.h"
49 #include "c64pla.h"
50 #include "cartio.h"
51 #include "cartridge.h"
52 #include "cia.h"
53 #include "clkguard.h"
54 #include "functionrom.h"
55 #include "georam.h"
56 #include "keyboard.h"
57 #include "log.h"
58 #include "machine.h"
59 #include "maincpu.h"
60 #include "monitor.h"
61 #include "ram.h"
62 #include "reu.h"
63 #include "sid.h"
64 #include "sid-resources.h"
65 #include "types.h"
66 #include "vdc-mem.h"
67 #include "vdc.h"
68 #include "vdctypes.h"
69 #include "vicii-mem.h"
70 #include "vicii-phi1.h"
71 #include "vicii.h"
72 #include "z80mem.h"
73 
74 /* #define DEBUG_MMU */
75 
76 #ifdef DEBUG_MMU
77 #define DEBUG_PRINT(x) printf x
78 #else
79 #define DEBUG_PRINT(x)
80 #endif
81 
82 /* ------------------------------------------------------------------------- */
83 
84 /* Number of possible video banks (16K each).  */
85 #define NUM_VBANKS 4
86 
87 /* The C128 memory.  */
88 uint8_t mem_ram[C128_RAM_SIZE];
89 uint8_t mem_chargen_rom[C128_CHARGEN_ROM_SIZE];
90 
91 /* Internal color memory.  */
92 static uint8_t mem_color_ram[0x800];
93 uint8_t *mem_color_ram_cpu, *mem_color_ram_vicii;
94 
95 /* Pointer to the chargen ROM.  */
96 uint8_t *mem_chargen_rom_ptr;
97 
98 /* Currently selected RAM bank.  */
99 uint8_t *ram_bank;
100 
101 /* Shared memory.  */
102 static uint16_t top_shared_limit, bottom_shared_limit;
103 
104 /* Pointers to pages 0 and 1 (which can be physically placed anywhere).  */
105 uint8_t *mem_page_zero, *mem_page_one;
106 
107 /* Pointers to the currently used memory read and write tables.  */
108 read_func_ptr_t *_mem_read_tab_ptr;
109 store_func_ptr_t *_mem_write_tab_ptr;
110 static uint8_t **_mem_read_base_tab_ptr;
111 static int *mem_read_limit_tab_ptr;
112 
113 #define NUM_CONFIGS 256
114 
115 /* Memory read and write tables.  */
116 static store_func_ptr_t mem_write_tab[NUM_VBANKS][NUM_CONFIGS][0x101];
117 static read_func_ptr_t mem_read_tab[NUM_CONFIGS][0x101];
118 static uint8_t *mem_read_base_tab[NUM_CONFIGS][0x101];
119 static int mem_read_limit_tab[NUM_CONFIGS][0x101];
120 
121 static store_func_ptr_t mem_write_tab_watch[0x101];
122 static read_func_ptr_t mem_read_tab_watch[0x101];
123 
124 /* Current video bank (0, 1, 2 or 3 in the first bank,
125    4, 5, 6 or 7 in the second bank).  */
126 static int vbank = 0;
127 
128 /* Tape sense status: 1 = some button pressed, 0 = no buttons pressed.  */
129 static int tape_sense = 0;
130 
131 static int tape_write_in = 0;
132 static int tape_motor_in = 0;
133 
134 /* Current memory configuration.  */
135 static int mem_config;
136 
137 /* Current watchpoint state. 1 = watchpoints active, 0 = no watchpoints */
138 static int watchpoints_active;
139 
140 /* Current machine type.  */
141 static unsigned int mem_machine_type;
142 
143 /* Logging goes here.  */
144 static log_t c128_mem_log = LOG_DEFAULT;
145 
146 /* Status of the CAPS key (ASCII/DIN).  */
147 static int caps_sense = 1;
148 
149 /* ------------------------------------------------------------------------- */
150 
watch_read(uint16_t addr)151 static uint8_t watch_read(uint16_t addr)
152 {
153     monitor_watch_push_load_addr(addr, e_comp_space);
154     return mem_read_tab[mem_config][addr >> 8](addr);
155 }
156 
watch_store(uint16_t addr,uint8_t value)157 static void watch_store(uint16_t addr, uint8_t value)
158 {
159     monitor_watch_push_store_addr(addr, e_comp_space);
160     mem_write_tab[vbank][mem_config][addr >> 8](addr, value);
161 }
162 
mem_toggle_watchpoints(int flag,void * context)163 void mem_toggle_watchpoints(int flag, void *context)
164 {
165     if (flag) {
166         _mem_read_tab_ptr = mem_read_tab_watch;
167         _mem_write_tab_ptr = mem_write_tab_watch;
168     } else {
169         _mem_read_tab_ptr = mem_read_tab[mem_config];
170         _mem_write_tab_ptr = mem_write_tab[vbank][mem_config];
171     }
172     watchpoints_active = flag;
173 }
174 
175 /* ------------------------------------------------------------------------- */
176 
mem_update_chargen(unsigned int chargen_high)177 static void mem_update_chargen(unsigned int chargen_high)
178 {
179     uint8_t *old_chargen_rom_ptr;
180 
181     old_chargen_rom_ptr = mem_chargen_rom_ptr;
182 
183     /* invert line on international version, fixes bug #781 */
184     if (mem_machine_type == C128_MACHINE_INT) {
185         chargen_high = chargen_high ? 0 : 1;
186     }
187 
188     if (chargen_high) {
189         mem_chargen_rom_ptr = mem_chargen_rom;
190     } else {
191         mem_chargen_rom_ptr = &mem_chargen_rom[0x1000];
192     }
193     if (old_chargen_rom_ptr != mem_chargen_rom_ptr) {
194         machine_update_memory_ptrs();
195     }
196 }
197 
mem_update_config(int config)198 void mem_update_config(int config)
199 {
200     mem_config = config;
201 
202     if (watchpoints_active) {
203         _mem_read_tab_ptr = mem_read_tab_watch;
204         _mem_write_tab_ptr = mem_write_tab_watch;
205     } else {
206         _mem_read_tab_ptr = mem_read_tab[mem_config];
207         _mem_write_tab_ptr = mem_write_tab[vbank][mem_config];
208     }
209 
210     _mem_read_base_tab_ptr = mem_read_base_tab[config];
211     mem_read_limit_tab_ptr = mem_read_limit_tab[config];
212 
213     maincpu_resync_limits();
214 
215     if (config >= 0x80) {
216         if (mem_machine_type == C128_MACHINE_INT) {
217             mem_update_chargen(0);
218         }
219         mem_color_ram_cpu = mem_color_ram;
220         mem_color_ram_vicii = mem_color_ram;
221         vicii_set_chargen_addr_options(0x7000, 0x1000);
222     } else {
223         if (mem_machine_type == C128_MACHINE_INT) {
224             mem_update_chargen(1);
225         }
226         if (pport.data_read & 1) {
227             mem_color_ram_cpu = mem_color_ram;
228         } else {
229             mem_color_ram_cpu = &mem_color_ram[0x400];
230         }
231         if (pport.data_read & 2) {
232             mem_color_ram_vicii = mem_color_ram;
233         } else {
234             mem_color_ram_vicii = &mem_color_ram[0x400];
235         }
236         if (pport.data_read & 4) {
237             vicii_set_chargen_addr_options(0xffff, 0xffff);
238         } else {
239             vicii_set_chargen_addr_options(0x3000, 0x1000);
240         }
241     }
242 }
243 
mem_set_machine_type(unsigned type)244 void mem_set_machine_type(unsigned type)
245 {
246     mem_machine_type = type;
247     caps_sense = 1;
248     mem_pla_config_changed();
249 }
250 
251 /* Change the current video bank.  Call this routine only when the vbank
252    has really changed.  */
mem_set_vbank(int new_vbank)253 void mem_set_vbank(int new_vbank)
254 {
255     vbank = (vbank & ~3) | new_vbank;
256     vicii_set_vbank(new_vbank & 3);
257 }
258 
mem_set_ram_config(uint8_t value)259 void mem_set_ram_config(uint8_t value)
260 {
261     unsigned int shared_size;
262 
263     /* XXX: We only support 128K here.  */
264     vicii_set_ram_base(mem_ram + ((value & 0x40) << 10));
265 
266     DEBUG_PRINT(("MMU: Store RCR = $%02x\n", value));
267     DEBUG_PRINT(("MMU: VIC-II base at $%05X\n", ((value & 0xc0) << 2)));
268 
269     if ((value & 0x3) == 0) {
270         shared_size = 1024;
271     } else {
272         shared_size = 0x1000 << ((value & 0x3) - 1);
273     }
274 
275     /* Share high memory?  */
276     if (value & 0x8) {
277         top_shared_limit = 0xffff - shared_size;
278         DEBUG_PRINT(("MMU: Sharing high RAM from $%04X\n", top_shared_limit + 1));
279     } else {
280         top_shared_limit = 0xffff;
281         DEBUG_PRINT(("MMU: No high shared RAM\n"));
282     }
283 
284     /* Share low memory?  */
285     if (value & 0x4) {
286         bottom_shared_limit = shared_size;
287         DEBUG_PRINT(("MMU: Sharing low RAM up to $%04X\n", bottom_shared_limit - 1));
288     } else {
289         bottom_shared_limit = 0;
290         DEBUG_PRINT(("MMU: No low shared RAM\n"));
291     }
292 }
293 
294 /* ------------------------------------------------------------------------- */
295 
mem_pla_config_changed(void)296 void mem_pla_config_changed(void)
297 {
298     /* NOTE: on the international/US version of the hardware, there is no DIN/ASCII key -
299              instead this key is caps lock */
300     c64pla_config_changed(tape_sense, tape_write_in, tape_motor_in, caps_sense, 0x57);
301 
302     mmu_set_config64(((~pport.dir | pport.data) & 0x7) | (export.exrom << 3) | (export.game << 4));
303 
304     /* on the international version, A8 of the chargen comes from the c64/c128 mode, not
305        from the status of the DIN/ASCII (capslock) key */
306     if (mem_machine_type != C128_MACHINE_INT) {
307         mem_update_chargen(pport.data_read & 0x40);
308     }
309 }
310 
mem_toggle_caps_key(void)311 static void mem_toggle_caps_key(void)
312 {
313     caps_sense = (caps_sense) ? 0 : 1;
314     mem_pla_config_changed();
315     log_message(c128_mem_log, "CAPS key (ASCII/DIN) %s.", (caps_sense) ? "released" : "pressed");
316 }
317 
318 /* ------------------------------------------------------------------------- */
319 
320 /* $00/$01 unused bits emulation
321 
322    - There are 2 different unused bits, 1) the output bits, 2) the input bits
323    - The output bits can be (re)set when the data-direction is set to output
324      for those bits and the output bits will not drop-off to 0.
325    - When the data-direction for the unused bits is set to output then the
326      unused input bits can be (re)set by writing to them, when set to 1 the
327      drop-off timer will start which will cause the unused input bits to drop
328      down to 0 in a certain amount of time.
329    - When an unused input bit already had the drop-off timer running, and is
330      set to 1 again, the drop-off timer will restart.
331    - when an unused bit changes from output to input, and the current output
332      bit is 1, the drop-off timer will restart again
333 
334     see testprogs/CPU/cpuport for details and tests
335 */
336 
clk_overflow_callback(CLOCK sub,void * unused_data)337 static void clk_overflow_callback(CLOCK sub, void *unused_data)
338 {
339     if (pport.data_set_clk_bit7 > (CLOCK)0) {
340         pport.data_set_clk_bit7 -= sub;
341     }
342     if (pport.data_falloff_bit7 && (pport.data_set_clk_bit7 < maincpu_clk)) {
343         pport.data_falloff_bit7 = 0;
344         pport.data_set_bit7 = 0;
345     }
346 }
347 
zero_read(uint16_t addr)348 uint8_t zero_read(uint16_t addr)
349 {
350     uint8_t retval;
351 
352 	addr &= 0xff;
353 
354     switch ((uint8_t)addr) {
355         case 0:
356             return pport.dir_read;
357         case 1:
358             retval = pport.data_read;
359 
360             /* discharge the "capacitor" */
361 
362             /* set real value of read bit 7 */
363             if (pport.data_falloff_bit7 && (pport.data_set_clk_bit7 < maincpu_clk)) {
364                 pport.data_falloff_bit7 = 0;
365                 pport.data_set_bit7 = 0;
366             }
367 
368             /* for unused bits in input mode, the value comes from the "capacitor" */
369 
370             /* set real value of bit 7 */
371             if (!(pport.dir_read & 0x80)) {
372                retval &= ~0x80;
373                retval |= pport.data_set_bit7;
374             }
375 
376             return retval;
377     }
378 
379     return mem_page_zero[addr];
380 }
381 
zero_store(uint16_t addr,uint8_t value)382 void zero_store(uint16_t addr, uint8_t value)
383 {
384     addr &= 0xff;
385 
386     switch ((uint8_t)addr) {
387         case 0:
388 #if 0
389             if (vbank == 0) {
390                 vicii_mem_vbank_store((uint16_t)0, vicii_read_phi1_lowlevel());
391             } else {
392 #endif
393             mem_page_zero[0] = vicii_read_phi1_lowlevel();
394             machine_handle_pending_alarms(maincpu_rmw_flag + 1);
395 #if 0
396     }
397 #endif
398             /* when switching an unused bit from output (where it contained a
399                stable value) to input mode (where the input is floating), some
400                of the charge is transferred to the floating input */
401 
402             /* check if bit 7 has flipped */
403             if ((pport.dir & 0x80)) {
404                 if ((pport.dir ^ value) & 0x80) {
405                     pport.data_set_clk_bit7 = maincpu_clk + C128_CPU8502_DATA_PORT_FALL_OFF_CYCLES;
406                     pport.data_set_bit7 = pport.data & 0x80;
407                     pport.data_falloff_bit7 = 1;
408                 }
409             }
410 
411             if (pport.dir != value) {
412                 pport.dir = value;
413                 mem_pla_config_changed();
414             }
415             break;
416         case 1:
417 #if 0
418             if (vbank == 0) {
419                 vicii_mem_vbank_store((uint16_t)1, vicii_read_phi1_lowlevel());
420             } else {
421 #endif
422             mem_page_zero[1] = vicii_read_phi1_lowlevel();
423             machine_handle_pending_alarms(maincpu_rmw_flag + 1);
424 #if 0
425     }
426 #endif
427             /* when writing to an unused bit that is output, charge the "capacitor",
428                otherwise don't touch it */
429             if (pport.dir & 0x80) {
430                 pport.data_set_bit7 = value & 0x80;
431                 pport.data_set_clk_bit7 = maincpu_clk + C128_CPU8502_DATA_PORT_FALL_OFF_CYCLES;
432                 pport.data_falloff_bit7 = 1;
433             }
434 
435             if (pport.data != value) {
436                 pport.data = value;
437                 mem_pla_config_changed();
438             }
439             break;
440         default:
441 #if 0
442             if (vbank == 0) {
443                 vicii_mem_vbank_store(addr, value);
444             } else {
445 #endif
446             mem_page_zero[addr] = value;
447 #if 0
448     }
449 #endif
450     }
451 }
452 
453 /* ------------------------------------------------------------------------- */
454 
one_read(uint16_t addr)455 uint8_t one_read(uint16_t addr)
456 {
457     return mem_page_one[addr - 0x100];
458 }
459 
one_store(uint16_t addr,uint8_t value)460 void one_store(uint16_t addr, uint8_t value)
461 {
462     mem_page_one[addr - 0x100] = value;
463 }
464 
465 /* ------------------------------------------------------------------------- */
466 
467 /* External memory access functions.  */
468 
chargen_read(uint16_t addr)469 uint8_t chargen_read(uint16_t addr)
470 {
471     return mem_chargen_rom_ptr[addr & 0x0fff];
472 }
473 
chargen_store(uint16_t addr,uint8_t value)474 void chargen_store(uint16_t addr, uint8_t value)
475 {
476     mem_chargen_rom_ptr[addr & 0x0fff] = value;
477 }
478 
479 /* ------------------------------------------------------------------------- */
480 
481 /* Generic memory access.  */
482 
mem_store(uint16_t addr,uint8_t value)483 void mem_store(uint16_t addr, uint8_t value)
484 {
485     _mem_write_tab_ptr[addr >> 8](addr, value);
486 }
487 
mem_read(uint16_t addr)488 uint8_t mem_read(uint16_t addr)
489 {
490     return _mem_read_tab_ptr[addr >> 8](addr);
491 }
492 
mem_store_without_ultimax(uint16_t addr,uint8_t value)493 void mem_store_without_ultimax(uint16_t addr, uint8_t value)
494 {
495     store_func_ptr_t *write_tab_ptr;
496 
497     write_tab_ptr = mem_write_tab[vbank][mem_config & 7];
498 
499     write_tab_ptr[addr >> 8](addr, value);
500 }
501 
mem_read_without_ultimax(uint16_t addr)502 uint8_t mem_read_without_ultimax(uint16_t addr)
503 {
504     read_func_ptr_t *read_tab_ptr;
505 
506     read_tab_ptr = mem_read_tab[mem_config & 7];
507 
508     return read_tab_ptr[addr >> 8](addr);
509 }
510 
mem_store_without_romlh(uint16_t addr,uint8_t value)511 void mem_store_without_romlh(uint16_t addr, uint8_t value)
512 {
513     store_func_ptr_t *write_tab_ptr;
514 
515     write_tab_ptr = mem_write_tab[vbank][0];
516 
517     write_tab_ptr[addr >> 8](addr, value);
518 }
519 
520 /* ------------------------------------------------------------------------- */
521 
522 /* CPU Memory interface.  */
523 
524 /* The MMU can basically do the following:
525 
526    - select one of the two (four) memory banks as the standard
527    (non-shared) memory;
528 
529    - turn ROM and I/O on and off;
530 
531    - enable/disable top/bottom shared RAM (from 1K to 16K, so bottom
532    shared RAM cannot go beyond $3FFF and top shared RAM cannot go
533    under $C000);
534 
535    - move pages 0 and 1 to any physical address.  */
536 
537 #define READ_TOP_SHARED(addr) ((addr) > top_shared_limit ? mem_ram[(addr)] : ram_bank[(addr)])
538 
539 #define STORE_TOP_SHARED(addr, value) ((addr) > top_shared_limit ? (mem_ram[(addr)] = (value)) : (ram_bank[(addr)] = (value)))
540 
541 #define READ_BOTTOM_SHARED(addr) ((addr) < bottom_shared_limit ? mem_ram[(addr)] : ram_bank[(addr)])
542 
543 #define STORE_BOTTOM_SHARED(addr, value) ((addr) < bottom_shared_limit ? (mem_ram[(addr)] = (value)) : (ram_bank[(addr)] = (value)))
544 
545 /* $0200 - $3FFF: RAM (normal or shared).  */
lo_read(uint16_t addr)546 uint8_t lo_read(uint16_t addr)
547 {
548     return READ_BOTTOM_SHARED(addr);
549 }
550 
lo_store(uint16_t addr,uint8_t value)551 void lo_store(uint16_t addr, uint8_t value)
552 {
553     STORE_BOTTOM_SHARED(addr, value);
554 }
555 
ram_read(uint16_t addr)556 uint8_t ram_read(uint16_t addr)
557 {
558     return ram_bank[addr];
559 }
560 
ram_store(uint16_t addr,uint8_t value)561 void ram_store(uint16_t addr, uint8_t value)
562 {
563     ram_bank[addr] = value;
564 }
565 
ram_hi_store(uint16_t addr,uint8_t value)566 void ram_hi_store(uint16_t addr, uint8_t value)
567 {
568     if (vbank == 3) {
569         vicii_mem_vbank_3fxx_store(addr, value);
570     } else {
571         ram_bank[addr] = value;
572     }
573 
574     if (addr == 0xff00) {
575         reu_dma(-1);
576     }
577 }
578 
579 /* $4000 - $7FFF: RAM or low BASIC ROM.  */
basic_lo_read(uint16_t addr)580 uint8_t basic_lo_read(uint16_t addr)
581 {
582     return c128memrom_basic_rom[addr - 0x4000];
583 }
584 
basic_lo_store(uint16_t addr,uint8_t value)585 void basic_lo_store(uint16_t addr, uint8_t value)
586 {
587     ram_bank[addr] = value;
588 }
589 
590 /* $8000 - $BFFF: RAM or high BASIC ROM.  */
basic_hi_read(uint16_t addr)591 uint8_t basic_hi_read(uint16_t addr)
592 {
593     return c128memrom_basic_rom[addr - 0x4000];
594 }
595 
basic_hi_store(uint16_t addr,uint8_t value)596 void basic_hi_store(uint16_t addr, uint8_t value)
597 {
598     ram_bank[addr] = value;
599 }
600 
601 /* $C000 - $CFFF: RAM (normal or shared) or Editor ROM.  */
editor_read(uint16_t addr)602 uint8_t editor_read(uint16_t addr)
603 {
604     return c128memrom_basic_rom[addr - 0x4000];
605 }
606 
editor_store(uint16_t addr,uint8_t value)607 void editor_store(uint16_t addr, uint8_t value)
608 {
609     STORE_TOP_SHARED(addr, value);
610 }
611 
d5xx_read(uint16_t addr)612 static uint8_t d5xx_read(uint16_t addr)
613 {
614     return vicii_read_phi1();
615 }
616 
d5xx_store(uint16_t addr,uint8_t value)617 static void d5xx_store(uint16_t addr, uint8_t value)
618 {
619 }
620 
d7xx_read(uint16_t addr)621 uint8_t d7xx_read(uint16_t addr)
622 {
623     if (sid_stereo && addr >= sid_stereo_address_start && addr < sid_stereo_address_end) {
624         return sid2_read(addr);
625     }
626     return vicii_read_phi1();
627 }
628 
d7xx_store(uint16_t addr,uint8_t value)629 void d7xx_store(uint16_t addr, uint8_t value)
630 {
631     if (sid_stereo && addr >= sid_stereo_address_start && addr < sid_stereo_address_end) {
632         sid2_store(addr, value);
633     }
634 }
635 
636 /* $E000 - $FFFF: RAM or Kernal.  */
hi_read(uint16_t addr)637 uint8_t hi_read(uint16_t addr)
638 {
639     return c128memrom_kernal_rom[addr & 0x1fff];
640 }
641 
hi_store(uint16_t addr,uint8_t value)642 void hi_store(uint16_t addr, uint8_t value)
643 {
644     STORE_TOP_SHARED(addr, value);
645 }
646 
top_shared_read(uint16_t addr)647 uint8_t top_shared_read(uint16_t addr)
648 {
649     return READ_TOP_SHARED(addr);
650 }
651 
top_shared_store(uint16_t addr,uint8_t value)652 void top_shared_store(uint16_t addr, uint8_t value)
653 {
654     STORE_TOP_SHARED(addr, value);
655 }
656 
657 /* ------------------------------------------------------------------------- */
658 
colorram_store(uint16_t addr,uint8_t value)659 void colorram_store(uint16_t addr, uint8_t value)
660 {
661     mem_color_ram_cpu[addr & 0x3ff] = value & 0xf;
662 }
663 
colorram_read(uint16_t addr)664 uint8_t colorram_read(uint16_t addr)
665 {
666     return mem_color_ram_cpu[addr & 0x3ff] | (vicii_read_phi1() & 0xf0);
667 }
668 
669 /* ------------------------------------------------------------------------- */
670 
mem_set_write_hook(int config,int page,store_func_t * f)671 void mem_set_write_hook(int config, int page, store_func_t *f)
672 {
673     int i;
674 
675     for (i = 0; i < NUM_VBANKS; i++) {
676         mem_write_tab[i][config][page] = f;
677     }
678 }
679 
mem_read_tab_set(unsigned int base,unsigned int index,read_func_ptr_t read_func)680 void mem_read_tab_set(unsigned int base, unsigned int index, read_func_ptr_t read_func)
681 {
682     mem_read_tab[base][index] = read_func;
683 }
684 
mem_read_base_set(unsigned int base,unsigned int index,uint8_t * mem_ptr)685 void mem_read_base_set(unsigned int base, unsigned int index, uint8_t *mem_ptr)
686 {
687     mem_read_base_tab[base][index] = mem_ptr;
688 }
689 
690 #ifdef _MSC_VER
691 #pragma optimize("",off)
692 #endif
693 
mem_initialize_memory(void)694 void mem_initialize_memory(void)
695 {
696     int i, j, k;
697 
698     clk_guard_add_callback(maincpu_clk_guard, clk_overflow_callback, NULL);
699 
700     mem_chargen_rom_ptr = mem_chargen_rom;
701     mem_color_ram_cpu = mem_color_ram;
702     mem_color_ram_vicii = mem_color_ram;
703 
704     mem_limit_init(mem_read_limit_tab);
705 
706     for (i = 0; i <= 0x100; i++) {
707         mem_read_tab_watch[i] = watch_read;
708         mem_write_tab_watch[i] = watch_store;
709     }
710 
711     c128meminit();
712 
713     /* C64 mode configuration.  */
714 
715     for (i = 0; i < 32; i++) {
716         mem_set_write_hook(128 + i, 0, zero_store);
717         mem_read_tab[128 + i][0] = zero_read;
718         mem_read_base_tab[128 + i][0] = mem_ram;
719         mem_set_write_hook(128 + i, 1, one_store);
720         mem_read_tab[128 + i][1] = one_read;
721         mem_read_base_tab[128 + i][1] = mem_ram;
722         for (j = 2; j <= 0xfe; j++) {
723             mem_read_tab[128 + i][j] = ram_read;
724             mem_read_base_tab[128 + i][j] = mem_ram;
725             for (k = 0; k < NUM_VBANKS; k++) {
726                 if ((j & 0xc0) == (k << 6)) {
727                     switch (j & 0x3f) {
728                         case 0x39:
729                             mem_write_tab[k][128 + i][j] = vicii_mem_vbank_39xx_store;
730                             break;
731                         case 0x3f:
732                             mem_write_tab[k][128 + i][j] = vicii_mem_vbank_3fxx_store;
733                             break;
734                         default:
735                             mem_write_tab[k][128 + i][j] = vicii_mem_vbank_store;
736                     }
737                 } else {
738                     mem_write_tab[k][128 + i][j] = ram_store;
739                 }
740             }
741         }
742         mem_read_tab[128 + i][0xff] = ram_read;
743         mem_read_base_tab[128 + i][0xff] = mem_ram;
744 
745         /* vbank access is handled within `ram_hi_store()'.  */
746         mem_set_write_hook(128 + i, 0xff, ram_hi_store);
747     }
748 
749     /* Setup character generator ROM at $D000-$DFFF (memory configs 1, 2,
750        3, 9, 10, 11, 25, 26, 27).  */
751     for (i = 0xd0; i <= 0xdf; i++) {
752         mem_read_tab[128 + 1][i] = chargen_read;
753         mem_read_tab[128 + 2][i] = chargen_read;
754         mem_read_tab[128 + 3][i] = chargen_read;
755         mem_read_tab[128 + 9][i] = chargen_read;
756         mem_read_tab[128 + 10][i] = chargen_read;
757         mem_read_tab[128 + 11][i] = chargen_read;
758         mem_read_tab[128 + 25][i] = chargen_read;
759         mem_read_tab[128 + 26][i] = chargen_read;
760         mem_read_tab[128 + 27][i] = chargen_read;
761         mem_read_base_tab[128 + 1][i] = NULL;
762         mem_read_base_tab[128 + 2][i] = NULL;
763         mem_read_base_tab[128 + 3][i] = NULL;
764         mem_read_base_tab[128 + 9][i] = NULL;
765         mem_read_base_tab[128 + 10][i] = NULL;
766         mem_read_base_tab[128 + 11][i] = NULL;
767         mem_read_base_tab[128 + 25][i] = NULL;
768         mem_read_base_tab[128 + 26][i] = NULL;
769         mem_read_base_tab[128 + 27][i] = NULL;
770     }
771 
772     c64meminit(128);
773 
774     /* Setup C128 specific I/O at $D000-$DFFF.  */
775     for (j = 0; j < 32; j++) {
776         if (c64meminit_io_config[j]) {
777             mem_read_tab[128 + j][0xd0] = c128_c64io_d000_read;
778             mem_set_write_hook(128 + j, 0xd0, c128_c64io_d000_store);
779             mem_read_tab[128 + j][0xd1] = c128_c64io_d100_read;
780             mem_set_write_hook(128 + j, 0xd1, c128_c64io_d100_store);
781             mem_read_tab[128 + j][0xd2] = c128_c64io_d200_read;
782             mem_set_write_hook(128 + j, 0xd2, c128_c64io_d200_store);
783             mem_read_tab[128 + j][0xd3] = c128_c64io_d300_read;
784             mem_set_write_hook(128 + j, 0xd3, c128_c64io_d300_store);
785             mem_read_tab[128 + j][0xd4] = c128_c64io_d400_read;
786             mem_set_write_hook(128 + j, 0xd4, c128_c64io_d400_store);
787             mem_read_tab[128 + j][0xd5] = c128_d5xx_read;
788             mem_set_write_hook(128 + j, 0xd5, c128_d5xx_store);
789             mem_read_tab[128 + j][0xd6] = c128_vdc_read;
790             mem_set_write_hook(128 + j, 0xd6, c128_vdc_store);
791             mem_read_tab[128 + j][0xd7] = c128_c64io_d700_read;
792             mem_set_write_hook(128 + j, 0xd7, c128_c64io_d700_store);
793             mem_read_tab[128 + j][0xd8] = c128_colorram_read;
794             mem_set_write_hook(128 + j, 0xd8, c128_colorram_store);
795             mem_read_tab[128 + j][0xd9] = c128_colorram_read;
796             mem_set_write_hook(128 + j, 0xd9, c128_colorram_store);
797             mem_read_tab[128 + j][0xda] = c128_colorram_read;
798             mem_set_write_hook(128 + j, 0xda, c128_colorram_store);
799             mem_read_tab[128 + j][0xdb] = c128_colorram_read;
800             mem_set_write_hook(128 + j, 0xdb, c128_colorram_store);
801             mem_read_tab[128 + j][0xdc] = c128_cia1_read;
802             mem_set_write_hook(128 + j, 0xdc, c128_cia1_store);
803             mem_read_tab[128 + j][0xdd] = c128_cia2_read;
804             mem_set_write_hook(128 + j, 0xdd, c128_cia2_store);
805             mem_read_tab[128 + j][0xde] = c128_c64io_de00_read;
806             mem_set_write_hook(128 + j, 0xde, c128_c64io_de00_store);
807             mem_read_tab[128 + j][0xdf] = c128_c64io_df00_read;
808             mem_set_write_hook(128 + j, 0xdf, c128_c64io_df00_store);
809         }
810     }
811 
812     for (i = 128; i < 128 + 32; i++) {
813         mem_read_tab[i][0x100] = mem_read_tab[i][0];
814         for (j = 0; j < NUM_VBANKS; j++) {
815             mem_write_tab[j][i][0x100] = mem_write_tab[j][i][0];
816         }
817         mem_read_base_tab[i][0x100] = mem_read_base_tab[i][0];
818     }
819 
820     vicii_set_chargen_addr_options(0xffff, 0xffff);
821 
822     mmu_reset();
823 
824     keyboard_register_caps_key(mem_toggle_caps_key);
825 
826     top_shared_limit = 0xffff;
827     bottom_shared_limit = 0x0000;
828     ram_bank = mem_ram;
829     mem_page_zero = mem_ram;
830     mem_page_one = mem_ram + 0x100;
831 
832     _mem_read_tab_ptr = mem_read_tab[3];
833     _mem_write_tab_ptr = mem_write_tab[vbank][3];
834     _mem_read_base_tab_ptr = mem_read_base_tab[3];
835     mem_read_limit_tab_ptr = mem_read_limit_tab[3];
836 
837     c64pla_pport_reset();
838 
839     cartridge_init_config();
840 }
841 
842 #ifdef _MSC_VER
843 #pragma optimize("",on)
844 #endif
845 
mem_mmu_translate(unsigned int addr,uint8_t ** base,int * start,int * limit)846 void mem_mmu_translate(unsigned int addr, uint8_t **base, int *start, int *limit)
847 {
848     uint8_t *p = _mem_read_base_tab_ptr[addr >> 8];
849 
850     *base = (p == NULL) ? NULL : p;
851     *start = addr; /* TODO */
852     *limit = mem_read_limit_tab_ptr[addr >> 8];
853 }
854 
855 /* ------------------------------------------------------------------------- */
856 
857 /* Initialize RAM for power-up.  */
mem_powerup(void)858 void mem_powerup(void)
859 {
860     ram_init(mem_ram, C128_RAM_SIZE);
861     cartridge_ram_init();  /* Clean cartridge ram too */
862 }
863 
864 /* ------------------------------------------------------------------------- */
865 
866 /* Set the tape sense status.  */
mem_set_tape_sense(int sense)867 void mem_set_tape_sense(int sense)
868 {
869     tape_sense = sense;
870     mem_pla_config_changed();
871 }
872 
873 /* Set the tape write in. */
mem_set_tape_write_in(int val)874 void mem_set_tape_write_in(int val)
875 {
876     tape_write_in = val;
877     mem_pla_config_changed();
878 }
879 
880 /* Set the tape motor in. */
mem_set_tape_motor_in(int val)881 void mem_set_tape_motor_in(int val)
882 {
883     tape_motor_in = val;
884     mem_pla_config_changed();
885 }
886 
887 /* ------------------------------------------------------------------------- */
888 
mem_get_basic_text(uint16_t * start,uint16_t * end)889 void mem_get_basic_text(uint16_t *start, uint16_t *end)
890 {
891     if (start != NULL) {
892         *start = mem_ram[0x2b] | (mem_ram[0x2c] << 8);
893     }
894     if (end != NULL) {
895         *end = mem_ram[0x1210] | (mem_ram[0x1211] << 8);
896     }
897 }
898 
mem_set_basic_text(uint16_t start,uint16_t end)899 void mem_set_basic_text(uint16_t start, uint16_t end)
900 {
901     mem_ram[0x2b] = mem_ram[0xac] = start & 0xff;
902     mem_ram[0x2c] = mem_ram[0xad] = start >> 8;
903     mem_ram[0x1210] = end & 0xff;
904     mem_ram[0x1211] = end >> 8;
905 }
906 
mem_inject(uint32_t addr,uint8_t value)907 void mem_inject(uint32_t addr, uint8_t value)
908 {
909     /* this could be altered to handle more that 64 Kb in some
910        useful way */
911     mem_ram[addr & 0xffff] = value;
912 }
913 
914 /* ------------------------------------------------------------------------- */
915 
mem_rom_trap_allowed(uint16_t addr)916 int mem_rom_trap_allowed(uint16_t addr)
917 {
918     if (addr >= 0xe000) {
919         if (mem_config >= 128) {
920             switch (mem_config - 128) {
921                 case 2:
922                 case 3:
923                 case 6:
924                 case 7:
925                 case 10:
926                 case 11:
927                 case 14:
928                 case 15:
929                 case 26:
930                 case 27:
931                 case 30:
932                 case 31:
933                     return 1;
934                 default:
935                     return 0;
936             }
937         }
938         return 1;
939     }
940 
941     return 0;
942 }
943 
944 /* ------------------------------------------------------------------------- */
945 
946 /* Banked memory access functions for the monitor */
947 
948 /* FIXME: peek, cartridge support */
949 
store_bank_io(uint16_t addr,uint8_t byte)950 void store_bank_io(uint16_t addr, uint8_t byte)
951 {
952     switch (addr & 0xff00) {
953         case 0xd000:
954             c64io_d000_store(addr, byte);
955             break;
956         case 0xd100:
957             c64io_d100_store(addr, byte);
958             break;
959         case 0xd200:
960             c64io_d200_store(addr, byte);
961             break;
962         case 0xd300:
963             c64io_d300_store(addr, byte);
964             break;
965         case 0xd400:
966             c64io_d400_store(addr, byte);
967             break;
968         case 0xd500:
969             mmu_store(addr, byte);
970             break;
971         case 0xd600:
972             vdc_store(addr, byte);
973             break;
974         case 0xd700:
975             c64io_d700_store(addr, byte);
976             break;
977         case 0xd800:
978         case 0xd900:
979         case 0xda00:
980         case 0xdb00:
981             colorram_store(addr, byte);
982             break;
983         case 0xdc00:
984             cia1_store(addr, byte);
985             break;
986         case 0xdd00:
987             cia2_store(addr, byte);
988             break;
989         case 0xde00:
990             c64io_de00_store(addr, byte);
991             break;
992         case 0xdf00:
993             c64io_df00_store(addr, byte);
994             break;
995     }
996     return;
997 }
998 
read_bank_io(uint16_t addr)999 uint8_t read_bank_io(uint16_t addr)
1000 {
1001     switch (addr & 0xff00) {
1002         case 0xd000:
1003             return c64io_d000_read(addr);
1004         case 0xd100:
1005             return c64io_d100_read(addr);
1006         case 0xd200:
1007             return c64io_d200_read(addr);
1008         case 0xd300:
1009             return c64io_d300_read(addr);
1010         case 0xd400:
1011             return c64io_d400_read(addr);
1012         case 0xd500:
1013             return mmu_read(addr);
1014         case 0xd600:
1015             return vdc_read(addr);
1016         case 0xd700:
1017             return c64io_d700_read(addr);
1018         case 0xd800:
1019         case 0xd900:
1020         case 0xda00:
1021         case 0xdb00:
1022             return colorram_read(addr);
1023         case 0xdc00:
1024             return cia1_read(addr);
1025         case 0xdd00:
1026             return cia2_read(addr);
1027         case 0xde00:
1028             return c64io_de00_read(addr);
1029         case 0xdf00:
1030             return c64io_df00_read(addr);
1031     }
1032     return 0xff;
1033 }
1034 
peek_bank_io(uint16_t addr)1035 static uint8_t peek_bank_io(uint16_t addr)
1036 {
1037     switch (addr & 0xff00) {
1038         case 0xd000:
1039             return c64io_d000_peek(addr);
1040         case 0xd100:
1041             return c64io_d100_peek(addr);
1042         case 0xd200:
1043             return c64io_d200_peek(addr);
1044         case 0xd300:
1045             return c64io_d300_peek(addr);
1046         case 0xd400:
1047             return c64io_d400_peek(addr);
1048         case 0xd500:
1049             return mmu_peek(addr);
1050         case 0xd600:
1051             return vdc_peek(addr);
1052         case 0xd700:
1053             return c64io_d700_peek(addr);
1054         case 0xd800:
1055         case 0xd900:
1056         case 0xda00:
1057         case 0xdb00:
1058             return colorram_read(addr);
1059         case 0xdc00:
1060             return cia1_peek(addr);
1061         case 0xdd00:
1062             return cia2_peek(addr);
1063         case 0xde00:
1064             return c64io_de00_peek(addr);
1065         case 0xdf00:
1066             return c64io_df00_peek(addr);
1067     }
1068     return 0xff;
1069 }
1070 
1071 /* Exported banked memory access functions for the monitor.  */
1072 
1073 static const char *banknames[] = {
1074     "default",
1075     "cpu",
1076     "ram",
1077     "rom",
1078     "io",
1079     "ram1",
1080     "intfunc",
1081     "extfunc",
1082     "cart",
1083     "c64rom",
1084     "vdc",
1085     NULL
1086 };
1087 
1088 static const int banknums[] = {
1089     1,
1090     0,
1091     1,
1092     2,
1093     3,
1094     4,
1095     5,
1096     6,
1097     7,
1098     8,
1099     9
1100 };
1101 
mem_bank_list(void)1102 const char **mem_bank_list(void)
1103 {
1104     return banknames;
1105 }
1106 
mem_bank_from_name(const char * name)1107 int mem_bank_from_name(const char *name)
1108 {
1109     int i = 0;
1110 
1111     while (banknames[i]) {
1112         if (!strcmp(name, banknames[i])) {
1113             return banknums[i];
1114         }
1115         i++;
1116     }
1117     return -1;
1118 }
1119 
mem_bank_read(int bank,uint16_t addr,void * context)1120 uint8_t mem_bank_read(int bank, uint16_t addr, void *context)
1121 {
1122     switch (bank) {
1123         case 0:                   /* current */
1124             return mem_read(addr);
1125         case 4:                   /* ram1 */
1126             return mem_ram[addr + 0x10000];
1127         case 3:                   /* io */
1128             if (addr >= 0xd000 && addr < 0xe000) {
1129                 return read_bank_io(addr);
1130             }
1131             /* FALL THROUGH */
1132         case 2:                   /* rom */
1133             if (addr <= 0x0fff) {
1134                 return bios_read(addr);
1135             }
1136             if (addr >= 0x4000 && addr <= 0xcfff) {
1137                 return c128memrom_basic_rom[addr - 0x4000];
1138             }
1139             if (addr >= 0xd000 && addr <= 0xdfff) {
1140                 return mem_chargen_rom[addr & 0x0fff];
1141             }
1142             if (addr >= 0xe000) {
1143                 return c128memrom_kernal_rom[addr & 0x1fff];
1144             }
1145             /* FALL THROUGH */
1146         case 1:                   /* ram */
1147             break;
1148         case 5:
1149             if (addr >= 0x8000) {
1150                 return int_function_rom[addr & 0x7fff];
1151             }
1152             break;
1153         case 6:
1154             if (addr >= 0x8000) {
1155                 return ext_function_rom[addr & 0x7fff];
1156             }
1157             break;
1158         case 7:
1159             return cartridge_peek_mem(addr);
1160         case 8:
1161             if (addr >= 0xa000 && addr <= 0xbfff) {
1162                 return c64memrom_basic64_rom[addr & 0x1fff];
1163             }
1164             if (addr >= 0xd000 && addr <= 0xdfff) {
1165                 return mem_chargen_rom[addr & 0x0fff];
1166             }
1167             if (addr >= 0xe000) {
1168                 return c64memrom_kernal64_rom[addr & 0x1fff];
1169             }
1170             break;
1171         case 9:
1172             return vdc_ram_read(addr);
1173     }
1174     return mem_ram[addr];
1175 }
1176 
mem_bank_peek(int bank,uint16_t addr,void * context)1177 uint8_t mem_bank_peek(int bank, uint16_t addr, void *context)
1178 {
1179     switch (bank) {
1180         case 0:                   /* current */
1181             /* FIXME: we must check for which bank is currently active, and only use peek_bank_io
1182                       when needed. doing this without checking is wrong, but we do it anyways to
1183                       avoid side effects
1184            */
1185             if (addr >= 0xd000 && addr < 0xe000) {
1186                 return peek_bank_io(addr);
1187             }
1188             return mem_read(addr);
1189             break;
1190         case 3:                   /* io */
1191             if (addr >= 0xd000 && addr < 0xe000) {
1192                 return peek_bank_io(addr);
1193             }
1194             break;
1195         case 7:
1196             return cartridge_peek_mem(addr);
1197     }
1198     return mem_bank_read(bank, addr, context);
1199 }
1200 
mem_bank_write(int bank,uint16_t addr,uint8_t byte,void * context)1201 void mem_bank_write(int bank, uint16_t addr, uint8_t byte, void *context)
1202 {
1203     switch (bank) {
1204         case 0:                   /* current */
1205             mem_store(addr, byte);
1206             return;
1207         case 4:                   /* ram1 */
1208             mem_ram[addr + 0x10000] = byte;
1209             return;
1210         case 3:                   /* io */
1211             if (addr >= 0xd000 && addr < 0xe000) {
1212                 store_bank_io(addr, byte);
1213                 return;
1214             }
1215             /* FALL THROUGH */
1216         case 2:                   /* rom */
1217             if (addr >= 0x4000 && addr <= 0xcfff) {
1218                 return;
1219             }
1220             if (addr >= 0xe000) {
1221                 return;
1222             }
1223             /* FALL THROUGH */
1224         case 1:                   /* ram */
1225             break;
1226         case 5:
1227             if (addr >= 0x8000) {
1228                 return;
1229             }
1230             break;
1231         case 6:
1232             if (addr >= 0x8000 && addr <= 0xbfff) {
1233                 return;
1234             }
1235             break;
1236         case 7:
1237             if (addr >= 0x8000 && addr <= 0x9fff) {
1238                 return;
1239             }
1240             if (addr >= 0xa000 && addr <= 0xbfff) {
1241                 return;
1242             }
1243             /* FALL THROUGH */
1244         case 8:
1245             if (addr >= 0xa000 && addr <= 0xbfff) {
1246                 return;
1247             }
1248             if (addr >= 0xd000 && addr <= 0xdfff) {
1249                 return;
1250             }
1251             if (addr >= 0xe000) {
1252                 return;
1253             }
1254             break;
1255         case 9:
1256             vdc_ram_store(addr, byte);
1257             break;
1258     }
1259     mem_ram[addr] = byte;
1260 }
1261 
mem_dump_io(void * context,uint16_t addr)1262 static int mem_dump_io(void *context, uint16_t addr)
1263 {
1264     if ((addr >= 0xdc00) && (addr <= 0xdc3f)) {
1265         return ciacore_dump(machine_context.cia1);
1266     } else if ((addr >= 0xdd00) && (addr <= 0xdd3f)) {
1267         return ciacore_dump(machine_context.cia2);
1268     }
1269     return -1;
1270 }
1271 
mem_ioreg_list_get(void * context)1272 mem_ioreg_list_t *mem_ioreg_list_get(void *context)
1273 {
1274     mem_ioreg_list_t *mem_ioreg_list = NULL;
1275 
1276     mon_ioreg_add_list(&mem_ioreg_list, "MMU", 0xd500, 0xd50b, mmu_dump, NULL);
1277     mon_ioreg_add_list(&mem_ioreg_list, "VDC", 0xd600, 0xd601, vdc_dump, NULL);
1278     mon_ioreg_add_list(&mem_ioreg_list, "CIA1", 0xdc00, 0xdc0f, mem_dump_io, NULL);
1279     mon_ioreg_add_list(&mem_ioreg_list, "CIA2", 0xdd00, 0xdd0f, mem_dump_io, NULL);
1280 
1281     io_source_ioreg_add_list(&mem_ioreg_list);
1282 
1283     return mem_ioreg_list;
1284 }
1285 
mem_get_screen_parameter(uint16_t * base,uint8_t * rows,uint8_t * columns,int * bank)1286 void mem_get_screen_parameter(uint16_t *base, uint8_t *rows, uint8_t *columns, int *bank)
1287 {
1288     /* Check the 40/80 DISPLAY switch state */
1289     if (peek_bank_io(0xD505) & 0x80) { /* 40 column so read VIC screen */
1290         *base = ((vicii_peek(0xd018) & 0xf0) << 6) | ((~cia2_peek(0xdd00) & 0x03) << 14);
1291         *rows = 25;
1292         *columns = 40;
1293         *bank = 0;
1294     } else { /* Read VDC */
1295         *base = (vdc.regs[12] << 8) | vdc.regs[13];
1296         *rows = vdc.regs[6];
1297         *columns = vdc.regs[1];
1298         *bank = 9;
1299     }
1300 }
1301 
1302 /* ------------------------------------------------------------------------- */
1303 
mem_color_ram_to_snapshot(uint8_t * color_ram)1304 void mem_color_ram_to_snapshot(uint8_t *color_ram)
1305 {
1306     unsigned int i;
1307 
1308     for (i = 0; i < 0x400; i++) {
1309         color_ram[i] = (mem_color_ram[i] & 15) | (mem_color_ram[i + 0x400] << 4);
1310     }
1311 }
1312 
mem_color_ram_from_snapshot(uint8_t * color_ram)1313 void mem_color_ram_from_snapshot(uint8_t *color_ram)
1314 {
1315     unsigned int i;
1316 
1317     for (i = 0; i < 0x400; i++) {
1318         mem_color_ram[i] = color_ram[i] & 15;
1319         mem_color_ram[i + 0x400] = color_ram[i] >> 4;
1320     }
1321 }
1322 
1323 /* ------------------------------------------------------------------------- */
1324 
1325 /* 8502 specific I/O function wrappers for 2mhz mode cycle stretching */
1326 
c128_c64io_d000_read(uint16_t addr)1327 uint8_t c128_c64io_d000_read(uint16_t addr)
1328 {
1329     uint8_t temp_value;
1330 
1331     temp_value = c64io_d000_read(addr);
1332     vicii_clock_read_stretch();
1333     return temp_value;
1334 }
1335 
c128_c64io_d000_store(uint16_t addr,uint8_t value)1336 void c128_c64io_d000_store(uint16_t addr, uint8_t value)
1337 {
1338     vicii_clock_write_stretch();
1339     c64io_d000_store(addr, value);
1340 }
1341 
c128_c64io_d100_read(uint16_t addr)1342 uint8_t c128_c64io_d100_read(uint16_t addr)
1343 {
1344     uint8_t temp_value;
1345 
1346     temp_value = c64io_d100_read(addr);
1347     vicii_clock_read_stretch();
1348     return temp_value;
1349 }
1350 
c128_c64io_d100_store(uint16_t addr,uint8_t value)1351 void c128_c64io_d100_store(uint16_t addr, uint8_t value)
1352 {
1353     vicii_clock_write_stretch();
1354     c64io_d100_store(addr, value);
1355 }
1356 
c128_c64io_d200_read(uint16_t addr)1357 uint8_t c128_c64io_d200_read(uint16_t addr)
1358 {
1359     uint8_t temp_value;
1360 
1361     temp_value = c64io_d200_read(addr);
1362     vicii_clock_read_stretch();
1363     return temp_value;
1364 }
1365 
c128_c64io_d200_store(uint16_t addr,uint8_t value)1366 void c128_c64io_d200_store(uint16_t addr, uint8_t value)
1367 {
1368     vicii_clock_write_stretch();
1369     c64io_d200_store(addr, value);
1370 }
1371 
c128_c64io_d300_read(uint16_t addr)1372 uint8_t c128_c64io_d300_read(uint16_t addr)
1373 {
1374     uint8_t temp_value;
1375 
1376     temp_value = c64io_d300_read(addr);
1377     vicii_clock_read_stretch();
1378     return temp_value;
1379 }
1380 
c128_c64io_d300_store(uint16_t addr,uint8_t value)1381 void c128_c64io_d300_store(uint16_t addr, uint8_t value)
1382 {
1383     vicii_clock_write_stretch();
1384     c64io_d300_store(addr, value);
1385 }
1386 
c128_c64io_d400_read(uint16_t addr)1387 uint8_t c128_c64io_d400_read(uint16_t addr)
1388 {
1389     uint8_t temp_value;
1390 
1391     temp_value = c64io_d400_read(addr);
1392     vicii_clock_read_stretch();
1393     return temp_value;
1394 }
1395 
c128_c64io_d400_store(uint16_t addr,uint8_t value)1396 void c128_c64io_d400_store(uint16_t addr, uint8_t value)
1397 {
1398     vicii_clock_write_stretch();
1399     c64io_d400_store(addr, value);
1400 }
1401 
c128_mmu_read(uint16_t addr)1402 uint8_t c128_mmu_read(uint16_t addr)
1403 {
1404     uint8_t temp_value;
1405 
1406     temp_value = mmu_read(addr);
1407     vicii_clock_read_stretch();
1408     return temp_value;
1409 }
1410 
c128_mmu_store(uint16_t addr,uint8_t value)1411 void c128_mmu_store(uint16_t addr, uint8_t value)
1412 {
1413     vicii_clock_write_stretch();
1414     mmu_store(addr, value);
1415 }
1416 
c128_d5xx_read(uint16_t addr)1417 uint8_t c128_d5xx_read(uint16_t addr)
1418 {
1419     uint8_t temp_value;
1420 
1421     temp_value = d5xx_read(addr);
1422     vicii_clock_read_stretch();
1423     return temp_value;
1424 }
1425 
c128_d5xx_store(uint16_t addr,uint8_t value)1426 void c128_d5xx_store(uint16_t addr, uint8_t value)
1427 {
1428     vicii_clock_write_stretch();
1429     d5xx_store(addr, value);
1430 }
1431 
c128_vdc_read(uint16_t addr)1432 uint8_t c128_vdc_read(uint16_t addr)
1433 {
1434     uint8_t temp_value;
1435 
1436     temp_value = vdc_read(addr);
1437     vicii_clock_read_stretch();
1438     return temp_value;
1439 }
1440 
c128_vdc_store(uint16_t addr,uint8_t value)1441 void c128_vdc_store(uint16_t addr, uint8_t value)
1442 {
1443     vicii_clock_write_stretch();
1444     vdc_store(addr, value);
1445 }
1446 
c128_c64io_d700_read(uint16_t addr)1447 uint8_t c128_c64io_d700_read(uint16_t addr)
1448 {
1449     uint8_t temp_value;
1450 
1451     temp_value = c64io_d700_read(addr);
1452     vicii_clock_read_stretch();
1453     return temp_value;
1454 }
1455 
c128_c64io_d700_store(uint16_t addr,uint8_t value)1456 void c128_c64io_d700_store(uint16_t addr, uint8_t value)
1457 {
1458     vicii_clock_write_stretch();
1459     c64io_d700_store(addr, value);
1460 }
1461 
c128_colorram_read(uint16_t addr)1462 uint8_t c128_colorram_read(uint16_t addr)
1463 {
1464     uint8_t temp_value;
1465 
1466     temp_value = colorram_read(addr);
1467     vicii_clock_read_stretch();
1468     return temp_value;
1469 }
1470 
c128_colorram_store(uint16_t addr,uint8_t value)1471 void c128_colorram_store(uint16_t addr, uint8_t value)
1472 {
1473     vicii_clock_write_stretch();
1474     colorram_store(addr, value);
1475 }
1476 
c128_cia1_read(uint16_t addr)1477 uint8_t c128_cia1_read(uint16_t addr)
1478 {
1479     uint8_t temp_value;
1480 
1481     temp_value = cia1_read(addr);
1482     vicii_clock_read_stretch();
1483     return temp_value;
1484 }
1485 
c128_cia1_store(uint16_t addr,uint8_t value)1486 void c128_cia1_store(uint16_t addr, uint8_t value)
1487 {
1488     vicii_clock_write_stretch();
1489     cia1_store(addr, value);
1490 }
1491 
c128_cia2_read(uint16_t addr)1492 uint8_t c128_cia2_read(uint16_t addr)
1493 {
1494     uint8_t temp_value;
1495 
1496     temp_value = cia2_read(addr);
1497     vicii_clock_read_stretch();
1498     return temp_value;
1499 }
1500 
c128_cia2_store(uint16_t addr,uint8_t value)1501 void c128_cia2_store(uint16_t addr, uint8_t value)
1502 {
1503     vicii_clock_write_stretch();
1504     cia2_store(addr, value);
1505 }
1506 
c128_c64io_de00_read(uint16_t addr)1507 uint8_t c128_c64io_de00_read(uint16_t addr)
1508 {
1509     uint8_t temp_value;
1510 
1511     temp_value = c64io_de00_read(addr);
1512     vicii_clock_read_stretch();
1513     return temp_value;
1514 }
1515 
c128_c64io_de00_store(uint16_t addr,uint8_t value)1516 void c128_c64io_de00_store(uint16_t addr, uint8_t value)
1517 {
1518     vicii_clock_write_stretch();
1519     c64io_de00_store(addr, value);
1520 }
1521 
c128_c64io_df00_read(uint16_t addr)1522 uint8_t c128_c64io_df00_read(uint16_t addr)
1523 {
1524     uint8_t temp_value;
1525 
1526     temp_value = c64io_df00_read(addr);
1527     vicii_clock_read_stretch();
1528     return temp_value;
1529 }
1530 
c128_c64io_df00_store(uint16_t addr,uint8_t value)1531 void c128_c64io_df00_store(uint16_t addr, uint8_t value)
1532 {
1533     vicii_clock_write_stretch();
1534     c64io_df00_store(addr, value);
1535 }
1536