1 /*
2  *  KCemu -- The emulator for the KC85 homecomputer series and much more.
3  *  Copyright (C) 1997-2010 Torsten Paul
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License along
16  *  with this program; if not, write to the Free Software Foundation, Inc.,
17  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #include <stdlib.h>
21 #include <fstream>
22 
23 #include "kc/system.h"
24 #include "kc/prefs/types.h"
25 
26 #include "kc/kc.h"
27 #include "kc/z80.h"
28 #include "kc/memory2.h"
29 
30 #include "ui/ui.h"
31 
32 using namespace std;
33 
Memory2(void)34 Memory2::Memory2(void) : Memory()
35 {
36   _access_color = false;
37 
38   load_rom(SystemROM::ROM_KEY_CAOSE, &_rom_caos);
39 
40   memory_group_t mem[] = {
41     { &_m_scr,   "-",     0x0000, 0x10000, 0,            256, 0, 1, -1 },
42     { &_m_ram,   "RAM 0", 0x0000,  0x4000, &_ram[0],       0, 0, 1, -1 },
43     { &_m_irm,   "IRM",   0x8000,  0x4000, &_irm[0],       1, 0, 1, -1 },
44     { &_m_caos,  "CAOS",  0xe000,  0x2000, &_rom_caos[0],  2, 1, 1, -1 },
45     { 0, },
46   };
47   init_memory_groups(mem);
48 
49   reset(true);
50   z80->register_ic(this);
51 }
52 
~Memory2(void)53 Memory2::~Memory2(void)
54 {
55   z80->unregister_ic(this);
56 }
57 
58 byte_t
memRead8(word_t addr)59 Memory2::memRead8(word_t addr)
60 {
61   if (_m_irm->is_active() && (addr >= 0x8000) && (addr <= 0xc000))
62     ui->memory_read(addr);
63 
64   return _memrptr[addr >> MemArea::PAGE_SHIFT][addr & MemArea::PAGE_MASK];
65 }
66 
67 void
memWrite8(word_t addr,byte_t val)68 Memory2::memWrite8(word_t addr, byte_t val)
69 {
70   if (_m_irm->is_active() && (addr >= 0x8000) && (addr <= 0xc000))
71     ui->memory_write(addr);
72 
73   _memwptr[addr >> MemArea::PAGE_SHIFT][addr & MemArea::PAGE_MASK] = val;
74 }
75 
76 byte_t *
get_irm(void)77 Memory2::get_irm(void)
78 {
79   return (byte_t *)_irm;
80 }
81 
82 byte_t *
get_char_rom(void)83 Memory2::get_char_rom(void)
84 {
85   return (byte_t *)0;
86 }
87 
88 void
dumpCore(void)89 Memory2::dumpCore(void)
90 {
91 #if 0
92   ofstream os;
93 
94   os.open("core.z80");
95 
96   cout.form("Memory: dumping core...\n");
97   if (!os)
98     {
99       cerr << "can't write 'core.z80'\n";
100       exit(0);
101     }
102 
103   os.write(&_ram[0], 0x4000);
104   os.write(&_irm[0],   0x4000);
105 
106   os.close();
107   cout.form("Memory: done.\n");
108 #endif
109 }
110 
111 void
enableCAOS(int v)112 Memory2::enableCAOS(int v)
113 {
114   _m_caos->set_active(v);
115   reload_mem_ptr();
116 }
117 
118 void
enableIRM(int v)119 Memory2::enableIRM(int v)
120 {
121   _m_irm->set_active(v);
122   reload_mem_ptr();
123 }
124 
125 void
enableRAM(int v)126 Memory2::enableRAM(int v)
127 {
128   _m_ram->set_active(v);
129   reload_mem_ptr();
130 }
131 
132 void
protectRAM(int v)133 Memory2::protectRAM(int v)
134 {
135   _m_ram->set_readonly(!v);
136   reload_mem_ptr();
137 }
138 
139 void
reset(bool power_on)140 Memory2::reset(bool power_on)
141 {
142   _m_ram->set_readonly(false);
143   _m_ram->set_active(true);
144   _m_irm->set_active(true);
145   _m_caos->set_active(true);
146   reload_mem_ptr();
147 
148   if (!power_on)
149     return;
150 
151   scratch_mem(&_ram[0],  0x4000);
152   scratch_mem(&_irm[0],  0x4000);
153 }
154