~ubuntu-branches/ubuntu/utopic/vice/utopic

« back to all changes in this revision

Viewing changes to src/scpu64/scpu64mem.c

  • Committer: Package Import Robot
  • Author(s): Logan Rosen
  • Date: 2014-05-10 21:08:23 UTC
  • mfrom: (17.2.1 utopic-proposed)
  • Revision ID: package-import@ubuntu.com-20140510210823-r7x98jmpl1x7rgop
Tags: 2.4.dfsg+2.4.6-1ubuntu1
Use autotools-dev to update config.{sub,guess} for new arches.

Show diffs side-by-side

added added

removed removed

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