1 /*
2 * realdevice.c - Real device access.
3 *
4 * Written by
5 * Andreas Boose <viceteam@t-online.de>
6 * Michael Klein <nip@c64.org>
7 *
8 * This file is part of VICE, the Versatile Commodore Emulator.
9 * See README for copyright notice.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 * 02111-1307 USA.
25 *
26 */
27
28 #include "vice.h"
29
30 #ifdef HAVE_OPENCBM
31
32 #include <stdio.h>
33
34 #include "opencbmlib.h"
35
36 #include "log.h"
37 #include "realdevice.h"
38 #include "serial.h"
39 #include "types.h"
40 #include "vsync.h"
41
42 /*#define DEBUG_RD*/
43
44
45 static log_t realdevice_log = LOG_DEFAULT;
46
47 static unsigned int realdevice_available = 0;
48
49 static unsigned int realdevice_enabled = 0;
50
51 static CBM_FILE realdevice_fd;
52
53 static opencbmlib_t opencbmlib;
54
55
realdevice_open(unsigned int device,uint8_t secondary,void (* st_func)(uint8_t))56 void realdevice_open(unsigned int device, uint8_t secondary, void (*st_func)(uint8_t))
57 {
58 vsync_suspend_speed_eval();
59
60 (*opencbmlib.p_cbm_open)(realdevice_fd, (uint8_t)(device & 0x0f),
61 (uint8_t)(secondary & 0x0f),
62 NULL, 0);
63
64 #ifdef DEBUG_RD
65 log_debug("OPEN DEVICE %i SECONDARY %i", device & 0x0f, secondary & 0x0f);
66 #endif
67 }
68
realdevice_close(unsigned int device,uint8_t secondary,void (* st_func)(uint8_t))69 void realdevice_close(unsigned int device, uint8_t secondary, void (*st_func)(uint8_t))
70 {
71 vsync_suspend_speed_eval();
72
73 (*opencbmlib.p_cbm_close)(realdevice_fd, (uint8_t)(device & 0x0f),
74 (uint8_t)(secondary & 0x0f));
75
76 #ifdef DEBUG_RD
77 log_debug("CLOSE DEVICE %i SECONDARY %i", device & 0x0f, secondary & 0x0f);
78 #endif
79 }
80
realdevice_listen(unsigned int device,uint8_t secondary,void (* st_func)(uint8_t))81 void realdevice_listen(unsigned int device, uint8_t secondary, void (*st_func)(uint8_t))
82 {
83 vsync_suspend_speed_eval();
84
85 (*opencbmlib.p_cbm_listen)(realdevice_fd, (uint8_t)(device & 0x0f),
86 (uint8_t)(secondary & 0x0f));
87 #ifdef DEBUG_RD
88 log_debug("LISTEN DEVICE %i SECONDARY %i", device & 0x0f,
89 secondary & 0x0f);
90 #endif
91 }
92
realdevice_talk(unsigned int device,uint8_t secondary,void (* st_func)(uint8_t))93 void realdevice_talk(unsigned int device, uint8_t secondary, void (*st_func)(uint8_t))
94 {
95 vsync_suspend_speed_eval();
96
97 (*opencbmlib.p_cbm_talk)(realdevice_fd, (uint8_t)(device & 0x0f),
98 (uint8_t)(secondary & 0x0f));
99 #ifdef DEBUG_RD
100 log_debug("TALK DEVICE %i SECONDARY %i", device & 0x0f,
101 secondary & 0x0f);
102 #endif
103 }
104
realdevice_unlisten(void (* st_func)(uint8_t))105 void realdevice_unlisten(void (*st_func)(uint8_t))
106 {
107 vsync_suspend_speed_eval();
108
109 (*opencbmlib.p_cbm_unlisten)(realdevice_fd);
110 #ifdef DEBUG_RD
111 log_debug("UNLISTEN");
112 #endif
113 }
114
realdevice_untalk(void (* st_func)(uint8_t))115 void realdevice_untalk(void (*st_func)(uint8_t))
116 {
117 vsync_suspend_speed_eval();
118
119 (*opencbmlib.p_cbm_untalk)(realdevice_fd);
120 #ifdef DEBUG_RD
121 log_debug("UNTALK");
122 #endif
123 }
124
realdevice_write(uint8_t data,void (* st_func)(uint8_t))125 void realdevice_write(uint8_t data, void (*st_func)(uint8_t))
126 {
127 uint8_t st;
128
129 #ifdef DEBUG_RD
130 uint8_t mydata = data;
131 #endif
132
133 vsync_suspend_speed_eval();
134
135 st = ((*opencbmlib.p_cbm_raw_write)(realdevice_fd, &data, 1) == 1)
136 ? 0 : 0x83;
137
138 #ifdef DEBUG_RD
139 log_debug("WRITE DATA %02x ST %02x", mydata, st);
140 #endif
141
142 st_func(st);
143 }
144
realdevice_read(void (* st_func)(uint8_t))145 uint8_t realdevice_read(void (*st_func)(uint8_t))
146 {
147 uint8_t st, data;
148
149 vsync_suspend_speed_eval();
150
151 st = ((*opencbmlib.p_cbm_raw_read)(realdevice_fd, &data, 1) == 1) ? 0 : 2;
152
153 #ifdef DEBUG_RD
154 log_debug("READ %02x ST %02x", data, st);
155 #endif
156
157 if ((*opencbmlib.p_cbm_get_eoi)(realdevice_fd)) {
158 st |= 0x40;
159 }
160
161 #ifdef DEBUG_RD
162 log_debug("READ NEWST %02x", st);
163 #endif
164
165 st_func(st);
166
167 return data;
168 }
169
realdevice_init(void)170 void realdevice_init(void)
171 {
172 realdevice_log = log_open("Real Device");
173 #ifdef DEBUG_RD
174 log_debug("realdevice_init()");
175 #endif
176
177 if (opencbmlib_open(&opencbmlib) >= 0) {
178 realdevice_available = 1;
179 }
180 }
181
realdevice_reset(void)182 void realdevice_reset(void)
183 {
184 #ifdef DEBUG_RD
185 log_debug("realdevice_reset()");
186 #endif
187 if (realdevice_enabled) {
188 (*opencbmlib.p_cbm_reset)(realdevice_fd);
189 }
190 }
191
realdevice_enable(void)192 int realdevice_enable(void)
193 {
194 #ifdef DEBUG_RD
195 log_debug("realdevice_enable()");
196 #endif
197 if (realdevice_available == 0 &&
198 opencbmlib_open(&opencbmlib) >= 0) {
199 realdevice_available = 1;
200 }
201
202 if (realdevice_available == 0) {
203 log_message(realdevice_log, "Real device access is not available!");
204 return -1;
205 }
206
207 if (realdevice_enabled == 0) {
208 #ifdef DEBUG_RD
209 log_debug("realdevice_enable: calling cbm_driver_open");
210 #endif
211 if ((*opencbmlib.p_cbm_driver_open)(&realdevice_fd, 0) != 0) {
212 log_message(realdevice_log,
213 "Cannot open %s, realdevice not available!",
214 (*opencbmlib.p_cbm_get_driver_name)(0));
215 return -1;
216 }
217
218 log_message(realdevice_log, "%s opened.",
219 (*opencbmlib.p_cbm_get_driver_name)(0));
220 }
221
222 #ifdef DEBUG_RD
223 log_debug("realdevice_enable: realdevice_enabled++");
224 #endif
225 realdevice_enabled++;
226
227 return 0;
228 }
229
realdevice_disable(void)230 void realdevice_disable(void)
231 {
232 #ifdef DEBUG_RD
233 log_debug("realdevice_disable()");
234 #endif
235 if (realdevice_enabled > 0) {
236 realdevice_enabled--;
237
238 if (realdevice_enabled == 0) {
239 (*opencbmlib.p_cbm_driver_close)(realdevice_fd);
240
241 log_message(realdevice_log, "%s closed.",
242 (*opencbmlib.p_cbm_get_driver_name)(0));
243
244 opencbmlib_close();
245 realdevice_available = 0;
246 }
247 }
248 }
249 #endif
250