1 /*
2 * cbm5x0mem.c - CBM-5x0 memory handling.
3 *
4 * Written by
5 * Andre Fachat <fachat@physik.tu-chemnitz.de>
6 *
7 * This file is part of VICE, the Versatile Commodore Emulator.
8 * See README for copyright notice.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23 * 02111-1307 USA.
24 *
25 */
26
27 #include "vice.h"
28
29 #include <stdio.h>
30 #include <string.h>
31
32 #include "archdep.h"
33 #include "cartio.h"
34 #include "cartridge.h"
35 #include "cbm2-resources.h"
36 #include "cbm2.h"
37 #include "cbm2acia.h"
38 #include "cbm2cart.h"
39 #include "cbm2cia.h"
40 #include "cbm2mem.h"
41 #include "cbm2model.h"
42 #include "cbm2tpi.h"
43 #include "cia.h"
44 #include "kbdbuf.h"
45 #include "machine.h"
46 #include "mem.h"
47 #include "maincpu.h"
48 #include "monitor.h"
49 #include "ram.h"
50 #include "resources.h"
51 #include "sid.h"
52 #include "sid-resources.h"
53 #include "tpi.h"
54 #include "types.h"
55 #include "vsync.h"
56 #include "vicii-mem.h"
57 #include "vicii-phi1.h"
58 #include "vicii.h"
59
cia1_set_extended_keyboard_rows_mask(uint8_t foo)60 void cia1_set_extended_keyboard_rows_mask(uint8_t foo)
61 {
62 }
63
64 /* ------------------------------------------------------------------------- */
65 /* The CBM-II memory. */
66
67 uint8_t mem_ram[CBM2_RAM_SIZE]; /* 1M, banks 0-14 plus extension RAM
68 in bank 15 */
69 uint8_t mem_rom[CBM2_ROM_SIZE]; /* complete bank 15 ROM + video RAM */
70 uint8_t mem_chargen_rom[CBM2_CHARGEN_ROM_SIZE];
71
72 /* Internal color memory. */
73 static uint8_t mem_color_ram[0x400];
74 uint8_t *mem_color_ram_cpu, *mem_color_ram_vicii;
75
76 /* Pointer to the chargen ROM. */
77 uint8_t *mem_chargen_rom_ptr;
78
79 uint8_t *mem_page_zero;
80 uint8_t *mem_page_one;
81
82 /* selected banks for normal access and indirect accesses */
83 int cbm2mem_bank_exec = -1;
84 int cbm2mem_bank_ind = -1;
85
86 /* Memory read and write tables - banked. */
87 static read_func_ptr_t _mem_read_tab[16][0x101];
88 static store_func_ptr_t _mem_write_tab[16][0x101];
89 static uint8_t *_mem_read_base_tab[16][0x101];
90 static int mem_read_limit_tab[3][0x101];
91
92 /* watch tables are fixed */
93 static read_func_ptr_t _mem_read_tab_watch[0x101];
94 static read_func_ptr_t _mem_read_ind_tab_watch[0x101];
95 static store_func_ptr_t _mem_write_tab_watch[0x101];
96 static store_func_ptr_t _mem_write_ind_tab_watch[0x101];
97
98 read_func_ptr_t *_mem_read_tab_ptr;
99 read_func_ptr_t *_mem_read_ind_tab_ptr;
100 store_func_ptr_t *_mem_write_tab_ptr;
101 store_func_ptr_t *_mem_write_ind_tab_ptr;
102 static uint8_t **_mem_read_base_tab_ptr;
103 static int *mem_read_limit_tab_ptr;
104
105 int cbm2_init_ok = 0;
106
107 /* ------------------------------------------------------------------------- */
108
109 /* state of tpi pc6/7 */
110 static int c500_vbank = 0;
111
112 /* 1= static video matrix RAM (phi2); 0= bank 0 */
113 static int c500_statvid = 1;
114
115 /* 1= character ROM in bank 15 (phi1); 0= bank 0 */
116 static int c500_vicdotsel = 1;
117
c500_set_phi2_bank(int b)118 void c500_set_phi2_bank(int b)
119 {
120 if (b == c500_statvid) {
121 return;
122 }
123
124 if (b) { /* bank 15 */
125 /* video memory at $c000/d000 depending on d818 */
126 vicii_set_phi2_addr_options(0x13ff, 0xc000);
127 /* no chargen mapping */
128 vicii_set_phi2_chargen_addr_options(0, 1);
129 /* memory mapping */
130 vicii_set_phi2_vbank(3); /* necessary? */
131 vicii_set_phi2_ram_base(mem_rom);
132 } else {
133 /* video memory in bank 0 */
134 vicii_set_phi2_addr_options(0xffff, 0x0000);
135 /* no chargen mapping */
136 vicii_set_phi2_chargen_addr_options(0, 1);
137 /* memory mapping */
138 vicii_set_phi2_vbank(c500_vbank);
139 vicii_set_phi2_ram_base(mem_ram);
140 }
141
142 c500_statvid = b;
143 }
144
c500_set_phi1_bank(int b)145 void c500_set_phi1_bank(int b)
146 {
147 if (b == c500_vicdotsel) {
148 return;
149 }
150
151 if (b) { /* bank 15 */
152 /* video memory at $c000/c800 depending on d818 */
153 vicii_set_phi1_addr_options(0x0fff, 0xc000);
154 /* no chargen mapping */
155 vicii_set_phi1_chargen_addr_options(0xc000, 0xc000);
156 /* memory mapping */
157 vicii_set_phi1_vbank(3); /* necessary? */
158 vicii_set_phi1_ram_base(mem_rom);
159 } else {
160 /* video memory in bank 0 */
161 vicii_set_phi1_addr_options(0xffff, 0x0000);
162 /* no chargen mapping */
163 vicii_set_phi1_chargen_addr_options(0, 1);
164 /* memory mapping */
165 vicii_set_phi1_vbank(c500_vbank);
166 vicii_set_phi1_ram_base(mem_ram);
167 }
168
169 c500_vicdotsel = b;
170 }
171
cbm2_set_tpi2pc(uint8_t b)172 void cbm2_set_tpi2pc(uint8_t b)
173 {
174 int vbank = (b & 0xc0) >> 6;
175 c500_vbank = vbank;
176
177 if (!c500_vicdotsel) {
178 vicii_set_phi1_vbank(vbank);
179 }
180 if (!c500_statvid) {
181 vicii_set_phi2_vbank(vbank);
182 }
183 }
184
cbm2_set_tpi1ca(int a)185 void cbm2_set_tpi1ca(int a)
186 {
187 c500_set_phi2_bank(a);
188 }
189
cbm2_set_tpi1cb(int a)190 void cbm2_set_tpi1cb(int a)
191 {
192 c500_set_phi1_bank(a);
193 }
194
195 /* ------------------------------------------------------------------------- */
196
cbm2mem_set_bank_exec(int val)197 void cbm2mem_set_bank_exec(int val)
198 {
199 int i;
200
201 val &= 0x0f;
202
203 if (val != cbm2mem_bank_exec) {
204 cbm2mem_bank_exec = val;
205
206 _mem_read_tab_ptr = _mem_read_tab[cbm2mem_bank_exec];
207 _mem_write_tab_ptr = _mem_write_tab[cbm2mem_bank_exec];
208 _mem_read_base_tab_ptr = _mem_read_base_tab[cbm2mem_bank_exec];
209 mem_read_limit_tab_ptr = mem_read_limit_tab[(cbm2mem_bank_exec < 15)
210 ? 0 : 1];
211 if (!_mem_read_base_tab_ptr[0]) {
212 /* disable fast opcode fetch when bank_base is null, i.e.
213 set all limits to 0 when no RAM available.
214 This might also happen when jumping to open mem in
215 bank 15, though. */
216 mem_read_limit_tab_ptr = mem_read_limit_tab[2];
217 }
218
219 maincpu_resync_limits();
220
221 /* set all register mirror locations */
222 for (i = 0; i < 16; i++) {
223 mem_ram[i << 16] = val;
224 }
225
226 mem_page_zero = _mem_read_base_tab_ptr[0];
227 mem_page_one = _mem_read_base_tab_ptr[1];
228
229 /* This sets the pointers to otherwise non-mapped memory, to
230 avoid that the CPU code uses illegal memory and segfaults. */
231 if (!mem_page_zero) {
232 mem_page_zero = mem_ram + 0xf0000;
233 }
234 if (!mem_page_one) {
235 mem_page_one = mem_ram + 0xf0100;
236 }
237 }
238 }
239
cbm2mem_set_bank_ind(int val)240 void cbm2mem_set_bank_ind(int val)
241 {
242 int i;
243 val &= 0x0f;
244
245 if (val != cbm2mem_bank_ind) {
246 cbm2mem_bank_ind = val;
247 _mem_read_ind_tab_ptr = _mem_read_tab[cbm2mem_bank_ind];
248 _mem_write_ind_tab_ptr = _mem_write_tab[cbm2mem_bank_ind];
249 /* set all register mirror locations */
250 for (i = 0; i < 16; i++) {
251 mem_ram[(i << 16) + 1] = val;
252 }
253 }
254 }
255
256 /* ------------------------------------------------------------------------- */
zero_read(uint16_t addr)257 uint8_t zero_read(uint16_t addr)
258 {
259 addr &= 0xff;
260
261 switch ((uint8_t)addr) {
262 case 0:
263 return cbm2mem_bank_exec;
264 case 1:
265 return cbm2mem_bank_ind;
266 }
267
268 return mem_page_zero[addr & 0xff];
269 }
270
zero_store(uint16_t addr,uint8_t value)271 void zero_store(uint16_t addr, uint8_t value)
272 {
273 if (addr == 0) {
274 cbm2mem_set_bank_exec(value);
275 } else if (addr == 1) {
276 cbm2mem_set_bank_ind(value);
277 }
278
279 _mem_write_tab_ptr[0]((uint16_t)(addr & 0xff), value);
280 }
281
282 #define STORE_ZERO(bank) \
283 static void store_zero_##bank(uint16_t addr, uint8_t value) \
284 { \
285 addr &= 0xff; \
286 \
287 if (addr == 0) { \
288 cbm2mem_set_bank_exec(value); \
289 } else if (addr == 1) { \
290 cbm2mem_set_bank_ind(value); \
291 } else { \
292 mem_ram[(0x##bank << 16) | addr] = value; \
293 } \
294 }
295
296 #define READ_ZERO(bank) \
297 static uint8_t read_zero_##bank(uint16_t addr) \
298 { \
299 return mem_ram[(0x##bank << 16) | (addr & 0xff)]; \
300 }
301
302 #define READ_RAM(bank) \
303 static uint8_t read_ram_##bank(uint16_t addr) \
304 { \
305 return mem_ram[(0x##bank << 16) | addr]; \
306 }
307
308 #define STORE_RAM(bank) \
309 static void store_ram_##bank(uint16_t addr, uint8_t byte) \
310 { \
311 if (addr == 0) { \
312 cbm2mem_set_bank_exec(byte); \
313 } else if (addr == 1) { \
314 cbm2mem_set_bank_ind(byte); \
315 } else { \
316 mem_ram[(0x##bank << 16) | addr] = byte; \
317 } \
318 }
319
320 STORE_ZERO(0)
321 STORE_ZERO(1)
322 STORE_ZERO(2)
323 STORE_ZERO(3)
324 STORE_ZERO(4)
325 STORE_ZERO(5)
326 STORE_ZERO(6)
327 STORE_ZERO(7)
328 STORE_ZERO(8)
329 STORE_ZERO(9)
330 STORE_ZERO(A)
331 STORE_ZERO(B)
332 STORE_ZERO(C)
333 STORE_ZERO(D)
334 STORE_ZERO(E)
335 STORE_ZERO(F)
336
337 READ_ZERO(0)
338 READ_ZERO(1)
339 READ_ZERO(2)
340 READ_ZERO(3)
341 READ_ZERO(4)
342 READ_ZERO(5)
343 READ_ZERO(6)
344 READ_ZERO(7)
345 READ_ZERO(8)
346 READ_ZERO(9)
347 READ_ZERO(A)
348 READ_ZERO(B)
349 READ_ZERO(C)
350 READ_ZERO(D)
351 READ_ZERO(E)
352 READ_ZERO(F)
353
354 STORE_RAM(0)
355 STORE_RAM(1)
356 STORE_RAM(2)
357 STORE_RAM(3)
358 STORE_RAM(4)
359 STORE_RAM(5)
360 STORE_RAM(6)
361 STORE_RAM(7)
362 STORE_RAM(8)
363 STORE_RAM(9)
364 STORE_RAM(A)
365 STORE_RAM(B)
366 STORE_RAM(C)
367 STORE_RAM(D)
368 STORE_RAM(E)
369 STORE_RAM(F)
370
371 READ_RAM(0)
372 READ_RAM(1)
373 READ_RAM(2)
374 READ_RAM(3)
375 READ_RAM(4)
376 READ_RAM(5)
377 READ_RAM(6)
378 READ_RAM(7)
379 READ_RAM(8)
380 READ_RAM(9)
381 READ_RAM(A)
382 READ_RAM(B)
383 READ_RAM(C)
384 READ_RAM(D)
385 READ_RAM(E)
386 READ_RAM(F)
387
388 static store_func_ptr_t store_zero_tab[16] = {
389 store_zero_0, store_zero_1, store_zero_2, store_zero_3,
390 store_zero_4, store_zero_5, store_zero_6, store_zero_7,
391 store_zero_8, store_zero_9, store_zero_A, store_zero_B,
392 store_zero_C, store_zero_D, store_zero_E, store_zero_F
393 };
394
395 static store_func_ptr_t store_ram_tab[16] = {
396 store_ram_0, store_ram_1, store_ram_2, store_ram_3,
397 store_ram_4, store_ram_5, store_ram_6, store_ram_7,
398 store_ram_8, store_ram_9, store_ram_A, store_ram_B,
399 store_ram_C, store_ram_D, store_ram_E, store_ram_F
400 };
401
402 static read_func_ptr_t read_ram_tab[16] = {
403 read_ram_0, read_ram_1, read_ram_2, read_ram_3,
404 read_ram_4, read_ram_5, read_ram_6, read_ram_7,
405 read_ram_8, read_ram_9, read_ram_A, read_ram_B,
406 read_ram_C, read_ram_D, read_ram_E, read_ram_F
407 };
408
409 static read_func_ptr_t read_zero_tab[16] = {
410 read_zero_0, read_zero_1, read_zero_2, read_zero_3,
411 read_zero_4, read_zero_5, read_zero_6, read_zero_7,
412 read_zero_8, read_zero_9, read_zero_A, read_zero_B,
413 read_zero_C, read_zero_D, read_zero_E, read_zero_F
414 };
415
416
store_zeroX(uint16_t addr,uint8_t value)417 static void store_zeroX(uint16_t addr, uint8_t value)
418 {
419 if (addr == 0) {
420 cbm2mem_set_bank_exec(value);
421 } else if (addr == 1) {
422 cbm2mem_set_bank_ind(value);
423 }
424 }
425
rom_read(uint16_t addr)426 uint8_t rom_read(uint16_t addr)
427 {
428 return mem_rom[addr];
429 }
430
read_chargen(uint16_t addr)431 static uint8_t read_chargen(uint16_t addr)
432 {
433 return mem_chargen_rom[addr & 0xfff];
434 }
435
rom_store(uint16_t addr,uint8_t value)436 void rom_store(uint16_t addr, uint8_t value)
437 {
438 mem_rom[addr] = value;
439 }
440
read_unused(uint16_t addr)441 uint8_t read_unused(uint16_t addr)
442 {
443 if (addr == 0) {
444 return cbm2mem_bank_exec;
445 } else if (addr == 1) {
446 return cbm2mem_bank_ind;
447 }
448 return vicii_read_phi1();
449 }
450
store_dummy(uint16_t addr,uint8_t value)451 static void store_dummy(uint16_t addr, uint8_t value)
452 {
453 return;
454 }
455
456 /* ------------------------------------------------------------------------- */
457
458 /* Functions for watchpoint memory access. */
459
zero_read_watch(uint16_t addr)460 static uint8_t zero_read_watch(uint16_t addr)
461 {
462 addr &= 0xff;
463 monitor_watch_push_load_addr(addr, e_comp_space);
464 return _mem_read_tab[cbm2mem_bank_exec][0](addr);
465 }
466
zero_store_watch(uint16_t addr,uint8_t value)467 static void zero_store_watch(uint16_t addr, uint8_t value)
468 {
469 addr &= 0xff;
470 monitor_watch_push_store_addr(addr, e_comp_space);
471 _mem_write_tab[cbm2mem_bank_exec][0](addr, value);
472 }
473
read_watch(uint16_t addr)474 static uint8_t read_watch(uint16_t addr)
475 {
476 monitor_watch_push_load_addr(addr, e_comp_space);
477 return _mem_read_tab[cbm2mem_bank_exec][addr >> 8](addr);
478 }
479
store_watch(uint16_t addr,uint8_t value)480 static void store_watch(uint16_t addr, uint8_t value)
481 {
482 monitor_watch_push_store_addr(addr, e_comp_space);
483 _mem_write_tab[cbm2mem_bank_exec][addr >> 8](addr, value);
484 }
485
read_ind_watch(uint16_t addr)486 static uint8_t read_ind_watch(uint16_t addr)
487 {
488 monitor_watch_push_load_addr(addr, e_comp_space);
489 return _mem_read_tab[cbm2mem_bank_ind][addr >> 8](addr);
490 }
491
store_ind_watch(uint16_t addr,uint8_t value)492 static void store_ind_watch(uint16_t addr, uint8_t value)
493 {
494 monitor_watch_push_store_addr(addr, e_comp_space);
495 _mem_write_tab[cbm2mem_bank_ind][addr >> 8](addr, value);
496 }
497
498 /* ------------------------------------------------------------------------- */
499
500 /* Generic memory access. */
501
mem_store(uint16_t addr,uint8_t value)502 void mem_store(uint16_t addr, uint8_t value)
503 {
504 _mem_write_tab_ptr[addr >> 8](addr, value);
505 }
506
mem_read(uint16_t addr)507 uint8_t mem_read(uint16_t addr)
508 {
509 return _mem_read_tab_ptr[addr >> 8](addr);
510 }
511
512 /* ------------------------------------------------------------------------- */
513
store_io(uint16_t addr,uint8_t value)514 static void store_io(uint16_t addr, uint8_t value)
515 {
516 switch (addr & 0xf800) {
517 case 0xd000:
518 rom_store(addr, value); /* video RAM mapped here... */
519 if (addr >= 0xd400) {
520 colorram_store(addr, value);
521 }
522 return;
523 case 0xd800:
524 switch (addr & 0xff00) {
525 case 0xd800:
526 cbm2io_d800_store(addr, value);
527 return;
528 case 0xd900:
529 cbm2io_d900_store(addr, value);
530 return;
531 case 0xda00:
532 cbm2io_da00_store(addr, value);
533 return;
534 case 0xdb00:
535 cbm2io_db00_store(addr, value);
536 return;
537 case 0xdc00:
538 cbm2io_dc00_store(addr, value);
539 return;
540 case 0xdd00:
541 cbm2io_dd00_store(addr, value);
542 return;
543 case 0xde00:
544 cbm2io_de00_store(addr, value);
545 return;
546 case 0xdf00:
547 cbm2io_df00_store(addr, value);
548 return;
549 }
550 }
551 }
552
read_io(uint16_t addr)553 static uint8_t read_io(uint16_t addr)
554 {
555 switch (addr & 0xf800) {
556 case 0xd000:
557 return rom_read(addr);
558 case 0xd800:
559 switch (addr & 0xff00) {
560 case 0xd800:
561 return cbm2io_d800_read(addr);
562 case 0xd900:
563 return cbm2io_d900_read(addr);
564 case 0xda00:
565 return cbm2io_da00_read(addr);
566 case 0xdb00:
567 return cbm2io_db00_read(addr);
568 case 0xdc00:
569 return cbm2io_dc00_read(addr);
570 case 0xdd00:
571 return cbm2io_dd00_read(addr);
572 case 0xde00:
573 return cbm2io_de00_read(addr);
574 case 0xdf00:
575 return cbm2io_df00_read(addr);
576 }
577 }
578 return read_unused(addr);
579 }
580
581
582 /* FIXME: TODO! */
mem_toggle_watchpoints(int flag,void * context)583 void mem_toggle_watchpoints(int flag, void *context)
584 {
585 if (flag) {
586 _mem_read_tab_ptr = _mem_read_tab_watch;
587 _mem_read_ind_tab_ptr = _mem_read_ind_tab_watch;
588 _mem_write_tab_ptr = _mem_write_tab_watch;
589 _mem_write_ind_tab_ptr = _mem_write_ind_tab_watch;
590 } else {
591 cbm2mem_set_bank_exec(cbm2mem_bank_exec);
592 cbm2mem_set_bank_ind(cbm2mem_bank_ind);
593 }
594 }
595
596 /* ------------------------------------------------------------------------- */
597 /* handle CPU reset */
598
mem_reset(void)599 void mem_reset(void)
600 {
601 cbm2mem_set_bank_exec(15);
602 cbm2mem_set_bank_ind(15);
603
604 c500_set_phi1_bank(15);
605 c500_set_phi2_bank(15);
606 }
607
608 /* ------------------------------------------------------------------------- */
609
colorram_store(uint16_t addr,uint8_t value)610 void colorram_store(uint16_t addr, uint8_t value)
611 {
612 mem_color_ram[addr & 0x3ff] = value & 0xf;
613 }
614
colorram_read(uint16_t addr)615 uint8_t colorram_read(uint16_t addr)
616 {
617 return mem_color_ram[addr & 0x3ff] | (vicii_read_phi1() & 0xf0);
618 }
619
620 /* ------------------------------------------------------------------------- */
621
mem_initialize_memory(void)622 void mem_initialize_memory(void)
623 {
624 int i;
625
626 mem_chargen_rom_ptr = mem_chargen_rom;
627 mem_color_ram_cpu = mem_color_ram;
628 mem_color_ram_vicii = mem_color_ram;
629
630 /* first the tables that hold the predefined bank mappings */
631 for (i = 0; i < 16; i++) { /* 16 banks possible */
632 mem_initialize_memory_bank(i);
633 }
634
635 /* set bank limit tables for optimized opcode fetch */
636 for (i = 256; i >= 0; i--) {
637 mem_read_limit_tab[0][i] = 0xfffd; /* all RAM banks go here */
638 mem_read_limit_tab[2][i] = 0; /* all empty banks go here */
639
640 if (!_mem_read_base_tab[15][i]) {
641 mem_read_limit_tab[1][i] = 0;
642 } else
643 if (i < 0x08) { /* system RAM */
644 mem_read_limit_tab[1][i] = 0x07fd;
645 } else
646 if (i < 0x10) { /* ROM/RAM 0800-0FFF */
647 mem_read_limit_tab[1][i] = 0x0ffd;
648 } else
649 if (i < 0x20) { /* ROM/RAM 1000-1FFF */
650 mem_read_limit_tab[1][i] = 0x1ffd;
651 } else
652 if (i < 0x40) { /* ROM/RAM 2000-3FFF */
653 mem_read_limit_tab[1][i] = 0x3ffd;
654 } else
655 if (i < 0x60) { /* ROM/RAM 4000-5FFF */
656 mem_read_limit_tab[1][i] = 0x5ffd;
657 } else
658 if (i < 0x80) { /* ROM/RAM 6000-7FFF */
659 mem_read_limit_tab[1][i] = 0x7ffd;
660 } else
661 if (i < 0xc0) { /* ROM 8000-BFFF */
662 mem_read_limit_tab[1][i] = 0xbffd;
663 } else
664 if (i < 0xd0) { /* C000-CFFF */
665 mem_read_limit_tab[1][i] = 0xcffd;
666 } else
667 if (i < 0xe0) { /* I/O D000-DFFF */
668 mem_read_limit_tab[1][i] = 0;
669 } else { /* ROM E000-FFFF */
670 mem_read_limit_tab[1][i] = 0xfffd;
671 }
672 }
673
674 /* set watchpoint tables */
675 for (i = 0; i <= 0x100; i++) {
676 _mem_read_tab_watch[i] = read_watch;
677 _mem_read_ind_tab_watch[i] = read_ind_watch;
678 _mem_write_tab_watch[i] = store_watch;
679 _mem_write_ind_tab_watch[i] = store_ind_watch;
680 }
681 /* FIXME: what about _ind_tab_watch ? */
682 _mem_read_tab_watch[0] = zero_read_watch;
683 _mem_write_tab_watch[0] = zero_store_watch;
684
685 vicii_set_chargen_addr_options(0x7000, 0x1000);
686 }
687
mem_initialize_memory_bank(int i)688 void mem_initialize_memory_bank(int i)
689 {
690 int j;
691
692 switch (i) {
693 case 0:
694 for (j = 255; j >= 0; j--) {
695 _mem_read_tab[i][j] = read_ram_tab[i];
696 _mem_write_tab[i][j] = store_ram_tab[i];
697 _mem_read_base_tab[i][j] = mem_ram + (i << 16) + (j << 8);
698 }
699 _mem_write_tab[i][0] = store_zero_tab[i];
700 _mem_read_tab[i][0] = read_zero_tab[i];
701 break;
702 case 1:
703 for (j = 255; j >= 0; j--) {
704 _mem_read_tab[i][j] = read_ram_tab[i];
705 _mem_write_tab[i][j] = store_ram_tab[i];
706 _mem_read_base_tab[i][j] = mem_ram + (i << 16) + (j << 8);
707 }
708 _mem_write_tab[i][0] = store_zero_tab[i];
709 _mem_read_tab[i][0] = read_zero_tab[i];
710 break;
711 case 2:
712 if (ramsize >= 128) {
713 for (j = 255; j >= 0; j--) {
714 _mem_read_tab[i][j] = read_ram_tab[i];
715 _mem_write_tab[i][j] = store_ram_tab[i];
716 _mem_read_base_tab[i][j] = mem_ram + (i << 16) + (j << 8);
717 }
718 _mem_write_tab[i][0] = store_zero_tab[i];
719 _mem_read_tab[i][0] = read_zero_tab[i];
720 break;
721 }
722 /* If this failed, we'll be handled by the failure case in case 14 */
723 /* FALL THROUGH */
724 case 3:
725 case 4:
726 if (ramsize >= 256) {
727 for (j = 255; j >= 0; j--) {
728 _mem_read_tab[i][j] = read_ram_tab[i];
729 _mem_write_tab[i][j] = store_ram_tab[i];
730 _mem_read_base_tab[i][j] = mem_ram + (i << 16) + (j << 8);
731 }
732 _mem_write_tab[i][0] = store_zero_tab[i];
733 _mem_read_tab[i][0] = read_zero_tab[i];
734 break;
735 }
736 /* If this failed, we'll be handled by the failure case in case 14 */
737 /* FALL THROUGH */
738 case 5:
739 case 6:
740 case 7:
741 if (ramsize >= 512) {
742 for (j = 255; j >= 0; j--) {
743 _mem_read_tab[i][j] = read_ram_tab[i];
744 _mem_write_tab[i][j] = store_ram_tab[i];
745 _mem_read_base_tab[i][j] = mem_ram + (i << 16) + (j << 8);
746 }
747 _mem_write_tab[i][0] = store_zero_tab[i];
748 _mem_read_tab[i][0] = read_zero_tab[i];
749 break;
750 }
751 /* If this failed, we'll be handled by the failure case in case 14 */
752 /* FALL THROUGH */
753 case 8:
754 case 9:
755 case 10:
756 case 11:
757 case 12:
758 case 13:
759 case 14:
760 if (ramsize >= 1024) {
761 for (j = 255; j >= 0; j--) {
762 _mem_read_tab[i][j] = read_ram_tab[i];
763 _mem_write_tab[i][j] = store_ram_tab[i];
764 _mem_read_base_tab[i][j] = mem_ram + (i << 16) + (j << 8);
765 }
766 _mem_write_tab[i][0] = store_zero_tab[i];
767 _mem_read_tab[i][0] = read_zero_tab[i];
768 break;
769 }
770 /* fallback for ramsize < some_value */
771 for (j = 255; j >= 0; j--) {
772 _mem_read_tab[i][j] = read_unused;
773 _mem_write_tab[i][j] = store_dummy;
774 _mem_read_base_tab[i][j] = NULL;
775 }
776 _mem_write_tab[i][0] = store_zeroX;
777 break;
778 case 15:
779 for (j = 0; j < 0x08; j++) {
780 _mem_read_tab[i][j] = read_ram_F;
781 _mem_write_tab[i][j] = store_ram_F;
782 _mem_read_base_tab[i][j] = mem_ram + (i << 16) + (j << 8);
783 }
784 for (; j < 0xc0; j++) { /* 0800-BFFF */
785 _mem_read_tab[i][j] = rom_read;
786 _mem_write_tab[i][j] = store_dummy;
787 _mem_read_base_tab[i][j] = mem_rom + (j << 8);
788 }
789 for (; j < 0xd0; j++) { /* C000-CFFF */
790 _mem_read_tab[i][j] = read_chargen;
791 _mem_write_tab[i][j] = store_dummy;
792 _mem_read_base_tab[i][j] = mem_chargen_rom + ((j << 8) & 0x0f);
793 }
794 for (; j < 0xe0; j++) { /* D000-DFFF */
795 _mem_read_tab[i][j] = read_io;
796 _mem_write_tab[i][j] = store_io;
797 _mem_read_base_tab[i][j] = NULL;
798 }
799 for (; j < 0x100; j++) {
800 _mem_read_tab[i][j] = rom_read;
801 _mem_write_tab[i][j] = store_dummy;
802 _mem_read_base_tab[i][j] = mem_rom + (j << 8);
803 }
804
805 if (cart08_ram) {
806 for (j = 0x08; j < 0x10; j++) {
807 _mem_read_tab[i][j] = read_ram_F;
808 _mem_write_tab[i][j] = store_ram_F;
809 _mem_read_base_tab[i][j] = mem_ram + (i << 16) + (j << 8);
810 }
811 }
812 if (cart1_ram) {
813 for (j = 0x10; j < 0x20; j++) {
814 _mem_read_tab[i][j] = read_ram_F;
815 _mem_write_tab[i][j] = store_ram_F;
816 _mem_read_base_tab[i][j] = mem_ram + (i << 16) + (j << 8);
817 }
818 }
819 if (cart2_ram) {
820 for (j = 0x20; j < 0x40; j++) {
821 _mem_read_tab[i][j] = read_ram_F;
822 _mem_write_tab[i][j] = store_ram_F;
823 _mem_read_base_tab[i][j] = mem_ram + (i << 16) + (j << 8);
824 }
825 }
826 if (cart4_ram) {
827 for (j = 0x40; j < 0x60; j++) {
828 _mem_read_tab[i][j] = read_ram_F;
829 _mem_write_tab[i][j] = store_ram_F;
830 _mem_read_base_tab[i][j] = mem_ram + (i << 16) + (j << 8);
831 }
832 }
833 if (cart6_ram) {
834 for (j = 0x60; j < 0x80; j++) {
835 _mem_read_tab[i][j] = read_ram_F;
836 _mem_write_tab[i][j] = store_ram_F;
837 _mem_read_base_tab[i][j] = mem_ram + (i << 16) + (j << 8);
838 }
839 }
840 if (cartC_ram) {
841 for (j = 0xc0; j < 0xd0; j++) {
842 _mem_read_tab[i][j] = read_ram_F;
843 _mem_write_tab[i][j] = store_ram_F;
844 _mem_read_base_tab[i][j] = mem_ram + (i << 16) + (j << 8);
845 }
846 }
847
848 _mem_write_tab[i][0] = store_zero_F;
849 _mem_read_tab[i][0] = read_zero_F;
850 _mem_read_base_tab[i][0] = mem_ram + 0xf0000;
851 break;
852 }
853 _mem_read_tab[i][0x100] = _mem_read_tab[i][0];
854 _mem_write_tab[i][0x100] = _mem_write_tab[i][0];
855 _mem_read_base_tab[i][0x100] = _mem_read_base_tab[i][0];
856 }
857
mem_mmu_translate(unsigned int addr,uint8_t ** base,int * start,int * limit)858 void mem_mmu_translate(unsigned int addr, uint8_t **base, int *start, int *limit)
859 {
860 uint8_t *p = _mem_read_base_tab_ptr[addr >> 8];
861
862 *base = (p == NULL) ? NULL : (p - (addr & 0xff00));
863 *start = addr; /* TODO */
864 *limit = mem_read_limit_tab_ptr[addr >> 8];
865 }
866
mem_powerup(void)867 void mem_powerup(void)
868 {
869 int i;
870
871 ram_init(mem_ram, CBM2_RAM_SIZE);
872
873 for (i = 0; i < 0x800; i += 0x80) {
874 memset(mem_rom + i, 0, 0x40);
875 memset(mem_rom + i + 0x40, 0xff, 0x40);
876 memset(mem_rom + 0x800 + i, 0, 0x40);
877 memset(mem_rom + 0x800 + i + 0x40, 0xff, 0x40);
878 memset(mem_rom + 0xd000 + i, 0, 0x40);
879 memset(mem_rom + 0xd000 + i + 0x40, 0xff, 0x40);
880 }
881
882 cbm2mem_bank_exec = 0;
883 cbm2mem_bank_ind = 0;
884 cbm2mem_set_bank_exec(15);
885 cbm2mem_set_bank_ind(15);
886 }
887
888 /* ------------------------------------------------------------------------- */
889
890 /* FIXME: To do! */
891
mem_get_basic_text(uint16_t * start,uint16_t * end)892 void mem_get_basic_text(uint16_t *start, uint16_t *end)
893 {
894 }
895
mem_set_basic_text(uint16_t start,uint16_t end)896 void mem_set_basic_text(uint16_t start, uint16_t end)
897 {
898 }
899
mem_inject(uint32_t addr,uint8_t value)900 void mem_inject(uint32_t addr, uint8_t value)
901 {
902 /* just call mem_store() to be safe.
903 This could possibly be changed to write straight into the
904 memory array. mem_ram[addr & mask] = value; */
905 mem_store((uint16_t)(addr & 0xffff), value);
906 }
907
908 /* ------------------------------------------------------------------------- */
909
mem_rom_trap_allowed(uint16_t addr)910 int mem_rom_trap_allowed(uint16_t addr)
911 {
912 return 1; /* (addr >= 0xf000) && !(map_reg & 0x80); */
913 }
914
mem_set_tape_sense(int value)915 void mem_set_tape_sense(int value)
916 {
917 }
918
919 /* ------------------------------------------------------------------------- */
920
921 /* Banked memory access functions for the monitor. */
922
peek_bank_io(uint16_t addr)923 static uint8_t peek_bank_io(uint16_t addr)
924 {
925 switch (addr & 0xf800) {
926 case 0xc000:
927 case 0xc800:
928 return read_unused(addr);
929 case 0xd000:
930 return rom_read(addr);
931 case 0xd800:
932 switch (addr & 0xff00) {
933 case 0xd800:
934 return cbm2io_d800_peek(addr);
935 case 0xd900:
936 return cbm2io_d900_peek(addr);
937 case 0xda00:
938 return cbm2io_da00_peek(addr);
939 case 0xdb00:
940 return cbm2io_db00_peek(addr);
941 case 0xdc00:
942 return cbm2io_dc00_peek(addr);
943 case 0xdd00:
944 return cbm2io_dd00_peek(addr);
945 case 0xde00:
946 return cbm2io_de00_peek(addr);
947 case 0xdf00:
948 return cbm2io_df00_peek(addr);
949 }
950 }
951 return read_unused(addr);
952 }
953
954 /* Exported banked memory access functions for the monitor. */
955
956 static const char *banknames[] = {
957 "default", "cpu", "ram0", "ram1", "ram2", "ram3",
958 "ram4", "ram5", "ram6", "ram7", "ram8", "ram9",
959 "ramA", "ramB", "ramC", "ramD", "ramE", "ramF",
960 "romio", "io", NULL
961 };
962
963 static const int banknums[] = {
964 17, 17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16
965 };
966
mem_bank_list(void)967 const char **mem_bank_list(void)
968 {
969 return banknames;
970 }
971
mem_bank_from_name(const char * name)972 int mem_bank_from_name(const char *name)
973 {
974 int i = 0;
975
976 while (banknames[i]) {
977 if (!strcmp(name, banknames[i])) {
978 return banknums[i];
979 }
980 i++;
981 }
982 return -1;
983 }
984
mem_bank_read(int bank,uint16_t addr,void * context)985 uint8_t mem_bank_read(int bank, uint16_t addr, void *context)
986 {
987 switch (bank) {
988 case 17: /* current */
989 return mem_read(addr);
990 case 16: /* romio */
991 if (addr >= 0xd000 && addr < 0xe000) {
992 return read_io(addr);
993 }
994 return _mem_read_tab[15][addr >> 8](addr);
995 default:
996 if (bank >= 0 && bank < 15) {
997 return read_ram_tab[bank](addr);
998 }
999 }
1000 return read_unused(addr);
1001 }
1002
mem_bank_peek(int bank,uint16_t addr,void * context)1003 uint8_t mem_bank_peek(int bank, uint16_t addr, void *context)
1004 {
1005 if (bank == 16) {
1006 if (addr >= 0xc000 && addr < 0xe000) {
1007 return peek_bank_io(addr);
1008 }
1009 }
1010 return mem_bank_read(bank, addr, context);
1011 }
1012
mem_bank_write(int bank,uint16_t addr,uint8_t byte,void * context)1013 void mem_bank_write(int bank, uint16_t addr, uint8_t byte, void *context)
1014 {
1015 switch (bank) {
1016 case 17: /* current */
1017 mem_store(addr, byte);
1018 return;
1019 case 16:
1020 if (addr >= 0xd000 && addr <= 0xdfff) {
1021 store_io(addr, byte);
1022 return;
1023 }
1024 _mem_write_tab[15][addr >> 8](addr, byte);
1025 return;
1026 default:
1027 if (bank >= 0 && bank < 16) {
1028 if (addr & 0xff00) {
1029 store_ram_tab[bank](addr, byte);
1030 } else {
1031 store_zero_tab[bank](addr, byte);
1032 }
1033 return;
1034 }
1035 }
1036 store_dummy(addr, byte);
1037 }
1038
mem_ioreg_list_get(void * context)1039 mem_ioreg_list_t *mem_ioreg_list_get(void *context)
1040 {
1041 mem_ioreg_list_t *mem_ioreg_list = NULL;
1042
1043 io_source_ioreg_add_list(&mem_ioreg_list);
1044
1045 return mem_ioreg_list;
1046 }
1047
mem_get_screen_parameter(uint16_t * base,uint8_t * rows,uint8_t * columns,int * bank)1048 void mem_get_screen_parameter(uint16_t *base, uint8_t *rows, uint8_t *columns, int *bank)
1049 {
1050 *base = 0xd000;
1051 *rows = 25;
1052 *columns = 40;
1053 *bank = 16;
1054 }
1055
mem_color_ram_to_snapshot(uint8_t * color_ram)1056 void mem_color_ram_to_snapshot(uint8_t *color_ram)
1057 {
1058 memcpy(color_ram, mem_color_ram, 0x400);
1059 }
1060
mem_color_ram_from_snapshot(uint8_t * color_ram)1061 void mem_color_ram_from_snapshot(uint8_t *color_ram)
1062 {
1063 memcpy(mem_color_ram, color_ram, 0x400);
1064 }
1065
mem_handle_pending_alarms_external(int cycles)1066 void mem_handle_pending_alarms_external(int cycles)
1067 {
1068 vicii_handle_pending_alarms_external(cycles);
1069 }
1070
mem_handle_pending_alarms_external_write(void)1071 void mem_handle_pending_alarms_external_write(void)
1072 {
1073 vicii_handle_pending_alarms_external_write();
1074 }
1075
1076 /* ------------------------------------------------------------------------- */
1077
cia1_dump(void)1078 static int cia1_dump(void)
1079 {
1080 return ciacore_dump(machine_context.cia1);
1081 }
1082
tpi1_dump(void)1083 static int tpi1_dump(void)
1084 {
1085 return tpicore_dump(machine_context.tpi1);
1086 }
1087
tpi2_dump(void)1088 static int tpi2_dump(void)
1089 {
1090 return tpicore_dump(machine_context.tpi2);
1091 }
1092
1093 /* ------------------------------------------------------------------------- */
1094
1095 static io_source_t vicii_device = {
1096 "VICII",
1097 IO_DETACH_CART, /* dummy */
1098 NULL, /* dummy */
1099 0xd800, 0xd8ff, 0x3f,
1100 1, /* read is always valid */
1101 vicii_store,
1102 vicii_read,
1103 vicii_peek,
1104 vicii_dump,
1105 0, /* dummy (not a cartridge) */
1106 IO_PRIO_HIGH, /* priority, device and mirrors never involved in collisions */
1107 0
1108 };
1109
1110 static io_source_t sid_device = {
1111 "SID",
1112 IO_DETACH_CART, /* dummy */
1113 NULL, /* dummy */
1114 0xda00, 0xdaff, 0x1f,
1115 1, /* read is always valid */
1116 sid_store,
1117 sid_read,
1118 sid_peek,
1119 sid_dump,
1120 0, /* dummy (not a cartridge) */
1121 IO_PRIO_HIGH, /* priority, device and mirrors never involved in collisions */
1122 0
1123 };
1124
1125 static io_source_t cia_device = {
1126 "CIA",
1127 IO_DETACH_CART, /* dummy */
1128 NULL, /* dummy */
1129 0xdc00, 0xdcff, 0xf,
1130 1, /* read is always valid */
1131 cia1_store,
1132 cia1_read,
1133 cia1_peek,
1134 cia1_dump,
1135 0, /* dummy (not a cartridge) */
1136 IO_PRIO_HIGH, /* priority, device and mirrors never involved in collisions */
1137 0
1138 };
1139
1140 static io_source_t acia_device = {
1141 "ACIA",
1142 IO_DETACH_CART, /* dummy */
1143 NULL, /* dummy */
1144 0xdd00, 0xddff, 3,
1145 1, /* read is always valid */
1146 acia1_store,
1147 acia1_read,
1148 acia1_peek,
1149 NULL, /* TODO: dump */
1150 0, /* dummy (not a cartridge) */
1151 IO_PRIO_HIGH, /* priority, device and mirrors never involved in collisions */
1152 0
1153 };
1154
1155 static io_source_t tpi1_device = {
1156 "TPI1",
1157 IO_DETACH_CART, /* dummy */
1158 NULL, /* dummy */
1159 0xde00, 0xdeff, 7,
1160 1, /* read is always valid */
1161 tpi1_store,
1162 tpi1_read,
1163 tpi1_peek,
1164 tpi1_dump,
1165 0, /* dummy (not a cartridge) */
1166 IO_PRIO_HIGH, /* priority, device and mirrors never involved in collisions */
1167 0
1168 };
1169
1170 static io_source_t tpi2_device = {
1171 "TPI2",
1172 IO_DETACH_CART, /* dummy */
1173 NULL, /* dummy */
1174 0xdf00, 0xdfff, 7,
1175 1, /* read is always valid */
1176 tpi2_store,
1177 tpi2_read,
1178 tpi2_peek,
1179 tpi2_dump,
1180 0, /* dummy (not a cartridge) */
1181 IO_PRIO_HIGH, /* priority, device and mirrors never involved in collisions */
1182 0
1183 };
1184
1185 static io_source_list_t *vicii_list_item = NULL;
1186 static io_source_list_t *sid_list_item = NULL;
1187 static io_source_list_t *cia_list_item = NULL;
1188 static io_source_list_t *acia_list_item = NULL;
1189 static io_source_list_t *tpi1_list_item = NULL;
1190 static io_source_list_t *tpi2_list_item = NULL;
1191
1192 /* CBM5x0-specific I/O initialization. */
cbm5x0io_init(void)1193 void cbm5x0io_init(void)
1194 {
1195 vicii_list_item = io_source_register(&vicii_device);
1196 sid_list_item = io_source_register(&sid_device);
1197 cia_list_item = io_source_register(&cia_device);
1198 acia_list_item = io_source_register(&acia_device);
1199 tpi1_list_item = io_source_register(&tpi1_device);
1200 tpi2_list_item = io_source_register(&tpi2_device);
1201 }
1202