1 // TC0110PCR
2 // Based on MAME sources by Nicola Salmoria
3 
4 #include "burnint.h"
5 #include "taito_ic.h"
6 
7 #define MAX_TC0110PCR		3
8 
9 static UINT8 *TC0110PCRRam[MAX_TC0110PCR];
10 UINT32 *TC0110PCRPalette = NULL;
11 static INT32 TC0110PCRAddr[MAX_TC0110PCR];
12 INT32 TC0110PCRTotalColours;
13 INT32 TC0110PCRCount = 0;
14 
pal5bit(UINT8 bits)15 static inline UINT8 pal5bit(UINT8 bits)
16 {
17 	bits &= 0x1f;
18 	return (bits << 3) | (bits >> 2);
19 }
20 
pal4bit(UINT8 bits)21 static inline UINT8 pal4bit(UINT8 bits)
22 {
23 	bits &= 0x0f;
24 	return (bits << 4) | (bits);
25 }
26 
TC0110PCRRecalcPalette()27 void TC0110PCRRecalcPalette()
28 {
29 	UINT16 Addr = TC0110PCRAddr[0];
30 
31 	for (INT32 i = 0; i < 0x1000; i++)
32 	{
33 		TC0110PCRWordWrite(0, 0, i); // latch
34 
35 		UINT16 pal = TC0110PCRWordRead(0); // read
36 
37 		TC0110PCRWordWrite(0, 1, pal); // write
38 	}
39 	TC0110PCRAddr[0] = Addr;
40 }
41 
TC0110PCRRecalcPaletteStep1()42 void TC0110PCRRecalcPaletteStep1()
43 {
44 	UINT16 Addr = TC0110PCRAddr[0];
45 
46 	for (INT32 i = 0; i < 0x1000; i++)
47 	{
48 		TC0110PCRStep1WordWrite(0, 0, i);
49 
50 		UINT16 pal = TC0110PCRWordRead(0);
51 
52 		TC0110PCRStep1WordWrite(0, 1, pal);
53 	}
54 	TC0110PCRAddr[0] = Addr;
55 }
56 
TC0110PCRRecalcPaletteStep1RBSwap()57 void TC0110PCRRecalcPaletteStep1RBSwap()
58 {
59 	UINT16 Addr = TC0110PCRAddr[0];
60 
61 	for (INT32 i = 0; i < 0x1000; i++)
62 	{
63 		TC0110PCRStep1RBSwapWordWrite(0, 0, i);
64 
65 		UINT16 pal = TC0110PCRWordRead(0);
66 
67 		TC0110PCRStep1RBSwapWordWrite(0, 1, pal);
68 	}
69 	TC0110PCRAddr[0] = Addr;
70 }
71 
TC0110PCRRecalcPaletteStep14rbg()72 void TC0110PCRRecalcPaletteStep14rbg()
73 {
74 	UINT16 Addr = TC0110PCRAddr[0];
75 
76 	for (INT32 i = 0; i < 0x1000; i++)
77 	{
78 		TC0110PCRStep14rbgWordWrite(0, 0, i);
79 
80 		UINT16 pal = TC0110PCRWordRead(0);
81 
82 		TC0110PCRStep14rbgWordWrite(0, 1, pal);
83 	}
84 	TC0110PCRAddr[0] = Addr;
85 }
86 
TC0110PCRWordRead(INT32 Chip)87 UINT16 TC0110PCRWordRead(INT32 Chip)
88 {
89 	UINT16 *PalRam = (UINT16*)TC0110PCRRam[Chip];
90 	return PalRam[TC0110PCRAddr[Chip]];
91 }
92 
TC0110PCRWordWrite(INT32 Chip,INT32 Offset,UINT16 Data)93 void TC0110PCRWordWrite(INT32 Chip, INT32 Offset, UINT16 Data)
94 {
95 	INT32 PaletteOffset = Chip * 0x1000;
96 
97 	switch (Offset) {
98 		case 0: {
99 			TC0110PCRAddr[Chip] = (Data >> 1) & 0xfff;
100 			return;
101 		}
102 
103 		case 1:	{
104 			UINT16 *PalRam = (UINT16*)TC0110PCRRam[Chip];
105 			INT32 r, g, b;
106 
107 			PalRam[TC0110PCRAddr[Chip]] = Data;
108 
109 			r = pal5bit(Data >>  0);
110 			g = pal5bit(Data >>  5);
111 			b = pal5bit(Data >> 10);
112 
113 			TC0110PCRPalette[TC0110PCRAddr[Chip] | PaletteOffset] = BurnHighCol(r, g, b, 0);
114 			return;
115 		}
116 	}
117 }
118 
TC0110PCRStep1WordWrite(INT32 Chip,INT32 Offset,UINT16 Data)119 void TC0110PCRStep1WordWrite(INT32 Chip, INT32 Offset, UINT16 Data)
120 {
121 	INT32 PaletteOffset = Chip * 0x1000;
122 
123 	switch (Offset) {
124 		case 0: {
125 			TC0110PCRAddr[Chip] = Data & 0xfff;
126 			return;
127 		}
128 
129 		case 1: {
130 			UINT16 *PalRam = (UINT16*)TC0110PCRRam[Chip];
131 			INT32 r, g, b;
132 
133 			PalRam[TC0110PCRAddr[Chip]] = Data;
134 
135 			r = pal5bit(Data >>  0);
136 			g = pal5bit(Data >>  5);
137 			b = pal5bit(Data >> 10);
138 
139 			TC0110PCRPalette[TC0110PCRAddr[Chip] | PaletteOffset] = BurnHighCol(r, g, b, 0);
140 			return;
141 		}
142 	}
143 }
144 
145 #if 0
146 // AquaJack wip/debug stuff for palette issue - save for another day
147 void TC0110PCRStep1WordWriteAJ(INT32 Chip, INT32 Offset, UINT16 Data)
148 {
149 	INT32 PaletteOffset = Chip * 0x1000;
150 
151 	switch (Offset) {
152 		case 0: {
153 			TC0110PCRAddr[Chip] = Data & 0xfff;
154 			return;
155 		}
156 
157 		case 1: {
158 			if ((TC0110PCRAddr[Chip]&0xff0) == 0x360) // good line
159 				bprintf(0, _T("a %x %X.\n"),TC0110PCRAddr[Chip], Data);
160 			if ((TC0110PCRAddr[Chip]&0xff0) == 0x370) // bad line
161 				bprintf(0, _T("A %x %X.\n"),TC0110PCRAddr[Chip], Data);
162 
163 			if (
164 				((TC0110PCRAddr[Chip]&0xff0) == 0x370) || // Level 4 Pal Lines, data written here is weird...
165 				((TC0110PCRAddr[Chip]&0xff0) == 0x380) ||
166 				((TC0110PCRAddr[Chip]&0xff0) == 0x450) ||
167 				((TC0110PCRAddr[Chip]&0xff0) == 0x520)) {
168 			   // TC0110PCRStep1RBSwapWordWrite(Chip, Offset, Data);
169 				//if (Data) Data |= 0x4900;
170 				//TC0110PCRStep1RBSwapWordWrite(Chip, Offset, Data);
171 				//return;
172 			}
173 			if (((TC0110PCRAddr[Chip]&0xff0) == 0x560) || // Level 1 fix
174 				((TC0110PCRAddr[Chip]&0xff0) == 0x620) ||
175 				((TC0110PCRAddr[Chip]&0xff0) == 0x5e0)) { // why are these addresses swapped?
176 				TC0110PCRStep1RBSwapWordWrite(Chip, Offset, Data);
177 				return;
178 			}
179 
180 			UINT16 *PalRam = (UINT16*)TC0110PCRRam[Chip];
181 			INT32 r, g, b;
182 
183 			PalRam[TC0110PCRAddr[Chip]] = Data;
184 
185 			r = pal5bit(Data >>  0);
186 			g = pal5bit(Data >>  5);
187 			b = pal5bit(Data >> 10);
188 
189 			TC0110PCRPalette[TC0110PCRAddr[Chip] | PaletteOffset] = BurnHighCol(r, g, b, 0);
190 			return;
191 		}
192 	}
193 }
194 #endif
195 
TC0110PCRStep14rbgWordWrite(INT32 Chip,INT32 Offset,UINT16 Data)196 void TC0110PCRStep14rbgWordWrite(INT32 Chip, INT32 Offset, UINT16 Data)
197 {
198 	INT32 PaletteOffset = Chip * 0x1000;
199 
200 	switch (Offset) {
201 		case 0: {
202 			TC0110PCRAddr[Chip] = Data & 0xfff;
203 			return;
204 		}
205 
206 		case 1: {
207 			UINT16 *PalRam = (UINT16*)TC0110PCRRam[Chip];
208 			INT32 r, g, b;
209 
210 			PalRam[TC0110PCRAddr[Chip]] = Data;
211 
212 			r = pal4bit(Data >>  0);
213 			g = pal4bit(Data >>  4);
214 			b = pal4bit(Data >>  8);
215 
216 			TC0110PCRPalette[TC0110PCRAddr[Chip] | PaletteOffset] = BurnHighCol(r, g, b, 0);
217 			return;
218 		}
219 	}
220 }
221 
TC0110PCRStep1RBSwapWordWrite(INT32 Chip,INT32 Offset,UINT16 Data)222 void TC0110PCRStep1RBSwapWordWrite(INT32 Chip, INT32 Offset, UINT16 Data)
223 {
224 	INT32 PaletteOffset = Chip * 0x1000;
225 
226 	switch (Offset) {
227 		case 0: {
228 			TC0110PCRAddr[Chip] = Data & 0xfff;
229 			return;
230 		}
231 
232 		case 1: {
233 			UINT16 *PalRam = (UINT16*)TC0110PCRRam[Chip];
234 			INT32 r, g, b;
235 
236 			PalRam[TC0110PCRAddr[Chip]] = Data;
237 
238 			r = pal5bit(Data >> 10);
239 			g = pal5bit(Data >>  5);
240 			b = pal5bit(Data >>  0);
241 
242 			TC0110PCRPalette[TC0110PCRAddr[Chip] | PaletteOffset] = BurnHighCol(r, g, b, 0);
243 			return;
244 		}
245 	}
246 }
247 
TC0110PCRReset()248 void TC0110PCRReset()
249 {
250 	TC0110PCRAddr[0] = 0;
251 }
252 
TC0110PCRInit(INT32 Num,INT32 nNumColours)253 void TC0110PCRInit(INT32 Num, INT32 nNumColours)
254 {
255 	for (INT32 i = 0; i < Num; i++) {
256 		TC0110PCRRam[i] = (UINT8*)BurnMalloc(0x4000);
257 		memset(TC0110PCRRam[i], 0, 0x4000);
258 	}
259 
260 	TC0110PCRPalette = (UINT32*)BurnMalloc(nNumColours * sizeof(UINT32));
261 	memset(TC0110PCRPalette, 0, nNumColours);
262 
263 	TC0110PCRTotalColours = nNumColours;
264 
265 	TC0110PCRCount = Num; // dink
266 
267 	TaitoIC_TC0110PCRInUse = 1;
268 }
269 
TC0110PCRExit()270 void TC0110PCRExit()
271 {
272 	for (INT32 i = 0; i < MAX_TC0110PCR; i++) {
273 		BurnFree(TC0110PCRRam[i]);
274 		TC0110PCRAddr[i] = 0;
275 	}
276 
277 	BurnFree(TC0110PCRPalette);
278 
279 	TC0110PCRTotalColours = 0;
280 	TC0110PCRCount = 0; // dink
281 }
282 
TC0110PCRScan(INT32 nAction)283 void TC0110PCRScan(INT32 nAction)
284 {
285 	struct BurnArea ba;
286 
287 	if (nAction & ACB_MEMORY_RAM) {
288 		for (INT32 i = 0; i < TC0110PCRCount; i++) {
289 			memset(&ba, 0, sizeof(ba));
290 			ba.Data	  = TC0110PCRRam[i];
291 			ba.nLen	  = 0x4000;
292 			ba.szName = "TC0110PCR Ram";
293 			BurnAcb(&ba);
294 		}
295 		memset(&ba, 0, sizeof(ba));
296 		ba.Data	  = TC0110PCRPalette;
297 		ba.nLen	  = TC0110PCRTotalColours * sizeof(UINT32);
298 		ba.szName = "TC0110PCR Palette";
299 		BurnAcb(&ba);
300 	}
301 
302 	if (nAction & ACB_DRIVER_DATA) {
303 		SCAN_VAR(TC0110PCRAddr);
304 	}
305 }
306