1 /*
2 * ssi2001-amiga-drv.c - ISA (using Golden Gate 2+ bridge) SSI2001 driver.
3 *
4 * Written by
5 * Marco van den Heuvel <blackystardust68@yahoo.com>
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 #ifdef AMIGA_SUPPORT
30
31 #if defined(HAVE_SSI2001) && defined(AMIGA_M68K)
32
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include "ssi2001.h"
37
38 #if !defined(USE_SDLUI) && !defined(USE_SDLUI2)
39 #include "loadlibs.h"
40 #else
41 #include "archdep.h"
42 #endif
43
44 #include "log.h"
45 #include "types.h"
46
47 #define MAXSID 1
48
49 static unsigned char read_sid(unsigned char reg); // Read a SID register
50 static void write_sid(unsigned char reg, unsigned char data); // Write a SID register
51
52 static int sids_found = -1;
53
54 static uint8_t *SSI2001base = NULL;
55
56 /* read value from SIDs */
ssi2001_drv_read(uint16_t addr,int chipno)57 int ssi2001_drv_read(uint16_t addr, int chipno)
58 {
59 /* check if chipno and addr is valid */
60 if (chipno < MAXSID && addr < 0x20) {
61 return read_sid(addr);
62 }
63
64 return 0;
65 }
66
67 /* write value into SID */
ssi2001_drv_store(uint16_t addr,uint8_t val,int chipno)68 void ssi2001_drv_store(uint16_t addr, uint8_t val, int chipno)
69 {
70 /* check if chipno and addr is valid */
71 if (chipno < MAXSID && addr < 0x20) {
72 write_sid(addr, val);
73 }
74 }
75
76 #undef BYTE
77 #undef WORD
78 #include <exec/types.h>
79 #include <exec/memory.h>
80 #include <libraries/dos.h>
81 #include <libraries/configvars.h>
82
83 #include <clib/exec_protos.h>
84 #include <clib/expansion_protos.h>
85
86 static struct Library *ExpansionBase = NULL;
87
detect_sid(void)88 static int detect_sid(void)
89 {
90 int i;
91
92 for (i = 0x18; i >= 0; --i) {
93 write_sid((uint8_t)i, 0);
94 }
95
96 write_sid(0x12, 0xff);
97
98 for (i = 0; i < 100; ++i) {
99 if (read_sid(0x1b)) {
100 return 0;
101 }
102 }
103
104 write_sid(0x0e, 0xff);
105 write_sid(0x0f, 0xff);
106 write_sid(0x12, 0x20);
107
108 for (i = 0; i < 100; ++i) {
109 if (read_sid(0x1b)) {
110 return 1;
111 }
112 }
113 return 0;
114 }
115
ssi2001_drv_open(void)116 int ssi2001_drv_open(void)
117 {
118 struct ConfigDev *myCD;
119 int i;
120
121 if (!sids_found) {
122 return -1;
123 }
124
125 if (sids_found > 0) {
126 return 0;
127 }
128
129 sids_found = 0;
130
131 log_message(LOG_DEFAULT, "Detecting GG2+ ISA SSI2001 boards.");
132
133 if ((ExpansionBase = OpenLibrary("expansion.library", 0L)) == NULL) {
134 log_message(LOG_DEFAULT, "Cannot open expansion library.");
135 return -1;
136 }
137
138 myCD = FindConfigDev(myCD, 2150, 1);
139
140 if (!myCD) {
141 log_message(LOG_DEFAULT, "No GG2+ board found.");
142 return -1;
143 }
144
145 SSI2001base = myCD->cd_BoardAddr;
146
147 if (!SSI2001base) {
148 log_message(LOG_DEFAULT, "No GG2+ board found.");
149 return -1;
150 }
151
152 if (!detect_sid()) {
153 log_message(LOG_DEFAULT, "No GG2+ ISA SSI2001 boards found.");
154 return -1;
155 }
156
157 /* mute all sids */
158 for (i = 0; i < 32; i++) {
159 write_sid(i, 0);
160 }
161
162 log_message(LOG_DEFAULT, "GG2+ ISA SSI2001 SID: opened");
163
164 sids_found = 1; /* ok */
165
166 return 0;
167 }
168
read_sid(unsigned char reg)169 static unsigned char read_sid(unsigned char reg)
170 {
171 return SSI2001base[((0x280 + (reg & 0x1f)) * 2) + 1];
172 }
173
write_sid(unsigned char reg,unsigned char data)174 static void write_sid(unsigned char reg, unsigned char data)
175 {
176 // Write data to the SID
177 SSI2001base[((0x280 + (reg & 0x1f)) * 2) + 1] = data;
178 }
179
ssi2001_drv_close(void)180 int ssi2001_drv_close(void)
181 {
182 unsigned int i;
183
184 /* mute all sids */
185 for (i = 0; i < 32; i++) {
186 write_sid(i, 0);
187 }
188
189 sids_found = -1;
190
191 log_message(LOG_DEFAULT, "GG2+ ISA SSI2001 SID: closed.");
192
193 return 0;
194 }
195
ssi2001_drv_available(void)196 int ssi2001_drv_available(void)
197 {
198 return sids_found;
199 }
200 #endif
201 #endif
202