1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4 
5     Currah Speech 64 cartridge emulation
6 
7 **********************************************************************/
8 
9 /*
10 
11 PCB Layout
12 ----------
13 
14 |===========================|
15 |=|                         |
16 |=|         VLSI            |
17 |=|                         |
18 |=|                         |
19 |=|         ROM             |
20 |=|                         |
21 |=|                         |
22 |=|         SP0256          |
23 |===========================|
24 
25 Notes:
26     All IC's shown.
27 
28     VLSI   - General Instruments LA05-164 custom
29     ROM    - General Instruments R09864CS-2030 8Kx8 ROM "778R01"
30     SP0256 - General Instruments SP0256A-AL2 Speech Synthesizer
31 
32 
33 LA05-164 Pinout
34 ---------------
35             _____   _____
36 DOTCLK   1 |*    \_/     | 28  +5V
37    CA7   2 |             | 27  CD7
38    CA6   3 |             | 26  CA8
39    CA5   4 |             | 25  CA9
40    CA4   5 |             | 24  CA11
41    CA3   6 |             | 23  BA
42    CA2   7 |  LA05-164   | 22  CA10
43    CA1   8 |             | 21  SP0256 _ALD
44    CA0   9 |             | 20  SP0256 OSC1
45         10 |             | 19  SP0256 SBY
46 _GA+EX  11 |             | 18  CA15
47   I/O1  12 |             | 17  CA12
48  _CR/W  13 |             | 16  CA13
49    GND  14 |_____________| 15  CA14
50 
51 Notes:
52     _GA+EX  - _GAME and _EXROM tied together
53 
54 */
55 
56 /*
57 
58     BASIC Commands
59     --------------
60 
61     INIT        Initialize the cartridge
62     BYE         Disable the cartridge
63     KON 0       Enable keyvoices, low voice
64     KON 1       Enable keyvoices, high voice
65     KOFF        Disable keyvoices
66     SAY 0/1 ""  Say words
67 
68 */
69 
70 #include "emu.h"
71 #include "currah_speech.h"
72 #include "speaker.h"
73 
74 
75 //**************************************************************************
76 //  DEVICE DEFINITIONS
77 //**************************************************************************
78 
79 DEFINE_DEVICE_TYPE(C64_CURRAH_SPEECH, c64_currah_speech_cartridge_device, "c64_cspeech", "C64 Currah Speech")
80 
81 
82 //-------------------------------------------------
83 //  ROM( c64_currah_speech )
84 //-------------------------------------------------
85 
ROM_START(c64_currah_speech)86 ROM_START( c64_currah_speech )
87 	ROM_REGION( 0x10000, "sp0256", 0 )
88 	ROM_LOAD( "sp0256a-al2", 0x1000, 0x0800, CRC(b504ac15) SHA1(e60fcb5fa16ff3f3b69d36c7a6e955744d3feafc) )
89 ROM_END
90 
91 
92 //-------------------------------------------------
93 //  rom_region - device-specific ROM region
94 //-------------------------------------------------
95 
96 const tiny_rom_entry *c64_currah_speech_cartridge_device::device_rom_region() const
97 {
98 	return ROM_NAME( c64_currah_speech );
99 }
100 
101 
102 //-------------------------------------------------
103 //  device_add_mconfig - add device configuration
104 //-------------------------------------------------
105 
device_add_mconfig(machine_config & config)106 void c64_currah_speech_cartridge_device::device_add_mconfig(machine_config &config)
107 {
108 	SPEAKER(config, "mono").front_center();
109 	SP0256(config, m_nsp, 4000000); // ???
110 	m_nsp->add_route(ALL_OUTPUTS, "mono", 1.00);
111 }
112 
113 
114 
115 //**************************************************************************
116 //  INLINE HELPERS
117 //**************************************************************************
118 
119 //-------------------------------------------------
120 //  set_osc1 -
121 //-------------------------------------------------
122 
set_osc1(int voice,int intonation)123 void c64_currah_speech_cartridge_device::set_osc1(int voice, int intonation)
124 {
125 	int dotclock = m_slot->dotclock();
126 
127 	// TODO intonation and correct dividers
128 	m_nsp->set_clock(dotclock / (2 << voice));
129 }
130 
131 
132 
133 //**************************************************************************
134 //  LIVE DEVICE
135 //**************************************************************************
136 
137 //-------------------------------------------------
138 //  c64_currah_speech_cartridge_device - constructor
139 //-------------------------------------------------
140 
c64_currah_speech_cartridge_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)141 c64_currah_speech_cartridge_device::c64_currah_speech_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
142 	device_t(mconfig, C64_CURRAH_SPEECH, tag, owner, clock),
143 	device_c64_expansion_card_interface(mconfig, *this),
144 	m_nsp(*this, "sp0256")
145 {
146 }
147 
148 
149 //-------------------------------------------------
150 //  device_start - device-specific startup
151 //-------------------------------------------------
152 
device_start()153 void c64_currah_speech_cartridge_device::device_start()
154 {
155 }
156 
157 
158 //-------------------------------------------------
159 //  device_reset - device-specific reset
160 //-------------------------------------------------
161 
device_reset()162 void c64_currah_speech_cartridge_device::device_reset()
163 {
164 	m_game = 1;
165 	m_exrom = 1;
166 }
167 
168 
169 //-------------------------------------------------
170 //  c64_cd_r - cartridge data read
171 //-------------------------------------------------
172 
c64_cd_r(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)173 uint8_t c64_currah_speech_cartridge_device::c64_cd_r(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
174 {
175 	if (!romh)
176 	{
177 		data = m_romh[offset & 0x1fff];
178 	}
179 	else if (!io1)
180 	{
181 		/*
182 
183 		    bit     description
184 
185 		    0
186 		    1
187 		    2
188 		    3
189 		    4
190 		    5
191 		    6
192 		    7       SBY
193 
194 		*/
195 
196 		data = m_nsp->sby_r() << 7;
197 	}
198 
199 	if (!machine().side_effects_disabled() && (offset == 0xa7f0))
200 	{
201 		m_game = !m_game;
202 		m_exrom = !m_exrom;
203 	}
204 
205 	return data;
206 }
207 
208 
209 //-------------------------------------------------
210 //  c64_cd_w - cartridge data write
211 //-------------------------------------------------
212 
c64_cd_w(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)213 void c64_currah_speech_cartridge_device::c64_cd_w(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
214 {
215 	if (!io1)
216 	{
217 		/*
218 
219 		    bit     description
220 
221 		    0       A1
222 		    1       A2
223 		    2       A3
224 		    3       A4
225 		    4       A5
226 		    5       A6
227 		    6
228 		    7       intonation
229 
230 		*/
231 
232 		int voice = BIT(offset, 0);
233 		int intonation = BIT(data, 7);
234 
235 		set_osc1(voice, intonation);
236 
237 		m_nsp->ald_w(data & 0x3f);
238 	}
239 }
240