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