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 <string.h>
21 #include <fstream>
22 #include <iostream>
23
24 #include "kc/system.h"
25
26 #include "kc/kc.h"
27 #include "kc/mod_disk.h"
28
29 #include "libdbg/dbg.h"
30
ModuleDisk(ModuleDisk & tmpl)31 ModuleDisk::ModuleDisk(ModuleDisk &tmpl) : ModuleROM(tmpl)
32 {
33 _val = 0;
34 _slot = tmpl._slot;
35 }
36
ModuleDisk(const char * rom_key,const char * name,byte_t id,int slot)37 ModuleDisk::ModuleDisk(const char *rom_key, const char *name, byte_t id, int slot) :
38 ModuleROM(rom_key, name, id)
39 {
40 _val = 0;
41 _slot = slot;
42 }
43
~ModuleDisk(void)44 ModuleDisk::~ModuleDisk(void)
45 {
46 }
47
48 word_t
get_addr(byte_t val)49 ModuleDisk::get_addr(byte_t val)
50 {
51 return (val & 0x20) ? 0xe000 : 0xc000;
52 }
53
54 /*
55 * SWITCH FC kk-------------------
56 * |
57 * |
58 * ---------------------------------
59 * Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
60 * ---------------------------------
61 * | | | Bit 1/0
62 * | | ---- ROM on/off
63 * | ----------- Kopplung on/off
64 * ------------------- Basisadresse E000/C000
65 *
66 */
67 void
m_out(word_t addr,byte_t val)68 ModuleDisk::m_out(word_t addr, byte_t val)
69 {
70 bool unreg, reg;
71
72 if (((_val & 0x25) ^ (val & 0x25)) == 0)
73 return;
74
75 word_t map_addr = get_addr(val);
76
77 DBG(2, form("KCemu/ModuleDisk/out",
78 "ModuleDisk::out(): %s: addr = %04x, val = %02x, old val = %02x\n",
79 get_name(), addr, val, _val));
80
81 // The module interface allows us to snoop on slots F8 and FC at
82 // the same time. So we can disable the memory of the not accessed
83 // slot.
84 reg = unreg = false;
85 if (((addr >> 8) & 0xfc) != _slot)
86 {
87 DBG(2, form("KCemu/ModuleDisk/out",
88 "ModuleDisk::out(): %s: I/O to module on other port detected!\n",
89 get_name()));
90 reg = false;
91 unreg = true;
92 }
93 else
94 {
95 if ((_val & 0x20) ^ (val & 0x20))
96 {
97 DBG(2, form("KCemu/ModuleDisk/out",
98 "ModuleDisk::out(): %s: new map address is %04x\n",
99 get_name(), map_addr));
100 reg = unreg = true;
101 }
102
103 if ((_val & 0x04) ^ (val & 0x04))
104 {
105 DBG(2, form("KCemu/ModuleDisk/out",
106 "ModuleDisk::out(): %s: shared memory is now %s\n",
107 get_name(), (val & 0x04) ? "on" : "off"));
108 }
109
110 if ((_val & 0x01) ^ (val & 0x01))
111 {
112 if (val & 1)
113 reg = true;
114 else
115 reg = false;
116 }
117
118 }
119
120 if (unreg)
121 if (_group)
122 {
123 if (_group) memory->unregister_memory(_group);
124 _group = 0;
125 }
126
127 if (reg)
128 _group = memory->register_memory(get_name(), map_addr, _size,
129 _rom, (addr >> 8), true);
130
131 _val = val;
132 }
133
134 ModuleInterface *
clone(void)135 ModuleDisk::clone(void)
136 {
137 return new ModuleDisk(*this);
138 }
139