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