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 
12 
13 /*Creation date: 98-02-18 */
14 /*  A few words of comment:
15 **
16 **   What's inside of this file is a PAL16R6 emulator. Maybe someday we will
17 **need to use it for some other game too. We will need to make it more exact
18 **then (some of the functionality of this chip IS NOT implemented). However I
19 **have bought a book about PALs and I'm able to improve it. Just LMK.
20 **	Jarek Burczynski
21 **	bujar@mame.net
22 */
23 
24 
25 /*table holds outputs of all ANDs (after AND map)*/
26 static unsigned char andmap[64];
27 
28 /*table holds inputs (ie. not x, x, not q, q) to the AND map*/
29 static unsigned char columnvalue[32];
30 
31 /*8 output pins (actually 6 output and 2 input/output)*/
32 static unsigned char outvalue[8];
33 
34 /*		64 rows x 32 columns
35 **  1 - fuse blown: disconnected from input (equal to 1)
36 **  0 - fuse not blown: connected to input (ie. x, not x, q, not q accordingly)
37 */
38 static unsigned char fusemap[64*32]=
39 {
40 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
41 1,1,1,1,1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1,0,1,1,1,0,1,1,1,1,1,
42 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
43 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
44 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
45 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
46 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
47 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
48 1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
49 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
50 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
51 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
52 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
53 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
54 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
55 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
56 1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
57 1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
58 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
59 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
60 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
61 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
63 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
64 1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
65 1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
66 1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
67 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
68 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
69 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
70 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
71 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72 1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,
73 1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,
74 1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,
75 1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,
76 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
77 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
78 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
79 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
80 1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,
81 1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
82 1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
83 1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
84 1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,
85 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
86 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
87 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
88 1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,
89 1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,
90 1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,
91 1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,
92 1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,
93 1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,
94 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
95 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
96 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
97 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,
98 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
99 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
100 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
101 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
102 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
103 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
104 };
105 
106 
update_pal(void)107 static void update_pal(void)
108 {
109 unsigned short rowoffs;
110 unsigned char row, column, val;
111 
112 /*calculate all rows ANDs*/
113 	for (row = 0; row < 64; row++)
114 	{
115 		rowoffs = row*32;
116 		val = 1; /*prepare for AND */
117 		for (column = 0; column < 32; column++)
118 		{
119 			if ( fusemap[ rowoffs + column ] == 0 )
120 				val &= columnvalue[column];
121 		}
122 		andmap[row] = val;
123 	}
124 
125 /* I/O pin #19 */
126 	val = 0; /*prepare for OR*/
127 	for (row = 1; row < 8; row++)
128 		val |= andmap[row];
129 	if (andmap[0] == 1)
130 	{
131 		columnvalue[2] = 1-val;
132 		columnvalue[3] = val;
133 		outvalue[0]    = 1-val;
134 	}
135 	else
136 	{
137 		/*pin is in INPUT configuration so it doesn't create output...*/
138 		columnvalue[2] = 0;
139 		columnvalue[3] = 1;
140 	}
141 
142 /* O pin #18 (D1) */
143 	val = 0; /*prepare for OR*/
144 	for (row = 8; row < 16; row++)
145 		val |= andmap[row];
146 	columnvalue[6] = 1-val;
147 	columnvalue[7] = val;
148 	outvalue[1]    = 1-val;
149 
150 /* O pin #17 (D2) */
151 	val = 0; /*prepare for OR*/
152 	for (row = 16; row < 24; row++)
153 		val |= andmap[row];
154 	columnvalue[10] = 1-val;
155 	columnvalue[11] = val;
156 	outvalue[2]     = 1-val;
157 
158 /* O pin #16 (D3) */
159 	val = 0; /*prepare for OR*/
160 	for (row = 24; row < 32; row++)
161 		val |= andmap[row];
162 	columnvalue[14] = 1-val;
163 	columnvalue[15] = val;
164 	outvalue[3]     = 1-val;
165 
166 /* O pin #15 (D4) */
167 	val = 0; /*prepare for OR*/
168 	for (row = 32; row < 40; row++)
169 		val |= andmap[row];
170 	columnvalue[18] = 1-val;
171 	columnvalue[19] = val;
172 	outvalue[4]     = 1-val;
173 
174 /* O pin #14 (D5) */
175 	val = 0; /*prepare for OR*/
176 	for (row = 40; row < 48; row++)
177 		val |= andmap[row];
178 	columnvalue[22] = 1-val;
179 	columnvalue[23] = val;
180 	outvalue[5]     = 1-val;
181 
182 /* O pin #13 (D6) */
183 	val = 0; /*prepare for OR*/
184 	for (row = 48; row < 56; row++)
185 		val |= andmap[row];
186 	columnvalue[26] = 1-val;
187 	columnvalue[27] = val;
188 	outvalue[6]     = 1-val;
189 
190 /* I/O pin #12 */
191 	val = 0; /*prepare for OR*/
192 	for (row = 57; row < 64; row++)
193 		val |= andmap[row];
194 	if (andmap[56] == 1)
195 	{
196 		columnvalue[30] = 1-val;
197 		columnvalue[31] = val;
198 		outvalue[7]     = 1-val;
199 	}
200 	else
201 	{
202 		/*pin is in INPUT configuration so it doesn't create output...*/
203 		columnvalue[30] = 0;
204 		columnvalue[31] = 1;
205 	}
206 
207 }
208 
209 
WRITE_HANDLER(bagman_pal16r6_w)210 WRITE_HANDLER( bagman_pal16r6_w )
211 {
212 unsigned char line;
213 
214 	line = offset*4;
215 	columnvalue[line  ] = data&1;
216 	columnvalue[line+1] = 1-(data&1);
217 }
218 
MACHINE_INIT(bagman)219 MACHINE_INIT( bagman )
220 {
221 	bagman_pal16r6_w(0,1);	/*pin 2*/
222 	bagman_pal16r6_w(1,1);	/*pin 3*/
223 	bagman_pal16r6_w(2,1);	/*pin 4*/
224 	bagman_pal16r6_w(3,1);	/*pin 5*/
225 	bagman_pal16r6_w(4,1);	/*pin 6*/
226 	bagman_pal16r6_w(5,1);	/*pin 7*/
227 	bagman_pal16r6_w(6,1);	/*pin 8*/
228 	bagman_pal16r6_w(7,1);	/*pin 9*/
229 	update_pal();
230 }
231 
READ_HANDLER(bagman_pal16r6_r)232 READ_HANDLER( bagman_pal16r6_r )
233 {
234 	update_pal();
235 	return	(outvalue[6]) + (outvalue[5]<<1) + (outvalue[4]<<2) +
236 		(outvalue[3]<<3) + (outvalue[2]<<4) + (outvalue[1]<<5);
237 
238 /* Bagman schematics show that this is right mapping order of PAL outputs to bits.
239 ** This is the PAL 16R6 shown almost in the middle of the schematics.
240 ** The /RD4 line goes low (active) whenever CPU reads from memory address a000.
241 */
242 }
243