1 /*
2  * machine-bus.c - Generic interface to IO bus functions.
3  *
4  * Written by
5  *  Andreas Boose <viceteam@t-online.de>
6  *
7  * This file is part of VICE, the Versatile Commodore Emulator.
8  * See README for copyright notice.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23  *  02111-1307  USA.
24  *
25  */
26 
27 #include "vice.h"
28 
29 #include <stdio.h>
30 
31 #include "lib.h"
32 #include "log.h"
33 #include "machine-bus.h"
34 #include "serial.h"
35 #include "types.h"
36 
37 /* #define DEBUG_BUS */
38 
39 #ifdef DEBUG_BUS
40 #define DBG(x)  printf x
41 #else
42 #define DBG(x)
43 #endif
44 
45 /* Call this if device is not attached: -128 == device not present.  */
46 
47 /*
48  * A whole bunch of function stubs with proper prototypes to fix warnings
49  * about incompatible function pointers
50  */
51 
fn_getf(struct vdrive_s * foo,uint8_t * bar,unsigned int bas)52 static int fn_getf(struct vdrive_s *foo, uint8_t *bar, unsigned int bas)
53 {
54     return 0x80;
55 }
56 
fn_putf(struct vdrive_s * foo,uint8_t bar,unsigned int bas)57 static int fn_putf(struct vdrive_s *foo, uint8_t bar, unsigned int bas)
58 {
59     return 0x80;
60 }
61 
62 
fn_openf(struct vdrive_s * foo,const uint8_t * bar,unsigned int bas,unsigned int meloen,struct cbmdos_cmd_parse_s * appel)63 static int fn_openf(struct vdrive_s *foo, const uint8_t *bar, unsigned int bas,
64         unsigned int meloen, struct cbmdos_cmd_parse_s *appel)
65 {
66     return 0x80;
67 }
68 
69 
fn_closef(struct vdrive_s * foo,unsigned int bar)70 static int fn_closef(struct vdrive_s *foo, unsigned int bar)
71 {
72     return 0x80;
73 }
74 
fn_flushf(struct vdrive_s * foo,unsigned int bar)75 static void fn_flushf(struct vdrive_s *foo, unsigned int bar)
76 {
77 }
78 
fn_listenf(struct vdrive_s * foo,unsigned int bar)79 static void fn_listenf(struct vdrive_s *foo, unsigned int bar)
80 {
81 }
82 
machine_bus_init(void)83 void machine_bus_init(void)
84 {
85     unsigned int i;
86 
87     for (i = 0; i < SERIAL_MAXDEVICES; i++) {
88         serial_t *p;
89 
90         p = serial_device_get(i);
91 
92         p->inuse = 0;
93         p->getf = fn_getf;
94         p->putf = fn_putf;
95         p->openf = fn_openf;
96         p->closef = fn_closef;
97         p->flushf = fn_flushf;
98         p->listenf = fn_listenf;
99     }
100 
101     machine_bus_init_machine();
102 }
103 
machine_bus_device_attach(unsigned int unit,const char * name,int (* getf)(struct vdrive_s *,uint8_t *,unsigned int),int (* putf)(struct vdrive_s *,uint8_t,unsigned int),int (* openf)(struct vdrive_s *,const uint8_t *,unsigned int,unsigned int,struct cbmdos_cmd_parse_s *),int (* closef)(struct vdrive_s *,unsigned int),void (* flushf)(struct vdrive_s *,unsigned int),void (* listenf)(struct vdrive_s *,unsigned int))104 int machine_bus_device_attach(unsigned int unit, const char *name,
105                               int (*getf)(struct vdrive_s *, uint8_t *, unsigned int),
106                               int (*putf)(struct vdrive_s *, uint8_t, unsigned int),
107                               int (*openf)(struct vdrive_s *, const uint8_t *,
108                                            unsigned int, unsigned int,
109                                            struct cbmdos_cmd_parse_s *),
110                               int (*closef)(struct vdrive_s *, unsigned int),
111                               void (*flushf)(struct vdrive_s *, unsigned int),
112                               void (*listenf)(struct vdrive_s *, unsigned int))
113 {
114     serial_t *p;
115     int i;
116 
117     if (unit >= SERIAL_MAXDEVICES) {
118         return 1;
119     }
120 
121     p = serial_device_get(unit);
122 
123     DBG(("machine_bus_device_attach unit %d devtype:%d inuse:%d\n", unit, p->device, p->inuse));
124 
125     if (p->inuse != 0) {
126         machine_bus_device_detach(unit);
127     }
128 
129     if (p->device != SERIAL_DEVICE_NONE) {
130         p->getf = getf;
131         p->putf = putf;
132         p->openf = openf;
133         p->closef = closef;
134         p->flushf = flushf;
135         p->listenf = listenf;
136         p->inuse = 1;
137         if (p->name) {
138             lib_free(p->name);
139         }
140         p->name = lib_stralloc(name);
141     }
142 
143     for (i = 0; i < 16; i++) {
144         p->nextok[i] = 0;
145         p->isopen[i] = 0;
146     }
147 
148     return 0;
149 }
150 
151 /* Detach and kill serial devices.  */
machine_bus_device_detach(unsigned int unit)152 int machine_bus_device_detach(unsigned int unit)
153 {
154     serial_t *p;
155 
156     DBG(("machine_bus_device_detach unit %d\n", unit));
157 
158     if (unit >= SERIAL_MAXDEVICES) {
159         log_error(LOG_DEFAULT, "Illegal device number %d.", unit);
160         return -1;
161     }
162 
163     p = serial_device_get(unit);
164 
165     if (p != NULL && p->inuse != 0) {
166         p->inuse = 0;
167         if (p->name) {
168             lib_free(p->name);
169         }
170         p->name = NULL;
171 
172         p->getf = fn_getf;
173         p->putf = fn_putf;
174         p->openf = fn_openf;
175         p->closef = fn_closef;
176         p->flushf = fn_flushf;
177         p->listenf = fn_listenf;
178     }
179 
180     return 0;
181 }
182