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