1 /***************************************************************************
2
3 machine.c
4
5 Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
6 I/O ports)
7
8 ***************************************************************************/
9
10 #include "driver.h"
11 #include "cpu/m68000/m68000.h"
12
13 unsigned char *toypop_sound_sharedram, *toypop_m68000_sharedram, *toypop_customio;
14 static unsigned char interrupt_enable_mainCPU, interrupt_enable_sound, interrupt_enable_68k;
15 // variables used by the coinage of Libble Rabble
16 static int credits, coinsA, coinsB;
17 static int coinageA[8][2] = {{1,1},{2,1},{1,3},{3,1},{1,2},{2,3},{1,6},{3,2}};
18 static int coinageB[4][2] = {{1,1},{1,7},{1,5},{2,1}};
19
MACHINE_INIT(toypop)20 MACHINE_INIT( toypop )
21 {
22 credits = coinsA = coinsB = 0;
23 interrupt_enable_mainCPU = 0;
24 interrupt_enable_sound = 0;
25 interrupt_enable_68k = 0;
26 }
27
READ_HANDLER(toypop_sound_sharedram_r)28 READ_HANDLER( toypop_sound_sharedram_r )
29 {
30 /* to speed up emulation, we check for the loop the sound CPU sits in most of the time
31 and end the current iteration (things will start going again with the next IRQ) */
32 if (offset == 0xa1 - 0x40 && toypop_sound_sharedram[offset] == 0 && activecpu_get_pc() == 0xe4df)
33 cpu_spinuntil_int();
34 return toypop_sound_sharedram[offset];
35 }
36
WRITE_HANDLER(toypop_sound_sharedram_w)37 WRITE_HANDLER( toypop_sound_sharedram_w )
38 {
39 toypop_sound_sharedram[offset] = data;
40 }
41
READ16_HANDLER(toypop_m68000_sharedram_r)42 READ16_HANDLER( toypop_m68000_sharedram_r )
43 {
44 return toypop_m68000_sharedram[offset];
45 }
46
WRITE16_HANDLER(toypop_m68000_sharedram_w)47 WRITE16_HANDLER( toypop_m68000_sharedram_w )
48 {
49 if (ACCESSING_LSB)
50 toypop_m68000_sharedram[offset] = data & 0xff;
51 }
52
WRITE_HANDLER(toypop_main_interrupt_enable_w)53 WRITE_HANDLER( toypop_main_interrupt_enable_w )
54 {
55 interrupt_enable_mainCPU = 1;
56 }
57
WRITE_HANDLER(toypop_main_interrupt_disable_w)58 WRITE_HANDLER( toypop_main_interrupt_disable_w )
59 {
60 interrupt_enable_mainCPU = 0;
61 }
62
WRITE_HANDLER(toypop_sound_interrupt_enable_w)63 WRITE_HANDLER( toypop_sound_interrupt_enable_w )
64 {
65 interrupt_enable_sound = 1;
66 }
67
WRITE_HANDLER(toypop_sound_interrupt_disable_w)68 WRITE_HANDLER( toypop_sound_interrupt_disable_w )
69 {
70 interrupt_enable_sound = 0;
71 }
72
WRITE16_HANDLER(toypop_m68000_interrupt_enable_w)73 WRITE16_HANDLER( toypop_m68000_interrupt_enable_w )
74 {
75 interrupt_enable_68k = 1;
76 }
77
WRITE16_HANDLER(toypop_m68000_interrupt_disable_w)78 WRITE16_HANDLER( toypop_m68000_interrupt_disable_w )
79 {
80 interrupt_enable_68k = 0;
81 }
82
INTERRUPT_GEN(toypop_main_interrupt)83 INTERRUPT_GEN( toypop_main_interrupt )
84 {
85 if (interrupt_enable_mainCPU)
86 irq0_line_hold();
87 }
88
INTERRUPT_GEN(toypop_sound_interrupt)89 INTERRUPT_GEN( toypop_sound_interrupt )
90 {
91 if (interrupt_enable_sound)
92 irq0_line_hold();
93 }
94
INTERRUPT_GEN(toypop_m68000_interrupt)95 INTERRUPT_GEN( toypop_m68000_interrupt )
96 {
97 if (interrupt_enable_68k)
98 cpu_set_irq_line(2, 6, HOLD_LINE);
99 }
100
READ_HANDLER(toypop_customio_r)101 READ_HANDLER( toypop_customio_r )
102 {
103 int mode = toypop_customio[8];
104
105 /* mode 5 values are actually checked against these numbers during power up */
106 if (mode == 5)
107 switch (offset) {
108 case 2:
109 return 15;
110 case 6:
111 return 12;
112 case 16:
113 return 6;
114 case 17:
115 return 9;
116 case 32:
117 return 6;
118 case 33:
119 return 9;
120 default:
121 return toypop_customio[offset];
122 }
123 else
124 switch (offset) {
125 case 4:
126 return readinputport(0) & 0x0f;
127 case 5:
128 return readinputport(0) >> 4;
129 case 6:
130 return readinputport(1) & 0x0f;
131 case 7:
132 return readinputport(1) >> 4;
133 case 16:
134 return readinputport(2) & 0x0f;
135 case 17:
136 return readinputport(2) >> 4;
137 case 18:
138 return readinputport(3) & 0x0f;
139 case 19:
140 return readinputport(3) >> 4;
141 default:
142 return toypop_customio[offset];
143 }
144 }
145
READ_HANDLER(liblrabl_customio_r)146 READ_HANDLER( liblrabl_customio_r )
147 {
148 static int lastcoin, laststart;
149 int val, tmp, mode = toypop_customio[24];
150
151 /* mode 7 values are actually checked against these numbers during power up */
152 if (mode == 7)
153 switch (offset) {
154 case 2:
155 return 15;
156 case 6:
157 return 12;
158 case 18:
159 return 14;
160 case 39:
161 return 6;
162 default:
163 return toypop_customio[offset];
164 }
165 else if (mode == 1)
166 switch (offset) {
167 case 0: // Coin slots
168 val = readinputport(3) & 0x0f;
169 // bit 0 is a trigger for the coin 1 slot
170 if ((val & 1) && !(lastcoin & 1)) {
171 tmp = (readinputport(1) & 0xe0) >> 5;
172 coinsA++;
173 if (coinsA == coinageA[tmp][0]) {
174 credits += coinageA[tmp][1];
175 coinsA = 0;
176 }
177 }
178 // bit 1 is a trigger for the coin 2 slot
179 if ((val & 2) && !(lastcoin & 2)) {
180 tmp = (readinputport(0) & 0x18) >> 3;
181 coinsB++;
182 if (coinsB == coinageB[tmp][0]) {
183 credits += coinageB[tmp][1];
184 coinsB = 0;
185 }
186 }
187 return lastcoin = val;
188 case 1: // Start buttons
189 val = readinputport(3) >> 4;
190 // bit 0 is a trigger for the 1 player start
191 if ((val & 1) && !(laststart & 1))
192 credits--;
193 // bit 1 is a trigger for the 2 player start
194 if ((val & 2) && !(laststart & 2)) {
195 if (credits >= 2)
196 credits -= 2;
197 else
198 val &= ~2; // otherwise you can start with no credits
199 }
200 return laststart = val;
201 case 2: // High BCD of credits
202 return credits / 10;
203 case 3: // Low BCD of credits
204 return credits % 10;
205 // case 5: // read, but unknown
206 // return readinputport(2) >> 4;
207 case 4: // Right joystick
208 return readinputport(4) >> 4;
209 case 6: // Player 2 right joystick in cocktail mode
210 return readinputport(5) >> 4;
211 case 16:
212 return readinputport(1) >> 4;
213 case 17:
214 return readinputport(0) & 0x0f;
215 case 18:
216 return readinputport(0) >> 4;
217 case 19:
218 return readinputport(1) & 0x0f;
219 case 34: // Left joystick
220 return readinputport(4) & 0x0f;
221 case 36: // Player 2 left joystick in cocktail mode
222 return readinputport(5) & 0x0f;
223 case 39:
224 return readinputport(2) & 0x0f;
225 default:
226 return toypop_customio[offset];
227 }
228 else
229 return toypop_customio[offset];
230 }
231
WRITE_HANDLER(toypop_sound_clear_w)232 WRITE_HANDLER( toypop_sound_clear_w )
233 {
234 cpu_set_reset_line(1, CLEAR_LINE);
235 }
236
WRITE_HANDLER(toypop_sound_assert_w)237 WRITE_HANDLER( toypop_sound_assert_w )
238 {
239 cpu_set_reset_line(1, ASSERT_LINE);
240 }
241
WRITE_HANDLER(toypop_m68000_clear_w)242 WRITE_HANDLER( toypop_m68000_clear_w )
243 {
244 cpu_set_reset_line(2, CLEAR_LINE);
245 }
246
WRITE_HANDLER(toypop_m68000_assert_w)247 WRITE_HANDLER( toypop_m68000_assert_w )
248 {
249 cpu_set_reset_line(2, ASSERT_LINE);
250 }
251