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