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 <stdio.h>
21 #include <iostream>
22 #include <iomanip>
23
24 #include "kc/system.h"
25
26 #include "kc/kc.h"
27 #include "kc/ports4.h"
28 #include "kc/memory4.h"
29
30 #include "libdbg/dbg.h"
31
32 #define memory ((Memory4 *)memory)
33
Ports4(void)34 Ports4::Ports4(void)
35 {
36 for (int a = 0;a < NR_PORTS;a++)
37 inout[a] = -1;
38 }
39
~Ports4(void)40 Ports4::~Ports4(void)
41 {
42 }
43
44 byte_t
in(word_t addr)45 Ports4::in(word_t addr)
46 {
47 byte_t a = addr & 0xff;
48 byte_t val = inout[a];
49
50 switch (a)
51 {
52 case 0x84:
53 case 0x86:
54 break;
55 default:
56 DBG(0, form("KCemu/internal_error",
57 "Ports4: called in() with undefined address %04xh\n",
58 addr));
59 break;
60 }
61
62 DBG(2, form("KCemu/Ports/4/in",
63 "Ports4: in() addr = %04x (returning %02x)\n",
64 addr, val));
65
66 return val;
67 }
68
69 void
out(word_t addr,byte_t val)70 Ports4::out(word_t addr, byte_t val)
71 {
72 byte_t a = addr & 0xff;
73
74 DBG(2, form("KCemu/Ports/4/out",
75 "Ports4: out() addr = %04x, val = %02x\n",
76 addr, val));
77
78 switch (a)
79 {
80 case 0x84:
81 if (inout[0x84] < 0)
82 inout[0x84] = ~val;
83 change_0x84(inout[0x84] ^ val, val);
84 break;
85 case 0x86:
86 if (inout[0x86] < 0)
87 inout[0x86] = ~val;
88 change_0x86(inout[0x86] ^ val, val);
89 break;
90 default:
91 DBG(0, form("KCemu/internal_error",
92 "Ports4: called out() with undefined address %04xh (val = %02xh)\n",
93 addr, val));
94 break;
95 }
96
97 inout[addr & 0xff] = val;
98 }
99
100 void
change_0x84(byte_t changed,byte_t val)101 Ports4::change_0x84(byte_t changed, byte_t val)
102 {
103 if (changed & 0x01)
104 {
105 DBG(2, form("KCemu/Ports/4/change/84",
106 "Ports 0x84: display screen %d\n",
107 val & 1));
108 memory->displaySCREEN_1(val & 0x01);
109 }
110 if (changed & 0x02)
111 {
112 DBG(2, form("KCemu/Ports/4/change/84",
113 "Ports 0x84: pixel/ color %d\n",
114 (val >> 1) & 1));
115 memory->enableCOLOR(val & 0x02);
116 }
117 if (changed & 0x04)
118 {
119 DBG(2, form("KCemu/Ports/4/change/84",
120 "Ports 0x84: access screen %d\n",
121 (val >> 2) & 1));
122 memory->enableSCREEN_1(val & 0x04);
123 }
124 if (changed & 0x08)
125 {
126 DBG(2, form("KCemu/Ports/4/change/84",
127 "Ports 0x84: high resolution %d\n",
128 (val >> 3) & 1));
129 }
130 if (changed & 0xf0)
131 {
132 DBG(2, form("KCemu/Ports/4/change/84",
133 "Ports 0x84: access RAM8 segment %d\n",
134 (val >> 4) & 0x0f));
135 memory->selectRAM_8((val >> 4) & 0x0f);
136 }
137 }
138
139 void
change_0x86(byte_t changed,byte_t val)140 Ports4::change_0x86(byte_t changed, byte_t val)
141 {
142 if (changed & 0x01)
143 {
144 DBG(2, form("KCemu/Ports/4/change/86",
145 "Ports 0x86: RAM 4 %d\n",
146 val & 1));
147 memory->enableRAM_4(val & 0x01);
148 }
149 if (changed & 0x02)
150 {
151 DBG(2, form("KCemu/Ports/4/change/86",
152 "Ports 0x86: write protect RAM 4 %d\n",
153 (val >> 1) & 1));
154 memory->protectRAM_4(val & 0x02);
155 }
156 if (changed & 0x04)
157 {
158 DBG(2, form("KCemu/Ports/4/change/86",
159 "Ports 0x86: unused 0x04 %d\n",
160 (val >> 2) & 1));
161 }
162 if (changed & 0x08)
163 {
164 DBG(2, form("KCemu/Ports/4/change/86",
165 "Ports 0x86: unused 0x08 %d\n",
166 (val >> 3) & 1));
167 }
168 if (changed & 0x10)
169 {
170 DBG(2, form("KCemu/Ports/4/change/86",
171 "Ports 0x86: unused 0x10 %d\n",
172 (val >> 4) & 1));
173 }
174 if (changed & 0x60)
175 {
176 DBG(2, form("KCemu/Ports/4/change/86",
177 "Ports 0x86: BASIC/USER ROM bank %d\n",
178 (val >> 5) & 3));
179 memory->selectROM_C((val >> 5) & 3);
180 }
181 if (changed & 0x80)
182 {
183 DBG(2, form("KCemu/Ports/4/change/86",
184 "Ports 0x86: CAOS C %d\n",
185 (val >> 7) & 1));
186 memory->enableCAOS_C(val & 0x80);
187 }
188 }
189