1 #define VERBOSE 0
2
3 /***************************************************************************
4
5 TODO:
6 - It seems shadows can both affect underlying sprites and not. This is currently
7 hardcoded in the drivers; there might be a control bit somewhere.
8 Games requiring shadows to affect sprites behind them:
9 - Surprise Attack (dark glass walls in level 3)
10 - 88 Games (angle indicator in the long jump event).
11 - Sunset Riders (bull's eye in the saloon cutscene)
12 Games requiring shadows to NOT affect sprites behind them:
13 - Asterix (Asterix's shadow would be over his feet otherwise)
14 - X-Men is dubious, see enemies halfway through level 1 coming from above with
15 boulders over their heads.
16
17 - scrollcontrol = 30 in Golfing Greats (leader board)
18
19 - detatwin: sprites are left on screen during attract mode
20
21
22 Emulated
23 |
24 board #|year CPU tiles sprites priority palette other
25 -----|---- ------- ------------- ------------- ------ ------ ----------------
26 Hyper Crash GX401 1985 GX400
27 Twinbee GX412*1985 68000 GX400
28 Yie Ar Kung Fu GX407*1985 6809
29 Gradius / Nemesis GX456*1985 68000 GX400
30 Shao-lins Road GX477*1985 6809
31 Jail Break GX507*1986 KONAMI-1 005849 PROMs
32 Finalizer GX523*1985 KONAMI-1 005885 PROMs
33 Konami's Ping Pong GX555*1985 Z80
34 Iron Horse GX560*1986 6809 005885 PROMs
35 Konami GT GX561*1985 68000 GX400
36 Green Beret GX577*1985 Z80 005849 PROMs
37 Galactic Warriors GX578*1985 68000 GX400
38 Salamander GX587*1986 68000 GX400
39 WEC Le Mans 24 GX602*1986 2x68000
40 BAW / Black Panther GX604*1987 68000 GX400 007593
41 Combat School / GX611*1987 6309 007121(x2) 007327
42 Boot Camp
43 Rock 'n Rage / GX620*1986 6309 007342 007420 007327
44 Koi no Hotrock
45 Mr Kabuki/Mr Goemon GX621*1986 Z80 005849
46 Jackal GX631*1986 6809? 005885(x2)
47 Contra / Gryzor GX633*1987 6809? 007121(x2) 007593
48 Flak Attack GX669*1987 6309 007121 007327 007452
49 Devil World / Dark GX687*1987 2x68000 TWIN16
50 Adventure / Majuu no Oukoku
51 Double Dribble GX690*1986 3x6809 005885(x2) 007327 007452
52 Kitten Kaboodle / GX712*1988 GX400 007593 051550
53 Nyan Nyan Panic
54 Chequered Flag GX717*1988 052001 051960 051937(x2) 051316(x2) (roz) 051733 (protection)
55 Fast Lane GX752*1987 6309 007121 051733 (protection) 007801
56 Hot Chase GX763*1988 2x68000 051316(x3) (roz) 007634 007635 007558 007557
57 Rack 'Em Up / GX765*1987 6309 007342 007420 007327 007324
58 The Hustler
59 Haunted Castle GX768*1988 052001 007121(x2) 007327
60 Ajax / Typhoon GX770*1987 6309+ 052109 051962 051960 051937 PROM 007327 051316 (roz)
61 052001
62 Labyrinth Runner / GX771*1987 6309 007121 007593 051733 (protection) 051550
63 Trick Trap
64 Super Contra GX775*1988 052001 052109 051962 051960 051937 PROM 007327
65 Battlantis GX777*1987 6309 007342 007420 007327 007324
66 Vulcan Venture / GX785*1988 2x68000 TWIN16
67 Gradius 2
68 City Bomber GX787*1987 68000 GX400 007593 051550
69 Over Drive GX789*1990 2x68000 053247 053246 053251 051316(x2) (roz) 053249 053250(x2) (road) 053252(*)
70 Hyper Crash GX790 1987
71 Blades of Steel GX797*1987 6309 007342 007420 007327 051733 (protection)
72 The Main Event GX799*1988 6309 052109 051962 051960 051937 PROM
73 Missing in Action GX808*1989 68000 052109 051962 051960 051937 PROM
74 Missing in Action J GX808*1989 2x68000 TWIN16
75 Crime Fighters GX821*1989 052526 052109 051962 051960 051937 PROM
76 Special Project Y GX857*1989 6309 052109 051962 051960 051937 PROM 052591 (protection)
77 '88 Games GX861*1988 052001 052109 051962 051960 051937 PROM 051316 (roz)
78 Final Round / GX870*1988 1x68000 TWIN16?
79 Hard Puncher
80 Thunder Cross GX873*1988 052001 052109 051962 051960 051937 PROM 007327 052591 (protection)
81 Aliens GX875*1990 052526 052109 051962 051960 051937 PROM
82 Gang Busters GX878*1988 052526 052109 051962 051960 051937 PROM
83 Devastators GX890*1988 6309 052109 051962 051960 051937 PROM 007324 051733 (protection)
84 Bottom of the Ninth GX891*1989 6809 052109 051962 051960 051937 PROM 051316 (roz)
85 Cue Brick GX903*1989 68000 052109 051962 051960 051937 PROM
86 Cue Brick GX903*1989 2x68000 TWIN16
87 Punk Shot GX907*1990 68000 052109 051962 051960 051937 053251
88 Ultraman GX910*1991 68000 ------ ------ 051960 051937 PROM 051316(x3) (roz) 051550
89 Surprise Attack GX911*1990 053248 052109 051962 053245 053244 053251
90 Lightning Fighters /GX939*1990 68000 052109 051962 053245 053244 053251
91 Trigon
92 Gradius 3 GX945*1989 2x68000 052109 051962 051960 051937 PROM
93 Parodius GX955*1990 053248 052109 051962 053245 053244 053251
94 TMNT GX963*1989 68000 052109 051962 051960 051937 PROM
95 Block Hole GX973*1989 052526 052109 051962 051960 051937 PROM
96 Escape Kids GX975*1991 053248 052109 051962 053247 053246 053251 053252(*)
97 Rollergames GX999*1991 053248 ------ ------ 053245 053244 051316 (roz) 053252(*)
98 Bells & Whistles / GX060*1991 68000 052109 051962 053245 053244 053251 054000 (collision)
99 Detana!! Twin Bee
100 Golfing Greats GX061*1991 68000 052109 051962 053245 053244 053251 053936 (roz+)
101 TMNT 2 GX063*1991 68000 052109 051962 053245 053244 053251 053990 (protection) 051550
102 Sunset Riders GX064*1991 68000 052109 051962 053245 053244 053251 054358
103 X-Men GX065*1992 68000 052109 051962 053247 053246 053251 054539 (sound)
104 XEXEX GX067*1991 68000 054157 054156 053247 053246 053251 053250?("road") 054338 (alpha blending) 054539 (sound)
105 Asterix GX068*1992 68000 054157 054156 053245 053244 053251 054358
106 G.I. Joe GX069*1992 68000 054157 054156 053247 053246 053251 054539 (sound)
107 The Simpsons GX072*1991 053248 052109 051962 053247 053246 053251
108 Thunder Cross 2 GX073*1991 68000 052109 051962 051960 051937 053251 054000 (collision)
109 Vendetta / GX081*1991 053248 052109 051962 053247 053246 053251 054000 (collision)
110 Crime Fighters 2
111 Premier Soccer GX101*1993 68000 052109 051962 053245 053244 053251 053936 (roz+) 054986
112 Hexion GX122*1992 Z80 052591 (protection) 053252(*)
113 Entapous / GX123*1993 68000 054157 054156 055673 053246 055555 053252(*) 054000 053936 (roz+)
114 Gaiapolis
115 Mystic Warrior GX128*1993 68000 054157 054156 055673 053246 055555 054338 (alpha blending) 053252(*) 054539(x2) (sound)
116 Cowboys of Moo Mesa GX151*1992 68000 054157 054156 053247 053246 053251 053252(*) 054338 (alpha blending) 053990 (protection)
117 Violent Storm GX168*1993 68000 054157 054156 055673 053246 055555 054338 (alpha blending) 055550 054539(x2) (sound)
118 Monster Maulers / GX170*1993 68000 054157 054156 055673 053246 055555 053252(*) 055550 054338 (alpha blending) 054539 (sound) 053936 (roz+)
119 Ultimate Battler Dadandarn
120 Bucky 'O Hare GX173*1992 68000 054157 054156 053247 053246 053251 054338 (alpha blending) 054539 (sound)
121 Potrio GX174 1992
122 Lethal Enforcers GX191*1992 6309 054157(x2) 054156 053245 053244(x2) 054000 054539 (sound)
123 Metamorphic Force GX224*1993 68000 054157 054157 055673 053246 055555
124 Martial Champion GX234*1993 68000 054157 054156 055673 053246 055555 053252(*) 054338 (alpha blending) 053990 054539 (sound)
125 Run and Gun GX247*1993 68000 (TTL tilemap) 055673 053246 053253(x2) 053252(*) 053936 (roz+) 054539(x2) (sound)
126 Quiz Gakumon no GX248*1993 68000 052109 051962 053245 053244 053251 053990 (protection) 051550 - same board as TMNT2
127 Susume
128 Polygonet Commander GX305+1993 68020 (TTL tilemap) XC56156-40(3D DSP) 054009(x2) 054010(x2) 054539 (sound)
129 System GX (ver 1) GX300*1993 68020 056832 054156 055673 053246 055555 054338 (alpha blending) 054539(x2) (sound) 053252(*) 053936 (optional on ROM board, roz+)
130 System GX (ver 2) GX300*1995 68020 056832 058143 055673 058142 055555 058144 (alpha blending) 058141 (sound) 053252(*) 053936 (optional on ROM board, roz+)
131 Beatmania DJ Main GX858+1996 68020 056832 058143 056766 055555 058144 (alpha blending) 058141 (sound) 053252(*)
132 Tail to Nose *1989 68000 V-System 051316 (roz)
133 F-1 Grand Prix *1991 2x68000 V-System 053936 (roz+)
134 F-1 Grand Prix Part II *1992 2x68000 V-System 053936 (roz+)
135 Lethal Crash Race *1993 68000 V-System 053936 (roz+)
136 Super Slams *1995 68000 V-System 053936 (roz+)
137 Blazing Tornado *1991 68000 Metro 053936 (roz+)
138 Dragonball Z 2 *1994 68000 054157 054156 053247 053246 053251(x2) 053936(x2) (roz+) 053252(*)
139
140
141 Notes:
142 * 053252 seems to be just a timing/interrupt controller (see Vendetta schematics).
143
144 - Old games use 051961 instead of 052109, it is an earlier version functionally
145 equivalent (maybe 052109 had bugs fixed). The list always shows 052109 because
146 the two are exchangeable and 052109's are found also on original boards whose
147 schematics show a 051961.
148
149 - Starting with the version 2 System GX mainboard, the following chip substitutions took place.
150 All "new" chips are equivalent to their older counterparts, but are in a smaller package (and
151 presumably are made on a smaller process). The exception is the 058141, which is equivalent
152 to 2 54539s (and yet takes less board space than even 1).
153
154 058141 = 054539 (x2) (2 sound chips in one)
155 058142 = 053246 (sprites)
156 058143 = 054156 (tiles)
157 058144 = 054338 (alpha blending)
158
159
160
161 Status of the ROM tests in the emulated games:
162
163 Chequered Flag pass
164 Ajax / Typhoon pass
165 Super Contra pass
166 Over Drive fails 16..20 (053250)
167 The Main Event pass
168 Missing in Action pass
169 Crime Fighters pass
170 Special Project Y pass
171 Konami 88 pass
172 Thunder Cross pass
173 Aliens pass
174 Gang Busters pass
175 Devastators pass
176 Bottom of the Ninth pass
177 Punk Shot pass
178 Surprise Attack fails D05-6 (052109) because it uses mirror addresses to
179 select banks, and supporting those addresses breaks the
180 normal game ;-(
181 Lightning Fighters pass
182 Gradius 3 pass
183 Parodius pass
184 TMNT pass
185 Block Hole pass
186 Escape Kids pass
187 Rollergames pass
188 Bells & Whistles pass
189 Golfing Greats pass
190 TMNT 2 pass
191 Sunset Riders pass
192 X-Men pass
193 The Simpsons pass
194 Thunder Cross 2 pass
195 Xexex pass
196 Asterix pass
197 GiJoe pass
198 Vendetta pass
199 Premier Soccer fails 16D 18D 18F (053936)
200 Hexion pass
201 Run and Gun fails 36M (053936) 2U 2Y 5U 5Y (sprites)
202 Quiz Gakumon no Susume pass
203 Dragonball Z 2 fails
204
205
206 THE FOLLOWING INFORMATION IS PRELIMINARY AND INACCURATE. DON'T RELY ON IT.
207
208
209 005885
210 ------
211 Some games use two of these in pair. Jackal even puts together the two 4bpp
212 tilemaps to form a single 8bpp one.
213 It manages sprites and 32x32 or 64x32 tilemap (only Double Dribble uses the
214 64x32 one).
215 The chip also generates clock and interrupt signals suitable for a 6809.
216 It uses 0x2000 bytes of RAM for the tilemaps and sprites, and an additional
217 0x100 bytes, maybe for scroll RAM and line buffers. The maximum addressable
218 ROM is 0x20000 bytes (addressed 16 bits at a time). Tile and sprite data both
219 come from the same ROM space. Double Dribble and Jackal have external circuitry
220 to extend the limits and use separated addressing spaces for sprites and tiles.
221 All games use external circuitry to reuse one or both the tile flip attributes
222 as an additional address bit.
223 Two 256x4 lookup PROMs are also used to increase the color combinations.
224 All tilemap / sprite priority handling is done internally and the chip exports
225 5 bits of color code, composed of 1 bit indicating tile or sprite, and 4 bits
226 of ROM data remapped through the PROM.
227
228 inputs:
229 - address lines (A0-A13)
230 - data lines (DB0-DB7)
231 - misc interface stuff
232 - data from the gfx ROMs (RDL0-RDL7, RDU0-RDU7)
233 - data from the tile lookup PROMs (VCD0-VCD3)
234 - data from the sprite lookup PROMs (OCD0-OCD3)
235
236 outputs:
237 - address lines for tilemap RAM (AX0-AX12)
238 - data lines for tilemap RAM (VO0-VO7)
239 - address lines for the small RAM (FA0-FA7)
240 - data lines for the small RAM (FD0-FD7)
241 - address lines for the gfx ROMs (R0-R15)
242 - address lines for the tile lookup PROMs (VCF0-VCF3, VCB0-VCB3)
243 - address lines for the sprite lookup PROMs (OCB0-OCB3, OCF0-OCF3)
244 - NNMI, NIRQ, NFIR, NCPE, NCPQ, NEQ for the main CPU
245 - misc interface stuff
246 - color code to be output on screen (COL0-COL4)
247
248
249 control registers
250 000: scroll y
251 001: scroll x (low 8 bits)
252 002: -------x scroll x (high bit)
253 ----xxx- row/colscroll control
254 000 = solid scroll (finalizr, ddribble bg)
255 100 = solid scroll (jackal)
256 001 = ? (ddribble fg)
257 011 = colscroll (jackal high scores)
258 101 = rowscroll (ironhors, jackal map)
259 003: ------xx high bits of the tile code
260 -----x-- unknown (finalizr)
261 ----x--- selects sprite buffer (and makes a copy to a private buffer?)
262 --x----- unknown (ironhors)
263 -x------ unknown (ironhors)
264 x------- unknown (ironhors, jackal)
265 004: -------x nmi enable
266 ------x- irq enable
267 -----x-- firq enable
268 ----x--- flip screen
269
270
271
272 007121
273 ------
274 This is an interesting beast. It is an evolution of the 005885, with more
275 features. Many games use two of these in pair.
276 It manages sprites and two 32x32 tilemaps. The tilemaps can be joined to form
277 a single 64x32 one, or one of them can be moved to the side of screen, giving
278 a high score display suitable for vertical games.
279 The chip also generates clock and interrupt signals suitable for a 6809.
280 It uses 0x2000 bytes of RAM for the tilemaps and sprites, and an additional
281 0x100 bytes, maybe for scroll RAM and line buffers. The maximum addressable
282 ROM is 0x80000 bytes (addressed 16 bits at a time). Tile and sprite data both
283 come from the same ROM space.
284 Two 256x4 lookup PROMs are also used to increase the color combinations.
285 All tilemap / sprite priority handling is done internally and the chip exports
286 7 bits of color code, composed of 2 bits of palette bank, 1 bit indicating tile
287 or sprite, and 4 bits of ROM data remapped through the PROM.
288
289 inputs:
290 - address lines (A0-A13)
291 - data lines (DB0-DB7)
292 - misc interface stuff
293 - data from the gfx ROMs (RDL0-RDL7, RDU0-RDU7)
294 - data from the tile lookup PROMs (VCD0-VCD3)
295 - data from the sprite lookup PROMs (OCD0-OCD3)
296
297 outputs:
298 - address lines for tilemap RAM (AX0-AX12)
299 - data lines for tilemap RAM (VO0-VO7)
300 - address lines for the small RAM (FA0-FA7)
301 - data lines for the small RAM (FD0-FD7)
302 - address lines for the gfx ROMs (R0-R17)
303 - address lines for the tile lookup PROMs (VCF0-VCF3, VCB0-VCB3)
304 - address lines for the sprite lookup PROMs (OCB0-OCB3, OCF0-OCF3)
305 - NNMI, NIRQ, NFIR, NE, NQ for the main CPU
306 - misc interface stuff
307 - color code to be output on screen (COA0-COA6)
308
309
310 control registers
311 000: scroll x (low 8 bits)
312 001: -------x scroll x (high bit)
313 ------x- enable rowscroll? (combasc)
314 ----x--- this probably selects an alternate screen layout used in combat
315 school where tilemap #2 is overlayed on front and doesn't scroll.
316 The 32 lines of the front layer can be individually turned on or
317 off using the second 32 bytes of scroll RAM.
318 002: scroll y
319 003: -------x bit 13 of the tile code
320 ------x- unknown (contra)
321 -----x-- might be sprite / tilemap priority (0 = sprites have priority)
322 (combat school, contra, haunted castle(0/1), labyrunr)
323 ----x--- selects sprite buffer (and makes a copy to a private buffer?)
324 ---x---- screen layout selector:
325 when this is set, 5 columns are added on the left of the screen
326 (that means 5 rows at the top for vertical games), and the
327 rightmost 2 columns are chopped away.
328 Tilemap #2 is used to display the 5 additional columns on the
329 left. The rest of tilemap #2 is not used and can be used as work
330 RAM by the program.
331 The visible area becomes 280x224.
332 Note that labyrunr changes this at runtime, setting it during
333 gameplay and resetting it on the title screen and crosshatch.
334 --x----- might be sprite / tilemap priority (0 = sprites have priority)
335 (combat school, contra, haunted castle(0/1), labyrunr)
336 -x------ Chops away the leftmost and rightmost columns, switching the
337 visible area from 256 to 240 pixels. This is used by combasc on
338 the scrolling stages, and by labyrunr on the title screen.
339 At first I thought that this enabled an extra bank of 0x40
340 sprites, needed by combasc, but labyrunr proves that this is not
341 the case
342 x------- unknown (contra)
343 004: ----xxxx bits 9-12 of the tile code. Only the bits enabled by the following
344 mask are actually used, and replace the ones selected by register
345 005.
346 xxxx---- mask enabling the above bits
347 005: selects where in the attribute byte to pick bits 9-12 of the tile code,
348 output to pins R12-R15. The bit of the attribute byte to use is the
349 specified bit (0-3) + 3, that is one of bits 3-6. Bit 7 is hardcoded as
350 bit 8 of the code. Bits 0-2 are used for the color, however note that
351 some games use bit 3 as well (see below).
352 ------xx attribute bit to use for tile code bit 9
353 ----xx-- attribute bit to use for tile code bit 10
354 --xx---- attribute bit to use for tile code bit 11
355 xx------ attribute bit to use for tile code bit 12
356 006: ----xxxx select additional effect for bits 3-6 of the tile attribute (the
357 same ones indexed by register 005). Note that an attribute bit
358 can therefore be used at the same time to be BOTH a tile code bit
359 and an additional effect.
360 -------x bit 3 of attribute is bit 3 of color (combasc, fastlane, flkatck)
361 ------x- bit 4 of attribute is tile flip X (assumption - no game uses this)
362 -----x-- bit 5 of attribute is tile flip Y (flkatck)
363 ----x--- bit 6 of attribute is tile priority over sprites (combasc, hcastle,
364 labyrunr)
365 Note that hcastle sets this bit for layer 0, and bit 6 of the
366 attribute is also used as bit 12 of the tile code, however that
367 bit is ALWAYS set throughout the game.
368 combasc uses the bit in the "graduation" scene during attract mode,
369 to place soldiers behind the stand.
370 Use in labyrunr has not been investigated yet.
371 --xx---- palette bank (both tiles and sprites, see contra)
372 007: -------x nmi enable
373 ------x- irq enable
374 -----x-- firq enable
375 ----x--- flip screen
376 ---x---- unknown (contra, labyrunr)
377
378
379
380 007342
381 ------
382 The 007342 manages 2 64x32 scrolling tilemaps with 8x8 characters, and
383 optionally generates timing clocks and interrupt signals. It uses 0x2000
384 bytes of RAM, plus 0x0200 bytes for scrolling, and a variable amount of ROM.
385 It cannot read the ROMs.
386
387 control registers
388 000: ------x- INT control
389 ---x---- flip screen (TODO: doesn't work with thehustl)
390 001: Used for banking in Rock'n'Rage
391 002: -------x MSB of x scroll 1
392 ------x- MSB of x scroll 2
393 ---xxx-- layer 1 row/column scroll control
394 000 = disabled
395 010 = unknown (bladestl shootout between periods)
396 011 = 32 columns (Blades of Steel)
397 101 = 256 rows (Battlantis, Rock 'n Rage)
398 x------- enable sprite wraparound from bottom to top (see Blades of Steel
399 high score table)
400 003: x scroll 1
401 004: y scroll 1
402 005: x scroll 2
403 006: y scroll 2
404 007: not used
405
406
407 007420
408 ------
409 Sprite generator. 8 bytes per sprite with zoom. It uses 0x200 bytes of RAM,
410 and a variable amount of ROM. Nothing is known about its external interface.
411
412
413
414 052109/051962
415 -------------
416 These work in pair.
417 The 052109 manages 3 64x32 scrolling tilemaps with 8x8 characters, and
418 optionally generates timing clocks and interrupt signals. It uses 0x4000
419 bytes of RAM, and a variable amount of ROM. It cannot read the ROMs:
420 instead, it exports 21 bits (16 from the tilemap RAM + 3 for the character
421 raster line + 2 additional ones for ROM banking) and these are externally
422 used to generate the address of the required data on the ROM; the output of
423 the ROMs is sent to the 051962, along with a color code. In theory you could
424 have any combination of bits in the tilemap RAM, as long as they add to 16.
425 In practice, all the games supported so far standardize on the same format
426 which uses 3 bits for the color code and 13 bits for the character code.
427 The 051962 multiplexes the data of the three layers and converts it into
428 palette indexes and transparency bits which will be mixed later in the video
429 chain.
430 Priority is handled externally: these chips only generate the tilemaps, they
431 don't mix them.
432 Both chips are interfaced with the main CPU. When the RMRD pin is asserted,
433 the CPU can read the gfx ROM data. This is done by telling the 052109 which
434 dword to read (this is a combination of some banking registers, and the CPU
435 address lines), and then reading it from the 051962.
436
437 052109 inputs:
438 - address lines (AB0-AB15, AB13-AB15 seem to have a different function)
439 - data lines (DB0-DB7)
440 - misc interface stuff
441
442 052109 outputs:
443 - address lines for the private RAM (RA0-RA12)
444 - data lines for the private RAM (VD0-VD15)
445 - NMI, IRQ, FIRQ for the main CPU
446 - misc interface stuff
447 - ROM bank selector (CAB1-CAB2)
448 - character "code" (VC0-VC10)
449 - character "color" (COL0-COL7); used foc color but also bank switching and tile
450 flipping. Exact meaning depends on externl connections. All evidence indicates
451 that COL2 and COL3 select the tile bank, and are replaced with the low 2 bits
452 from the bank register. The top 2 bits of the register go to CAB1-CAB2.
453 However, this DOES NOT WORK with Gradius III. "color" seems to pass through
454 unaltered.
455 - layer A horizontal scroll (ZA1H-ZA4H)
456 - layer B horizontal scroll (ZB1H-ZB4H)
457 - ????? (BEN)
458
459 051962 inputs:
460 - gfx data from the ROMs (VC0-VC31)
461 - color code (COL0-COL7); only COL4-COL7 seem to really be used for color; COL0
462 is tile flip X.
463 - layer A horizontal scroll (ZA1H-ZA4H)
464 - layer B horizontal scroll (ZB1H-ZB4H)
465 - let main CPU read the gfx ROMs (RMRD)
466 - address lines to be used with RMRD (AB0-AB1)
467 - data lines to be used with RMRD (DB0-DB7)
468 - ????? (BEN)
469 - misc interface stuff
470
471 051962 outputs:
472 - FIX layer palette index (DFI0-DFI7)
473 - FIX layer transparency (NFIC)
474 - A layer palette index (DSA0-DSAD); DSAA-DSAD seem to be unused
475 - A layer transparency (NSAC)
476 - B layer palette index (DSB0-DSBD); DSBA-DSBD seem to be unused
477 - B layer transparency (NSBC)
478 - misc interface stuff
479
480
481 052109 memory layout:
482 0000-07ff: layer FIX tilemap (attributes)
483 0800-0fff: layer A tilemap (attributes)
484 1000-1fff: layer B tilemap (attributes)
485 180c-1833: A y scroll
486 1a00-1bff: A x scroll
487 1c00 : ?
488 1c80 : row/column scroll control
489 ------xx layer A row scroll
490 00 = disabled
491 01 = disabled? (gradius3, vendetta)
492 10 = 32 lines
493 11 = 256 lines
494 -----x-- layer A column scroll
495 0 = disabled
496 1 = 64 (actually 40) columns
497 ---xx--- layer B row scroll
498 --x----- layer B column scroll
499 surpratk sets this register to 70 during the second boss. There is
500 nothing obviously wrong so it's not clear what should happen.
501 glfgreat sets it to 30 when showing the leader board
502 1d00 : bits 0 & 1 might enable NMI and FIRQ, not sure
503 : bit 2 = IRQ enable
504 1d80 : ROM bank selector bits 0-3 = bank 0 bits 4-7 = bank 1
505 1e00 : ROM subbank selector for ROM testing
506 1e80 : bit 0 = flip screen (applies to tilemaps only, not sprites)
507 : bit 1 = set by crimfght, mainevt, surpratk, xmen, mia, punkshot, thndrx2, spy
508 : it seems to enable tile flip X, however flip X is handled by the
509 : 051962 and it is not hardwired to a specific tile attribute.
510 : Note that xmen, punkshot and thndrx2 set the bit but the current
511 : drivers don't use flip X and seem to work fine.
512 : bit 2 = enables tile flip Y when bit 1 of the tile attribute is set
513 1f00 : ROM bank selector bits 0-3 = bank 2 bits 4-7 = bank 3
514 2000-27ff: layer FIX tilemap (code)
515 2800-2fff: layer A tilemap (code)
516 3000-37ff: layer B tilemap (code)
517 3800-3807: nothing here, so the chip can share address space with a 051937
518 380c-3833: B y scroll
519 3a00-3bff: B x scroll
520 3c00-3fff: nothing here, so the chip can share address space with a 051960
521 3d80 : mirror of 1d80, but ONLY during ROM test (surpratk)
522 3e00 : mirror of 1e00, but ONLY during ROM test (surpratk)
523 3f00 : mirror of 1f00, but ONLY during ROM test (surpratk)
524 EXTRA ADDRESSING SPACE USED BY X-MEN:
525 4000-47ff: layer FIX tilemap (code high bits)
526 4800-4fff: layer A tilemap (code high bits)
527 5000-57ff: layer B tilemap (code high bits)
528
529 The main CPU doesn't have direct acces to the RAM used by the 052109, it has
530 to through the chip.
531
532
533
534 054156/054157
535 054156/056832
536 -------------
537
538 [Except for tilemap sizes, all numbers are in hex]
539
540 These work in pairs. Similar in principle to the 052109/051962, they
541 manage 4 64x32 or 64x64 tilemaps. They also handle linescroll on each
542 layer, and optional tile banking. They use 4000 to 10000 bytes of
543 RAM, organized in 1000 or 2000 bytes banks.
544
545 The 56832 is a complete superset of the 54157 and supports higher color
546 depths (the 156/157 combo only goes to 5 bpp, the 156/832 combo goes to 8bpp).
547
548 These chips work in a fairly unusual way. There are 4, 8, or 16 pages of VRAM, arranged
549 conceptually in a 4x4 2 dimensional grid. Each page is a complete 64x32 tile tilemap.
550
551 The 4 physical tilemaps A, B, C, and, D are made up of these pages "glued together".
552 Each physical tilemap has an X and Y position in the 4x4 page grid indicating where
553 the page making up it's upper left corner is, as well as a width and height in pages.
554 If two tilemaps try to use the same page, the higher-letter one wins and the lower-letter
555 one is disabled completely. E.g. A > B > C > D, so if A and B both try to use the
556 same page only A will be displayed. Some games rely on this behavior to implicitly
557 disable tilemaps which otherwise should be displayed.
558
559 Tile encoding 2 bytes/tile (banks of 1000 bytes):
560 pppx bbcc cccc cccc
561 p = color palette
562 x = flip x
563 b = tile bank (0..3)
564 c = tile code (0..3ff)
565
566
567 Tile encoding 4 bytes/tile (banks of 2000 bytes):
568 ---- ---- pppp --yx cccc cccc cccc cccc
569 p = color palette
570 x = flip x
571 y = flip y
572 b = tile bank (0..3)
573 c = tile code (0..3ff)
574
575
576 Communication with these ics go through 4 memory zones:
577 1000/2000 bytes: access to the currently selected ram bank
578 2000 bytes: readonly access the the currently select tile
579 rom bank for rom checksumming
580 40 bytes: writeonly access to the first register bank
581 8 bytes: writeonly access to the second register bank
582
583 One of the register banks is probably on the 054156, and the other on
584 the 054157.
585
586 First register bank map (offsets in bytes, '-' means unused):
587 00 ---- ---- ??yx ????
588 flip control
589
590 02 ---- ---- ???? ????
591 unknown
592
593 04 ---- ---- ???? ????
594 unknown (bit 1 may be bank count selection, 0 in xexex, 1 everywhere
595 else)
596
597 06 ---- ---- ???? ???e
598 enable irq
599
600 08 ---- ---- ???? ????
601 unknown
602
603 0a ---- ---- 3322 1100
604 linescroll control, each pair of bits indicates the mode for the
605 corresponding layer:
606 0: per-line linescroll
607 1: unused/unknown
608 2: per-8 lines linescroll
609 3: no linescroll
610
611 0c ---- ---- ???? ????
612 unknown (bit 1 may be bank size selection, 1 in asterix, 0 everywhere
613 else)
614
615 0e ---- ---- ---- ----
616
617 10-13 ---- ---- ---y y-hh
618 layer Y position in the VRAM grid and height in pages
619
620 14-17 ---- ---- ---x x-ww
621 layer X position in the VRAM grid and width in pages
622 18-1f ---- ---- ???? ????
623
624 20-27 yyyy yyyy yyyy yyyy
625 scroll y position for each layer
626
627 28-2f xxxx xxxx xxxx xxxx
628 scroll x position for each layer
629
630 30 ---- ---- ---b b--b
631 linescroll ram bank selection
632
633 32 ---- ---- ---b b--b
634 cpu-accessible ram bank selection
635
636 34 bbbb bbbb bbbb bbbb
637 rom bank selection for checksumming (each bank is 0x2000 bytes)
638
639 36 ---- ---- ---- bbbb
640 secondary rom bank selection for checksumming when tile banking is
641 used
642
643 38 3333 2222 1111 0000
644 tile banking look up table. 4 bits are looked up here for the two
645 bits in the tile data.
646
647 3a ???? ???? ???? ????
648 unknown
649
650 3c ???? ???? ???? ????
651 unknown
652
653 3e ---- ---- ---- ----
654
655
656 Second register bank map:
657 00 ---- ---- ???? ????
658 unknown
659
660 02-07 are copies of the 02-07 registers from the first bank.
661
662
663 Linescroll:
664
665 The linescroll is controlled by the register 0b, and uses the data in
666 the ram bank pointed by register 31. The data for tilemap <n> starts
667 at offset 400*n in the bank for 1000 bytes ram banks, and 800*n+2 for
668 2000 bytes ram banks. The scrolling information is a vector of half
669 words separated by 1 word padding for 2000 bytes banks.
670
671 This is a source-oriented linescroll, i.e. the first word is
672 associated to the first one of the tilemap, not matter what the
673 current scrolly position is.
674
675 In per-line mode, each word indicates the horizontal scroll of the
676 associated line. Global scrollx is ignored.
677
678 In per-8 lines mode, each word associated to a line multiple of 8
679 indicates the horizontal scroll for that line and the 7 following
680 ones. The other 7 words are ignored. Global scrollx is ignored.
681
682
683
684 051960/051937
685 -------------
686 Sprite generators. Designed to work in pair. The 051960 manages the sprite
687 list and produces and address that is fed to the gfx ROMs. The data from the
688 ROMs is sent to the 051937, along with color code and other stuff from the
689 051960. The 051937 outputs up to 12 bits of palette index, plus "shadow" and
690 transparency information.
691 Both chips are interfaced to the main CPU, through 8-bit data buses and 11
692 bits of address space. The 051937 sits in the range 000-007, while the 051960
693 in the range 400-7ff (all RAM). The main CPU can read the gfx ROM data though
694 the 051937 data bus, while the 051960 provides the address lines.
695 The 051960 is designed to directly address 1MB of ROM space, since it produces
696 18 address lines that go to two 16-bit wide ROMs (the 051937 has a 32-bit data
697 bus to the ROMs). However, the addressing space can be increased by using one
698 or more of the "color attribute" bits of the sprites as bank selectors.
699 Moreover a few games store the gfx data in the ROMs in a format different from
700 the one expected by the 051960, and use external logic to reorder the address
701 lines.
702 The 051960 can also genenrate IRQ, FIRQ and NMI signals.
703
704 memory map:
705 000-007 is for the 051937, but also seen by the 051960
706 400-7ff is 051960 only
707 000 R bit 0 = unknown, looks like a status flag or something
708 aliens waits for it to be 0 before starting to copy sprite data
709 thndrx2 needs it to pulse for the startup checks to succeed
710 000 W bit 0 = irq enable/acknowledge?
711 bit 2 = nmi enable?
712 bit 3 = flip screen (applies to sprites only, not tilemaps)
713 bit 4 = unknown, used by Devastators, TMNT, Aliens, Chequered Flag, maybe others
714 aliens sets it just after checking bit 0, and before copying
715 the sprite data
716 bit 5 = enable gfx ROM reading
717 001 W Devastators sets bit 1, function unknown.
718 Ultraman sets the register to 0x0f.
719 None of the other games I tested seem to set this register to other than 0.
720 002-003 W selects the portion of the gfx ROMs to be read.
721 004 W Aliens uses this to select the ROM bank to be read, but Punk Shot
722 and TMNT don't, they use another bit of the registers above. Many
723 other games write to this register before testing.
724 It is possible that bits 2-7 of 003 go to OC0-OC5, and bits 0-1 of
725 004 go to OC6-OC7.
726 004-007 R reads data from the gfx ROMs (32 bits in total). The address of the
727 data is determined by the register above and by the last address
728 accessed on the 051960; plus bank switch bits for larger ROMs.
729 It seems that the data can also be read directly from the 051960
730 address space: 88 Games does this. First it reads 004 and discards
731 the result, then it reads from the 051960 the data at the address
732 it wants. The normal order is the opposite, read from the 051960 at
733 the address you want, discard the result, and fetch the data from
734 004-007.
735 400-7ff RW sprite RAM, 8 bytes per sprite
736
737
738
739 053245/053244
740 -------------
741 Sprite generators. The 053245 has a 16-bit data bus to the main CPU.
742 The sprites are buffered, a write to 006 activates to copy between the
743 main ram and the buffer.
744
745 053244 memory map (but the 053245 sees and processes them too):
746 000-001 W global X offset
747 002-003 W global Y offset
748 004 W unknown
749 005 W bit 0 = flip screen X
750 bit 1 = flip screen Y
751 bit 2 = unknown, used by Parodius
752 bit 4 = enable gfx ROM reading
753 bit 5 = unknown, used by Rollergames
754 006 RW accessing this register copies the sprite ram to the internal buffer
755 007 W unknown
756 008-009 W low 16 bits of the ROM address to read
757 00a-00b W high bits of the ROM address to read. 3 bits for most games, 1 for asterix
758 00c-00f R reads data from the gfx ROMs (32 bits in total). The address of the
759 data is determined by the registers above; plus bank switch bits for
760 larger ROMs.
761
762
763
764 053247/053246
765 -------------
766 Sprite generators. Nothing is known about their external interface.
767 The sprite RAM format is very similar to the 053245.
768
769 053246 memory map (but the 053247 sees and processes them too):
770 000-001 W global X offset
771 002-003 W global Y offset
772 004 W low 8 bits of the ROM address to read
773 005 W bit 0 = flip screen X
774 bit 1 = flip screen Y
775 bit 2 = unknown
776 bit 4 = interrupt enable
777 bit 5 = unknown
778 006-007 W high 16 bits of the ROM address to read
779
780 ???-??? R reads data from the gfx ROMs (16 bits in total). The address of the
781 data is determined by the registers above
782
783
784
785 051316
786 ------
787 Manages a 32x32 tilemap (16x16 tiles, 512x512 pixels) which can be zoomed,
788 distorted and rotated.
789 It uses two internal 24 bit counters which are incremented while scanning the
790 picture. The coordinates of the pixel in the tilemap that has to be drawn to
791 the current beam position are the counters / (2^11).
792 The chip doesn't directly generate the color information for the pixel, it
793 just generates a 24 bit address (whose top 16 bits are the contents of the
794 tilemap RAM), and a "visible" signal. It's up to external circuitry to convert
795 the address into a pixel color. Most games seem to use 4bpp graphics, but Ajax
796 uses 7bpp.
797 If the value in the internal counters is out of the visible range (0..511), it
798 is truncated and the corresponding address is still generated, but the "visible"
799 signal is not asserted. The external circuitry might ignore that signal and
800 still generate the pixel, therefore making the tilemap a continuous playfield
801 that wraps around instead of a large sprite.
802
803 control registers
804 000-001 X counter starting value / 256
805 002-003 amount to add to the X counter after each horizontal pixel
806 004-005 amount to add to the X counter after each line (0 = no rotation)
807 006-007 Y counter starting value / 256
808 008-009 amount to add to the Y counter after each horizontal pixel (0 = no rotation)
809 00a-00b amount to add to the Y counter after each line
810 00c-00d ROM bank to read, used during ROM testing
811 00e bit 0 = enable ROM reading (active low). This only makes the chip output the
812 requested address: the ROM is actually read externally, not through
813 the chip's data bus.
814 bit 1 = unknown
815 bit 2 = unknown
816 00f unused
817
818
819
820 053936
821 ------
822 Evolution of the 051316. The data bus is 16-bit instead of 8-bit.
823 When used in "simple" mode it can generate the same effects of the 051316, but it
824 doesn't have internal tilemap RAM, so it just generates a couple of X/Y coordinates
825 indicating the pixel to display at each moment. Therefore, the tilemap and tile
826 sizes are not fixed.
827 The important addition over the 051316 is 512x4 words of internal RAM used to control
828 rotation and zoom scanline by scanline instead that on the whole screen, allowing for
829 effects like linescroll (Super Slams) or 3D rotation of the tilemap (Golfing Greats,
830 Premier Soccer).
831
832 control registers
833 000 X counter starting value / 256
834 001 Y counter starting value / 256
835 002 ["simple" mode only] amount to add to the X counter after each line (0 = no rotation)
836 003 ["simple" mode only] amount to add to the Y counter after each line
837 004 ["simple" mode only] amount to add to the X counter after each horizontal pixel
838 005 ["simple" mode only] amount to add to the Y counter after each horizontal pixel (0 = no rotation)
839 006 x------- -------- when set, register (line*4)+2 must be multiplied by 256
840 -x------ -------- when set, registers 002 and 003 must be multiplied by 256
841 --xxxxxx -------- clipping for the generated address? usually 3F, Premier Soccer
842 sets it to 07 before penalty kicks
843 -------- x------- when set, register (line*4)+3 must be multiplied by 256
844 -------- -x------ when set, registers 004 and 005 must be multiplied by 256
845 -------- --xxxxxx clipping for the generated address? usually 3F, Premier Soccer
846 sets it to 0F before penalty kicks
847 007 -------- -x------ enable "super" mode
848 -------- --x----- unknown (enable address clipping from register 006?)
849 -------- ---x---- unknown
850 -------- ------x- (not sure) enable clipping with registers 008-00b
851 008 min x screen coordinate to draw to (only when enabled by register 7)
852 009 max x screen coordinate to draw to (only when enabled by register 7)
853 00a min y screen coordinate to draw to (only when enabled by register 7)
854 00b max y screen coordinate to draw to (only when enabled by register 7)
855 00c unknown
856 00d unknown
857 00e unknown
858 00f unknown
859
860 additional control from extra RAM:
861 (line*4)+0 X counter starting value / 256 (add to register 000)
862 (line*4)+1 Y counter starting value / 256 (add to register 001)
863 (line*4)+2 amount to add to the X counter after each horizontal pixel
864 (line*4)+3 amount to add to the Y counter after each horizontal pixel
865
866
867
868 053251
869 ------
870 Priority encoder.
871
872 The chip has inputs for 5 layers (CI0-CI4); only 4 are used (CI1-CI4)
873 CI0-CI2 are 9(=5+4) bits inputs, CI3-CI4 8(=4+4) bits
874
875 The input connctions change from game to game. E.g. in Simpsons,
876 CI0 = grounded (background color)
877 CI1 = sprites
878 CI2 = FIX
879 CI3 = A
880 CI4 = B
881
882 in lgtnfght:
883 CI0 = grounded
884 CI1 = sprites
885 CI2 = FIX
886 CI3 = B
887 CI4 = A
888
889 there are three 6 bit priority inputs, PR0-PR2
890
891 simpsons:
892 PR0 = 111111
893 PR1 = xxxxx0 x bits coming from the sprite attributes
894 PR2 = 111111
895
896 lgtnfght:
897 PR0 = 111111
898 PR1 = 1xx000 x bits coming from the sprite attributes
899 PR2 = 111111
900
901 also two shadow inputs, SDI0 and SDI1 (from the sprite attributes)
902
903 the chip outputs the 11 bit palette index, CO0-CO10, and two shadow bits.
904
905 16 internal registers; registers are 6 bits wide (input is D0-D5)
906 For the most part, their meaning is unknown
907 All registers are write only.
908 There must be a way to enable/disable the three external PR inputs.
909 Some games initialize the priorities of the sprite & background layers,
910 others don't. It isn't clear whether the data written to those registers is
911 actually used, since the priority is taken from the external ports.
912
913 0 priority of CI0 (higher = lower priority)
914 punkshot: unused?
915 lgtnfght: unused?
916 simpsons: 3f = 111111
917 xmen: 05 = 000101 default value
918 xmen: 09 = 001001 used to swap CI0 and CI2
919 1 priority of CI1 (higher = lower priority)
920 punkshot: 28 = 101000
921 lgtnfght: unused?
922 simpsons: unused?
923 xmen: 02 = 000010
924 2 priority of CI2 (higher = lower priority)
925 punkshot: 24 = 100100
926 lgtnfght: 24 = 100100
927 simpsons: 04 = 000100
928 xmen: 09 = 001001 default value
929 xmen: 05 = 000101 used to swap CI0 and CI2
930 3 priority of CI3 (higher = lower priority)
931 punkshot: 34 = 110100
932 lgtnfght: 34 = 110100
933 simpsons: 28 = 101000
934 xmen: 00 = 000000
935 4 priority of CI4 (higher = lower priority)
936 punkshot: 2c = 101100 default value
937 punkshot: 3c = 111100 used to swap CI3 and CI4
938 punkshot: 26 = 100110 used to swap CI1 and CI4
939 lgtnfght: 2c = 101100
940 simpsons: 18 = 011000
941 xmen: fe = 111110
942 5 unknown
943 punkshot: unused?
944 lgtnfght: 2a = 101010
945 simpsons: unused?
946 xmen: unused?
947 6 unknown
948 punkshot: 26 = 100110
949 lgtnfght: 30 = 110000
950 simpsons: 17 = 010111
951 xmen: 03 = 000011 (written after initial tests)
952 7 unknown
953 punkshot: unused?
954 lgtnfght: unused?
955 simpsons: 27 = 100111
956 xmen: 07 = 000111 (written after initial tests)
957 8 unknown
958 punkshot: unused?
959 lgtnfght: unused?
960 simpsons: 37 = 110111
961 xmen: ff = 111111 (written after initial tests)
962 9 ----xx CI0 palette index base (CO9-CO10)
963 --xx-- CI1 palette index base (CO9-CO10)
964 xx---- CI2 palette index base (CO9-CO10)
965 10 ---xxx CI3 palette index base (CO8-CO10)
966 xxx--- CI4 palette index base (CO8-CO10)
967 11 unknown
968 punkshot: 00 = 000000
969 lgtnfght: 00 = 000000
970 simpsons: 00 = 000000
971 xmen: 00 = 000000 (written after initial tests)
972 12 unknown
973 punkshot: 04 = 000100
974 lgtnfght: 04 = 000100
975 simpsons: 05 = 000101
976 xmen: 05 = 000101
977 13 unused
978 14 unused
979 15 unused
980
981
982 054000
983 ------
984 Sort of a protection device, used for collision detection.
985 It is passed a few parameters, and returns a boolean telling if collision
986 happened. It has no access to gfx data, it only does arithmetical operations
987 on the parameters.
988
989 Memory map:
990 00 unused
991 01-03 W A center X
992 04 W unknown, needed by thndrx2 to pass the startup check, we use a hack
993 05 unused
994 06 W A semiaxis X
995 07 W A semiaxis Y
996 08 unused
997 09-0b W A center Y
998 0c W unknown, needed by thndrx2 to pass the startup check, we use a hack
999 0d unused
1000 0e W B semiaxis X
1001 0f W B semiaxis Y
1002 10 unused
1003 11-13 W B center Y
1004 14 unused
1005 15-17 W B center X
1006 18 R 0 = collision, 1 = no collision
1007
1008
1009 051733
1010 ------
1011 Sort of a protection device, used for collision detection, and for
1012 arithmetical operations.
1013 It is passed a few parameters, and returns the result.
1014
1015 Memory map(preliminary):
1016 ------------------------
1017 00-01 W operand 1
1018 02-03 W operand 2
1019 04-05 W operand 3
1020
1021 00-01 R operand 1 / operand 2
1022 02-03 R operand 1 % operand 2?
1023 04-05 R sqrt(operand 3<<16)
1024
1025 06-07 W distance for collision check
1026 08-09 W Y pos of obj1
1027 0a-0b W X pos of obj1
1028 0c-0d W Y pos of obj2
1029 0e-0f W X pos of obj2
1030 13 W unknown
1031
1032 07 R collision (0x80 = no, 0x00 = yes)
1033 0a-0b R unknown (chequered flag), might just read back X pos
1034 0e-0f R unknown (chequered flag), might just read back X pos
1035
1036 Other addresses are unknown or unused.
1037
1038 Fast Lane:
1039 ----------
1040 $9def:
1041 This routine is called only after a collision.
1042 (R) 0x0006: unknown. Only bits 0-3 are used.
1043
1044 Blades of Steel:
1045 ----------------
1046 $ac2f:
1047 (R) 0x2f86: unknown. Only uses bit 0.
1048
1049 $a5de:
1050 writes to 0x2f84-0x2f85, waits a little, and then reads from 0x2f84.
1051
1052 $7af3:
1053 (R) 0x2f86: unknown. Only uses bit 0.
1054
1055
1056 Devastators:
1057 ------------
1058 $6ce8:
1059 reads from 0x0006, and only uses bit 1.
1060
1061
1062 K055550
1063 -------
1064
1065 Protection chip which performs a memset() operation.
1066
1067 Used in Violent Storm and Ultimate Battler to clear VRAM between scenes, among
1068 other things. May also perform other functions since Violent Storm still isn't
1069 happy...
1070
1071 Has word-wide registers as follows:
1072
1073 0: Count of units to transfer. The write here triggers the transfer.
1074 1-6: Unknown
1075 7: Destination address, MSW
1076 8: Destination address, LSW
1077 9: Unknown
1078 10: Size of transfer units, MSW
1079 11: Size of transfer units, LSW
1080 12: Unknown
1081 13: Value to fill destination region with
1082 14-15: Unknown
1083
1084
1085 K055555
1086 -------
1087
1088 Priority encoder. Always found in conjunction with K054338, but the reverse
1089 isn't true. The 55555 has 8 inputs: "A", "B", "C", and "D" intended for a 156/157
1090 type tilemap chip, "OBJ" intended for a '246 type sprite chip, and "SUB1-SUB3"
1091 which can be used for 3 additional layers.
1092
1093 When used in combintion with a K054338, each input can be chosen to participate
1094 in shadow/highlight operations, R/G/B alpha blending, and R/G/B brightness control.
1095 Per-tile priority is supported for tilemap planes A and B.
1096
1097 There are also 3 shadow priority registers. When these are enabled, layers and
1098 sprites with a priority greater than or equal to them become a shadow, and either
1099 then gets drawn as a shadow/highlight or not at all (I'm not sure what selects
1100 this yet. Dadandarn relies on this mechanism to hide the 53936 plane when
1101 it doesn't want it visible).
1102
1103 It also appears that brightness control and alpha blend can be decided per-tile
1104 and per-sprite, although this is not certain.
1105
1106 Additionally the 55555 can provide a gradient background with one palette entry
1107 per scanline. This is fairly rarely used, but does turn up in Gokujou Parodius as
1108 well as the Sexy Parodius title screen.
1109
1110 Lots of byte-wise registers. A partial map:
1111
1112 0: Palette index(?) for the gradient background
1113 1: related to tilemap brightness control
1114 2-5: COLSEL for various inputs (?)
1115 6: COLCHG ON
1116 7-18: priority levels (VA1/VA2/VAC/VB1/VB2/VBC/VC/VD/OBJ/S1/S2/S3)
1117 19-22: INPRI for OBJ/S1/S2/S3
1118 23-32: palette bases (VA/VB/VC/VD/OBJ/S1/S2/S3)
1119 37: shadow 1 priority
1120 38: shadow 2 priority
1121 39: shadow 3 priority
1122 40: shadow/highlight master enable
1123 41: master shadow/highlight priority
1124 42: VBRI: enables brightness control for each VRAM layer (bits: x x x x D B C A)
1125 43: OSBRI: enables brightness control for OBJ and SUB layers, depending for OBJ on attr bits
1126 44: OSBRI_ON: not quite sure
1127 45: input enables. bits as follows: (MSB) S3 S2 S1 OB VD VC VB VA (LSB)
1128
1129
1130 K054338
1131 -------
1132 Color combiner engine. Designed for use with the 55555, but also found in games
1133 without one.
1134
1135 Registers (word-wise):
1136
1137 0: first 8 bits unknown, second 8 bits are the R component of the background color
1138 1: G and B components (8 bits each) of the background color
1139 2-4: shadow 1 R/G/B (16 bits per component. In shadow mode, determines a blend
1140 value between total blackness and the original color. In highlight mode,
1141 determines a blend value between total whiteness and the original color.
1142 The hardware clamps at black or white as necessary: see the Graphics Test
1143 in many System GX games).
1144 5-7: shadow 2 R/G/B
1145 8-10: shadow 3 R/G/B
1146 11-12: brightness R/G/B (external circuit such as the 55555 decides which layers
1147 this applies to)
1148 13-14: alpha blend R/G/B (external circuit such as the 55555 decides which layers
1149 this applies to)
1150
1151 ***************************************************************************/
1152
1153 #include "driver.h"
1154 #include "state.h"
1155 #include "vidhrdw/konamiic.h"
1156
1157 /*
1158 This recursive function doesn't use additional memory
1159 (it could be easily converted into an iterative one).
1160 It's called shuffle because it mimics the shuffling of a deck of cards.
1161 */
shuffle(UINT16 * buf,int len)1162 static void shuffle(UINT16 *buf,int len)
1163 {
1164 int i;
1165 UINT16 t;
1166
1167 if (len == 2) return;
1168
1169 if (len % 4) exit(1); /* must not happen */
1170
1171 len /= 2;
1172
1173 for (i = 0;i < len/2;i++)
1174 {
1175 t = buf[len/2 + i];
1176 buf[len/2 + i] = buf[len + i];
1177 buf[len + i] = t;
1178 }
1179
1180 shuffle(buf,len);
1181 shuffle(buf + len,len);
1182 }
1183
1184
1185 /* helper function to join two 16-bit ROMs and form a 32-bit data stream */
konami_rom_deinterleave_2(int mem_region)1186 void konami_rom_deinterleave_2(int mem_region)
1187 {
1188 shuffle((UINT16 *)memory_region(mem_region),memory_region_length(mem_region)/2);
1189 }
1190
1191 /* hacked version of rom_deinterleave_2_half for Lethal Enforcers */
konami_rom_deinterleave_2_half(int mem_region)1192 void konami_rom_deinterleave_2_half(int mem_region)
1193 {
1194 data8_t *rgn = memory_region(mem_region);
1195
1196 shuffle((UINT16 *)rgn,memory_region_length(mem_region)/4);
1197 shuffle((UINT16 *)(rgn+memory_region_length(mem_region)/2),memory_region_length(mem_region)/4);
1198 }
1199
1200 /* helper function to join four 16-bit ROMs and form a 64-bit data stream */
konami_rom_deinterleave_4(int mem_region)1201 void konami_rom_deinterleave_4(int mem_region)
1202 {
1203 konami_rom_deinterleave_2(mem_region);
1204 konami_rom_deinterleave_2(mem_region);
1205 }
1206
1207
1208
1209
1210
1211
1212 /***************************************************************************/
1213 /* */
1214 /* 007121 */
1215 /* */
1216 /***************************************************************************/
1217
1218 /*static*/ unsigned char K007121_ctrlram[MAX_K007121][8];
1219 /*static*/ int K007121_flipscreen[MAX_K007121];
1220
1221
K007121_ctrl_w(int chip,int offset,int data)1222 void K007121_ctrl_w(int chip,int offset,int data)
1223 {
1224 switch (offset)
1225 {
1226 case 6:
1227 /* palette bank change */
1228 if ((K007121_ctrlram[chip][offset] & 0x30) != (data & 0x30))
1229 tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
1230 break;
1231 case 7:
1232 K007121_flipscreen[chip] = data & 0x08;
1233 break;
1234 }
1235
1236 K007121_ctrlram[chip][offset] = data;
1237 }
1238
WRITE_HANDLER(K007121_ctrl_0_w)1239 WRITE_HANDLER( K007121_ctrl_0_w )
1240 {
1241 K007121_ctrl_w(0,offset,data);
1242 }
1243
WRITE_HANDLER(K007121_ctrl_1_w)1244 WRITE_HANDLER( K007121_ctrl_1_w )
1245 {
1246 K007121_ctrl_w(1,offset,data);
1247 }
1248
1249
1250 /*
1251 * Sprite Format
1252 * ------------------
1253 *
1254 * There are 0x40 sprites, each one using 5 bytes. However the number of
1255 * sprites can be increased to 0x80 with a control register (Combat School
1256 * sets it on and off during the game).
1257 *
1258 * Byte | Bit(s) | Use
1259 * -----+-76543210-+----------------
1260 * 0 | xxxxxxxx | sprite code
1261 * 1 | xxxx---- | color
1262 * 1 | ----xx-- | sprite code low 2 bits for 16x8/8x8 sprites
1263 * 1 | ------xx | sprite code bank bits 1/0
1264 * 2 | xxxxxxxx | y position
1265 * 3 | xxxxxxxx | x position (low 8 bits)
1266 * 4 | xx------ | sprite code bank bits 3/2
1267 * 4 | --x----- | flip y
1268 * 4 | ---x---- | flip x
1269 * 4 | ----xxx- | sprite size 000=16x16 001=16x8 010=8x16 011=8x8 100=32x32
1270 * 4 | -------x | x position (high bit)
1271 *
1272 * Flack Attack uses a different, "wider" layout with 32 bytes per sprite,
1273 * mapped as follows, and the priority order is reversed. Maybe it is a
1274 * compatibility mode with an older custom IC. It is not known how this
1275 * alternate layout is selected.
1276 *
1277 * 0 -> e
1278 * 1 -> f
1279 * 2 -> 6
1280 * 3 -> 4
1281 * 4 -> 8
1282 *
1283 */
1284
K007121_sprites_draw(int chip,struct mame_bitmap * bitmap,const struct rectangle * cliprect,const unsigned char * source,int base_color,int global_x_offset,int bank_base,UINT32 pri_mask)1285 void K007121_sprites_draw(int chip,struct mame_bitmap *bitmap,const struct rectangle *cliprect,
1286 const unsigned char *source,int base_color,int global_x_offset,int bank_base,
1287 UINT32 pri_mask)
1288 {
1289 const struct GfxElement *gfx = Machine->gfx[chip];
1290 int flipscreen = K007121_flipscreen[chip];
1291 int i,num,inc,offs[5],trans;
1292 int is_flakatck = K007121_ctrlram[chip][0x06] & 0x04; /* WRONG!!!! */
1293
1294 #if 0
1295 log_cb(RETRO_LOG_DEBUG, LOGPRE "%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
1296 K007121_ctrlram[0][0x00],K007121_ctrlram[0][0x01],K007121_ctrlram[0][0x02],K007121_ctrlram[0][0x03],K007121_ctrlram[0][0x04],K007121_ctrlram[0][0x05],K007121_ctrlram[0][0x06],K007121_ctrlram[0][0x07],
1297 K007121_ctrlram[1][0x00],K007121_ctrlram[1][0x01],K007121_ctrlram[1][0x02],K007121_ctrlram[1][0x03],K007121_ctrlram[1][0x04],K007121_ctrlram[1][0x05],K007121_ctrlram[1][0x06],K007121_ctrlram[1][0x07]);
1298
1299 if (keyboard_pressed(KEYCODE_D))
1300 {
1301 FILE *fp;
1302 fp=fopen(chip?"SPRITE1.DMP":"SPRITE0.DMP", "w+b");
1303 if (fp)
1304 {
1305 fwrite(source, 0x800, 1, fp);
1306 usrintf_showmessage("saved");
1307 fclose(fp);
1308 }
1309 }
1310 #endif
1311
1312 if (is_flakatck)
1313 {
1314 num = 0x40;
1315 inc = -0x20;
1316 source += 0x3f*0x20;
1317 offs[0] = 0x0e;
1318 offs[1] = 0x0f;
1319 offs[2] = 0x06;
1320 offs[3] = 0x04;
1321 offs[4] = 0x08;
1322 /* Flak Attack doesn't use a lookup PROM, it maps the color code directly */
1323 /* to a palette entry */
1324 trans = TRANSPARENCY_PEN;
1325 }
1326 else /* all others */
1327 {
1328 /*num = (K007121_ctrlram[chip][0x03] & 0x40) ? 0x80 : 0x40; WRONG!!! (needed by combasc) */
1329 num = 0x40; /* Combasc writes 70 sprites to VRAM at peak but the chip only processes the first 64.*/
1330
1331 inc = 5;
1332 offs[0] = 0x00;
1333 offs[1] = 0x01;
1334 offs[2] = 0x02;
1335 offs[3] = 0x03;
1336 offs[4] = 0x04;
1337 trans = TRANSPARENCY_COLOR;
1338 /* when using priority buffer, draw front to back */
1339 if (pri_mask != -1)
1340 {
1341 source += (num-1)*inc;
1342 inc = -inc;
1343 }
1344 }
1345
1346 for (i = 0;i < num;i++)
1347 {
1348 int number = source[offs[0]]; /* sprite number */
1349 int sprite_bank = source[offs[1]] & 0x0f; /* sprite bank */
1350 int sx = source[offs[3]]; /* vertical position */
1351 int sy = source[offs[2]]; /* horizontal position */
1352 int attr = source[offs[4]]; /* attributes */
1353 int xflip = source[offs[4]] & 0x10; /* flip x */
1354 int yflip = source[offs[4]] & 0x20; /* flip y */
1355 int color = base_color + ((source[offs[1]] & 0xf0) >> 4);
1356 int width,height;
1357 static int x_offset[4] = {0x0,0x1,0x4,0x5};
1358 static int y_offset[4] = {0x0,0x2,0x8,0xa};
1359 int x,y, ex, ey;
1360
1361 if (attr & 0x01) sx -= 256;
1362 if (sy >= 240) sy -= 256;
1363
1364 number += ((sprite_bank & 0x3) << 8) + ((attr & 0xc0) << 4);
1365 number = number << 2;
1366 number += (sprite_bank >> 2) & 3;
1367
1368 if (!is_flakatck || source[0x00]) /* Flak Attack needs this */
1369 {
1370 number += bank_base;
1371
1372 switch( attr&0xe )
1373 {
1374 case 0x06: width = height = 1; break;
1375 case 0x04: width = 1; height = 2; number &= (~2); break;
1376 case 0x02: width = 2; height = 1; number &= (~1); break;
1377 case 0x00: width = height = 2; number &= (~3); break;
1378 case 0x08: width = height = 4; number &= (~3); break;
1379 default: width = 1; height = 1;
1380 /* log_cb(RETRO_LOG_DEBUG, LOGPRE "Unknown sprite size %02x\n",attr&0xe);*/
1381 /* usrintf_showmessage("Unknown sprite size %02x\n",attr&0xe);*/
1382 }
1383
1384 for (y = 0;y < height;y++)
1385 {
1386 for (x = 0;x < width;x++)
1387 {
1388 ex = xflip ? (width-1-x) : x;
1389 ey = yflip ? (height-1-y) : y;
1390
1391 if (flipscreen)
1392 {
1393 if (pri_mask != -1)
1394 pdrawgfx(bitmap,gfx,
1395 number + x_offset[ex] + y_offset[ey],
1396 color,
1397 !xflip,!yflip,
1398 248-(sx+x*8),248-(sy+y*8),
1399 cliprect,trans,0,
1400 pri_mask);
1401 else
1402 drawgfx(bitmap,gfx,
1403 number + x_offset[ex] + y_offset[ey],
1404 color,
1405 !xflip,!yflip,
1406 248-(sx+x*8),248-(sy+y*8),
1407 cliprect,trans,0);
1408 }
1409 else
1410 {
1411 if (pri_mask != -1)
1412 pdrawgfx(bitmap,gfx,
1413 number + x_offset[ex] + y_offset[ey],
1414 color,
1415 xflip,yflip,
1416 global_x_offset+sx+x*8,sy+y*8,
1417 cliprect,trans,0,
1418 pri_mask);
1419 else
1420 drawgfx(bitmap,gfx,
1421 number + x_offset[ex] + y_offset[ey],
1422 color,
1423 xflip,yflip,
1424 global_x_offset+sx+x*8,sy+y*8,
1425 cliprect,trans,0);
1426 }
1427 }
1428 }
1429 }
1430
1431 source += inc;
1432 }
1433 }
1434
1435
1436
1437 /***************************************************************************/
1438 /* */
1439 /* 007342 */
1440 /* */
1441 /***************************************************************************/
1442
1443 static unsigned char *K007342_ram,*K007342_scroll_ram;
1444 static int K007342_gfxnum;
1445 static int K007342_int_enabled;
1446 static int K007342_flipscreen;
1447 static int K007342_scrollx[2];
1448 static int K007342_scrolly[2];
1449 static unsigned char *K007342_videoram_0,*K007342_colorram_0;
1450 static unsigned char *K007342_videoram_1,*K007342_colorram_1;
1451 static int K007342_regs[8];
1452 static void (*K007342_callback)(int tilemap, int bank, int *code, int *color);
1453 static struct tilemap *K007342_tilemap[2];
1454
1455 /***************************************************************************
1456
1457 Callbacks for the TileMap code
1458
1459 ***************************************************************************/
1460
1461 /*
1462 data format:
1463 video RAM xxxxxxxx tile number (bits 0-7)
1464 color RAM x------- tiles with priority over the sprites
1465 color RAM -x------ depends on external conections
1466 color RAM --x----- flip Y
1467 color RAM ---x---- flip X
1468 color RAM ----xxxx depends on external connections (usually color and banking)
1469 */
1470
K007342_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)1471 static UINT32 K007342_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)
1472 {
1473 /* logical (col,row) -> memory offset */
1474 return (col & 0x1f) + ((row & 0x1f) << 5) + ((col & 0x20) << 5);
1475 }
1476
K007342_get_tile_info(int tile_index,int layer,data8_t * cram,data8_t * vram)1477 static INLINE void K007342_get_tile_info(int tile_index,int layer,data8_t *cram,data8_t *vram)
1478 {
1479 int color, code;
1480
1481 color = cram[tile_index];
1482 code = vram[tile_index];
1483
1484 tile_info.flags = TILE_FLIPYX((color & 0x30) >> 4);
1485 tile_info.priority = (color & 0x80) >> 7;
1486
1487 (*K007342_callback)(layer, K007342_regs[1], &code, &color);
1488
1489 SET_TILE_INFO(
1490 K007342_gfxnum,
1491 code,
1492 color,
1493 tile_info.flags)
1494 }
1495
K007342_get_tile_info0(int tile_index)1496 static void K007342_get_tile_info0(int tile_index) { K007342_get_tile_info(tile_index,0,K007342_colorram_0,K007342_videoram_0); }
K007342_get_tile_info1(int tile_index)1497 static void K007342_get_tile_info1(int tile_index) { K007342_get_tile_info(tile_index,1,K007342_colorram_1,K007342_videoram_1); }
1498
1499
1500
K007342_vh_start(int gfx_index,void (* callback)(int tilemap,int bank,int * code,int * color))1501 int K007342_vh_start(int gfx_index, void (*callback)(int tilemap, int bank, int *code, int *color))
1502 {
1503 K007342_gfxnum = gfx_index;
1504 K007342_callback = callback;
1505
1506 K007342_tilemap[0] = tilemap_create(K007342_get_tile_info0,K007342_scan,TILEMAP_TRANSPARENT,8,8,64,32);
1507 K007342_tilemap[1] = tilemap_create(K007342_get_tile_info1,K007342_scan,TILEMAP_TRANSPARENT,8,8,64,32);
1508
1509 K007342_ram = auto_malloc(0x2000);
1510 K007342_scroll_ram = auto_malloc(0x0200);
1511
1512 if (!K007342_ram || !K007342_scroll_ram || !K007342_tilemap[0] || !K007342_tilemap[1])
1513 return 1;
1514
1515 memset(K007342_ram,0,0x2000);
1516
1517 K007342_colorram_0 = &K007342_ram[0x0000];
1518 K007342_colorram_1 = &K007342_ram[0x1000];
1519 K007342_videoram_0 = &K007342_ram[0x0800];
1520 K007342_videoram_1 = &K007342_ram[0x1800];
1521
1522 tilemap_set_transparent_pen(K007342_tilemap[0],0);
1523 tilemap_set_transparent_pen(K007342_tilemap[1],0);
1524
1525 return 0;
1526 }
1527
READ_HANDLER(K007342_r)1528 READ_HANDLER( K007342_r )
1529 {
1530 return K007342_ram[offset];
1531 }
1532
WRITE_HANDLER(K007342_w)1533 WRITE_HANDLER( K007342_w )
1534 {
1535 if (offset < 0x1000)
1536 { /* layer 0 */
1537 if (K007342_ram[offset] != data)
1538 {
1539 K007342_ram[offset] = data;
1540 tilemap_mark_tile_dirty(K007342_tilemap[0],offset & 0x7ff);
1541 }
1542 }
1543 else
1544 { /* layer 1 */
1545 if (K007342_ram[offset] != data)
1546 {
1547 K007342_ram[offset] = data;
1548 tilemap_mark_tile_dirty(K007342_tilemap[1],offset & 0x7ff);
1549 }
1550 }
1551 }
1552
READ_HANDLER(K007342_scroll_r)1553 READ_HANDLER( K007342_scroll_r )
1554 {
1555 return K007342_scroll_ram[offset];
1556 }
1557
WRITE_HANDLER(K007342_scroll_w)1558 WRITE_HANDLER( K007342_scroll_w )
1559 {
1560 K007342_scroll_ram[offset] = data;
1561 }
1562
WRITE_HANDLER(K007342_vreg_w)1563 WRITE_HANDLER( K007342_vreg_w )
1564 {
1565 switch(offset)
1566 {
1567 case 0x00:
1568 /* bit 1: INT control */
1569 K007342_int_enabled = data & 0x02;
1570 K007342_flipscreen = data & 0x10;
1571 tilemap_set_flip(K007342_tilemap[0],K007342_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
1572 tilemap_set_flip(K007342_tilemap[1],K007342_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
1573 break;
1574 case 0x01: /* used for banking in Rock'n'Rage */
1575 if (data != K007342_regs[1])
1576 tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
1577 case 0x02:
1578 K007342_scrollx[0] = (K007342_scrollx[0] & 0xff) | ((data & 0x01) << 8);
1579 K007342_scrollx[1] = (K007342_scrollx[1] & 0xff) | ((data & 0x02) << 7);
1580 break;
1581 case 0x03: /* scroll x (register 0) */
1582 K007342_scrollx[0] = (K007342_scrollx[0] & 0x100) | data;
1583 break;
1584 case 0x04: /* scroll y (register 0) */
1585 K007342_scrolly[0] = data;
1586 break;
1587 case 0x05: /* scroll x (register 1) */
1588 K007342_scrollx[1] = (K007342_scrollx[1] & 0x100) | data;
1589 break;
1590 case 0x06: /* scroll y (register 1) */
1591 K007342_scrolly[1] = data;
1592 case 0x07: /* unused */
1593 break;
1594 }
1595 K007342_regs[offset] = data;
1596 }
1597
K007342_tilemap_update(void)1598 void K007342_tilemap_update(void)
1599 {
1600 int offs;
1601
1602
1603 /* update scroll */
1604 switch (K007342_regs[2] & 0x1c)
1605 {
1606 case 0x00:
1607 case 0x08: /* unknown, blades of steel shootout between periods */
1608 tilemap_set_scroll_rows(K007342_tilemap[0],1);
1609 tilemap_set_scroll_cols(K007342_tilemap[0],1);
1610 tilemap_set_scrollx(K007342_tilemap[0],0,K007342_scrollx[0]);
1611 tilemap_set_scrolly(K007342_tilemap[0],0,K007342_scrolly[0]);
1612 break;
1613
1614 case 0x0c: /* 32 columns */
1615 tilemap_set_scroll_rows(K007342_tilemap[0],1);
1616 tilemap_set_scroll_cols(K007342_tilemap[0],512);
1617 tilemap_set_scrollx(K007342_tilemap[0],0,K007342_scrollx[0]);
1618 for (offs = 0;offs < 256;offs++)
1619 tilemap_set_scrolly(K007342_tilemap[0],(offs + K007342_scrollx[0]) & 0x1ff,
1620 K007342_scroll_ram[2*(offs/8)] + 256 * K007342_scroll_ram[2*(offs/8)+1]);
1621 break;
1622
1623 case 0x14: /* 256 rows */
1624 tilemap_set_scroll_rows(K007342_tilemap[0],256);
1625 tilemap_set_scroll_cols(K007342_tilemap[0],1);
1626 tilemap_set_scrolly(K007342_tilemap[0],0,K007342_scrolly[0]);
1627 for (offs = 0;offs < 256;offs++)
1628 tilemap_set_scrollx(K007342_tilemap[0],(offs + K007342_scrolly[0]) & 0xff,
1629 K007342_scroll_ram[2*offs] + 256 * K007342_scroll_ram[2*offs+1]);
1630 break;
1631
1632 default:
1633 /* usrintf_showmessage("unknown scroll ctrl %02x",K007342_regs[2] & 0x1c);*/
1634 break;
1635 }
1636
1637 tilemap_set_scrollx(K007342_tilemap[1],0,K007342_scrollx[1]);
1638 tilemap_set_scrolly(K007342_tilemap[1],0,K007342_scrolly[1]);
1639
1640 #if 0
1641 {
1642 static int current_layer = 0;
1643
1644 if (keyboard_pressed_memory(KEYCODE_Z)) current_layer = !current_layer;
1645 tilemap_set_enable(K007342_tilemap[current_layer], 1);
1646 tilemap_set_enable(K007342_tilemap[!current_layer], 0);
1647
1648 usrintf_showmessage("regs:%02x %02x %02x %02x-%02x %02x %02x %02x:%02x",
1649 K007342_regs[0], K007342_regs[1], K007342_regs[2], K007342_regs[3],
1650 K007342_regs[4], K007342_regs[5], K007342_regs[6], K007342_regs[7],
1651 current_layer);
1652 }
1653 #endif
1654 }
1655
K007342_tilemap_set_enable(int tilemap,int enable)1656 void K007342_tilemap_set_enable(int tilemap, int enable)
1657 {
1658 tilemap_set_enable(K007342_tilemap[tilemap], enable);
1659 }
1660
K007342_tilemap_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int num,int flags,UINT32 priority)1661 void K007342_tilemap_draw(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int num,int flags,UINT32 priority)
1662 {
1663 tilemap_draw(bitmap,cliprect,K007342_tilemap[num],flags,priority);
1664 }
1665
K007342_is_INT_enabled(void)1666 int K007342_is_INT_enabled(void)
1667 {
1668 return K007342_int_enabled;
1669 }
1670
1671
1672
1673 /***************************************************************************/
1674 /* */
1675 /* 007420 */
1676 /* */
1677 /***************************************************************************/
1678
1679 static struct GfxElement *K007420_gfx;
1680 static void (*K007420_callback)(int *code,int *color);
1681 static unsigned char *K007420_ram;
1682 static int K007420_banklimit;
1683
K007420_vh_start(int gfxnum,void (* callback)(int * code,int * color))1684 int K007420_vh_start(int gfxnum, void (*callback)(int *code,int *color))
1685 {
1686 K007420_gfx = Machine->gfx[gfxnum];
1687 K007420_callback = callback;
1688 K007420_ram = auto_malloc(0x200);
1689 if (!K007420_ram) return 1;
1690
1691 memset(K007420_ram,0,0x200);
1692
1693 K007420_banklimit = -1;
1694
1695 return 0;
1696 }
1697
READ_HANDLER(K007420_r)1698 READ_HANDLER( K007420_r )
1699 {
1700 return K007420_ram[offset];
1701 }
1702
WRITE_HANDLER(K007420_w)1703 WRITE_HANDLER( K007420_w )
1704 {
1705 K007420_ram[offset] = data;
1706 }
1707
1708 /*
1709 * Sprite Format
1710 * ------------------
1711 *
1712 * Byte | Bit(s) | Use
1713 * -----+-76543210-+----------------
1714 * 0 | xxxxxxxx | y position
1715 * 1 | xxxxxxxx | sprite code (low 8 bits)
1716 * 2 | xxxxxxxx | depends on external conections. Usually banking
1717 * 3 | xxxxxxxx | x position (low 8 bits)
1718 * 4 | x------- | x position (high bit)
1719 * 4 | -xxx---- | sprite size 000=16x16 001=8x16 010=16x8 011=8x8 100=32x32
1720 * 4 | ----x--- | flip y
1721 * 4 | -----x-- | flip x
1722 * 4 | ------xx | zoom (bits 8 & 9)
1723 * 5 | xxxxxxxx | zoom (low 8 bits) 0x080 = normal, < 0x80 enlarge, > 0x80 reduce
1724 * 6 | xxxxxxxx | unused
1725 * 7 | xxxxxxxx | unused
1726 */
1727
K007420_sprites_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect)1728 void K007420_sprites_draw(struct mame_bitmap *bitmap,const struct rectangle *cliprect)
1729 {
1730 #define K007420_SPRITERAM_SIZE 0x200
1731 int offs;
1732 int codemask = K007420_banklimit;
1733 int bankmask = ~K007420_banklimit;
1734
1735 for (offs = K007420_SPRITERAM_SIZE - 8; offs >= 0; offs -= 8)
1736 {
1737 int ox,oy,code,color,flipx,flipy,zoom,w,h,x,y,bank;
1738 static int xoffset[4] = { 0, 1, 4, 5 };
1739 static int yoffset[4] = { 0, 2, 8, 10 };
1740
1741 code = K007420_ram[offs+1];
1742 color = K007420_ram[offs+2];
1743 ox = K007420_ram[offs+3] - ((K007420_ram[offs+4] & 0x80) << 1);
1744 oy = 256 - K007420_ram[offs+0];
1745 flipx = K007420_ram[offs+4] & 0x04;
1746 flipy = K007420_ram[offs+4] & 0x08;
1747
1748 (*K007420_callback)(&code,&color);
1749
1750 bank = code & bankmask;
1751 code &= codemask;
1752
1753 /* 0x080 = normal scale, 0x040 = double size, 0x100 half size */
1754 zoom = K007420_ram[offs+5] | ((K007420_ram[offs+4] & 0x03) << 8);
1755 if (!zoom) continue;
1756 zoom = 0x10000 * 128 / zoom;
1757
1758 switch (K007420_ram[offs+4] & 0x70)
1759 {
1760 case 0x30: w = h = 1; break;
1761 case 0x20: w = 2; h = 1; code &= (~1); break;
1762 case 0x10: w = 1; h = 2; code &= (~2); break;
1763 case 0x00: w = h = 2; code &= (~3); break;
1764 case 0x40: w = h = 4; code &= (~3); break;
1765 default: w = 1; h = 1;
1766 /*logerror("Unknown sprite size %02x\n",(K007420_ram[offs+4] & 0x70)>>4);*/
1767 }
1768
1769 if (K007342_flipscreen)
1770 {
1771 ox = 256 - ox - ((zoom * w + (1<<12)) >> 13);
1772 oy = 256 - oy - ((zoom * h + (1<<12)) >> 13);
1773 flipx = !flipx;
1774 flipy = !flipy;
1775 }
1776
1777 if (zoom == 0x10000)
1778 {
1779 int sx,sy;
1780
1781 for (y = 0;y < h;y++)
1782 {
1783 sy = oy + 8 * y;
1784
1785 for (x = 0;x < w;x++)
1786 {
1787 int c = code;
1788
1789 sx = ox + 8 * x;
1790 if (flipx) c += xoffset[(w-1-x)];
1791 else c += xoffset[x];
1792 if (flipy) c += yoffset[(h-1-y)];
1793 else c += yoffset[y];
1794
1795 if (c & bankmask) continue; else c += bank;
1796
1797 drawgfx(bitmap,K007420_gfx,
1798 c,
1799 color,
1800 flipx,flipy,
1801 sx,sy,
1802 cliprect,TRANSPARENCY_PEN,0);
1803
1804 if (K007342_regs[2] & 0x80)
1805 drawgfx(bitmap,K007420_gfx,
1806 c,
1807 color,
1808 flipx,flipy,
1809 sx,sy-256,
1810 cliprect,TRANSPARENCY_PEN,0);
1811 }
1812 }
1813 }
1814 else
1815 {
1816 int sx,sy,zw,zh;
1817 for (y = 0;y < h;y++)
1818 {
1819 sy = oy + ((zoom * y + (1<<12)) >> 13);
1820 zh = (oy + ((zoom * (y+1) + (1<<12)) >> 13)) - sy;
1821
1822 for (x = 0;x < w;x++)
1823 {
1824 int c = code;
1825
1826 sx = ox + ((zoom * x + (1<<12)) >> 13);
1827 zw = (ox + ((zoom * (x+1) + (1<<12)) >> 13)) - sx;
1828 if (flipx) c += xoffset[(w-1-x)];
1829 else c += xoffset[x];
1830 if (flipy) c += yoffset[(h-1-y)];
1831 else c += yoffset[y];
1832
1833 if (c & bankmask) continue; else c += bank;
1834
1835 drawgfxzoom(bitmap,K007420_gfx,
1836 c,
1837 color,
1838 flipx,flipy,
1839 sx,sy,
1840 cliprect,TRANSPARENCY_PEN,0,
1841 (zw << 16) / 8,(zh << 16) / 8);
1842
1843 if (K007342_regs[2] & 0x80)
1844 drawgfxzoom(bitmap,K007420_gfx,
1845 c,
1846 color,
1847 flipx,flipy,
1848 sx,sy-256,
1849 cliprect,TRANSPARENCY_PEN,0,
1850 (zw << 16) / 8,(zh << 16) / 8);
1851 }
1852 }
1853 }
1854 }
1855 #if 0
1856 {
1857 static int current_sprite = 0;
1858
1859 if (keyboard_pressed_memory(KEYCODE_Z)) current_sprite = (current_sprite+1) & ((K007420_SPRITERAM_SIZE/8)-1);
1860 if (keyboard_pressed_memory(KEYCODE_X)) current_sprite = (current_sprite-1) & ((K007420_SPRITERAM_SIZE/8)-1);
1861
1862 usrintf_showmessage("%02x:%02x %02x %02x %02x %02x %02x %02x %02x", current_sprite,
1863 K007420_ram[(current_sprite*8)+0], K007420_ram[(current_sprite*8)+1],
1864 K007420_ram[(current_sprite*8)+2], K007420_ram[(current_sprite*8)+3],
1865 K007420_ram[(current_sprite*8)+4], K007420_ram[(current_sprite*8)+5],
1866 K007420_ram[(current_sprite*8)+6], K007420_ram[(current_sprite*8)+7]);
1867 }
1868 #endif
1869 }
1870
K007420_set_banklimit(int limit)1871 void K007420_set_banklimit(int limit)
1872 {
1873 K007420_banklimit = limit;
1874 }
1875
1876
1877
1878 /***************************************************************************/
1879 /* */
1880 /* 052109 */
1881 /* */
1882 /***************************************************************************/
1883
1884 static int K052109_memory_region;
1885 static int K052109_gfxnum;
1886 static void (*K052109_callback)(int tilemap,int bank,int *code,int *color);
1887 static unsigned char *K052109_ram;
1888 static unsigned char *K052109_videoram_F,*K052109_videoram2_F,*K052109_colorram_F;
1889 static unsigned char *K052109_videoram_A,*K052109_videoram2_A,*K052109_colorram_A;
1890 static unsigned char *K052109_videoram_B,*K052109_videoram2_B,*K052109_colorram_B;
1891 static unsigned char K052109_charrombank[4];
1892 static int has_extra_video_ram;
1893 static int K052109_RMRD_line;
1894 static int K052109_tileflip_enable;
1895 static int K052109_irq_enabled;
1896 static int K052109_dx[3], K052109_dy[3];
1897 static unsigned char K052109_romsubbank,K052109_scrollctrl;
1898 struct tilemap *K052109_tilemap[3];
1899
1900
1901
1902 /***************************************************************************
1903
1904 Callbacks for the TileMap code
1905
1906 ***************************************************************************/
1907
1908 /*
1909 data format:
1910 video RAM xxxxxxxx tile number (low 8 bits)
1911 color RAM xxxx---- depends on external connections (usually color and banking)
1912 color RAM ----xx-- bank select (0-3): these bits are replaced with the 2
1913 bottom bits of the bank register before being placed on
1914 the output pins. The other two bits of the bank register are
1915 placed on the CAB1 and CAB2 output pins.
1916 color RAM ------xx depends on external connections (usually banking, flip)
1917 */
1918
K052109_get_tile_info(int tile_index,int layer,data8_t * cram,data8_t * vram1,data8_t * vram2)1919 static INLINE void K052109_get_tile_info(int tile_index,int layer,data8_t *cram,data8_t *vram1,data8_t *vram2)
1920 {
1921 int flipy = 0;
1922 int code = vram1[tile_index] + 256 * vram2[tile_index];
1923 int color = cram[tile_index];
1924 int bank = K052109_charrombank[(color & 0x0c) >> 2];
1925 if (has_extra_video_ram) bank = (color & 0x0c) >> 2; /* kludge for X-Men */
1926 color = (color & 0xf3) | ((bank & 0x03) << 2);
1927 bank >>= 2;
1928
1929 flipy = color & 0x02;
1930
1931 tile_info.flags = 0;
1932
1933 (*K052109_callback)(layer,bank,&code,&color);
1934
1935 SET_TILE_INFO(
1936 K052109_gfxnum,
1937 code,
1938 color,
1939 tile_info.flags);
1940
1941 /* if the callback set flip X but it is not enabled, turn it off */
1942 if (!(K052109_tileflip_enable & 1)) tile_info.flags &= ~TILE_FLIPX;
1943
1944 /* if flip Y is enabled and the attribute but is set, turn it on */
1945 if (flipy && (K052109_tileflip_enable & 2)) tile_info.flags |= TILE_FLIPY;
1946 }
1947
K052109_get_tile_info0(int tile_index)1948 static void K052109_get_tile_info0(int tile_index) { K052109_get_tile_info(tile_index,0,K052109_colorram_F,K052109_videoram_F,K052109_videoram2_F); }
K052109_get_tile_info1(int tile_index)1949 static void K052109_get_tile_info1(int tile_index) { K052109_get_tile_info(tile_index,1,K052109_colorram_A,K052109_videoram_A,K052109_videoram2_A); }
K052109_get_tile_info2(int tile_index)1950 static void K052109_get_tile_info2(int tile_index) { K052109_get_tile_info(tile_index,2,K052109_colorram_B,K052109_videoram_B,K052109_videoram2_B); }
1951
1952
K052109_tileflip_reset(void)1953 static void K052109_tileflip_reset(void)
1954 {
1955 int data = K052109_ram[0x1e80];
1956 tilemap_set_flip(K052109_tilemap[0],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
1957 tilemap_set_flip(K052109_tilemap[1],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
1958 tilemap_set_flip(K052109_tilemap[2],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
1959 K052109_tileflip_enable = ((data & 0x06) >> 1);
1960 }
1961
1962
K052109_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,void (* callback)(int tilemap,int bank,int * code,int * color))1963 int K052109_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,
1964 void (*callback)(int tilemap,int bank,int *code,int *color))
1965 {
1966 int gfx_index, i;
1967 static struct GfxLayout charlayout =
1968 {
1969 8,8,
1970 0, /* filled in later */
1971 4,
1972 { 0, 0, 0, 0 }, /* filled in later */
1973 { 0, 1, 2, 3, 4, 5, 6, 7 },
1974 { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
1975 32*8
1976 };
1977
1978
1979 /* find first empty slot to decode gfx */
1980 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
1981 if (Machine->gfx[gfx_index] == 0)
1982 break;
1983 if (gfx_index == MAX_GFX_ELEMENTS)
1984 return 1;
1985
1986 /* tweak the structure for the number of tiles we have */
1987 charlayout.total = memory_region_length(gfx_memory_region) / 32;
1988 charlayout.planeoffset[0] = plane3 * 8;
1989 charlayout.planeoffset[1] = plane2 * 8;
1990 charlayout.planeoffset[2] = plane1 * 8;
1991 charlayout.planeoffset[3] = plane0 * 8;
1992
1993 /* decode the graphics */
1994 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&charlayout);
1995 if (!Machine->gfx[gfx_index])
1996 return 1;
1997
1998 /* set the color information */
1999 if (Machine->drv->color_table_len)
2000 {
2001 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
2002 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
2003 }
2004 else
2005 {
2006 Machine->gfx[gfx_index]->colortable = Machine->pens;
2007 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / 16;
2008 }
2009
2010 K052109_memory_region = gfx_memory_region;
2011 K052109_gfxnum = gfx_index;
2012 K052109_callback = callback;
2013 K052109_RMRD_line = CLEAR_LINE;
2014 K052109_irq_enabled = 0;
2015
2016 has_extra_video_ram = 0;
2017
2018 K052109_tilemap[0] = tilemap_create(K052109_get_tile_info0,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,64,32);
2019 K052109_tilemap[1] = tilemap_create(K052109_get_tile_info1,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,64,32);
2020 K052109_tilemap[2] = tilemap_create(K052109_get_tile_info2,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,64,32);
2021
2022 K052109_ram = auto_malloc(0x6000);
2023
2024 if (!K052109_ram || !K052109_tilemap[0] || !K052109_tilemap[1] || !K052109_tilemap[2])
2025 return 1;
2026
2027 memset(K052109_ram,0,0x6000);
2028
2029 K052109_colorram_F = &K052109_ram[0x0000];
2030 K052109_colorram_A = &K052109_ram[0x0800];
2031 K052109_colorram_B = &K052109_ram[0x1000];
2032 K052109_videoram_F = &K052109_ram[0x2000];
2033 K052109_videoram_A = &K052109_ram[0x2800];
2034 K052109_videoram_B = &K052109_ram[0x3000];
2035 K052109_videoram2_F = &K052109_ram[0x4000];
2036 K052109_videoram2_A = &K052109_ram[0x4800];
2037 K052109_videoram2_B = &K052109_ram[0x5000];
2038
2039 tilemap_set_transparent_pen(K052109_tilemap[0],0);
2040 tilemap_set_transparent_pen(K052109_tilemap[1],0);
2041 tilemap_set_transparent_pen(K052109_tilemap[2],0);
2042
2043 for (i = 0; i < 3; i++)
2044 {
2045 K052109_dx[i] = K052109_dy[i] = 0;
2046 }
2047
2048 state_save_register_UINT8("k052109", 0, "ram", K052109_ram, 0x6000);
2049 state_save_register_int ("k052109", 0, "rmrd", &K052109_RMRD_line);
2050 state_save_register_UINT8("k052109", 0, "romsubbank", &K052109_romsubbank, 1);
2051 state_save_register_UINT8("k052109", 0, "scrollctrl", &K052109_scrollctrl, 1);
2052 state_save_register_int ("k052109", 0, "irqen", &K052109_irq_enabled);
2053 state_save_register_UINT8("k052109", 0, "charbank", K052109_charrombank, 4);
2054 state_save_register_INT32("k052109", 0, "dx", &K052109_dx[0], 3);
2055 state_save_register_INT32("k052109", 0, "dy", &K052109_dy[0], 3);
2056 state_save_register_int ("k052109", 0, "extra", &has_extra_video_ram);
2057
2058 state_save_register_func_postload(K052109_tileflip_reset);
2059 return 0;
2060 }
2061
2062
2063
READ_HANDLER(K052109_r)2064 READ_HANDLER( K052109_r )
2065 {
2066 if (K052109_RMRD_line == CLEAR_LINE)
2067 {
2068 if ((offset & 0x1fff) >= 0x1800)
2069 {
2070 if (offset >= 0x180c && offset < 0x1834)
2071 { /* A y scroll */ }
2072 else if (offset >= 0x1a00 && offset < 0x1c00)
2073 { /* A x scroll */ }
2074 else if (offset == 0x1d00)
2075 { /* read for bitwise operations before writing */ }
2076 else if (offset >= 0x380c && offset < 0x3834)
2077 { /* B y scroll */ }
2078 else if (offset >= 0x3a00 && offset < 0x3c00)
2079 { /* B x scroll */ }
2080 /* else*/
2081 /*logerror("%04x: read from unknown 052109 address %04x\n",activecpu_get_pc(),offset);*/
2082 }
2083
2084 return K052109_ram[offset];
2085 }
2086 else /* Punk Shot and TMNT read from 0000-1fff, Aliens from 2000-3fff */
2087 {
2088 int code = (offset & 0x1fff) >> 5;
2089 int color = K052109_romsubbank;
2090 int bank = K052109_charrombank[(color & 0x0c) >> 2] >> 2; /* discard low bits (TMNT) */
2091 int addr;
2092
2093 if (has_extra_video_ram) code |= color << 8; /* kludge for X-Men */
2094 else
2095 (*K052109_callback)(0,bank,&code,&color);
2096
2097 addr = (code << 5) + (offset & 0x1f);
2098 addr &= memory_region_length(K052109_memory_region)-1;
2099
2100 /* usrintf_showmessage("%04x: off%04x sub%02x (bnk%x) adr%06x",activecpu_get_pc(),offset,K052109_romsubbank,bank,addr);*/
2101
2102 return memory_region(K052109_memory_region)[addr];
2103 }
2104 }
2105
WRITE_HANDLER(K052109_w)2106 WRITE_HANDLER( K052109_w )
2107 {
2108 if ((offset & 0x1fff) < 0x1800) /* tilemap RAM */
2109 {
2110 if (K052109_ram[offset] != data)
2111 {
2112 if (offset >= 0x4000) has_extra_video_ram = 1; /* kludge for X-Men */
2113 K052109_ram[offset] = data;
2114 tilemap_mark_tile_dirty(K052109_tilemap[(offset & 0x1800) >> 11],offset & 0x7ff);
2115 }
2116 }
2117 else /* control registers */
2118 {
2119 K052109_ram[offset] = data;
2120
2121 if (offset >= 0x180c && offset < 0x1834)
2122 { /* A y scroll */ }
2123 else if (offset >= 0x1a00 && offset < 0x1c00)
2124 { /* A x scroll */ }
2125 else if (offset == 0x1c80)
2126 {
2127 if (K052109_scrollctrl != data)
2128 {
2129 /*usrintf_showmessage("scrollcontrol = %02x",data);*/
2130 /*logerror("%04x: rowscrollcontrol = %02x\n",activecpu_get_pc(),data);*/
2131 K052109_scrollctrl = data;
2132 }
2133 }
2134 else if (offset == 0x1d00)
2135 {
2136 /*logerror("%04x: 052109 register 1d00 = %02x\n",activecpu_get_pc(),data);*/
2137 /* bit 2 = irq enable */
2138 /* the custom chip can also generate NMI and FIRQ, for use with a 6809 */
2139 K052109_irq_enabled = data & 0x04;
2140 }
2141 else if (offset == 0x1d80)
2142 {
2143 int dirty = 0;
2144
2145 if (K052109_charrombank[0] != (data & 0x0f)) dirty |= 1;
2146 if (K052109_charrombank[1] != ((data >> 4) & 0x0f)) dirty |= 2;
2147 if (dirty)
2148 {
2149 int i;
2150
2151 K052109_charrombank[0] = data & 0x0f;
2152 K052109_charrombank[1] = (data >> 4) & 0x0f;
2153
2154 for (i = 0;i < 0x1800;i++)
2155 {
2156 int bank = (K052109_ram[i]&0x0c) >> 2;
2157 if ((bank == 0 && (dirty & 1)) || (bank == 1 && dirty & 2))
2158 {
2159 tilemap_mark_tile_dirty(K052109_tilemap[(i & 0x1800) >> 11],i & 0x7ff);
2160 }
2161 }
2162 }
2163 }
2164 else if (offset == 0x1e00)
2165 {
2166 /*logerror("%04x: 052109 register 1e00 = %02x\n",activecpu_get_pc(),data);*/
2167 K052109_romsubbank = data;
2168 }
2169 else if (offset == 0x1e80)
2170 {
2171 /*if ((data & 0xfe)) log_cb(RETRO_LOG_DEBUG, LOGPRE "%04x: 052109 register 1e80 = %02x\n",activecpu_get_pc(),data);*/
2172 tilemap_set_flip(K052109_tilemap[0],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
2173 tilemap_set_flip(K052109_tilemap[1],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
2174 tilemap_set_flip(K052109_tilemap[2],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
2175 if (K052109_tileflip_enable != ((data & 0x06) >> 1))
2176 {
2177 K052109_tileflip_enable = ((data & 0x06) >> 1);
2178
2179 tilemap_mark_all_tiles_dirty(K052109_tilemap[0]);
2180 tilemap_mark_all_tiles_dirty(K052109_tilemap[1]);
2181 tilemap_mark_all_tiles_dirty(K052109_tilemap[2]);
2182 }
2183 }
2184 else if (offset == 0x1f00)
2185 {
2186 int dirty = 0;
2187
2188 if (K052109_charrombank[2] != (data & 0x0f)) dirty |= 1;
2189 if (K052109_charrombank[3] != ((data >> 4) & 0x0f)) dirty |= 2;
2190 if (dirty)
2191 {
2192 int i;
2193
2194 K052109_charrombank[2] = data & 0x0f;
2195 K052109_charrombank[3] = (data >> 4) & 0x0f;
2196
2197 for (i = 0;i < 0x1800;i++)
2198 {
2199 int bank = (K052109_ram[i] & 0x0c) >> 2;
2200 if ((bank == 2 && (dirty & 1)) || (bank == 3 && dirty & 2))
2201 tilemap_mark_tile_dirty(K052109_tilemap[(i & 0x1800) >> 11],i & 0x7ff);
2202 }
2203 }
2204 }
2205 else if (offset >= 0x380c && offset < 0x3834)
2206 { /* B y scroll */ }
2207 else if (offset >= 0x3a00 && offset < 0x3c00)
2208 { /* B x scroll */ }
2209 /* else*/
2210 /*logerror("%04x: write %02x to unknown 052109 address %04x\n",activecpu_get_pc(),data,offset);*/
2211 }
2212 }
2213
READ16_HANDLER(K052109_word_r)2214 READ16_HANDLER( K052109_word_r )
2215 {
2216 return K052109_r(offset + 0x2000) | (K052109_r(offset) << 8);
2217 }
2218
WRITE16_HANDLER(K052109_word_w)2219 WRITE16_HANDLER( K052109_word_w )
2220 {
2221 if (ACCESSING_MSB)
2222 K052109_w(offset,(data >> 8) & 0xff);
2223 if (ACCESSING_LSB)
2224 K052109_w(offset + 0x2000,data & 0xff);
2225 }
2226
READ16_HANDLER(K052109_lsb_r)2227 READ16_HANDLER(K052109_lsb_r)
2228 {
2229 return K052109_r(offset);
2230 }
2231
WRITE16_HANDLER(K052109_lsb_w)2232 WRITE16_HANDLER(K052109_lsb_w)
2233 {
2234 if(ACCESSING_LSB)
2235 K052109_w(offset, data & 0xff);
2236 }
2237
K052109_set_RMRD_line(int state)2238 void K052109_set_RMRD_line(int state)
2239 {
2240 K052109_RMRD_line = state;
2241 }
2242
2243
K052109_tilemap_update(void)2244 void K052109_tilemap_update(void)
2245 {
2246 #if 0
2247 {
2248 usrintf_showmessage("%x %x %x %x",
2249 K052109_charrombank[0],
2250 K052109_charrombank[1],
2251 K052109_charrombank[2],
2252 K052109_charrombank[3]);
2253 }
2254 #endif
2255 if ((K052109_scrollctrl & 0x03) == 0x02)
2256 {
2257 int xscroll,yscroll,offs;
2258 unsigned char *scrollram = &K052109_ram[0x1a00];
2259
2260
2261 tilemap_set_scroll_rows(K052109_tilemap[1],256);
2262 tilemap_set_scroll_cols(K052109_tilemap[1],1);
2263 yscroll = K052109_ram[0x180c];
2264 tilemap_set_scrolly(K052109_tilemap[1],0,yscroll+K052109_dy[1]);
2265 for (offs = 0;offs < 256;offs++)
2266 {
2267 xscroll = scrollram[2*(offs&0xfff8)+0] + 256 * scrollram[2*(offs&0xfff8)+1];
2268 xscroll -= 6;
2269 tilemap_set_scrollx(K052109_tilemap[1],(offs+yscroll)&0xff,xscroll+K052109_dx[1]);
2270 }
2271 }
2272 else if ((K052109_scrollctrl & 0x03) == 0x03)
2273 {
2274 int xscroll,yscroll,offs;
2275 unsigned char *scrollram = &K052109_ram[0x1a00];
2276
2277
2278 tilemap_set_scroll_rows(K052109_tilemap[1],256);
2279 tilemap_set_scroll_cols(K052109_tilemap[1],1);
2280 yscroll = K052109_ram[0x180c];
2281 tilemap_set_scrolly(K052109_tilemap[1],0,yscroll+K052109_dy[1]);
2282 for (offs = 0;offs < 256;offs++)
2283 {
2284 xscroll = scrollram[2*offs+0] + 256 * scrollram[2*offs+1];
2285 xscroll -= 6;
2286 tilemap_set_scrollx(K052109_tilemap[1],(offs+yscroll)&0xff,xscroll+K052109_dx[1]);
2287 }
2288 }
2289 else if ((K052109_scrollctrl & 0x04) == 0x04)
2290 {
2291 int xscroll,yscroll,offs;
2292 unsigned char *scrollram = &K052109_ram[0x1800];
2293
2294
2295 tilemap_set_scroll_rows(K052109_tilemap[1],1);
2296 tilemap_set_scroll_cols(K052109_tilemap[1],512);
2297 xscroll = K052109_ram[0x1a00] + 256 * K052109_ram[0x1a01];
2298 xscroll -= 6;
2299 tilemap_set_scrollx(K052109_tilemap[1],0,xscroll+K052109_dx[1]);
2300 for (offs = 0;offs < 512;offs++)
2301 {
2302 yscroll = scrollram[offs/8];
2303 tilemap_set_scrolly(K052109_tilemap[1],(offs+xscroll)&0x1ff,yscroll+K052109_dy[1]);
2304 }
2305 }
2306 else
2307 {
2308 int xscroll,yscroll;
2309 unsigned char *scrollram = &K052109_ram[0x1a00];
2310
2311
2312 tilemap_set_scroll_rows(K052109_tilemap[1],1);
2313 tilemap_set_scroll_cols(K052109_tilemap[1],1);
2314 xscroll = scrollram[0] + 256 * scrollram[1];
2315 xscroll -= 6;
2316 yscroll = K052109_ram[0x180c];
2317 tilemap_set_scrollx(K052109_tilemap[1],0,xscroll+K052109_dx[1]);
2318 tilemap_set_scrolly(K052109_tilemap[1],0,yscroll+K052109_dy[1]);
2319 }
2320
2321 if ((K052109_scrollctrl & 0x18) == 0x10)
2322 {
2323 int xscroll,yscroll,offs;
2324 unsigned char *scrollram = &K052109_ram[0x3a00];
2325
2326
2327 tilemap_set_scroll_rows(K052109_tilemap[2],256);
2328 tilemap_set_scroll_cols(K052109_tilemap[2],1);
2329 yscroll = K052109_ram[0x380c];
2330 tilemap_set_scrolly(K052109_tilemap[2],0,yscroll+K052109_dy[2]);
2331 for (offs = 0;offs < 256;offs++)
2332 {
2333 xscroll = scrollram[2*(offs&0xfff8)+0] + 256 * scrollram[2*(offs&0xfff8)+1];
2334 xscroll -= 6;
2335 tilemap_set_scrollx(K052109_tilemap[2],(offs+yscroll)&0xff,xscroll+K052109_dx[2]);
2336 }
2337 }
2338 else if ((K052109_scrollctrl & 0x18) == 0x18)
2339 {
2340 int xscroll,yscroll,offs;
2341 unsigned char *scrollram = &K052109_ram[0x3a00];
2342
2343
2344 tilemap_set_scroll_rows(K052109_tilemap[2],256);
2345 tilemap_set_scroll_cols(K052109_tilemap[2],1);
2346 yscroll = K052109_ram[0x380c];
2347 tilemap_set_scrolly(K052109_tilemap[2],0,yscroll+K052109_dy[2]);
2348 for (offs = 0;offs < 256;offs++)
2349 {
2350 xscroll = scrollram[2*offs+0] + 256 * scrollram[2*offs+1];
2351 xscroll -= 6;
2352 tilemap_set_scrollx(K052109_tilemap[2],(offs+yscroll)&0xff,xscroll+K052109_dx[2]);
2353 }
2354 }
2355 else if ((K052109_scrollctrl & 0x20) == 0x20)
2356 {
2357 int xscroll,yscroll,offs;
2358 unsigned char *scrollram = &K052109_ram[0x3800];
2359
2360
2361 tilemap_set_scroll_rows(K052109_tilemap[2],1);
2362 tilemap_set_scroll_cols(K052109_tilemap[2],512);
2363 xscroll = K052109_ram[0x3a00] + 256 * K052109_ram[0x3a01];
2364 xscroll -= 6;
2365 tilemap_set_scrollx(K052109_tilemap[2],0,xscroll+K052109_dx[2]);
2366 for (offs = 0;offs < 512;offs++)
2367 {
2368 yscroll = scrollram[offs/8];
2369 tilemap_set_scrolly(K052109_tilemap[2],(offs+xscroll)&0x1ff,yscroll+K052109_dy[2]);
2370 }
2371 }
2372 else
2373 {
2374 int xscroll,yscroll;
2375 unsigned char *scrollram = &K052109_ram[0x3a00];
2376
2377
2378 tilemap_set_scroll_rows(K052109_tilemap[2],1);
2379 tilemap_set_scroll_cols(K052109_tilemap[2],1);
2380 xscroll = scrollram[0] + 256 * scrollram[1];
2381 xscroll -= 6;
2382 yscroll = K052109_ram[0x380c];
2383 tilemap_set_scrollx(K052109_tilemap[2],0,xscroll+K052109_dx[2]);
2384 tilemap_set_scrolly(K052109_tilemap[2],0,yscroll+K052109_dy[2]);
2385 }
2386
2387 #if 0
2388 if ((K052109_scrollctrl & 0x03) == 0x01 ||
2389 (K052109_scrollctrl & 0x18) == 0x08 ||
2390 ((K052109_scrollctrl & 0x04) && (K052109_scrollctrl & 0x03)) ||
2391 ((K052109_scrollctrl & 0x20) && (K052109_scrollctrl & 0x18)) ||
2392 (K052109_scrollctrl & 0xc0) != 0)
2393 usrintf_showmessage("scrollcontrol = %02x",K052109_scrollctrl);
2394
2395 if (keyboard_pressed(KEYCODE_F))
2396 {
2397 FILE *fp;
2398 fp=fopen("TILE.DMP", "w+b");
2399 if (fp)
2400 {
2401 fwrite(K052109_ram, 0x6000, 1, fp);
2402 usrintf_showmessage("saved");
2403 fclose(fp);
2404 }
2405 }
2406 #endif
2407 }
2408
K052109_is_IRQ_enabled(void)2409 int K052109_is_IRQ_enabled(void)
2410 {
2411 return K052109_irq_enabled;
2412 }
2413
K052109_set_layer_offsets(int layer,int dx,int dy)2414 void K052109_set_layer_offsets(int layer, int dx, int dy)
2415 {
2416 K052109_dx[layer] = dx;
2417 K052109_dy[layer] = dy;
2418 }
2419
2420
2421 /***************************************************************************/
2422 /* */
2423 /* 051960 */
2424 /* */
2425 /***************************************************************************/
2426
2427 static int K051960_memory_region;
2428 static struct GfxElement *K051960_gfx;
2429 static void (*K051960_callback)(int *code,int *color,int *priority,int *shadow);
2430 static int K051960_romoffset;
2431 static int K051960_spriteflip,K051960_readroms;
2432 static unsigned char K051960_spriterombank[3];
2433 static unsigned char *K051960_ram;
2434 static int K051960_irq_enabled, K051960_nmi_enabled;
2435
2436
K051960_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,void (* callback)(int * code,int * color,int * priority,int * shadow))2437 int K051960_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,
2438 void (*callback)(int *code,int *color,int *priority,int *shadow))
2439 {
2440 int gfx_index,i;
2441 static struct GfxLayout spritelayout =
2442 {
2443 16,16,
2444 0, /* filled in later */
2445 4,
2446 { 0, 0, 0, 0 }, /* filled in later */
2447 { 0, 1, 2, 3, 4, 5, 6, 7,
2448 8*32+0, 8*32+1, 8*32+2, 8*32+3, 8*32+4, 8*32+5, 8*32+6, 8*32+7 },
2449 { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32,
2450 16*32, 17*32, 18*32, 19*32, 20*32, 21*32, 22*32, 23*32 },
2451 128*8
2452 };
2453
2454
2455 /* find first empty slot to decode gfx */
2456 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
2457 if (Machine->gfx[gfx_index] == 0)
2458 break;
2459 if (gfx_index == MAX_GFX_ELEMENTS)
2460 return 1;
2461
2462 /* tweak the structure for the number of tiles we have */
2463 spritelayout.total = memory_region_length(gfx_memory_region) / 128;
2464 spritelayout.planeoffset[0] = plane0 * 8;
2465 spritelayout.planeoffset[1] = plane1 * 8;
2466 spritelayout.planeoffset[2] = plane2 * 8;
2467 spritelayout.planeoffset[3] = plane3 * 8;
2468
2469 /* decode the graphics */
2470 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&spritelayout);
2471 if (!Machine->gfx[gfx_index])
2472 return 1;
2473
2474 /* set the color information */
2475 if (Machine->drv->color_table_len)
2476 {
2477 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
2478 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
2479 }
2480 else
2481 {
2482 Machine->gfx[gfx_index]->colortable = Machine->pens;
2483 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / 16;
2484 }
2485
2486 if (!(Machine->drv->video_attributes & VIDEO_HAS_SHADOWS))
2487 log_cb(RETRO_LOG_DEBUG, LOGPRE "driver should use VIDEO_HAS_SHADOWS");
2488
2489 /* prepare shadow draw table */
2490 gfx_drawmode_table[0] = DRAWMODE_NONE;
2491 for (i = 1;i < 15;i++)
2492 gfx_drawmode_table[i] = DRAWMODE_SOURCE;
2493 gfx_drawmode_table[15] = DRAWMODE_SHADOW;
2494
2495 K051960_memory_region = gfx_memory_region;
2496 K051960_gfx = Machine->gfx[gfx_index];
2497 K051960_callback = callback;
2498 K051960_ram = auto_malloc(0x400);
2499 if (!K051960_ram) return 1;
2500 memset(K051960_ram,0,0x400);
2501
2502 return 0;
2503 }
2504
2505
K051960_fetchromdata(int byte)2506 static int K051960_fetchromdata(int byte)
2507 {
2508 int code,color,pri,shadow,off1,addr;
2509
2510
2511 addr = K051960_romoffset + (K051960_spriterombank[0] << 8) +
2512 ((K051960_spriterombank[1] & 0x03) << 16);
2513 code = (addr & 0x3ffe0) >> 5;
2514 off1 = addr & 0x1f;
2515 color = ((K051960_spriterombank[1] & 0xfc) >> 2) + ((K051960_spriterombank[2] & 0x03) << 6);
2516 pri = 0;
2517 shadow = color & 0x80;
2518 (*K051960_callback)(&code,&color,&pri,&shadow);
2519
2520 addr = (code << 7) | (off1 << 2) | byte;
2521 addr &= memory_region_length(K051960_memory_region)-1;
2522
2523 /* usrintf_showmessage("%04x: addr %06x",activecpu_get_pc(),addr);*/
2524
2525 return memory_region(K051960_memory_region)[addr];
2526 }
2527
READ_HANDLER(K051960_r)2528 READ_HANDLER( K051960_r )
2529 {
2530 if (K051960_readroms)
2531 {
2532 /* the 051960 remembers the last address read and uses it when reading the sprite ROMs */
2533 K051960_romoffset = (offset & 0x3fc) >> 2;
2534 return K051960_fetchromdata(offset & 3); /* only 88 Games reads the ROMs from here */
2535 }
2536 else
2537 return K051960_ram[offset];
2538 }
2539
WRITE_HANDLER(K051960_w)2540 WRITE_HANDLER( K051960_w )
2541 {
2542 K051960_ram[offset] = data;
2543 }
2544
READ16_HANDLER(K051960_word_r)2545 READ16_HANDLER( K051960_word_r )
2546 {
2547 return K051960_r(offset*2 + 1) | (K051960_r(offset*2) << 8);
2548 }
2549
WRITE16_HANDLER(K051960_word_w)2550 WRITE16_HANDLER( K051960_word_w )
2551 {
2552 if (ACCESSING_MSB)
2553 K051960_w(offset*2,(data >> 8) & 0xff);
2554 if (ACCESSING_LSB)
2555 K051960_w(offset*2 + 1,data & 0xff);
2556 }
2557
READ_HANDLER(K051937_r)2558 READ_HANDLER( K051937_r )
2559 {
2560 if (K051960_readroms && offset >= 4 && offset < 8)
2561 {
2562 return K051960_fetchromdata(offset & 3);
2563 }
2564 else
2565 {
2566 if (offset == 0)
2567 {
2568 static int counter;
2569
2570 /* some games need bit 0 to pulse */
2571 return (counter++) & 1;
2572 }
2573 /*logerror("%04x: read unknown 051937 address %x\n",activecpu_get_pc(),offset);*/
2574 return 0;
2575 }
2576 }
2577
WRITE_HANDLER(K051937_w)2578 WRITE_HANDLER( K051937_w )
2579 {
2580 if (offset == 0)
2581 {
2582
2583 /*if (data & 0xc2) usrintf_showmessage("051937 reg 00 = %02x",data);*/
2584
2585 /* bit 0 is IRQ enable */
2586 K051960_irq_enabled = (data & 0x01);
2587
2588 /* bit 1: probably FIRQ enable */
2589
2590 /* bit 2 is NMI enable */
2591 K051960_nmi_enabled = (data & 0x04);
2592
2593 /* bit 3 = flip screen */
2594 K051960_spriteflip = data & 0x08;
2595
2596 /* bit 4 used by Devastators and TMNT, unknown */
2597
2598 /* bit 5 = enable gfx ROM reading */
2599 K051960_readroms = data & 0x20;
2600 /*logerror("%04x: write %02x to 051937 address %x\n",activecpu_get_pc(),data,offset);*/
2601 }
2602 else if (offset == 1)
2603 {
2604 /* usrintf_showmessage("%04x: write %02x to 051937 address %x",activecpu_get_pc(),data,offset);*/
2605 /*logerror("%04x: write %02x to unknown 051937 address %x\n",activecpu_get_pc(),data,offset);*/
2606 }
2607 else if (offset >= 2 && offset < 5)
2608 {
2609 K051960_spriterombank[offset - 2] = data;
2610 }
2611 else
2612 {
2613 /* usrintf_showmessage("%04x: write %02x to 051937 address %x",activecpu_get_pc(),data,offset);*/
2614 /*logerror("%04x: write %02x to unknown 051937 address %x\n",activecpu_get_pc(),data,offset);*/
2615 }
2616 }
2617
READ16_HANDLER(K051937_word_r)2618 READ16_HANDLER( K051937_word_r )
2619 {
2620 return K051937_r(offset*2 + 1) | (K051937_r(offset*2) << 8);
2621 }
2622
WRITE16_HANDLER(K051937_word_w)2623 WRITE16_HANDLER( K051937_word_w )
2624 {
2625 if (ACCESSING_MSB)
2626 K051937_w(offset*2,(data >> 8) & 0xff);
2627 if (ACCESSING_LSB)
2628 K051937_w(offset*2 + 1,data & 0xff);
2629 }
2630
2631
2632 /*
2633 * Sprite Format
2634 * ------------------
2635 *
2636 * Byte | Bit(s) | Use
2637 * -----+-76543210-+----------------
2638 * 0 | x------- | active (show this sprite)
2639 * 0 | -xxxxxxx | priority order
2640 * 1 | xxx----- | sprite size (see below)
2641 * 1 | ---xxxxx | sprite code (high 5 bits)
2642 * 2 | xxxxxxxx | sprite code (low 8 bits)
2643 * 3 | xxxxxxxx | "color", but depends on external connections (see below)
2644 * 4 | xxxxxx-- | zoom y (0 = normal, >0 = shrink)
2645 * 4 | ------x- | flip y
2646 * 4 | -------x | y position (high bit)
2647 * 5 | xxxxxxxx | y position (low 8 bits)
2648 * 6 | xxxxxx-- | zoom x (0 = normal, >0 = shrink)
2649 * 6 | ------x- | flip x
2650 * 6 | -------x | x position (high bit)
2651 * 7 | xxxxxxxx | x position (low 8 bits)
2652 *
2653 * Example of "color" field for Punk Shot:
2654 * 3 | x------- | shadow
2655 * 3 | -xx----- | priority
2656 * 3 | ---x---- | use second gfx ROM bank
2657 * 3 | ----xxxx | color code
2658 *
2659 * shadow enables transparent shadows. Note that it applies to pen 0x0f ONLY.
2660 * The rest of the sprite remains normal.
2661 * Note that Aliens also uses the shadow bit to select the second sprite bank.
2662 */
2663
K051960_sprites_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int min_priority,int max_priority)2664 void K051960_sprites_draw(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int min_priority,int max_priority)
2665 {
2666 #define NUM_SPRITES 128
2667 int offs,pri_code;
2668 int sortedlist[NUM_SPRITES];
2669
2670 for (offs = 0;offs < NUM_SPRITES;offs++)
2671 sortedlist[offs] = -1;
2672
2673 /* prebuild a sorted table */
2674 for (offs = 0;offs < 0x400;offs += 8)
2675 {
2676 if (K051960_ram[offs] & 0x80)
2677 {
2678 if (max_priority == -1) /* draw front to back when using priority buffer */
2679 sortedlist[(K051960_ram[offs] & 0x7f) ^ 0x7f] = offs;
2680 else
2681 sortedlist[K051960_ram[offs] & 0x7f] = offs;
2682 }
2683 }
2684
2685 for (pri_code = 0;pri_code < NUM_SPRITES;pri_code++)
2686 {
2687 int ox,oy,code,color,pri,shadow,size,w,h,x,y,flipx,flipy,zoomx,zoomy;
2688 /* sprites can be grouped up to 8x8. The draw order is
2689 0 1 4 5 16 17 20 21
2690 2 3 6 7 18 19 22 23
2691 8 9 12 13 24 25 28 29
2692 10 11 14 15 26 27 30 31
2693 32 33 36 37 48 49 52 53
2694 34 35 38 39 50 51 54 55
2695 40 41 44 45 56 57 60 61
2696 42 43 46 47 58 59 62 63
2697 */
2698 static int xoffset[8] = { 0, 1, 4, 5, 16, 17, 20, 21 };
2699 static int yoffset[8] = { 0, 2, 8, 10, 32, 34, 40, 42 };
2700 static int width[8] = { 1, 2, 1, 2, 4, 2, 4, 8 };
2701 static int height[8] = { 1, 1, 2, 2, 2, 4, 4, 8 };
2702
2703
2704 offs = sortedlist[pri_code];
2705 if (offs == -1) continue;
2706
2707 code = K051960_ram[offs+2] + ((K051960_ram[offs+1] & 0x1f) << 8);
2708 color = K051960_ram[offs+3] & 0xff;
2709 pri = 0;
2710 shadow = color & 0x80;
2711 (*K051960_callback)(&code,&color,&pri,&shadow);
2712
2713 if (max_priority != -1)
2714 if (pri < min_priority || pri > max_priority) continue;
2715
2716 size = (K051960_ram[offs+1] & 0xe0) >> 5;
2717 w = width[size];
2718 h = height[size];
2719
2720 if (w >= 2) code &= ~0x01;
2721 if (h >= 2) code &= ~0x02;
2722 if (w >= 4) code &= ~0x04;
2723 if (h >= 4) code &= ~0x08;
2724 if (w >= 8) code &= ~0x10;
2725 if (h >= 8) code &= ~0x20;
2726
2727 ox = (256 * K051960_ram[offs+6] + K051960_ram[offs+7]) & 0x01ff;
2728 oy = 256 - ((256 * K051960_ram[offs+4] + K051960_ram[offs+5]) & 0x01ff);
2729 flipx = K051960_ram[offs+6] & 0x02;
2730 flipy = K051960_ram[offs+4] & 0x02;
2731 zoomx = (K051960_ram[offs+6] & 0xfc) >> 2;
2732 zoomy = (K051960_ram[offs+4] & 0xfc) >> 2;
2733 zoomx = 0x10000 / 128 * (128 - zoomx);
2734 zoomy = 0x10000 / 128 * (128 - zoomy);
2735
2736 if (K051960_spriteflip)
2737 {
2738 ox = 512 - (zoomx * w >> 12) - ox;
2739 oy = 256 - (zoomy * h >> 12) - oy;
2740 flipx = !flipx;
2741 flipy = !flipy;
2742 }
2743
2744 if (zoomx == 0x10000 && zoomy == 0x10000)
2745 {
2746 int sx,sy;
2747
2748 for (y = 0;y < h;y++)
2749 {
2750 sy = oy + 16 * y;
2751
2752 for (x = 0;x < w;x++)
2753 {
2754 int c = code;
2755
2756 sx = ox + 16 * x;
2757 if (flipx) c += xoffset[(w-1-x)];
2758 else c += xoffset[x];
2759 if (flipy) c += yoffset[(h-1-y)];
2760 else c += yoffset[y];
2761
2762 if (max_priority == -1)
2763 pdrawgfx(bitmap,K051960_gfx,
2764 c,
2765 color,
2766 flipx,flipy,
2767 sx & 0x1ff,sy,
2768 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,pri);
2769 else
2770 drawgfx(bitmap,K051960_gfx,
2771 c,
2772 color,
2773 flipx,flipy,
2774 sx & 0x1ff,sy,
2775 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0);
2776 }
2777 }
2778 }
2779 else
2780 {
2781 int sx,sy,zw,zh;
2782
2783 for (y = 0;y < h;y++)
2784 {
2785 sy = oy + ((zoomy * y + (1<<11)) >> 12);
2786 zh = (oy + ((zoomy * (y+1) + (1<<11)) >> 12)) - sy;
2787
2788 for (x = 0;x < w;x++)
2789 {
2790 int c = code;
2791
2792 sx = ox + ((zoomx * x + (1<<11)) >> 12);
2793 zw = (ox + ((zoomx * (x+1) + (1<<11)) >> 12)) - sx;
2794 if (flipx) c += xoffset[(w-1-x)];
2795 else c += xoffset[x];
2796 if (flipy) c += yoffset[(h-1-y)];
2797 else c += yoffset[y];
2798
2799 if (max_priority == -1)
2800 pdrawgfxzoom(bitmap,K051960_gfx,
2801 c,
2802 color,
2803 flipx,flipy,
2804 sx & 0x1ff,sy,
2805 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,
2806 (zw << 16) / 16,(zh << 16) / 16,pri);
2807 else
2808 drawgfxzoom(bitmap,K051960_gfx,
2809 c,
2810 color,
2811 flipx,flipy,
2812 sx & 0x1ff,sy,
2813 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,
2814 (zw << 16) / 16,(zh << 16) / 16);
2815 }
2816 }
2817 }
2818 }
2819 #if 0
2820 if (keyboard_pressed(KEYCODE_D))
2821 {
2822 FILE *fp;
2823 fp=fopen("SPRITE.DMP", "w+b");
2824 if (fp)
2825 {
2826 fwrite(K051960_ram, 0x400, 1, fp);
2827 usrintf_showmessage("saved");
2828 fclose(fp);
2829 }
2830 }
2831 #endif
2832 #undef NUM_SPRITES
2833 }
2834
K051960_is_IRQ_enabled(void)2835 int K051960_is_IRQ_enabled(void)
2836 {
2837 return K051960_irq_enabled;
2838 }
2839
K051960_is_NMI_enabled(void)2840 int K051960_is_NMI_enabled(void)
2841 {
2842 return K051960_nmi_enabled;
2843 }
2844
2845
2846
2847
READ_HANDLER(K052109_051960_r)2848 READ_HANDLER( K052109_051960_r )
2849 {
2850 if (K052109_RMRD_line == CLEAR_LINE)
2851 {
2852 if (offset >= 0x3800 && offset < 0x3808)
2853 return K051937_r(offset - 0x3800);
2854 else if (offset < 0x3c00)
2855 return K052109_r(offset);
2856 else
2857 return K051960_r(offset - 0x3c00);
2858 }
2859 else return K052109_r(offset);
2860 }
2861
WRITE_HANDLER(K052109_051960_w)2862 WRITE_HANDLER( K052109_051960_w )
2863 {
2864 if (offset >= 0x3800 && offset < 0x3808)
2865 K051937_w(offset - 0x3800,data);
2866 else if (offset < 0x3c00)
2867 K052109_w(offset,data);
2868 else
2869 K051960_w(offset - 0x3c00,data);
2870 }
2871
2872
2873
2874 /***************************************************************************/
2875 /* */
2876 /* 05324x Family Sprite Generators */
2877 /* */
2878 /***************************************************************************/
2879
2880 static int K05324x_z_rejection = -1;
2881
2882 /*
2883 In a K053247+K055555 setup objects with Z-code 0x00 should be ignored
2884 when PRFLIP is cleared, while objects with Z-code 0xff should be
2885 ignored when PRFLIP is set.
2886
2887 These behaviors can also be seen in older K053245(6)+K053251 setups.
2888 Bucky'O Hare, The Simpsons and Sunset Riders rely on their implications
2889 to prepare and retire sprites. They probably apply to many other Konami
2890 games but it's hard to tell because most artifacts have been filtered
2891 by exclusion sort.
2892
2893 A driver may call K05324x_set_z_rejection() to set which zcode to ignore.
2894 Parameter:
2895 -1 = accept all(default)
2896 0x00-0xff = zcode to ignore
2897 */
K05324x_set_z_rejection(int zcode)2898 void K05324x_set_z_rejection(int zcode)
2899 {
2900 K05324x_z_rejection = zcode;
2901 }
2902
2903
2904
2905 /***************************************************************************/
2906 /* */
2907 /* 053245 */
2908 /* */
2909 /***************************************************************************/
2910
2911 #define MAX_K053245_CHIPS 2
2912
2913 static int K053245_memory_region[MAX_K053245_CHIPS];
2914 static struct GfxElement *K053245_gfx[MAX_K053245_CHIPS];
2915 static void (*K053245_callback[MAX_K053245_CHIPS])(int *code,int *color,int *priority);
2916 static int K053244_rombank[MAX_K053245_CHIPS];
2917 static int K053245_ramsize[MAX_K053245_CHIPS];
2918 static data16_t *K053245_ram[MAX_K053245_CHIPS], *K053245_buffer[MAX_K053245_CHIPS];
2919 static data8_t K053244_regs[MAX_K053245_CHIPS][0x10];
2920 static int K053245_dx[MAX_K053245_CHIPS], K053245_dy[MAX_K053245_CHIPS];
2921
K053245_vh_start(int chip,int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,void (* callback)(int * code,int * color,int * priority))2922 int K053245_vh_start(int chip, int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,
2923 void (*callback)(int *code,int *color,int *priority))
2924 {
2925 int gfx_index,i;
2926 static struct GfxLayout spritelayout =
2927 {
2928 16,16,
2929 0, /* filled in later */
2930 4,
2931 { 0, 0, 0, 0 }, /* filled in later */
2932 { 0, 1, 2, 3, 4, 5, 6, 7,
2933 8*32+0, 8*32+1, 8*32+2, 8*32+3, 8*32+4, 8*32+5, 8*32+6, 8*32+7 },
2934 { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32,
2935 16*32, 17*32, 18*32, 19*32, 20*32, 21*32, 22*32, 23*32 },
2936 128*8
2937 };
2938
2939 if (chip>=MAX_K053245_CHIPS)
2940 {
2941 printf("K053245_vh_start chip >= MAX_K053245_CHIPS\n");
2942 return 1;
2943 }
2944
2945 K053245_memory_region[chip]=2;
2946
2947
2948
2949 /* find first empty slot to decode gfx */
2950 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
2951 if (Machine->gfx[gfx_index] == 0)
2952 break;
2953 if (gfx_index == MAX_GFX_ELEMENTS)
2954 return 1;
2955
2956 /* tweak the structure for the number of tiles we have */
2957 spritelayout.total = memory_region_length(gfx_memory_region) / 128;
2958 spritelayout.planeoffset[0] = plane3 * 8;
2959 spritelayout.planeoffset[1] = plane2 * 8;
2960 spritelayout.planeoffset[2] = plane1 * 8;
2961 spritelayout.planeoffset[3] = plane0 * 8;
2962
2963 /* decode the graphics */
2964 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&spritelayout);
2965 if (!Machine->gfx[gfx_index])
2966 return 1;
2967
2968 /* set the color information */
2969 if (Machine->drv->color_table_len)
2970 {
2971 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
2972 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
2973 }
2974 else
2975 {
2976 Machine->gfx[gfx_index]->colortable = Machine->pens;
2977 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / 16;
2978 }
2979
2980
2981 if (!(Machine->drv->video_attributes & VIDEO_HAS_SHADOWS))
2982 log_cb(RETRO_LOG_DEBUG, LOGPRE "driver should use VIDEO_HAS_SHADOWS");
2983
2984 /* prepare shadow draw table */
2985 gfx_drawmode_table[0] = DRAWMODE_NONE;
2986 for (i = 1;i < 15;i++)
2987 gfx_drawmode_table[i] = DRAWMODE_SOURCE;
2988 gfx_drawmode_table[15] = DRAWMODE_SHADOW;
2989 K05324x_z_rejection = -1;
2990 K053245_memory_region[chip] = gfx_memory_region;
2991 K053245_gfx[chip] = Machine->gfx[gfx_index];
2992 K053245_callback[chip] = callback;
2993 K053244_rombank[chip] = 0;
2994 K053245_ramsize[chip] = 0x800;
2995 K053245_ram[chip] = auto_malloc(K053245_ramsize[chip]);
2996 K053245_dx[chip] = K053245_dy[chip] = 0;
2997 if (!K053245_ram[chip]) return 1;
2998
2999 K053245_buffer[chip] = auto_malloc(K053245_ramsize[chip]);
3000 if (!K053245_buffer[chip])
3001 return 1;
3002
3003 memset(K053245_ram[chip],0,K053245_ramsize[chip]);
3004 memset(K053245_buffer[chip],0,K053245_ramsize[chip]);
3005
3006 return 0;
3007 }
3008
K053245_set_SpriteOffset(int chip,int offsx,int offsy)3009 void K053245_set_SpriteOffset(int chip,int offsx, int offsy)
3010 {
3011 K053245_dx[chip] = offsx;
3012 K053245_dy[chip] = offsy;
3013 }
3014
READ16_HANDLER(K053245_word_r)3015 READ16_HANDLER( K053245_word_r )
3016 {
3017 return K053245_ram[0][offset];
3018 }
3019
WRITE16_HANDLER(K053245_word_w)3020 WRITE16_HANDLER( K053245_word_w )
3021 {
3022 COMBINE_DATA(K053245_ram[0]+offset);
3023 }
3024
READ_HANDLER(K053245_r)3025 READ_HANDLER( K053245_r )
3026 {
3027 if(offset & 1)
3028 return K053245_ram[0][offset>>1] & 0xff;
3029 else
3030 return (K053245_ram[0][offset>>1]>>8) & 0xff;
3031 }
3032
3033
K053245_chip_w(int chip,int offset,int data)3034 void K053245_chip_w(int chip,int offset,int data)
3035 {
3036 if(offset & 1)
3037 K053245_ram[chip][offset>>1] = (K053245_ram[chip][offset>>1] & 0xff00) | data;
3038 else
3039 K053245_ram[chip][offset>>1] = (K053245_ram[chip][offset>>1] & 0x00ff) | (data<<8);
3040 }
3041
WRITE_HANDLER(K053245_w)3042 WRITE_HANDLER( K053245_w )
3043 {
3044 K053245_chip_w(0,offset,data);
3045 }
3046
3047 /* 2nd chip */
WRITE_HANDLER(K053245_1_w)3048 WRITE_HANDLER( K053245_1_w )
3049 {
3050 K053245_chip_w(1,offset,data);
3051 }
3052
K053245_clear_buffer(int chip)3053 void K053245_clear_buffer(int chip)
3054 {
3055 int i, e;
3056 for (e=K053245_ramsize[chip]/2, i=0; i<e; i+=8) K053245_buffer[chip][i] = 0;
3057 }
3058
K053245_update_buffer(int chip)3059 static INLINE void K053245_update_buffer( int chip )
3060 {
3061 memcpy(K053245_buffer[chip], K053245_ram[chip], K053245_ramsize[chip]);
3062 }
3063
K053244_chip_r(int chip,int offset)3064 UINT8 K053244_chip_r (int chip, int offset)
3065 {
3066 if ((K053244_regs[chip][5] & 0x10) && offset >= 0x0c && offset < 0x10)
3067 {
3068 int addr;
3069
3070 addr = (K053244_rombank[chip] << 19) | ((K053244_regs[chip][11] & 0x7) << 18)
3071 | (K053244_regs[chip][8] << 10) | (K053244_regs[chip][9] << 2)
3072 | ((offset & 3) ^ 1);
3073 addr &= memory_region_length(K053245_memory_region[chip])-1;
3074
3075 /* usrintf_showmessage("%04x: offset %02x addr %06x",activecpu_get_pc(),offset&3,addr);*/
3076
3077 return memory_region(K053245_memory_region[chip])[addr];
3078 }
3079 else if (offset == 0x06)
3080 {
3081 K053245_update_buffer(chip);
3082 return 0;
3083 }
3084 else
3085 {
3086 /*logerror("%04x: read from unknown 053244 address %x\n",activecpu_get_pc(),offset);*/
3087 return 0;
3088 }
3089 }
3090
READ_HANDLER(K053244_r)3091 READ_HANDLER( K053244_r )
3092 {
3093 return K053244_chip_r(0,offset);
3094 }
3095
K053244_chip_w(int chip,int offset,int data)3096 void K053244_chip_w(int chip, int offset, int data)
3097 {
3098 K053244_regs[chip][offset] = data;
3099
3100 switch(offset) {
3101 case 0x05: {
3102 /* if (data & 0xc8)*/
3103 /* usrintf_showmessage("053244 reg 05 = %02x",data);*/
3104 /* bit 2 = unknown, Parodius uses it */
3105 /* bit 5 = unknown, Rollergames uses it */
3106 /* log_cb(RETRO_LOG_DEBUG, LOGPRE "%04x: write %02x to 053244 address 5\n",activecpu_get_pc(),data);*/
3107 break;
3108 }
3109 case 0x06:
3110 K053245_update_buffer(chip);
3111 break;
3112 }
3113 }
3114
WRITE_HANDLER(K053244_w)3115 WRITE_HANDLER( K053244_w )
3116 {
3117 K053244_chip_w(0,offset,data);
3118 }
3119
3120 /* 2nd chip */
WRITE_HANDLER(K053244_1_w)3121 WRITE_HANDLER( K053244_1_w )
3122 {
3123 K053244_chip_w(1,offset,data);
3124 }
3125
3126
READ16_HANDLER(K053244_lsb_r)3127 READ16_HANDLER( K053244_lsb_r )
3128 {
3129 return K053244_r(offset);
3130 }
3131
WRITE16_HANDLER(K053244_lsb_w)3132 WRITE16_HANDLER( K053244_lsb_w )
3133 {
3134 if (ACCESSING_LSB)
3135 K053244_w(offset, data & 0xff);
3136 }
3137
READ16_HANDLER(K053244_word_r)3138 READ16_HANDLER( K053244_word_r )
3139 {
3140 return (K053244_r(offset*2)<<8)|K053244_r(offset*2+1);
3141 }
3142
WRITE16_HANDLER(K053244_word_w)3143 WRITE16_HANDLER( K053244_word_w )
3144 {
3145 if (ACCESSING_MSB)
3146 K053244_w(offset*2, (data >> 8) & 0xff);
3147 if (ACCESSING_LSB)
3148 K053244_w(offset*2+1, data & 0xff);
3149 }
3150
K053244_bankselect(int chip,int bank)3151 void K053244_bankselect(int chip, int bank)
3152 {
3153 K053244_rombank[chip] = bank;
3154 }
3155
3156 /*
3157 * Sprite Format
3158 * ------------------
3159 *
3160 * Word | Bit(s) | Use
3161 * -----+-fedcba9876543210-+----------------
3162 * 0 | x--------------- | active (show this sprite)
3163 * 0 | -x-------------- | maintain aspect ratio (when set, zoom y acts on both axis)
3164 * 0 | --x------------- | flip y
3165 * 0 | ---x------------ | flip x
3166 * 0 | ----xxxx-------- | sprite size (see below)
3167 * 0 | ---------xxxxxxx | priority order
3168 * 1 | --xxxxxxxxxxxxxx | sprite code. We use an additional bit in TMNT2, but this is
3169 * probably not accurate (protection related so we can't verify)
3170 * 2 | ------xxxxxxxxxx | y position
3171 * 3 | ------xxxxxxxxxx | x position
3172 * 4 | xxxxxxxxxxxxxxxx | zoom y (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
3173 * 5 | xxxxxxxxxxxxxxxx | zoom x (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
3174 * 6 | ------x--------- | mirror y (top half is drawn as mirror image of the bottom)
3175 * 6 | -------x-------- | mirror x (right half is drawn as mirror image of the left)
3176 * 6 | --------x------- | shadow
3177 * 6 | ---------xxxxxxx | "color", but depends on external connections
3178 * 7 | ---------------- |
3179 *
3180 * shadow enables transparent shadows. Note that it applies to pen 0x0f ONLY.
3181 * The rest of the sprite remains normal.
3182 */
3183
K053245_sprites_draw(int chip,struct mame_bitmap * bitmap,const struct rectangle * cliprect)3184 void K053245_sprites_draw(int chip, struct mame_bitmap *bitmap,const struct rectangle *cliprect)
3185 {
3186 #define NUM_SPRITES 128
3187 int offs,pri_code,i;
3188 int sortedlist[NUM_SPRITES];
3189 int flipscreenX, flipscreenY, spriteoffsX, spriteoffsY;
3190
3191 flipscreenX = K053244_regs[chip][5] & 0x01;
3192 flipscreenY = K053244_regs[chip][5] & 0x02;
3193 spriteoffsX = (K053244_regs[chip][0] << 8) | K053244_regs[chip][1];
3194 spriteoffsY = (K053244_regs[chip][2] << 8) | K053244_regs[chip][3];
3195
3196 for (offs = 0;offs < NUM_SPRITES;offs++)
3197 sortedlist[offs] = -1;
3198
3199 /* prebuild a sorted table */
3200 for (i=K053245_ramsize[chip]/2, offs=0; offs<i; offs+=8)
3201 {
3202 pri_code = K053245_buffer[chip][offs];
3203 if (pri_code & 0x8000)
3204 {
3205 pri_code &= 0x007f;
3206
3207 if (offs && pri_code == K05324x_z_rejection) continue;
3208
3209 if (sortedlist[pri_code] == -1) sortedlist[pri_code] = offs;
3210 }
3211 }
3212
3213 for (pri_code = NUM_SPRITES-1;pri_code >= 0;pri_code--)
3214 {
3215 int ox,oy,color,code,size,w,h,x,y,flipx,flipy,mirrorx,mirrory,shadow,zoomx,zoomy,pri;
3216
3217 offs = sortedlist[pri_code];
3218 if (offs == -1) continue;
3219
3220 /* the following changes the sprite draw order from
3221 0 1 4 5 16 17 20 21
3222 2 3 6 7 18 19 22 23
3223 8 9 12 13 24 25 28 29
3224 10 11 14 15 26 27 30 31
3225 32 33 36 37 48 49 52 53
3226 34 35 38 39 50 51 54 55
3227 40 41 44 45 56 57 60 61
3228 42 43 46 47 58 59 62 63
3229
3230 to
3231
3232 0 1 2 3 4 5 6 7
3233 8 9 10 11 12 13 14 15
3234 16 17 18 19 20 21 22 23
3235 24 25 26 27 28 29 30 31
3236 32 33 34 35 36 37 38 39
3237 40 41 42 43 44 45 46 47
3238 48 49 50 51 52 53 54 55
3239 56 57 58 59 60 61 62 63
3240 */
3241
3242 /* NOTE: from the schematics, it looks like the top 2 bits should be ignored */
3243 /* (there are not output pins for them), and probably taken from the "color" */
3244 /* field to do bank switching. However this applies only to TMNT2, with its */
3245 /* protection mcu creating the sprite table, so we don't know where to fetch */
3246 /* the bits from. */
3247 code = K053245_buffer[chip][offs+1];
3248 code = ((code & 0xffe1) + ((code & 0x0010) >> 2) + ((code & 0x0008) << 1)
3249 + ((code & 0x0004) >> 1) + ((code & 0x0002) << 2));
3250 color = K053245_buffer[chip][offs+6] & 0x00ff;
3251 pri = 0;
3252
3253 (*K053245_callback[chip])(&code,&color,&pri);
3254
3255 size = (K053245_buffer[chip][offs] & 0x0f00) >> 8;
3256
3257 w = 1 << (size & 0x03);
3258 h = 1 << ((size >> 2) & 0x03);
3259
3260 /* zoom control:
3261 0x40 = normal scale
3262 <0x40 enlarge (0x20 = double size)
3263 >0x40 reduce (0x80 = half size)
3264 */
3265 zoomy = K053245_buffer[chip][offs+4];
3266 if (zoomy > 0x2000) continue;
3267 if (zoomy) zoomy = (0x400000+zoomy/2) / zoomy;
3268 else zoomy = 2 * 0x400000;
3269 if ((K053245_buffer[chip][offs] & 0x4000) == 0)
3270 {
3271 zoomx = K053245_buffer[chip][offs+5];
3272 if (zoomx > 0x2000) continue;
3273 if (zoomx) zoomx = (0x400000+zoomx/2) / zoomx;
3274 else zoomx = 2 * 0x400000;
3275 /* else zoomx = zoomy; workaround for TMNT2 */
3276 }
3277 else zoomx = zoomy;
3278
3279 ox = K053245_buffer[chip][offs+3] + spriteoffsX;
3280 oy = K053245_buffer[chip][offs+2];
3281
3282 ox += K053245_dx[chip];
3283 oy += K053245_dy[chip];
3284
3285 flipx = K053245_buffer[chip][offs] & 0x1000;
3286 flipy = K053245_buffer[chip][offs] & 0x2000;
3287 mirrorx = K053245_buffer[chip][offs+6] & 0x0100;
3288 if (mirrorx) flipx = 0; /* documented and confirmed */
3289 mirrory = K053245_buffer[chip][offs+6] & 0x0200;
3290 shadow = K053245_buffer[chip][offs+6] & 0x0080;
3291
3292 if (flipscreenX)
3293 {
3294 ox = 512 - ox;
3295 if (!mirrorx) flipx = !flipx;
3296 }
3297 if (flipscreenY)
3298 {
3299 oy = -oy;
3300 if (!mirrory) flipy = !flipy;
3301 }
3302
3303 ox = (ox + 0x5d) & 0x3ff;
3304 if (ox >= 768) ox -= 1024;
3305 oy = (-(oy + spriteoffsY + 0x07)) & 0x3ff;
3306 if (oy >= 640) oy -= 1024;
3307
3308 /* the coordinates given are for the *center* of the sprite */
3309 ox -= (zoomx * w) >> 13;
3310 oy -= (zoomy * h) >> 13;
3311
3312 for (y = 0;y < h;y++)
3313 {
3314 int sx,sy,zw,zh;
3315
3316 sy = oy + ((zoomy * y + (1<<11)) >> 12);
3317 zh = (oy + ((zoomy * (y+1) + (1<<11)) >> 12)) - sy;
3318
3319 for (x = 0;x < w;x++)
3320 {
3321 int c,fx,fy;
3322
3323 sx = ox + ((zoomx * x + (1<<11)) >> 12);
3324 zw = (ox + ((zoomx * (x+1) + (1<<11)) >> 12)) - sx;
3325 c = code;
3326 if (mirrorx)
3327 {
3328 if ((flipx == 0) ^ (2*x < w))
3329 {
3330 /* mirror left/right */
3331 c += (w-x-1);
3332 fx = 1;
3333 }
3334 else
3335 {
3336 c += x;
3337 fx = 0;
3338 }
3339 }
3340 else
3341 {
3342 if (flipx) c += w-1-x;
3343 else c += x;
3344 fx = flipx;
3345 }
3346 if (mirrory)
3347 {
3348 if ((flipy == 0) ^ (2*y >= h))
3349 {
3350 /* mirror top/bottom */
3351 c += 8*(h-y-1);
3352 fy = 1;
3353 }
3354 else
3355 {
3356 c += 8*y;
3357 fy = 0;
3358 }
3359 }
3360 else
3361 {
3362 if (flipy) c += 8*(h-1-y);
3363 else c += 8*y;
3364 fy = flipy;
3365 }
3366
3367 /* the sprite can start at any point in the 8x8 grid, but it must stay */
3368 /* in a 64 entries window, wrapping around at the edges. The animation */
3369 /* at the end of the saloon level in Sunset Riders breaks otherwise. */
3370 c = (c & 0x3f) | (code & ~0x3f);
3371
3372 if (zoomx == 0x10000 && zoomy == 0x10000)
3373 {
3374 pdrawgfx(bitmap,K053245_gfx[chip],
3375 c,
3376 color,
3377 fx,fy,
3378 sx,sy,
3379 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,pri);
3380 }
3381 else
3382 {
3383 pdrawgfxzoom(bitmap,K053245_gfx[chip],
3384 c,
3385 color,
3386 fx,fy,
3387 sx,sy,
3388 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,
3389 (zw << 16) / 16,(zh << 16) / 16,pri);
3390
3391 }
3392 }
3393 }
3394 }
3395 #if 0
3396 if (keyboard_pressed(KEYCODE_D))
3397 {
3398 FILE *fp;
3399 fp=fopen("SPRITE.DMP", "w+b");
3400 if (fp)
3401 {
3402 fwrite(K053245_buffer, 0x800, 1, fp);
3403 usrintf_showmessage("saved");
3404 fclose(fp);
3405 }
3406 }
3407 #endif
3408 #undef NUM_SPRITES
3409 }
3410
3411 /* Lethal Enforcers has 2 of these chips hooked up in parallel to give 6bpp gfx.. lets cheat a
3412 bit and make emulating it a little less messy by using a custom function instead */
K053245_sprites_draw_lethal(int chip,struct mame_bitmap * bitmap,const struct rectangle * cliprect)3413 void K053245_sprites_draw_lethal(int chip, struct mame_bitmap *bitmap,const struct rectangle *cliprect)
3414 {
3415 #define NUM_SPRITES 128
3416 int offs,pri_code,i;
3417 int sortedlist[NUM_SPRITES];
3418 int flipscreenX, flipscreenY, spriteoffsX, spriteoffsY;
3419
3420 flipscreenX = K053244_regs[chip][5] & 0x01;
3421 flipscreenY = K053244_regs[chip][5] & 0x02;
3422 spriteoffsX = (K053244_regs[chip][0] << 8) | K053244_regs[chip][1];
3423 spriteoffsY = (K053244_regs[chip][2] << 8) | K053244_regs[chip][3];
3424
3425 for (offs = 0;offs < NUM_SPRITES;offs++)
3426 sortedlist[offs] = -1;
3427
3428 /* prebuild a sorted table */
3429 for (i=K053245_ramsize[chip]/2, offs=0; offs<i; offs+=8)
3430 {
3431 pri_code = K053245_buffer[chip][offs];
3432 if (pri_code & 0x8000)
3433 {
3434 pri_code &= 0x007f;
3435
3436 if (offs && pri_code == K05324x_z_rejection) continue;
3437
3438 if (sortedlist[pri_code] == -1) sortedlist[pri_code] = offs;
3439 }
3440 }
3441
3442 for (pri_code = NUM_SPRITES-1;pri_code >= 0;pri_code--)
3443 {
3444 int ox,oy,color,code,size,w,h,x,y,flipx,flipy,mirrorx,mirrory,shadow,zoomx,zoomy,pri;
3445
3446 offs = sortedlist[pri_code];
3447 if (offs == -1) continue;
3448
3449 /* the following changes the sprite draw order from
3450 0 1 4 5 16 17 20 21
3451 2 3 6 7 18 19 22 23
3452 8 9 12 13 24 25 28 29
3453 10 11 14 15 26 27 30 31
3454 32 33 36 37 48 49 52 53
3455 34 35 38 39 50 51 54 55
3456 40 41 44 45 56 57 60 61
3457 42 43 46 47 58 59 62 63
3458
3459 to
3460
3461 0 1 2 3 4 5 6 7
3462 8 9 10 11 12 13 14 15
3463 16 17 18 19 20 21 22 23
3464 24 25 26 27 28 29 30 31
3465 32 33 34 35 36 37 38 39
3466 40 41 42 43 44 45 46 47
3467 48 49 50 51 52 53 54 55
3468 56 57 58 59 60 61 62 63
3469 */
3470
3471 /* NOTE: from the schematics, it looks like the top 2 bits should be ignored */
3472 /* (there are not output pins for them), and probably taken from the "color" */
3473 /* field to do bank switching. However this applies only to TMNT2, with its */
3474 /* protection mcu creating the sprite table, so we don't know where to fetch */
3475 /* the bits from. */
3476 code = K053245_buffer[chip][offs+1];
3477 code = ((code & 0xffe1) + ((code & 0x0010) >> 2) + ((code & 0x0008) << 1)
3478 + ((code & 0x0004) >> 1) + ((code & 0x0002) << 2));
3479 color = K053245_buffer[chip][offs+6] & 0x00ff;
3480 pri = 0;
3481
3482 (*K053245_callback[chip])(&code,&color,&pri);
3483
3484 size = (K053245_buffer[chip][offs] & 0x0f00) >> 8;
3485
3486 w = 1 << (size & 0x03);
3487 h = 1 << ((size >> 2) & 0x03);
3488
3489 /* zoom control:
3490 0x40 = normal scale
3491 <0x40 enlarge (0x20 = double size)
3492 >0x40 reduce (0x80 = half size)
3493 */
3494 zoomy = K053245_buffer[chip][offs+4];
3495 if (zoomy > 0x2000) continue;
3496 if (zoomy) zoomy = (0x400000+zoomy/2) / zoomy;
3497 else zoomy = 2 * 0x400000;
3498 if ((K053245_buffer[chip][offs] & 0x4000) == 0)
3499 {
3500 zoomx = K053245_buffer[chip][offs+5];
3501 if (zoomx > 0x2000) continue;
3502 if (zoomx) zoomx = (0x400000+zoomx/2) / zoomx;
3503 else zoomx = 2 * 0x400000;
3504 /* else zoomx = zoomy; workaround for TMNT2 */
3505 }
3506 else zoomx = zoomy;
3507
3508 ox = K053245_buffer[chip][offs+3] + spriteoffsX;
3509 oy = K053245_buffer[chip][offs+2];
3510
3511 ox += K053245_dx[chip];
3512 oy += K053245_dy[chip];
3513
3514 flipx = K053245_buffer[chip][offs] & 0x1000;
3515 flipy = K053245_buffer[chip][offs] & 0x2000;
3516 mirrorx = K053245_buffer[chip][offs+6] & 0x0100;
3517 if (mirrorx) flipx = 0; /* documented and confirmed */
3518 mirrory = K053245_buffer[chip][offs+6] & 0x0200;
3519 shadow = K053245_buffer[chip][offs+6] & 0x0080;
3520
3521 if (flipscreenX)
3522 {
3523 ox = 512 - ox;
3524 if (!mirrorx) flipx = !flipx;
3525 }
3526 if (flipscreenY)
3527 {
3528 oy = -oy;
3529 if (!mirrory) flipy = !flipy;
3530 }
3531
3532 ox = (ox + 0x5d) & 0x3ff;
3533 if (ox >= 768) ox -= 1024;
3534 oy = (-(oy + spriteoffsY + 0x07)) & 0x3ff;
3535 if (oy >= 640) oy -= 1024;
3536
3537 /* the coordinates given are for the *center* of the sprite */
3538 ox -= (zoomx * w) >> 13;
3539 oy -= (zoomy * h) >> 13;
3540
3541 for (y = 0;y < h;y++)
3542 {
3543 int sx,sy,zw,zh;
3544
3545 sy = oy + ((zoomy * y + (1<<11)) >> 12);
3546 zh = (oy + ((zoomy * (y+1) + (1<<11)) >> 12)) - sy;
3547
3548 for (x = 0;x < w;x++)
3549 {
3550 int c,fx,fy;
3551
3552 sx = ox + ((zoomx * x + (1<<11)) >> 12);
3553 zw = (ox + ((zoomx * (x+1) + (1<<11)) >> 12)) - sx;
3554 c = code;
3555 if (mirrorx)
3556 {
3557 if ((flipx == 0) ^ (2*x < w))
3558 {
3559 /* mirror left/right */
3560 c += (w-x-1);
3561 fx = 1;
3562 }
3563 else
3564 {
3565 c += x;
3566 fx = 0;
3567 }
3568 }
3569 else
3570 {
3571 if (flipx) c += w-1-x;
3572 else c += x;
3573 fx = flipx;
3574 }
3575 if (mirrory)
3576 {
3577 if ((flipy == 0) ^ (2*y >= h))
3578 {
3579 /* mirror top/bottom */
3580 c += 8*(h-y-1);
3581 fy = 1;
3582 }
3583 else
3584 {
3585 c += 8*y;
3586 fy = 0;
3587 }
3588 }
3589 else
3590 {
3591 if (flipy) c += 8*(h-1-y);
3592 else c += 8*y;
3593 fy = flipy;
3594 }
3595
3596 /* the sprite can start at any point in the 8x8 grid, but it must stay */
3597 /* in a 64 entries window, wrapping around at the edges. The animation */
3598 /* at the end of the saloon level in Sunset Riders breaks otherwise. */
3599 c = (c & 0x3f) | (code & ~0x3f);
3600
3601 if (zoomx == 0x10000 && zoomy == 0x10000)
3602 {
3603 pdrawgfx(bitmap,Machine->gfx[0], /* hardcoded to 0 (decoded 6bpp gfx) for le */
3604 c,
3605 color,
3606 fx,fy,
3607 sx,sy,
3608 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,pri);
3609 }
3610 else
3611 {
3612 pdrawgfxzoom(bitmap,Machine->gfx[0], /* hardcoded to 0 (decoded 6bpp gfx) for le */
3613 c,
3614 color,
3615 fx,fy,
3616 sx,sy,
3617 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,
3618 (zw << 16) / 16,(zh << 16) / 16,pri);
3619
3620 }
3621 }
3622 }
3623 }
3624 #if 0
3625 if (code_pressed(KEYCODE_D))
3626 {
3627 FILE *fp;
3628 fp=fopen("SPRITE.DMP", "w+b");
3629 if (fp)
3630 {
3631 fwrite(K053245_buffer, 0x800, 1, fp);
3632 usrintf_showmessage("saved");
3633 fclose(fp);
3634 }
3635 }
3636 #endif
3637 #undef NUM_SPRITES
3638 }
3639
3640
3641 /***************************************************************************/
3642 /* */
3643 /* 053246/053247 */
3644 /* */
3645 /***************************************************************************/
3646
3647 static int K053247_memory_region, K053247_dx, K053247_dy, K053247_wraparound;
3648 static data8_t K053246_regs[8];
3649 static data16_t K053247_regs[16];
3650 data16_t *K053247_ram=0;
3651 static struct GfxElement *K053247_gfx;
3652 static void (*K053247_callback)(int *code,int *color,int *priority);
3653 static int K053246_OBJCHA_line;
3654
K053247_export_config(data16_t ** ram,struct GfxElement ** gfx,void (** callback)(int *,int *,int *),int * dx,int * dy)3655 void K053247_export_config(data16_t **ram, struct GfxElement **gfx, void (**callback)(int *, int *, int *), int *dx, int *dy)
3656 {
3657 if(ram)
3658 *ram = K053247_ram;
3659 if(gfx)
3660 *gfx = K053247_gfx;
3661 if(callback)
3662 *callback = K053247_callback;
3663 if(dx)
3664 *dx = K053247_dx;
3665 if(dy)
3666 *dy = K053247_dy;
3667 }
3668
K053246_read_register(int regnum)3669 int K053246_read_register(int regnum) { return(K053246_regs[regnum]); }
K053247_read_register(int regnum)3670 int K053247_read_register(int regnum) { return(K053247_regs[regnum]); }
3671
K053247_set_SpriteOffset(int offsx,int offsy)3672 void K053247_set_SpriteOffset(int offsx, int offsy)
3673 {
3674 K053247_dx = offsx;
3675 K053247_dy = offsy;
3676 }
3677
K053247_wraparound_enable(int status)3678 void K053247_wraparound_enable(int status)
3679 {
3680 K053247_wraparound = status;
3681 }
3682
K053247_vh_start(int gfx_memory_region,int dx,int dy,int plane0,int plane1,int plane2,int plane3,void (* callback)(int * code,int * color,int * priority))3683 int K053247_vh_start(int gfx_memory_region, int dx, int dy, int plane0,int plane1,int plane2,int plane3,
3684 void (*callback)(int *code,int *color,int *priority))
3685 {
3686 int gfx_index,i;
3687 static struct GfxLayout spritelayout =
3688 {
3689 16,16,
3690 0, /* filled in later */
3691 4,
3692 { 0, 0, 0, 0 }, /* filled in later */
3693 { 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4,
3694 10*4, 11*4, 8*4, 9*4, 14*4, 15*4, 12*4, 13*4 },
3695 { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64,
3696 8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 },
3697 128*8
3698 };
3699
3700
3701 /* find first empty slot to decode gfx */
3702 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
3703 if (Machine->gfx[gfx_index] == 0)
3704 break;
3705 if (gfx_index == MAX_GFX_ELEMENTS)
3706 return 1;
3707
3708 /* tweak the structure for the number of tiles we have */
3709 spritelayout.total = memory_region_length(gfx_memory_region) / 128;
3710 spritelayout.planeoffset[0] = plane0;
3711 spritelayout.planeoffset[1] = plane1;
3712 spritelayout.planeoffset[2] = plane2;
3713 spritelayout.planeoffset[3] = plane3;
3714
3715 /* decode the graphics */
3716 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&spritelayout);
3717 if (!Machine->gfx[gfx_index])
3718 return 1;
3719
3720 /* set the color information */
3721 if (Machine->drv->color_table_len)
3722 {
3723 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
3724 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
3725 }
3726 else
3727 {
3728 Machine->gfx[gfx_index]->colortable = Machine->pens;
3729 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / 16;
3730 }
3731
3732 if (Machine->color_depth == 32)
3733 {
3734 if ((Machine->drv->video_attributes & (VIDEO_HAS_SHADOWS|VIDEO_HAS_HIGHLIGHTS)) != VIDEO_HAS_SHADOWS+VIDEO_HAS_HIGHLIGHTS)
3735 log_cb(RETRO_LOG_DEBUG, LOGPRE "driver missing SHADOWS or HIGHLIGHTS flag");
3736 }
3737 else
3738 {
3739 if (!(Machine->drv->video_attributes & VIDEO_HAS_SHADOWS))
3740 log_cb(RETRO_LOG_DEBUG, LOGPRE "driver should use VIDEO_HAS_SHADOWS");
3741 }
3742
3743 /* prepare shadow draw table */
3744 gfx_drawmode_table[0] = DRAWMODE_NONE;
3745 for (i = 1;i < 15;i++)
3746 gfx_drawmode_table[i] = DRAWMODE_SOURCE;
3747 gfx_drawmode_table[15] = DRAWMODE_SHADOW;
3748
3749 K053247_dx = dx;
3750 K053247_dy = dy;
3751 K053247_wraparound = 1;
3752 K05324x_z_rejection = -1;
3753 K053247_memory_region = gfx_memory_region;
3754 K053247_gfx = Machine->gfx[gfx_index];
3755 K053247_callback = callback;
3756 K053246_OBJCHA_line = CLEAR_LINE;
3757 K053247_ram = auto_malloc(0x1000);
3758 if (!K053247_ram) return 1;
3759
3760 memset(K053247_ram, 0, 0x1000);
3761 memset(K053246_regs, 0, 8);
3762 memset(K053247_regs, 0, 32);
3763
3764 state_save_register_UINT16("K053246", 0, "memory", K053247_ram, 0x800);
3765 state_save_register_UINT8 ("K053246", 0, "registers", K053246_regs, 8);
3766 state_save_register_UINT16("K053246", 0, "registers2",K053247_regs, 16);
3767 state_save_register_int ("K053246", 0, "objcha", &K053246_OBJCHA_line);
3768
3769 return 0;
3770 }
3771
3772 /* K055673 used with the 54246 in PreGX/Run and Gun/System GX games */
K055673_vh_start(int gfx_memory_region,int layout,int dx,int dy,void (* callback)(int * code,int * color,int * priority))3773 int K055673_vh_start(int gfx_memory_region, int layout, int dx, int dy, void (*callback)(int *code,int *color,int *priority))
3774 {
3775 int gfx_index;
3776
3777 static struct GfxLayout spritelayout = /* System GX sprite layout */
3778 {
3779 16,16,
3780 32768, /* filled in later */
3781 5,
3782 { 32, 24, 16, 8, 0 },
3783 { 0, 1, 2, 3, 4, 5, 6, 7, 40, 41, 42, 43, 44, 45, 46, 47 },
3784 { 0, 10*8, 10*8*2, 10*8*3, 10*8*4, 10*8*5, 10*8*6, 10*8*7, 10*8*8,
3785 10*8*9, 10*8*10, 10*8*11, 10*8*12, 10*8*13, 10*8*14, 10*8*15 },
3786 16*16*5
3787 };
3788 static struct GfxLayout spritelayout2 = /* Run and Gun sprite layout */
3789 {
3790 16,16,
3791 32768, /* filled in later */
3792 4,
3793 { 24, 16, 8, 0 },
3794 { 0, 1, 2, 3, 4, 5, 6, 7, 32, 33, 34, 35, 36, 37, 38, 39 },
3795 { 0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960 },
3796 16*16*4
3797 };
3798 static struct GfxLayout spritelayout3 = /* Lethal Enforcers II sprite layout */
3799 {
3800 16,16,
3801 32768, /* filled in later */
3802 8,
3803 { 8*1,8*0,8*3,8*2,8*5,8*4,8*7,8*6 },
3804 { 0,1,2,3,4,5,6,7,64+0,64+1,64+2,64+3,64+4,64+5,64+6,64+7 },
3805 { 128*0, 128*1, 128*2, 128*3, 128*4, 128*5, 128*6, 128*7,
3806 128*8, 128*9, 128*10, 128*11, 128*12, 128*13, 128*14, 128*15 },
3807 128*16
3808 };
3809 static struct GfxLayout spritelayout4 = /* System GX 6bpp sprite layout */
3810 {
3811 16,16,
3812 32768, /* filled in later */
3813 6,
3814 { 40, 32, 24, 16, 8, 0 },
3815 { 0, 1, 2, 3, 4, 5, 6, 7, 48, 49, 50, 51, 52, 53, 54, 55 },
3816 { 0, 12*8, 12*8*2, 12*8*3, 12*8*4, 12*8*5, 12*8*6, 12*8*7, 12*8*8,
3817 12*8*9, 12*8*10, 12*8*11, 12*8*12, 12*8*13, 12*8*14, 12*8*15 },
3818 16*16*6
3819 };
3820 unsigned char *s1, *s2, *d;
3821 long i, c;
3822 data16_t *K055673_rom;
3823
3824 /* find first empty slot to decode gfx */
3825 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
3826 if (Machine->gfx[gfx_index] == 0)
3827 break;
3828 if (gfx_index == MAX_GFX_ELEMENTS)
3829 return 1;
3830
3831 switch(layout) {
3832 case K055673_LAYOUT_GX:
3833 {
3834 int size4 = (memory_region_length(gfx_memory_region)/(1024*1024))/5;
3835 size4 *= 4*1024*1024;
3836 /* set the # of tiles based on the 4bpp section */
3837 spritelayout.total = size4 / 128;
3838 if (!(K055673_rom = (data16_t *)auto_malloc(size4 * 5))) return 1;
3839 d = (data8_t *)K055673_rom;
3840 /* now combine the graphics together to form 5bpp*/
3841 s1 = memory_region(gfx_memory_region); /* 4bpp area*/
3842 s2 = s1 + (size4); /* 1bpp area*/
3843 for (i = 0; i < size4; i+= 4)
3844 {
3845 *d++ = *s1++;
3846 *d++ = *s1++;
3847 *d++ = *s1++;
3848 *d++ = *s1++;
3849 *d++ = *s2++;
3850 }
3851 /* decode the graphics */
3852 Machine->gfx[gfx_index] = decodegfx((data8_t *)K055673_rom, &spritelayout);
3853 break;
3854 }
3855 case K055673_LAYOUT_RNG:
3856 K055673_rom = (data16_t *)memory_region(gfx_memory_region);
3857 spritelayout2.total = memory_region_length(gfx_memory_region) / (16*16/2);
3858
3859 /* decode the graphics */
3860 Machine->gfx[gfx_index] = decodegfx((data8_t *)K055673_rom, &spritelayout2);
3861 break;
3862 case K055673_LAYOUT_LE2:
3863 K055673_rom = (data16_t *)memory_region(gfx_memory_region);
3864 spritelayout3.total = memory_region_length(gfx_memory_region) / (16*16);
3865
3866 /* decode the graphics */
3867 Machine->gfx[gfx_index] = decodegfx((data8_t *)K055673_rom, &spritelayout3);
3868 break;
3869 case K055673_LAYOUT_GX6:
3870 K055673_rom = (data16_t *)memory_region(gfx_memory_region);
3871 spritelayout4.total = memory_region_length(gfx_memory_region) / (16*16*6/8);
3872
3873 /* decode the graphics */
3874 Machine->gfx[gfx_index] = decodegfx((data8_t *)K055673_rom, &spritelayout4);
3875 break;
3876 }
3877
3878 if (!Machine->gfx[gfx_index])
3879 return 1;
3880
3881 /* set the color information */
3882 if (Machine->drv->color_table_len)
3883 {
3884 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
3885 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
3886 }
3887 else
3888 {
3889 Machine->gfx[gfx_index]->colortable = Machine->pens;
3890 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / 16;
3891 }
3892
3893 if (!(Machine->drv->video_attributes & VIDEO_HAS_SHADOWS))
3894 log_cb(RETRO_LOG_DEBUG, LOGPRE "driver should use VIDEO_HAS_SHADOWS");
3895
3896 /* prepare shadow draw table */
3897 c = Machine->gfx[gfx_index]->color_granularity-1;
3898 gfx_drawmode_table[0] = DRAWMODE_NONE;
3899 for (i = 1;i < c;i++)
3900 gfx_drawmode_table[i] = DRAWMODE_SOURCE;
3901 gfx_drawmode_table[c] = DRAWMODE_SHADOW;
3902
3903 K053247_dx = dx;
3904 K053247_dy = dy;
3905 K053247_wraparound = 1;
3906 K05324x_z_rejection = -1;
3907 K053247_memory_region = gfx_memory_region;
3908 K053247_gfx = Machine->gfx[gfx_index];
3909 K053247_callback = callback;
3910 K053246_OBJCHA_line = CLEAR_LINE;
3911 K053247_ram = auto_malloc(0x1000);
3912 if (!K053247_ram) return 1;
3913
3914 memset(K053247_ram, 0, 0x1000);
3915 memset(K053246_regs, 0, 8);
3916 memset(K053247_regs, 0, 32);
3917
3918 state_save_register_UINT16("K053246", 0, "memory", K053247_ram, 0x800);
3919 state_save_register_UINT8 ("K053246", 0, "registers", K053246_regs, 8);
3920 state_save_register_UINT16("K053246", 0, "registers2",K053247_regs, 16);
3921 state_save_register_int ("K053246", 0, "objcha", &K053246_OBJCHA_line);
3922
3923 return 0;
3924 }
3925
WRITE16_HANDLER(K053247_reg_word_w)3926 WRITE16_HANDLER( K053247_reg_word_w ) /* write-only OBJSET2 registers (see p.43 table 6.1)*/
3927 {
3928 COMBINE_DATA(K053247_regs + offset);
3929 }
3930
WRITE32_HANDLER(K053247_reg_long_w)3931 WRITE32_HANDLER( K053247_reg_long_w )
3932 {
3933 offset <<= 1;
3934 COMBINE_DATA(K053247_regs + offset + 1);
3935 mem_mask >>= 16;
3936 data >>= 16;
3937 COMBINE_DATA(K053247_regs + offset);
3938 }
3939
READ16_HANDLER(K053247_word_r)3940 READ16_HANDLER( K053247_word_r )
3941 {
3942 return K053247_ram[offset];
3943 }
3944
WRITE16_HANDLER(K053247_word_w)3945 WRITE16_HANDLER( K053247_word_w )
3946 {
3947 COMBINE_DATA(K053247_ram + offset);
3948 }
3949
READ32_HANDLER(K053247_long_r)3950 READ32_HANDLER( K053247_long_r )
3951 {
3952 return K053247_ram[offset*2+1] | (K053247_ram[offset*2]<<16);
3953 }
3954
WRITE32_HANDLER(K053247_long_w)3955 WRITE32_HANDLER( K053247_long_w )
3956 {
3957 offset <<= 1;
3958 COMBINE_DATA(K053247_ram + offset + 1);
3959 mem_mask >>= 16;
3960 data >>= 16;
3961 COMBINE_DATA(K053247_ram + offset);
3962 }
3963
READ_HANDLER(K053247_r)3964 READ_HANDLER( K053247_r )
3965 {
3966 int offs = offset >> 1;
3967
3968 if (offset & 1)
3969 return(K053247_ram[offs] & 0xff);
3970 else
3971 return(K053247_ram[offs] >> 8);
3972 }
3973
WRITE_HANDLER(K053247_w)3974 WRITE_HANDLER( K053247_w )
3975 {
3976 int offs = offset >> 1;
3977
3978 if (offset & 1)
3979 K053247_ram[offs] = (K053247_ram[offs] & 0xff00) | data;
3980 else
3981 K053247_ram[offs] = (K053247_ram[offs] & 0x00ff) | (data<<8);
3982 }
3983
3984 /* Mystic Warriors hardware games support a non-OBJCHA based ROM readback*/
3985 /* write the address to the 246 as usual, but there's a completely separate ROM*/
3986 /* window that works without needing an OBJCHA line.*/
3987 /* in this window, +0 = 32 bits from one set of ROMs, and +8 = 32 bits from another set*/
READ16_HANDLER(K055673_rom_word_r)3988 READ16_HANDLER( K055673_rom_word_r ) /* 5bpp*/
3989 {
3990 data8_t *ROM8 = (data8_t *)memory_region(K053247_memory_region);
3991 data16_t *ROM = (data16_t *)memory_region(K053247_memory_region);
3992 int size4 = (memory_region_length(K053247_memory_region)/(1024*1024))/5;
3993 int romofs;
3994
3995 size4 *= 4*1024*1024; /* get offset to 5th bit*/
3996 ROM8 += size4;
3997
3998 romofs = K053246_regs[6]<<16 | K053246_regs[7]<<8 | K053246_regs[4];
3999
4000 switch (offset)
4001 {
4002 case 0: /* 20k / 36u*/
4003 return ROM[romofs+2];
4004 break;
4005 case 1: /* 17k / 36y*/
4006 return ROM[romofs+3];
4007 break;
4008 case 2: /* 10k / 32y*/
4009 case 3:
4010 romofs /= 2;
4011 return ROM8[romofs+1];
4012 break;
4013 case 4: /* 22k / 34u*/
4014 return ROM[romofs];
4015 break;
4016 case 5: /* 19k / 34y*/
4017 return ROM[romofs+1];
4018 break;
4019 case 6: /* 12k / 29y*/
4020 case 7:
4021 romofs /= 2;
4022 return ROM8[romofs];
4023 break;
4024 default:
4025 log_cb(RETRO_LOG_DEBUG, LOGPRE "55673_rom_word_r: Unknown read offset %x\n", offset);
4026 break;
4027 }
4028
4029 return 0;
4030 }
4031
READ16_HANDLER(K055673_GX6bpp_rom_word_r)4032 READ16_HANDLER( K055673_GX6bpp_rom_word_r )
4033 {
4034 data16_t *ROM = (data16_t *)memory_region(K053247_memory_region);
4035 int romofs;
4036
4037 romofs = K053246_regs[6]<<16 | K053246_regs[7]<<8 | K053246_regs[4];
4038
4039 romofs /= 4; /* romofs increments 4 at a time*/
4040 romofs *= 12/2; /* each increment of romofs = 12 new bytes (6 new words)*/
4041
4042 switch (offset)
4043 {
4044 case 0:
4045 return ROM[romofs+3];
4046 break;
4047 case 1:
4048 return ROM[romofs+4];
4049 break;
4050 case 2:
4051 case 3:
4052 return ROM[romofs+5];
4053 break;
4054 case 4:
4055 return ROM[romofs];
4056 break;
4057 case 5:
4058 return ROM[romofs+1];
4059 break;
4060 case 6:
4061 case 7:
4062 return ROM[romofs+2];
4063 break;
4064 default:
4065 log_cb(RETRO_LOG_DEBUG, LOGPRE "55673_rom_word_r: Unknown read offset %x (PC=%x)\n", offset, activecpu_get_pc());
4066 break;
4067 }
4068
4069 return 0;
4070 }
4071
READ_HANDLER(K053246_r)4072 READ_HANDLER( K053246_r )
4073 {
4074 if (K053246_OBJCHA_line == ASSERT_LINE)
4075 {
4076 int addr;
4077
4078 addr = (K053246_regs[6] << 17) | (K053246_regs[7] << 9) | (K053246_regs[4] << 1) | ((offset & 1) ^ 1);
4079 addr &= memory_region_length(K053247_memory_region)-1;
4080 log_cb(RETRO_LOG_DEBUG, LOGPRE "%04x: offset %02x addr %06x",activecpu_get_pc(),offset,addr);
4081 return memory_region(K053247_memory_region)[addr];
4082 }
4083 else
4084 {
4085 log_cb(RETRO_LOG_DEBUG, LOGPRE "%04x: read from unknown 053246 address %x\n",activecpu_get_pc(),offset);
4086 return 0;
4087 }
4088 }
4089
WRITE_HANDLER(K053246_w)4090 WRITE_HANDLER( K053246_w )
4091 {
4092 K053246_regs[offset] = data;
4093 }
4094
READ16_HANDLER(K053246_word_r)4095 READ16_HANDLER( K053246_word_r )
4096 {
4097 offset <<= 1;
4098 return K053246_r(offset + 1) | (K053246_r(offset) << 8);
4099 }
4100
WRITE16_HANDLER(K053246_word_w)4101 WRITE16_HANDLER( K053246_word_w )
4102 {
4103 if (ACCESSING_MSB)
4104 K053246_w(offset<<1,(data >> 8) & 0xff);
4105 if (ACCESSING_LSB)
4106 K053246_w((offset<<1) + 1,data & 0xff);
4107 }
4108
READ32_HANDLER(K053246_long_r)4109 READ32_HANDLER( K053246_long_r )
4110 {
4111 offset <<= 1;
4112 return (K053246_word_r(offset+1, 0xffff) | K053246_word_r(offset, 0xffff)<<16);
4113 }
4114
WRITE32_HANDLER(K053246_long_w)4115 WRITE32_HANDLER( K053246_long_w )
4116 {
4117 offset <<= 1;
4118 K053246_word_w(offset, data>>16, mem_mask >> 16);
4119 K053246_word_w(offset+1, data, mem_mask);
4120 }
4121
K053246_set_OBJCHA_line(int state)4122 void K053246_set_OBJCHA_line(int state)
4123 {
4124 K053246_OBJCHA_line = state;
4125 }
4126
K053246_is_IRQ_enabled(void)4127 int K053246_is_IRQ_enabled(void)
4128 {
4129 /* This bit enables obj DMA rather than obj IRQ even though the two functions usually coincide.*/
4130 return K053246_regs[5] & 0x10;
4131 }
4132
4133 /*
4134 * Sprite Format
4135 * ------------------
4136 *
4137 * Word | Bit(s) | Use
4138 * -----+-fedcba9876543210-+----------------
4139 * 0 | x--------------- | active (show this sprite)
4140 * 0 | -x-------------- | maintain aspect ratio (when set, zoom y acts on both axis)
4141 * 0 | --x------------- | flip y
4142 * 0 | ---x------------ | flip x
4143 * 0 | ----xxxx-------- | sprite size (see below)
4144 * 0 | --------xxxxxxxx | zcode
4145 * 1 | xxxxxxxxxxxxxxxx | sprite code
4146 * 2 | ------xxxxxxxxxx | y position
4147 * 3 | ------xxxxxxxxxx | x position
4148 * 4 | xxxxxxxxxxxxxxxx | zoom y (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
4149 * 5 | xxxxxxxxxxxxxxxx | zoom x (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
4150 * 6 | x--------------- | mirror y (top half is drawn as mirror image of the bottom)
4151 * 6 | -x-------------- | mirror x (right half is drawn as mirror image of the left)
4152 * 6 | --xx------------ | reserved (sprites with these two bits set don't seem to be graphics data at all)
4153 * 6 | ----xx---------- | shadow code: 0=off, 0x400=preset1, 0x800=preset2, 0xc00=preset3
4154 * 6 | ------xx-------- | effect code: flicker, upper palette, full shadow...etc. (game dependent)
4155 * 6 | --------xxxxxxxx | "color", but depends on external connections (implies priority)
4156 * 7 | xxxxxxxxxxxxxxxx | game dependent
4157 *
4158 * shadow enables transparent shadows. Note that it applies to the last sprite pen ONLY.
4159 * The rest of the sprite remains normal.
4160 */
4161
K053247_sprites_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect)4162 void K053247_sprites_draw(struct mame_bitmap *bitmap,const struct rectangle *cliprect) /***/
4163 {
4164 #define NUM_SPRITES 256
4165
4166 /* sprites can be grouped up to 8x8. The draw order is
4167 0 1 4 5 16 17 20 21
4168 2 3 6 7 18 19 22 23
4169 8 9 12 13 24 25 28 29
4170 10 11 14 15 26 27 30 31
4171 32 33 36 37 48 49 52 53
4172 34 35 38 39 50 51 54 55
4173 40 41 44 45 56 57 60 61
4174 42 43 46 47 58 59 62 63
4175 */
4176 static int xoffset[8] = { 0, 1, 4, 5, 16, 17, 20, 21 };
4177 static int yoffset[8] = { 0, 2, 8, 10, 32, 34, 40, 42 };
4178
4179 int sortedlist[NUM_SPRITES];
4180 int offs,zcode;
4181 int ox,oy,color,code,size,w,h,x,y,xa,ya,flipx,flipy,mirrorx,mirrory,shadow,zoomx,zoomy,primask;
4182 int shdmask,nozoom,count,temp;
4183
4184 int flipscreenx = K053246_regs[5] & 0x01;
4185 int flipscreeny = K053246_regs[5] & 0x02;
4186 int offx = (short)((K053246_regs[0] << 8) | K053246_regs[1]);
4187 int offy = (short)((K053246_regs[2] << 8) | K053246_regs[3]);
4188
4189 int solidpens = K053247_gfx->color_granularity - 1;
4190 int screen_width = Machine->drv->screen_width;
4191
4192 /*
4193 safeguard older drivers missing any of the following video attributes:
4194
4195 VIDEO_NEEDS_6BITS_PER_GUN | VIDEO_RGB_DIRECT | VIDEO_HAS_SHADOWS | VIDEO_HAS_HIGHLIGHTS
4196 */
4197 if (Machine->drv->video_attributes & VIDEO_HAS_SHADOWS)
4198 {
4199 if (Machine->color_depth == 32 && (Machine->drv->video_attributes & VIDEO_HAS_HIGHLIGHTS))
4200 shdmask = 3; /* enable all shadows and highlights*/
4201 else
4202 shdmask = 0; /* enable default shadows*/
4203 }
4204 else
4205 shdmask = -1; /* disable everything*/
4206
4207 /*
4208 The K053247 does not draw pixels on top of those with equal or smaller Z-values
4209 regardless of priority. Embedded shadows inherit Z-values from their host sprites
4210 but do not assume host priorities unless explicitly told. In other words shadows
4211 can have priorities different from that of normal pens in the same sprite,
4212 in addition to the ability of masking themselves from specific layers or pixels
4213 on the other sprites.
4214
4215 In front-to-back rendering, sprites cannot sandwich between alpha blended layers
4216 or the draw code will have to figure out the percentage opacities of what is on
4217 top and beneath each sprite pixel and blend the target accordingly. The process
4218 is overly demanding for realtime software and is thus another shortcoming of
4219 pdrawgfx and pixel based mixers. Even mahjong games with straight forward video
4220 subsystems are feeling the impact by which the girls cannot appear under
4221 translucent dialogue boxes.
4222
4223 These are a small part of the K053247's feature set but many games expect them
4224 to be the minimum compliances. The specification will undoubtedly require
4225 redesigning the priority system from the ground up. Drawgfx.c and tilemap.c must
4226 also undergo heavy facelifts but in the end the changes could hurt simpler games
4227 more than they help complex systems; therefore the new engine should remain
4228 completely stand alone and self-contained. Implementation details are being
4229 hammered down but too early to make propositions.
4230 */
4231
4232 /* Prebuild a sorted table by descending Z-order.*/
4233 zcode = K05324x_z_rejection;
4234 offs = count = 0;
4235
4236 if (zcode == -1)
4237 {
4238 for (; offs<0x800; offs+=8)
4239 if (K053247_ram[offs] & 0x8000) sortedlist[count++] = offs;
4240 }
4241 else
4242 {
4243 for (; offs<0x800; offs+=8)
4244 if ((K053247_ram[offs] & 0x8000) && ((K053247_ram[offs] & 0xff) != zcode)) sortedlist[count++] = offs;
4245 }
4246
4247 w = count;
4248 count--;
4249 h = count;
4250
4251 if (!(K053247_regs[0xc/2] & 0x10))
4252 {
4253 /* sort objects in decending order(smaller z closer) when OPSET PRI is clear*/
4254 for (y=0; y<h; y++)
4255 {
4256 offs = sortedlist[y];
4257 zcode = K053247_ram[offs] & 0xff;
4258 for (x=y+1; x<w; x++)
4259 {
4260 temp = sortedlist[x];
4261 code = K053247_ram[temp] & 0xff;
4262 if (zcode <= code) { zcode = code; sortedlist[x] = offs; sortedlist[y] = offs = temp; }
4263 }
4264 }
4265 }
4266 else
4267 {
4268 /* sort objects in ascending order(bigger z closer) when OPSET PRI is set*/
4269 for (y=0; y<h; y++)
4270 {
4271 offs = sortedlist[y];
4272 zcode = K053247_ram[offs] & 0xff;
4273 for (x=y+1; x<w; x++)
4274 {
4275 temp = sortedlist[x];
4276 code = K053247_ram[temp] & 0xff;
4277 if (zcode >= code) { zcode = code; sortedlist[x] = offs; sortedlist[y] = offs = temp; }
4278 }
4279 }
4280 }
4281
4282 for (; count>=0; count--)
4283 {
4284 offs = sortedlist[count];
4285
4286 code = K053247_ram[offs+1];
4287 shadow = color = K053247_ram[offs+6];
4288 primask = 0;
4289
4290 (*K053247_callback)(&code,&color,&primask);
4291
4292 temp = K053247_ram[offs];
4293
4294 size = (temp & 0x0f00) >> 8;
4295 w = 1 << (size & 0x03);
4296 h = 1 << ((size >> 2) & 0x03);
4297
4298 /* the sprite can start at any point in the 8x8 grid. We have to */
4299 /* adjust the offsets to draw it correctly. Simpsons does this all the time. */
4300 xa = 0;
4301 ya = 0;
4302 if (code & 0x01) xa += 1;
4303 if (code & 0x02) ya += 1;
4304 if (code & 0x04) xa += 2;
4305 if (code & 0x08) ya += 2;
4306 if (code & 0x10) xa += 4;
4307 if (code & 0x20) ya += 4;
4308 code &= ~0x3f;
4309
4310 oy = (short)K053247_ram[offs+2];
4311 ox = (short)K053247_ram[offs+3];
4312
4313 if (K053247_wraparound)
4314 {
4315 offx &= 0x3ff;
4316 offy &= 0x3ff;
4317 oy &= 0x3ff;
4318 ox &= 0x3ff;
4319 }
4320
4321 /* zoom control:
4322 0x40 = normal scale
4323 <0x40 enlarge (0x20 = double size)
4324 >0x40 reduce (0x80 = half size)
4325 */
4326 y = zoomy = K053247_ram[offs+4] & 0x3ff;
4327 if (zoomy) zoomy = (0x400000+(zoomy>>1)) / zoomy; else zoomy = 0x800000;
4328 if (!(temp & 0x4000))
4329 {
4330 x = zoomx = K053247_ram[offs+5] & 0x3ff;
4331 if (zoomx) zoomx = (0x400000+(zoomx>>1)) / zoomx;
4332 else zoomx = 0x800000;
4333 }
4334 else { zoomx = zoomy; x = y; }
4335
4336 /* *************************************************************************************/
4337 /* for Escape Kids (GX975)*/
4338 /* *************************************************************************************/
4339 /* Escape Kids use 053246 #5 register's UNKNOWN Bit #5, #3 and #2.*/
4340 /* Bit #5, #3, #2 always set "1".*/
4341 /* Maybe, Bit #5 or #3 or #2 or combination means "FIX SPRITE WIDTH TO HALF" ?????*/
4342 /* Below 7 lines supports this 053246's(???) function.*/
4343 /* Don't rely on it, Please. But, Escape Kids works correctly!*/
4344 /* *************************************************************************************/
4345 if ( K053246_regs[5] & 0x08 ) /* Check only "Bit #3 is '1'?" (NOTE: good guess)*/
4346 {
4347 zoomx >>= 1; /* Fix sprite width to HALF size*/
4348 ox = (ox >> 1) + 1; /* Fix sprite draw position*/
4349 if (flipscreenx) ox += screen_width;
4350 nozoom = 0;
4351 }
4352 else
4353 nozoom = (x == 0x40 && y == 0x40);
4354
4355 flipx = temp & 0x1000;
4356 flipy = temp & 0x2000;
4357 mirrorx = shadow & 0x4000;
4358 if (mirrorx) flipx = 0; /* documented and confirmed*/
4359 mirrory = shadow & 0x8000;
4360
4361 if (color == -1)
4362 {
4363 /* drop the entire sprite to shadow unconditionally*/
4364 if (shdmask < 0) continue;
4365 color = 0;
4366 shadow = -1;
4367 for (temp=1; temp<solidpens; temp++) gfx_drawmode_table[temp] = DRAWMODE_SHADOW;
4368 palette_set_shadow_mode(0);
4369 }
4370 else
4371 {
4372 if (shdmask >= 0)
4373 {
4374 shadow = (color & K053247_CUSTOMSHADOW) ? (color>>K053247_SHDSHIFT) : (shadow>>10);
4375 if (shadow &= 3) palette_set_shadow_mode((shadow-1) & shdmask);
4376 }
4377 else
4378 shadow = 0;
4379 }
4380
4381 color &= 0xffff; /* strip attribute flags */
4382
4383 if (flipscreenx)
4384 {
4385 ox = -ox;
4386 if (!mirrorx) flipx = !flipx;
4387 }
4388 if (flipscreeny)
4389 {
4390 oy = -oy;
4391 if (!mirrory) flipy = !flipy;
4392 }
4393
4394 /* apply wrapping and global offsets*/
4395 if (K053247_wraparound)
4396 {
4397 ox = ( ox - offx) & 0x3ff;
4398 oy = (-oy - offy) & 0x3ff;
4399 if (ox >= 0x300) ox -= 0x400;
4400 if (oy >= 0x280) oy -= 0x400;
4401 }
4402 else
4403 {
4404 ox = ox - offx;
4405 oy = -oy - offy;
4406 }
4407 ox += K053247_dx;
4408 oy -= K053247_dy;
4409
4410 /* apply global and display window offsets*/
4411
4412 /* the coordinates given are for the *center* of the sprite */
4413 ox -= (zoomx * w) >> 13;
4414 oy -= (zoomy * h) >> 13;
4415
4416 for (y = 0;y < h;y++)
4417 {
4418 int sx,sy,zw,zh;
4419
4420 sy = oy + ((zoomy * y + (1<<11)) >> 12);
4421 zh = (oy + ((zoomy * (y+1) + (1<<11)) >> 12)) - sy;
4422
4423 for (x = 0;x < w;x++)
4424 {
4425 int c,fx,fy;
4426
4427 sx = ox + ((zoomx * x + (1<<11)) >> 12);
4428 zw = (ox + ((zoomx * (x+1) + (1<<11)) >> 12)) - sx;
4429 c = code;
4430 if (mirrorx)
4431 {
4432 if ((flipx == 0) ^ ((x<<1) < w))
4433 {
4434 /* mirror left/right */
4435 c += xoffset[(w-1-x+xa)&7];
4436 fx = 1;
4437 }
4438 else
4439 {
4440 c += xoffset[(x+xa)&7];
4441 fx = 0;
4442 }
4443 }
4444 else
4445 {
4446 if (flipx) c += xoffset[(w-1-x+xa)&7];
4447 else c += xoffset[(x+xa)&7];
4448 fx = flipx;
4449 }
4450 if (mirrory)
4451 {
4452 if ((flipy == 0) ^ ((y<<1) >= h))
4453 {
4454 /* mirror top/bottom */
4455 c += yoffset[(h-1-y+ya)&7];
4456 fy = 1;
4457 }
4458 else
4459 {
4460 c += yoffset[(y+ya)&7];
4461 fy = 0;
4462 }
4463 }
4464 else
4465 {
4466 if (flipy) c += yoffset[(h-1-y+ya)&7];
4467 else c += yoffset[(y+ya)&7];
4468 fy = flipy;
4469 }
4470
4471 if (nozoom)
4472 {
4473 pdrawgfx(bitmap,K053247_gfx,
4474 c,
4475 color,
4476 fx,fy,
4477 sx,sy,
4478 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,primask);
4479 }
4480 else
4481 {
4482 pdrawgfxzoom(bitmap,K053247_gfx,
4483 c,
4484 color,
4485 fx,fy,
4486 sx,sy,
4487 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,
4488 (zw << 16) >> 4,(zh << 16) >> 4,primask);
4489 }
4490
4491 if (mirrory && h == 1) /* Simpsons shadows */
4492 {
4493 if (nozoom)
4494 {
4495 pdrawgfx(bitmap,K053247_gfx,
4496 c,
4497 color,
4498 fx,!fy,
4499 sx,sy,
4500 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,primask);
4501 }
4502 else
4503 {
4504 pdrawgfxzoom(bitmap,K053247_gfx,
4505 c,
4506 color,
4507 fx,!fy,
4508 sx,sy,
4509 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,
4510 (zw << 16) >> 4,(zh << 16) >> 4,primask);
4511 }
4512 }
4513 } /* end of X loop*/
4514 } /* end of Y loop*/
4515
4516 /* reset drawmode_table*/
4517 if (shadow == -1) for (temp=1; temp<solidpens; temp++) gfx_drawmode_table[temp] = DRAWMODE_SOURCE;
4518
4519 } /* end of sprite-list loop*/
4520 #undef NUM_SPRITES
4521 }
4522
4523
4524
4525 /***************************************************************************/
4526 /* */
4527 /* 051316 */
4528 /* */
4529 /***************************************************************************/
4530
4531 #define MAX_K051316 3
4532
4533 static int K051316_memory_region[MAX_K051316];
4534 static int K051316_gfxnum[MAX_K051316];
4535 static int K051316_wraparound[MAX_K051316];
4536 static int K051316_offset[MAX_K051316][2];
4537 static int K051316_bpp[MAX_K051316];
4538 static void (*K051316_callback[MAX_K051316])(int *code,int *color);
4539 static unsigned char *K051316_ram[MAX_K051316];
4540 static unsigned char K051316_ctrlram[MAX_K051316][16];
4541 static struct tilemap *K051316_tilemap[MAX_K051316];
4542
4543 /***************************************************************************
4544
4545 Callbacks for the TileMap code
4546
4547 ***************************************************************************/
4548
K051316_get_tile_info(int tile_index,int chip)4549 static INLINE void K051316_get_tile_info(int tile_index,int chip)
4550 {
4551 int code = K051316_ram[chip][tile_index];
4552 int color = K051316_ram[chip][tile_index + 0x400];
4553
4554 tile_info.flags = 0;
4555
4556 (*K051316_callback[chip])(&code,&color);
4557
4558 SET_TILE_INFO(
4559 K051316_gfxnum[chip],
4560 code,
4561 color,
4562 tile_info.flags)
4563 }
4564
K051316_get_tile_info0(int tile_index)4565 static void K051316_get_tile_info0(int tile_index) { K051316_get_tile_info(tile_index,0); }
K051316_get_tile_info1(int tile_index)4566 static void K051316_get_tile_info1(int tile_index) { K051316_get_tile_info(tile_index,1); }
K051316_get_tile_info2(int tile_index)4567 static void K051316_get_tile_info2(int tile_index) { K051316_get_tile_info(tile_index,2); }
4568
4569
K051316_vh_start(int chip,int gfx_memory_region,int bpp,int tilemap_type,int transparent_pen,void (* callback)(int * code,int * color))4570 int K051316_vh_start(int chip, int gfx_memory_region,int bpp,
4571 int tilemap_type,int transparent_pen,
4572 void (*callback)(int *code,int *color))
4573 {
4574 int gfx_index;
4575 static void (*get_tile_info[3])(int tile_index) = { K051316_get_tile_info0,K051316_get_tile_info1,K051316_get_tile_info2 };
4576
4577 /* find first empty slot to decode gfx */
4578 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
4579 if (Machine->gfx[gfx_index] == 0)
4580 break;
4581 if (gfx_index == MAX_GFX_ELEMENTS)
4582 return 1;
4583
4584 if (bpp == 4)
4585 {
4586 static struct GfxLayout charlayout =
4587 {
4588 16,16,
4589 0, /* filled in later */
4590 4,
4591 { 0, 1, 2, 3 },
4592 { 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4,
4593 8*4, 9*4, 10*4, 11*4, 12*4, 13*4, 14*4, 15*4 },
4594 { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64,
4595 8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 },
4596 128*8
4597 };
4598
4599
4600 /* tweak the structure for the number of tiles we have */
4601 charlayout.total = memory_region_length(gfx_memory_region) / 128;
4602
4603 /* decode the graphics */
4604 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&charlayout);
4605 }
4606 else if (bpp == 7 || bpp == 8)
4607 {
4608 static struct GfxLayout charlayout =
4609 {
4610 16,16,
4611 0, /* filled in later */
4612 0, /* filled in later */
4613 { 0 }, /* filled in later */
4614 { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8,
4615 8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 },
4616 { 0*128, 1*128, 2*128, 3*128, 4*128, 5*128, 6*128, 7*128,
4617 8*128, 9*128, 10*128, 11*128, 12*128, 13*128, 14*128, 15*128 },
4618 256*8
4619 };
4620 int i;
4621
4622
4623 /* tweak the structure for the number of tiles we have */
4624 charlayout.total = memory_region_length(gfx_memory_region) / 256;
4625 charlayout.planes = bpp;
4626 if (bpp == 7) for (i = 0;i < 7;i++) charlayout.planeoffset[i] = i+1;
4627 else for (i = 0;i < 8;i++) charlayout.planeoffset[i] = i;
4628
4629 /* decode the graphics */
4630 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&charlayout);
4631 }
4632 else
4633 {
4634 /*logerror("K051316_vh_start supports only 4, 7 and 8 bpp\n");*/
4635 return 1;
4636 }
4637
4638 if (!Machine->gfx[gfx_index])
4639 return 1;
4640
4641 /* set the color information */
4642 if (Machine->drv->color_table_len)
4643 {
4644 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
4645 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / (1 << bpp);
4646 }
4647 else
4648 {
4649 Machine->gfx[gfx_index]->colortable = Machine->pens;
4650 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / (1 << bpp);
4651 }
4652
4653 K051316_memory_region[chip] = gfx_memory_region;
4654 K051316_gfxnum[chip] = gfx_index;
4655 K051316_bpp[chip] = bpp;
4656 K051316_callback[chip] = callback;
4657
4658 K051316_tilemap[chip] = tilemap_create(get_tile_info[chip],tilemap_scan_rows,tilemap_type,16,16,32,32);
4659
4660 K051316_ram[chip] = auto_malloc(0x800);
4661
4662 if (!K051316_ram[chip] || !K051316_tilemap[chip])
4663 return 1;
4664
4665 tilemap_set_transparent_pen(K051316_tilemap[chip],transparent_pen);
4666
4667 K051316_wraparound[chip] = 0; /* default = no wraparound */
4668 K051316_offset[chip][0] = K051316_offset[chip][1] = 0;
4669
4670 return 0;
4671 }
4672
K051316_vh_start_0(int gfx_memory_region,int bpp,int tilemap_type,int transparent_pen,void (* callback)(int * code,int * color))4673 int K051316_vh_start_0(int gfx_memory_region,int bpp,
4674 int tilemap_type,int transparent_pen,
4675 void (*callback)(int *code,int *color))
4676 {
4677 return K051316_vh_start(0,gfx_memory_region,bpp,tilemap_type,transparent_pen,callback);
4678 }
4679
K051316_vh_start_1(int gfx_memory_region,int bpp,int tilemap_type,int transparent_pen,void (* callback)(int * code,int * color))4680 int K051316_vh_start_1(int gfx_memory_region,int bpp,
4681 int tilemap_type,int transparent_pen,
4682 void (*callback)(int *code,int *color))
4683 {
4684 return K051316_vh_start(1,gfx_memory_region,bpp,tilemap_type,transparent_pen,callback);
4685 }
4686
K051316_vh_start_2(int gfx_memory_region,int bpp,int tilemap_type,int transparent_pen,void (* callback)(int * code,int * color))4687 int K051316_vh_start_2(int gfx_memory_region,int bpp,
4688 int tilemap_type,int transparent_pen,
4689 void (*callback)(int *code,int *color))
4690 {
4691 return K051316_vh_start(2,gfx_memory_region,bpp,tilemap_type,transparent_pen,callback);
4692 }
4693
4694
K051316_r(int chip,int offset)4695 int K051316_r(int chip, int offset)
4696 {
4697 return K051316_ram[chip][offset];
4698 }
4699
READ_HANDLER(K051316_0_r)4700 READ_HANDLER( K051316_0_r )
4701 {
4702 return K051316_r(0, offset);
4703 }
4704
READ_HANDLER(K051316_1_r)4705 READ_HANDLER( K051316_1_r )
4706 {
4707 return K051316_r(1, offset);
4708 }
4709
READ_HANDLER(K051316_2_r)4710 READ_HANDLER( K051316_2_r )
4711 {
4712 return K051316_r(2, offset);
4713 }
4714
4715
K051316_w(int chip,int offset,int data)4716 void K051316_w(int chip,int offset,int data)
4717 {
4718 if (K051316_ram[chip][offset] != data)
4719 {
4720 K051316_ram[chip][offset] = data;
4721 tilemap_mark_tile_dirty(K051316_tilemap[chip],offset & 0x3ff);
4722 }
4723 }
4724
WRITE_HANDLER(K051316_0_w)4725 WRITE_HANDLER( K051316_0_w )
4726 {
4727 K051316_w(0,offset,data);
4728 }
4729
WRITE_HANDLER(K051316_1_w)4730 WRITE_HANDLER( K051316_1_w )
4731 {
4732 K051316_w(1,offset,data);
4733 }
4734
WRITE_HANDLER(K051316_2_w)4735 WRITE_HANDLER( K051316_2_w )
4736 {
4737 K051316_w(2,offset,data);
4738 }
4739
4740
K051316_rom_r(int chip,int offset)4741 int K051316_rom_r(int chip, int offset)
4742 {
4743 if ((K051316_ctrlram[chip][0x0e] & 0x01) == 0)
4744 {
4745 int addr;
4746
4747 addr = offset + (K051316_ctrlram[chip][0x0c] << 11) + (K051316_ctrlram[chip][0x0d] << 19);
4748 if (K051316_bpp[chip] <= 4) addr /= 2;
4749 addr &= memory_region_length(K051316_memory_region[chip])-1;
4750
4751 /* log_cb(RETRO_LOG_DEBUG, ERROR "%04x: offset %04x addr %04x",activecpu_get_pc(),offset,addr);*/
4752
4753 return memory_region(K051316_memory_region[chip])[addr];
4754 }
4755 else
4756 {
4757 /*logerror("%04x: read 051316 ROM offset %04x but reg 0x0c bit 0 not clear\n",activecpu_get_pc(),offset);*/
4758 return 0;
4759 }
4760 }
4761
READ_HANDLER(K051316_rom_0_r)4762 READ_HANDLER( K051316_rom_0_r )
4763 {
4764 return K051316_rom_r(0,offset);
4765 }
4766
READ_HANDLER(K051316_rom_1_r)4767 READ_HANDLER( K051316_rom_1_r )
4768 {
4769 return K051316_rom_r(1,offset);
4770 }
4771
READ_HANDLER(K051316_rom_2_r)4772 READ_HANDLER( K051316_rom_2_r )
4773 {
4774 return K051316_rom_r(2,offset);
4775 }
4776
4777
4778
K051316_ctrl_w(int chip,int offset,int data)4779 void K051316_ctrl_w(int chip,int offset,int data)
4780 {
4781 K051316_ctrlram[chip][offset] = data;
4782 /*if (offset >= 0x0c) log_cb(RETRO_LOG_DEBUG, LOGPRE "%04x: write %02x to 051316 reg %x\n",activecpu_get_pc(),data,offset);*/
4783 }
4784
WRITE_HANDLER(K051316_ctrl_0_w)4785 WRITE_HANDLER( K051316_ctrl_0_w )
4786 {
4787 K051316_ctrl_w(0,offset,data);
4788 }
4789
WRITE_HANDLER(K051316_ctrl_1_w)4790 WRITE_HANDLER( K051316_ctrl_1_w )
4791 {
4792 K051316_ctrl_w(1,offset,data);
4793 }
4794
WRITE_HANDLER(K051316_ctrl_2_w)4795 WRITE_HANDLER( K051316_ctrl_2_w )
4796 {
4797 K051316_ctrl_w(2,offset,data);
4798 }
4799
K051316_wraparound_enable(int chip,int status)4800 void K051316_wraparound_enable(int chip, int status)
4801 {
4802 K051316_wraparound[chip] = status;
4803 }
4804
K051316_set_offset(int chip,int xoffs,int yoffs)4805 void K051316_set_offset(int chip, int xoffs, int yoffs)
4806 {
4807 K051316_offset[chip][0] = xoffs;
4808 K051316_offset[chip][1] = yoffs;
4809 }
4810
4811
K051316_zoom_draw(int chip,struct mame_bitmap * bitmap,const struct rectangle * cliprect,int flags,UINT32 priority)4812 void K051316_zoom_draw(int chip, struct mame_bitmap *bitmap,const struct rectangle *cliprect,int flags,UINT32 priority)
4813 {
4814 UINT32 startx,starty;
4815 int incxx,incxy,incyx,incyy;
4816
4817 startx = 256 * ((INT16)(256 * K051316_ctrlram[chip][0x00] + K051316_ctrlram[chip][0x01]));
4818 incxx = (INT16)(256 * K051316_ctrlram[chip][0x02] + K051316_ctrlram[chip][0x03]);
4819 incyx = (INT16)(256 * K051316_ctrlram[chip][0x04] + K051316_ctrlram[chip][0x05]);
4820 starty = 256 * ((INT16)(256 * K051316_ctrlram[chip][0x06] + K051316_ctrlram[chip][0x07]));
4821 incxy = (INT16)(256 * K051316_ctrlram[chip][0x08] + K051316_ctrlram[chip][0x09]);
4822 incyy = (INT16)(256 * K051316_ctrlram[chip][0x0a] + K051316_ctrlram[chip][0x0b]);
4823
4824 startx -= (16 + K051316_offset[chip][1]) * incyx;
4825 starty -= (16 + K051316_offset[chip][1]) * incyy;
4826
4827 startx -= (89 + K051316_offset[chip][0]) * incxx;
4828 starty -= (89 + K051316_offset[chip][0]) * incxy;
4829
4830 tilemap_draw_roz(bitmap,cliprect,K051316_tilemap[chip],startx << 5,starty << 5,
4831 incxx << 5,incxy << 5,incyx << 5,incyy << 5,
4832 K051316_wraparound[chip],
4833 flags,priority);
4834
4835 #if 0
4836 log_cb(RETRO_LOG_DEBUG, LOGPRE "%02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x",
4837 K051316_ctrlram[chip][0x00],
4838 K051316_ctrlram[chip][0x01],
4839 K051316_ctrlram[chip][0x02],
4840 K051316_ctrlram[chip][0x03],
4841 K051316_ctrlram[chip][0x04],
4842 K051316_ctrlram[chip][0x05],
4843 K051316_ctrlram[chip][0x06],
4844 K051316_ctrlram[chip][0x07],
4845 K051316_ctrlram[chip][0x08],
4846 K051316_ctrlram[chip][0x09],
4847 K051316_ctrlram[chip][0x0a],
4848 K051316_ctrlram[chip][0x0b],
4849 K051316_ctrlram[chip][0x0c], /* bank for ROM testing */
4850 K051316_ctrlram[chip][0x0d],
4851 K051316_ctrlram[chip][0x0e], /* 0 = test ROMs */
4852 K051316_ctrlram[chip][0x0f]);
4853 #endif
4854 }
4855
K051316_zoom_draw_0(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int flags,UINT32 priority)4856 void K051316_zoom_draw_0(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int flags,UINT32 priority)
4857 {
4858 K051316_zoom_draw(0,bitmap,cliprect,flags,priority);
4859 }
4860
K051316_zoom_draw_1(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int flags,UINT32 priority)4861 void K051316_zoom_draw_1(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int flags,UINT32 priority)
4862 {
4863 K051316_zoom_draw(1,bitmap,cliprect,flags,priority);
4864 }
4865
K051316_zoom_draw_2(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int flags,UINT32 priority)4866 void K051316_zoom_draw_2(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int flags,UINT32 priority)
4867 {
4868 K051316_zoom_draw(2,bitmap,cliprect,flags,priority);
4869 }
4870
4871
4872
4873 /***************************************************************************/
4874 /* */
4875 /* 053936 */
4876 /* */
4877 /***************************************************************************/
4878
4879 #define K053936_MAX_CHIPS 2
4880
4881 data16_t *K053936_0_ctrl,*K053936_0_linectrl;
4882 data16_t *K053936_1_ctrl,*K053936_1_linectrl;
4883 static int K053936_offset[K053936_MAX_CHIPS][2];
4884 static int K053936_wraparound[K053936_MAX_CHIPS];
4885
4886
K053936_zoom_draw(int chip,data16_t * ctrl,data16_t * linectrl,struct mame_bitmap * bitmap,const struct rectangle * cliprect,struct tilemap * tilemap,int flags,UINT32 priority)4887 static void K053936_zoom_draw(int chip,data16_t *ctrl,data16_t *linectrl,struct mame_bitmap *bitmap,const struct rectangle *cliprect,struct tilemap *tilemap,int flags,UINT32 priority)
4888 {
4889 if (ctrl[0x07] & 0x0040) /* "super" mode */
4890 {
4891 UINT32 startx,starty;
4892 int incxx,incxy;
4893 struct rectangle my_clip;
4894 int y,maxy;
4895
4896 if ((ctrl[0x07] & 0x0002) && ctrl[0x09]) /* wrong, but fixes glfgreat */
4897 {
4898 my_clip.min_x = ctrl[0x08] + K053936_offset[chip][0]+2;
4899 my_clip.max_x = ctrl[0x09] + K053936_offset[chip][0]+2 - 1;
4900 if (my_clip.min_x < cliprect->min_x)
4901 my_clip.min_x = cliprect->min_x;
4902 if (my_clip.max_x > cliprect->max_x)
4903 my_clip.max_x = cliprect->max_x;
4904
4905 y = ctrl[0x0a] + K053936_offset[chip][1]-2;
4906 if (y < cliprect->min_y)
4907 y = cliprect->min_y;
4908 maxy = ctrl[0x0b] + K053936_offset[chip][1]-2 - 1;
4909 if (maxy > cliprect->max_y)
4910 maxy = cliprect->max_y;
4911 }
4912 else
4913 {
4914 my_clip.min_x = cliprect->min_x;
4915 my_clip.max_x = cliprect->max_x;
4916
4917 y = cliprect->min_y;
4918 maxy = cliprect->max_y;
4919 }
4920
4921 while (y <= maxy)
4922 {
4923 data16_t *lineaddr = linectrl + 4*((y - K053936_offset[chip][1]) & 0x1ff);
4924 my_clip.min_y = my_clip.max_y = y;
4925
4926 startx = 256 * (INT16)(lineaddr[0] + ctrl[0x00]);
4927 starty = 256 * (INT16)(lineaddr[1] + ctrl[0x01]);
4928 incxx = (INT16)(lineaddr[2]);
4929 incxy = (INT16)(lineaddr[3]);
4930
4931 if (ctrl[0x06] & 0x8000) incxx *= 256;
4932 if (ctrl[0x06] & 0x0080) incxy *= 256;
4933
4934 startx -= K053936_offset[chip][0] * incxx;
4935 starty -= K053936_offset[chip][0] * incxy;
4936
4937 tilemap_draw_roz(bitmap,&my_clip,tilemap,startx << 5,starty << 5,
4938 incxx << 5,incxy << 5,0,0,
4939 K053936_wraparound[chip],
4940 flags,priority);
4941
4942 y++;
4943 }
4944 }
4945 else /* "simple" mode */
4946 {
4947 UINT32 startx,starty;
4948 int incxx,incxy,incyx,incyy;
4949
4950 startx = 256 * (INT16)(ctrl[0x00]);
4951 starty = 256 * (INT16)(ctrl[0x01]);
4952 incyx = (INT16)(ctrl[0x02]);
4953 incyy = (INT16)(ctrl[0x03]);
4954 incxx = (INT16)(ctrl[0x04]);
4955 incxy = (INT16)(ctrl[0x05]);
4956
4957 if (ctrl[0x06] & 0x4000) { incyx *= 256; incyy *= 256; }
4958 if (ctrl[0x06] & 0x0040) { incxx *= 256; incxy *= 256; }
4959
4960 startx -= K053936_offset[chip][1] * incyx;
4961 starty -= K053936_offset[chip][1] * incyy;
4962
4963 startx -= K053936_offset[chip][0] * incxx;
4964 starty -= K053936_offset[chip][0] * incxy;
4965
4966 tilemap_draw_roz(bitmap,cliprect,tilemap,startx << 5,starty << 5,
4967 incxx << 5,incxy << 5,incyx << 5,incyy << 5,
4968 K053936_wraparound[chip],
4969 flags,priority);
4970 }
4971
4972 #if 0
4973 if (keyboard_pressed(KEYCODE_D))
4974 log_cb(RETRO_LOG_DEBUG, LOGPRE "%04x %04x %04x %04x\n%04x %04x %04x %04x\n%04x %04x %04x %04x\n%04x %04x %04x %04x",
4975 ctrl[0x00],
4976 ctrl[0x01],
4977 ctrl[0x02],
4978 ctrl[0x03],
4979 ctrl[0x04],
4980 ctrl[0x05],
4981 ctrl[0x06],
4982 ctrl[0x07],
4983 ctrl[0x08],
4984 ctrl[0x09],
4985 ctrl[0x0a],
4986 ctrl[0x0b],
4987 ctrl[0x0c],
4988 ctrl[0x0d],
4989 ctrl[0x0e],
4990 ctrl[0x0f]);
4991 #endif
4992 }
4993
4994
K053936_0_zoom_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect,struct tilemap * tilemap,int flags,UINT32 priority)4995 void K053936_0_zoom_draw(struct mame_bitmap *bitmap,const struct rectangle *cliprect,struct tilemap *tilemap,int flags,UINT32 priority)
4996 {
4997 K053936_zoom_draw(0,K053936_0_ctrl,K053936_0_linectrl,bitmap,cliprect,tilemap,flags,priority);
4998 }
4999
K053936_1_zoom_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect,struct tilemap * tilemap,int flags,UINT32 priority)5000 void K053936_1_zoom_draw(struct mame_bitmap *bitmap,const struct rectangle *cliprect,struct tilemap *tilemap,int flags,UINT32 priority)
5001 {
5002 K053936_zoom_draw(1,K053936_1_ctrl,K053936_1_linectrl,bitmap,cliprect,tilemap,flags,priority);
5003 }
5004
5005
K053936_wraparound_enable(int chip,int status)5006 void K053936_wraparound_enable(int chip, int status)
5007 {
5008 K053936_wraparound[chip] = status;
5009 }
5010
5011
K053936_set_offset(int chip,int xoffs,int yoffs)5012 void K053936_set_offset(int chip, int xoffs, int yoffs)
5013 {
5014 K053936_offset[chip][0] = xoffs;
5015 K053936_offset[chip][1] = yoffs;
5016 }
5017
5018
5019
5020 /***************************************************************************/
5021 /* */
5022 /* 053251 */
5023 /* */
5024 /***************************************************************************/
5025
5026 static unsigned char K053251_ram[16];
5027 static int K053251_palette_index[5];
5028 static struct tilemap *K053251_tilemaps[5];
5029 static int K053251_tilemaps_set;
5030
K053251_reset_indexes(void)5031 static void K053251_reset_indexes(void)
5032 {
5033 K053251_palette_index[0] = 32 * ((K053251_ram[9] >> 0) & 0x03);
5034 K053251_palette_index[1] = 32 * ((K053251_ram[9] >> 2) & 0x03);
5035 K053251_palette_index[2] = 32 * ((K053251_ram[9] >> 4) & 0x03);
5036 K053251_palette_index[3] = 16 * ((K053251_ram[10] >> 0) & 0x07);
5037 K053251_palette_index[4] = 16 * ((K053251_ram[10] >> 3) & 0x07);
5038 }
5039
K053251_vh_start(void)5040 int K053251_vh_start(void)
5041 {
5042 K053251_set_tilemaps(NULL,NULL,NULL,NULL,NULL);
5043
5044 state_save_register_UINT8("K053251", 0, "registers", K053251_ram, 16);
5045 state_save_register_func_postload(K053251_reset_indexes);
5046
5047 return 0;
5048 }
5049
K053251_set_tilemaps(struct tilemap * ci0,struct tilemap * ci1,struct tilemap * ci2,struct tilemap * ci3,struct tilemap * ci4)5050 void K053251_set_tilemaps(struct tilemap *ci0,struct tilemap *ci1,struct tilemap *ci2,struct tilemap *ci3,struct tilemap *ci4)
5051 {
5052 K053251_tilemaps[0] = ci0;
5053 K053251_tilemaps[1] = ci1;
5054 K053251_tilemaps[2] = ci2;
5055 K053251_tilemaps[3] = ci3;
5056 K053251_tilemaps[4] = ci4;
5057
5058 K053251_tilemaps_set = (ci0 || ci1 || ci2 || ci3 || ci4) ? 1 : 0;
5059 }
5060
WRITE_HANDLER(K053251_w)5061 WRITE_HANDLER( K053251_w )
5062 {
5063 int i,newind;
5064
5065 data &= 0x3f;
5066
5067 if (K053251_ram[offset] != data)
5068 {
5069 K053251_ram[offset] = data;
5070 if (offset == 9)
5071 {
5072 /* palette base index */
5073 for (i = 0;i < 3;i++)
5074 {
5075 newind = 32 * ((data >> 2*i) & 0x03);
5076 if (K053251_palette_index[i] != newind)
5077 {
5078 K053251_palette_index[i] = newind;
5079 if (K053251_tilemaps[i])
5080 tilemap_mark_all_tiles_dirty(K053251_tilemaps[i]);
5081
5082 }
5083 }
5084
5085 if (!K053251_tilemaps_set)
5086 tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
5087 }
5088 else if (offset == 10)
5089 {
5090 /* palette base index */
5091 for (i = 0;i < 2;i++)
5092 {
5093 newind = 16 * ((data >> 3*i) & 0x07);
5094 if (K053251_palette_index[3+i] != newind)
5095 {
5096 K053251_palette_index[3+i] = newind;
5097 if (K053251_tilemaps[3+i])
5098 tilemap_mark_all_tiles_dirty(K053251_tilemaps[3+i]);
5099
5100 }
5101 }
5102
5103 if (!K053251_tilemaps_set)
5104 tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
5105 }
5106 }
5107 }
5108
WRITE16_HANDLER(K053251_lsb_w)5109 WRITE16_HANDLER( K053251_lsb_w )
5110 {
5111 if (ACCESSING_LSB)
5112 K053251_w(offset, data & 0xff);
5113 }
5114
WRITE16_HANDLER(K053251_msb_w)5115 WRITE16_HANDLER( K053251_msb_w )
5116 {
5117 if (ACCESSING_MSB)
5118 K053251_w(offset, (data >> 8) & 0xff);
5119 }
5120
K053251_get_priority(int ci)5121 int K053251_get_priority(int ci)
5122 {
5123 return K053251_ram[ci];
5124 }
5125
K053251_get_palette_index(int ci)5126 int K053251_get_palette_index(int ci)
5127 {
5128 return K053251_palette_index[ci];
5129 }
5130
5131
5132
5133 /***************************************************************************/
5134 /* */
5135 /* 054000 */
5136 /* */
5137 /***************************************************************************/
5138
5139 static unsigned char K054000_ram[0x20];
5140
WRITE_HANDLER(K054000_w)5141 WRITE_HANDLER( K054000_w )
5142 {
5143 /*logerror("%04x: write %02x to 054000 address %02x\n",activecpu_get_pc(),data,offset);*/
5144
5145 K054000_ram[offset] = data;
5146 }
5147
READ_HANDLER(K054000_r)5148 READ_HANDLER( K054000_r )
5149 {
5150 int Acx,Acy,Aax,Aay;
5151 int Bcx,Bcy,Bax,Bay;
5152
5153 /*logerror("%04x: read 054000 address %02x\n",activecpu_get_pc(),offset);*/
5154
5155 if (offset != 0x18) return 0;
5156
5157 Acx = (K054000_ram[0x01] << 16) | (K054000_ram[0x02] << 8) | K054000_ram[0x03];
5158 Acy = (K054000_ram[0x09] << 16) | (K054000_ram[0x0a] << 8) | K054000_ram[0x0b];
5159 /* TODO: this is a hack to make thndrx2 pass the startup check. It is certainly wrong. */
5160 if (K054000_ram[0x04] == 0xff) Acx+=3;
5161 if (K054000_ram[0x0c] == 0xff) Acy+=3;
5162 Aax = K054000_ram[0x06] + 1;
5163 Aay = K054000_ram[0x07] + 1;
5164
5165 Bcx = (K054000_ram[0x15] << 16) | (K054000_ram[0x16] << 8) | K054000_ram[0x17];
5166 Bcy = (K054000_ram[0x11] << 16) | (K054000_ram[0x12] << 8) | K054000_ram[0x13];
5167 Bax = K054000_ram[0x0e] + 1;
5168 Bay = K054000_ram[0x0f] + 1;
5169
5170 if (Acx + Aax < Bcx - Bax)
5171 return 1;
5172
5173 if (Bcx + Bax < Acx - Aax)
5174 return 1;
5175
5176 if (Acy + Aay < Bcy - Bay)
5177 return 1;
5178
5179 if (Bcy + Bay < Acy - Aay)
5180 return 1;
5181
5182 return 0;
5183 }
5184
READ16_HANDLER(K054000_lsb_r)5185 READ16_HANDLER( K054000_lsb_r )
5186 {
5187 return K054000_r(offset);
5188 }
5189
WRITE16_HANDLER(K054000_lsb_w)5190 WRITE16_HANDLER( K054000_lsb_w )
5191 {
5192 if (ACCESSING_LSB)
5193 K054000_w(offset, data & 0xff);
5194 }
5195
5196
5197
5198 /***************************************************************************/
5199 /* */
5200 /* 051733 */
5201 /* */
5202 /***************************************************************************/
5203
5204 static unsigned char K051733_ram[0x20];
5205
WRITE_HANDLER(K051733_w)5206 WRITE_HANDLER( K051733_w )
5207 {
5208 /*logerror("%04x: write %02x to 051733 address %02x\n",activecpu_get_pc(),data,offset);*/
5209
5210 K051733_ram[offset] = data;
5211 }
5212
5213
int_sqrt(UINT32 op)5214 static int int_sqrt(UINT32 op)
5215 {
5216 UINT32 i,step;
5217
5218 i = 0x8000;
5219 step = 0x4000;
5220 while (step)
5221 {
5222 if (i*i == op) return i;
5223 else if (i*i > op) i -= step;
5224 else i += step;
5225 step >>= 1;
5226 }
5227 return i;
5228 }
5229
READ_HANDLER(K051733_r)5230 READ_HANDLER( K051733_r )
5231 {
5232 int op1 = (K051733_ram[0x00] << 8) | K051733_ram[0x01];
5233 int op2 = (K051733_ram[0x02] << 8) | K051733_ram[0x03];
5234 int op3 = (K051733_ram[0x04] << 8) | K051733_ram[0x05];
5235
5236 int rad = (K051733_ram[0x06] << 8) | K051733_ram[0x07];
5237 int yobj1c = (K051733_ram[0x08] << 8) | K051733_ram[0x09];
5238 int xobj1c = (K051733_ram[0x0a] << 8) | K051733_ram[0x0b];
5239 int yobj2c = (K051733_ram[0x0c] << 8) | K051733_ram[0x0d];
5240 int xobj2c = (K051733_ram[0x0e] << 8) | K051733_ram[0x0f];
5241
5242 /*logerror("%04x: read 051733 address %02x\n",activecpu_get_pc(),offset);*/
5243
5244 switch(offset){
5245 case 0x00:
5246 if (op2) return (op1 / op2) >> 8;
5247 else return 0xff;
5248 case 0x01:
5249 if (op2) return (op1 / op2) & 0xff;
5250 else return 0xff;
5251
5252 /* this is completely unverified */
5253 case 0x02:
5254 if (op2) return (op1 % op2) >> 8;
5255 else return 0xff;
5256 case 0x03:
5257 if (op2) return (op1 % op2) & 0xff;
5258 else return 0xff;
5259
5260 case 0x04:
5261 return int_sqrt(op3<<16) >> 8;
5262
5263 case 0x05:
5264 return int_sqrt(op3<<16) & 0xff;
5265
5266 case 0x06:
5267 return K051733_ram[0x13]; /*RNG read, used by Chequered Flag for differentiate cars, could be wrong */
5268
5269 case 0x07:{ /* note: Chequered Flag definitely wants all these bits to be enabled */
5270 if (xobj1c + rad < xobj2c)
5271 return 0xff;
5272
5273 if (xobj2c + rad < xobj1c)
5274 return 0xff;
5275
5276 if (yobj1c + rad < yobj2c)
5277 return 0xff;
5278
5279 if (yobj2c + rad < yobj1c)
5280 return 0xff;
5281
5282 return 0;
5283 }
5284 case 0x0e: /* best guess */
5285 return (xobj2c - xobj1c) >> 8;
5286 case 0x0f:
5287 return (xobj2c - xobj1c) & 0xff;
5288 default:
5289 return K051733_ram[offset];
5290 }
5291 }
5292
5293
5294
5295 /***************************************************************************/
5296 /* */
5297 /* 054157 */
5298 /* */
5299 /***************************************************************************/
5300
5301 static struct tilemap *K054157_tilemap[4], *K054157_cur_tilemap;
5302 static struct tilemap *K054157_tilemapb[4], *K054157_tilemaps[4];
5303
5304 static data16_t K054157_regs[0x20], K054157_regsb[4];
5305 static void (*K054157_linescroll_updater[4])(int layer);
5306
5307 static int K054157_cur_rombank, K054157_romnbbanks;
5308 static int K054157_uses_tile_banks, K054157_cur_tile_bank;
5309 static int K054157_gfxnum, K054157_memory_region;
5310 static int K054157_cur_offset;
5311 static data16_t *K054157_rambase, *K054157_cur_spbase, *K054157_cur_rambase;
5312 static data8_t *K054157_rombase;
5313 static data16_t *K054157_rambasel[8];
5314 static int K054157_tilemapl[8], K054157_offsetl[8];
5315
5316 static void (*K054157_callback)(int, int *, int *);
5317
K054157_get_tile_info(int tile_index,int layer)5318 static INLINE void K054157_get_tile_info(int tile_index,int layer)
5319 {
5320 data16_t *addr;
5321 int attr, code;
5322 data16_t *lbase = K054157_rambase + 0x2000*layer;
5323 if(tile_index < 64*32)
5324 addr = lbase + (tile_index<<1);
5325 else
5326 addr = lbase + (tile_index<<1) + 0x1000 - 64*32*2;
5327
5328 attr = addr[0];
5329 code = addr[1];
5330 tile_info.flags = 0;
5331
5332 (*K054157_callback)(layer, &code, &attr);
5333 SET_TILE_INFO(K054157_gfxnum,
5334 code,
5335 attr,
5336 tile_info.flags)
5337 }
5338
K054157_get_tile_info0(int tile_index)5339 static void K054157_get_tile_info0(int tile_index) { K054157_get_tile_info(tile_index,0); }
K054157_get_tile_info1(int tile_index)5340 static void K054157_get_tile_info1(int tile_index) { K054157_get_tile_info(tile_index,1); }
K054157_get_tile_info2(int tile_index)5341 static void K054157_get_tile_info2(int tile_index) { K054157_get_tile_info(tile_index,2); }
K054157_get_tile_info3(int tile_index)5342 static void K054157_get_tile_info3(int tile_index) { K054157_get_tile_info(tile_index,3); }
5343
5344
K054157_lsu_1_256(int layer)5345 static void K054157_lsu_1_256(int layer)
5346 {
5347 int y;
5348 int basey = K054157_regs[0x10|layer];
5349
5350 data16_t *baseram = K054157_cur_spbase + layer*0x400;
5351 for(y=0; y<256; y++) {
5352 int offset = (((basey + y) & 0x1ff) << 1) | 1;
5353 tilemap_set_scrollx(K054157_tilemap[layer], y, baseram[offset]);
5354 }
5355 }
5356
K054157_lsu_1_512(int layer)5357 static void K054157_lsu_1_512(int layer)
5358 {
5359 int y;
5360 int basey = K054157_regs[0x10|layer];
5361
5362 data16_t *baseram = K054157_cur_spbase + layer*0x400;
5363 for(y=0; y<512; y++) {
5364 int offset = (((basey + y) & 0x1ff) << 1) | 1;
5365 tilemap_set_scrollx(K054157_tilemap[layer], y, baseram[offset]);
5366 }
5367 }
5368
K054157_lsu_8_256(int layer)5369 static void K054157_lsu_8_256(int layer)
5370 {
5371 int y;
5372 int basey = K054157_regs[0x10|layer];
5373
5374 data16_t *baseram = K054157_cur_spbase + layer*0x400;
5375 for(y=0; y<256; y++) {
5376 int offset = (((basey + y) & 0x1f8) << 1) | 1;
5377 tilemap_set_scrollx(K054157_tilemap[layer], y, baseram[offset]);
5378 }
5379 }
5380
K054157_lsu_8_512(int layer)5381 static void K054157_lsu_8_512(int layer)
5382 {
5383 int y;
5384 int basey = K054157_regs[0x10|layer];
5385
5386 data16_t *baseram = K054157_cur_spbase + layer*0x400;
5387 for(y=0; y<512; y++) {
5388 int offset = (((basey + y) & 0x1f8) << 1) | 1;
5389 tilemap_set_scrollx(K054157_tilemap[layer], y, baseram[offset]);
5390 }
5391 }
5392
K054157_lsu_full(int layer)5393 static void K054157_lsu_full(int layer)
5394 {
5395 tilemap_set_scrollx(K054157_tilemap[layer], 0, K054157_regs[0x14|layer]);
5396 }
5397
K054157_reset_linescroll(void)5398 static void K054157_reset_linescroll(void)
5399 {
5400 int layer;
5401 int mode = K054157_regs[5];
5402 for(layer=0; layer < 4; layer++) {
5403 int lmode = (mode >> (layer << 1)) & 3;
5404 switch(lmode) {
5405 case 0:
5406 if(K054157_tilemap[layer] == K054157_tilemaps[layer]) {
5407 K054157_linescroll_updater[layer] = K054157_lsu_1_256;
5408 tilemap_set_scroll_rows(K054157_tilemap[layer], 256);
5409 } else {
5410 K054157_linescroll_updater[layer] = K054157_lsu_1_512;
5411 tilemap_set_scroll_rows(K054157_tilemap[layer], 512);
5412 }
5413 break;
5414 case 1:
5415 /* log_cb(RETRO_LOG_DEBUG, LOGPRE "LS mode layer %d unknown (%d)\n", layer, lmode);*/
5416 goto rhaaa_lovely;
5417 case 2:
5418 if(K054157_tilemap[layer] == K054157_tilemaps[layer]) {
5419 K054157_linescroll_updater[layer] = K054157_lsu_8_256;
5420 tilemap_set_scroll_rows(K054157_tilemap[layer], 256);
5421 } else {
5422 K054157_linescroll_updater[layer] = K054157_lsu_8_512;
5423 tilemap_set_scroll_rows(K054157_tilemap[layer], 512);
5424 }
5425 break;
5426 case 3:
5427 rhaaa_lovely:
5428 K054157_linescroll_updater[layer] = K054157_lsu_full;
5429 tilemap_set_scroll_rows(K054157_tilemap[layer], 1);
5430 break;
5431 }
5432 }
5433 }
5434
K054157_change_tilemap(int layer)5435 static void K054157_change_tilemap(int layer)
5436 {
5437 int flip = 0;
5438 if(K054157_regs[8|layer] & 1) {
5439 tilemap_set_enable(K054157_tilemapb[layer], 1);
5440 tilemap_set_enable(K054157_tilemaps[layer], 0);
5441 K054157_tilemap[layer] = K054157_tilemapb[layer];
5442 } else {
5443 tilemap_set_enable(K054157_tilemapb[layer], 0);
5444 tilemap_set_enable(K054157_tilemaps[layer], 1);
5445 K054157_tilemap[layer] = K054157_tilemaps[layer];
5446 }
5447 tilemap_mark_all_tiles_dirty(K054157_tilemap[layer]);
5448
5449 if(K054157_regs[0] & 0x20)
5450 flip |= TILEMAP_FLIPY;
5451 if(K054157_regs[0] & 0x10)
5452 flip |= TILEMAP_FLIPX;
5453
5454 tilemap_set_flip(K054157_tilemap[layer], flip);
5455
5456 K054157_reset_linescroll();
5457 }
5458
K054157_reset_tilemaps(void)5459 static void K054157_reset_tilemaps(void)
5460 {
5461 int i;
5462 /* To avoid crashes in K054157_reset_linescroll()*/
5463 for(i=0; i<4; i++)
5464 K054157_tilemap[i] = K054157_tilemaps[i];
5465 for(i=0; i<4; i++)
5466 K054157_change_tilemap(i);
5467 }
5468
K054157_change_flip(void)5469 static void K054157_change_flip(void)
5470 {
5471 int flip = 0;
5472
5473 if(K054157_regs[0] & 0x20)
5474 flip |= TILEMAP_FLIPY;
5475 if(K054157_regs[0] & 0x10)
5476 flip |= TILEMAP_FLIPX;
5477 tilemap_set_flip(K054157_tilemap[0], flip);
5478 tilemap_set_flip(K054157_tilemap[1], flip);
5479 tilemap_set_flip(K054157_tilemap[2], flip);
5480 tilemap_set_flip(K054157_tilemap[3], flip);
5481 }
5482
K054157_change_rambank(void)5483 static void K054157_change_rambank(void)
5484 {
5485 int bank = ((K054157_regs[0x19]>>2) & 6) | (K054157_regs[0x19] & 1);
5486
5487 K054157_cur_rambase = K054157_rambasel[bank];
5488 K054157_cur_tilemap = K054157_tilemap[K054157_tilemapl[bank]];
5489 K054157_cur_offset = K054157_offsetl[bank];
5490 }
5491
K054157_get_current_rambank(void)5492 int K054157_get_current_rambank(void)
5493 {
5494 return ((K054157_regs[0x19]>>2) & 6) | (K054157_regs[0x19] & 1);
5495 }
5496
K054157_change_splayer(void)5497 static void K054157_change_splayer(void)
5498 {
5499 int bank = ((K054157_regs[0x18]>>2) & 6) | (K054157_regs[0x18] & 1);
5500 K054157_cur_spbase = K054157_rambasel[bank];
5501 }
5502
K054157_change_rombank(void)5503 static void K054157_change_rombank(void)
5504 {
5505 int bank;
5506
5507 if (K054157_uses_tile_banks) /* asterix */
5508 bank = (K054157_regs[0x1a] >> 8) | (K054157_regs[0x1b] << 4) | (K054157_cur_tile_bank << 6);
5509 else /* everything else */
5510 bank = K054157_regs[0x1a] | (K054157_regs[0x1b] << 16);
5511
5512 K054157_cur_rombank = bank % K054157_romnbbanks;
5513 /*log_cb(RETRO_LOG_DEBUG, LOGPRE "%04x: %04x %04x %04x",activecpu_get_pc(),K054157_regs[0x1a],K054157_regs[0x1b],K054157_cur_rombank);*/
5514 }
5515
K054157_vh_start(int gfx_memory_region,int big,int (* scrolld)[4][2],int plane0,int plane1,int plane2,int plane3,void (* callback)(int,int *,int *))5516 int K054157_vh_start(int gfx_memory_region, int big, int (*scrolld)[4][2], int plane0,int plane1,int plane2,int plane3, void (*callback)(int, int *, int *))
5517 {
5518 int gfx_index;
5519 int i;
5520 static struct GfxLayout charlayout =
5521 {
5522 8, 8,
5523 0, /* filled in later */
5524 4,
5525 { 0, 0, 0, 0 }, /* filled in later */
5526 { 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4 },
5527 { 0*8*4, 1*8*4, 2*8*4, 3*8*4, 4*8*4, 5*8*4, 6*8*4, 7*8*4 },
5528 8*8*4
5529 };
5530
5531 /* find first empty slot to decode gfx */
5532 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
5533 if (Machine->gfx[gfx_index] == 0)
5534 break;
5535 if (gfx_index == MAX_GFX_ELEMENTS)
5536 return 1;
5537
5538 /* tweak the structure for the number of tiles we have */
5539 charlayout.total = memory_region_length(gfx_memory_region) / (8*4);
5540 charlayout.planeoffset[0] = plane0;
5541 charlayout.planeoffset[1] = plane1;
5542 charlayout.planeoffset[2] = plane2;
5543 charlayout.planeoffset[3] = plane3;
5544
5545 /* decode the graphics */
5546 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region), &charlayout);
5547 if (!Machine->gfx[gfx_index])
5548 return 1;
5549
5550 /* set the color information */
5551 if (Machine->drv->color_table_len)
5552 {
5553 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
5554 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
5555 }
5556 else
5557 {
5558 Machine->gfx[gfx_index]->colortable = Machine->pens;
5559 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / 16;
5560 }
5561
5562 K054157_memory_region = gfx_memory_region;
5563 K054157_gfxnum = gfx_index;
5564 K054157_callback = callback;
5565
5566 K054157_rombase = memory_region(gfx_memory_region);
5567 K054157_romnbbanks = memory_region_length(gfx_memory_region)/0x2000;
5568 K054157_cur_rombank = 0;
5569 K054157_uses_tile_banks = 0;
5570
5571 K054157_tilemapb[0] = tilemap_create(K054157_get_tile_info0, tilemap_scan_rows,
5572 TILEMAP_TRANSPARENT, 8, 8, 64, 64);
5573 K054157_tilemapb[1] = tilemap_create(K054157_get_tile_info1, tilemap_scan_rows,
5574 TILEMAP_TRANSPARENT, 8, 8, 64, 64);
5575 K054157_tilemapb[2] = tilemap_create(K054157_get_tile_info2, tilemap_scan_rows,
5576 TILEMAP_TRANSPARENT, 8, 8, 64, 64);
5577 K054157_tilemapb[3] = tilemap_create(K054157_get_tile_info3, tilemap_scan_rows,
5578 TILEMAP_TRANSPARENT, 8, 8, 64, 64);
5579 K054157_tilemaps[0] = tilemap_create(K054157_get_tile_info0, tilemap_scan_rows,
5580 TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5581 K054157_tilemaps[1] = tilemap_create(K054157_get_tile_info1, tilemap_scan_rows,
5582 TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5583 K054157_tilemaps[2] = tilemap_create(K054157_get_tile_info2, tilemap_scan_rows,
5584 TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5585 K054157_tilemaps[3] = tilemap_create(K054157_get_tile_info3, tilemap_scan_rows,
5586 TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5587
5588 K054157_rambase = auto_malloc(0x14000);
5589
5590 if(!K054157_rambase
5591 || !K054157_tilemapb[0] || !K054157_tilemapb[1] || !K054157_tilemapb[2] || !K054157_tilemapb[3]
5592 || !K054157_tilemaps[0] || !K054157_tilemaps[1] || !K054157_tilemaps[2] || !K054157_tilemaps[3])
5593 return 1;
5594
5595 if(big) {
5596 K054157_rambasel[0] = K054157_rambase + 0x2000;
5597 K054157_rambasel[1] = K054157_rambase + 0x6000;
5598 K054157_rambasel[2] = K054157_rambase + 0x3000;
5599 K054157_rambasel[3] = K054157_rambase + 0x7000;
5600 K054157_rambasel[4] = K054157_rambase + 0x4000;
5601 K054157_rambasel[5] = K054157_rambase + 0x0000;
5602 K054157_rambasel[6] = K054157_rambase + 0x5000;
5603 K054157_rambasel[7] = K054157_rambase + 0x1000;
5604 } else {
5605 K054157_rambasel[0] = K054157_rambase + 0x0000;
5606 K054157_rambasel[1] = K054157_rambase + 0x2000;
5607 K054157_rambasel[2] = K054157_rambase + 0x4000;
5608 K054157_rambasel[3] = K054157_rambase + 0x6000;
5609 K054157_rambasel[4] = 0;
5610 K054157_rambasel[5] = 0;
5611 K054157_rambasel[6] = 0;
5612 K054157_rambasel[7] = 0;
5613 }
5614
5615 for(i=0; i<8; i++) {
5616 if(K054157_rambasel[i]) {
5617 int delta = K054157_rambasel[i] - K054157_rambase;
5618 K054157_tilemapl[i] = delta >> 13;
5619 K054157_offsetl [i] = (delta & 0x1000) ? 64*32 : 0;
5620 } else {
5621 K054157_tilemapl[i] = 0;
5622 K054157_offsetl [i] = 0;
5623 }
5624 }
5625
5626 memset(K054157_rambase, 0, 0x10000);
5627 memset(K054157_regs, 0, 0x40);
5628 memset(K054157_regsb, 0, 8);
5629
5630 for(i=0; i<4; i++) {
5631 tilemap_set_transparent_pen(K054157_tilemapb[i],0);
5632 tilemap_set_scrolldx(K054157_tilemapb[i], -scrolld[0][i][0], -scrolld[1][i][0]);
5633 tilemap_set_scrolldy(K054157_tilemapb[i], -scrolld[0][i][1], -scrolld[1][i][1]);
5634
5635 tilemap_set_transparent_pen(K054157_tilemaps[i],0);
5636 tilemap_set_scrolldx(K054157_tilemaps[i], -scrolld[0][i][0], -scrolld[1][i][0]);
5637 tilemap_set_scrolldy(K054157_tilemaps[i], -scrolld[0][i][1], -scrolld[1][i][1]);
5638 }
5639
5640 K054157_reset_tilemaps();
5641 K054157_change_rambank();
5642 K054157_change_rombank();
5643 K054157_change_splayer();
5644
5645 state_save_register_UINT16("K054157", 0, "memory", K054157_rambase, 0x8000);
5646 state_save_register_UINT16("K054157", 0, "registers", K054157_regs, 0x20);
5647 state_save_register_UINT16("K054157", 0, "registers b", K054157_regsb, 0x4);
5648
5649 state_save_register_func_postload(K054157_reset_tilemaps);
5650 state_save_register_func_postload(K054157_change_rambank);
5651 state_save_register_func_postload(K054157_change_rombank);
5652
5653 return 0;
5654 }
5655
5656
READ16_HANDLER(K054157_ram_word_r)5657 READ16_HANDLER( K054157_ram_word_r )
5658 {
5659 return K054157_cur_rambase[offset];
5660 }
5661
READ16_HANDLER(K054157_ram_half_word_r)5662 READ16_HANDLER( K054157_ram_half_word_r )
5663 {
5664 return K054157_cur_rambase[((offset << 1) & 0xffe) | ((offset >> 11) ^ 1)];
5665 }
5666
READ16_HANDLER(K054157_rom_word_r)5667 READ16_HANDLER( K054157_rom_word_r )
5668 {
5669 int addr = 0x2000*K054157_cur_rombank + 2*offset;
5670
5671 /* log_cb(RETRO_LOG_DEBUG, LOGPRE "%04x: addr %06x",activecpu_get_pc(),addr);*/
5672
5673 return K054157_rombase[addr+1] | (K054157_rombase[addr] << 8);
5674 }
5675
READ16_HANDLER(K054157_rom_word_8000_r)5676 READ16_HANDLER( K054157_rom_word_8000_r )
5677 {
5678 int addr = 0x8000*K054157_cur_rombank + 2*offset;
5679
5680 /* log_cb(RETRO_LOG_DEBUG, LOGPRE "%04x: addr %06x",activecpu_get_pc(),addr);*/
5681
5682 /* log_cb(RETRO_LOG_DEBUG, LOGPRE "rd @ %x (bank %x, final %x)\n", offset*2, K054157_cur_rombank, addr);*/
5683
5684 return K054157_rombase[addr+1] | (K054157_rombase[addr] << 8);
5685 }
5686
WRITE16_HANDLER(K054157_ram_word_w)5687 WRITE16_HANDLER( K054157_ram_word_w )
5688 {
5689 data16_t *adr = K054157_cur_rambase + offset;
5690 data16_t old = *adr;
5691
5692 COMBINE_DATA(adr);
5693 if(*adr != old && K054157_cur_tilemap)
5694 tilemap_mark_tile_dirty(K054157_cur_tilemap, offset/2 + K054157_cur_offset);
5695 }
5696
WRITE16_HANDLER(K054157_ram_half_word_w)5697 WRITE16_HANDLER( K054157_ram_half_word_w )
5698 {
5699 data16_t *adr = K054157_cur_rambase + (((offset << 1) & 0xffe) | 1);
5700 data16_t old = *adr;
5701
5702 COMBINE_DATA(adr);
5703 if(*adr != old)
5704 tilemap_mark_tile_dirty(K054157_cur_tilemap, (offset & 0x7ff) + K054157_cur_offset);
5705 }
5706
WRITE16_HANDLER(K054157_word_w)5707 WRITE16_HANDLER( K054157_word_w )
5708 {
5709 UINT16 old = K054157_regs[offset];
5710 COMBINE_DATA (K054157_regs + offset);
5711
5712 if(K054157_regs[offset] != old)
5713 {
5714 switch(offset) {
5715 case 0x00:
5716 if((K054157_regs[0] & 0x30) != (old & 0x30))
5717 K054157_change_flip();
5718 break;
5719 case 0x05:
5720 K054157_reset_linescroll();
5721 break;
5722 case 0x08:
5723 case 0x09:
5724 case 0x0a:
5725 case 0x0b:
5726 if((K054157_regs[offset] & 1) ^ (K054157_tilemap[offset & 3] == K054157_tilemapb[offset & 3]))
5727 K054157_change_tilemap(offset & 3);
5728 break;
5729 case 0x18:
5730 K054157_change_splayer();
5731 break;
5732 case 0x19:
5733 K054157_change_rambank();
5734 break;
5735 case 0x1a:
5736 case 0x1b:
5737 K054157_change_rombank();
5738 break;
5739 case 0x1c:
5740 tilemap_mark_all_tiles_dirty(K054157_tilemapb[0]);
5741 tilemap_mark_all_tiles_dirty(K054157_tilemapb[1]);
5742 tilemap_mark_all_tiles_dirty(K054157_tilemapb[2]);
5743 tilemap_mark_all_tiles_dirty(K054157_tilemapb[3]);
5744 tilemap_mark_all_tiles_dirty(K054157_tilemaps[0]);
5745 tilemap_mark_all_tiles_dirty(K054157_tilemaps[1]);
5746 tilemap_mark_all_tiles_dirty(K054157_tilemaps[2]);
5747 tilemap_mark_all_tiles_dirty(K054157_tilemaps[3]);
5748 break;
5749 }
5750 }
5751 }
5752
WRITE16_HANDLER(K054157_b_word_w)5753 WRITE16_HANDLER( K054157_b_word_w )
5754 {
5755 COMBINE_DATA (K054157_regsb + offset);
5756 }
5757
K054157_tilemap_update(void)5758 void K054157_tilemap_update(void)
5759 {
5760 int layer;
5761
5762 for(layer=0; layer<4; layer++)
5763 {
5764 K054157_linescroll_updater[layer](layer);
5765 tilemap_set_scrolly(K054157_tilemap[layer], 0, K054157_regs[0x10|layer]);
5766 }
5767 }
5768
K054157_tilemap_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int num,int flags,UINT32 priority)5769 void K054157_tilemap_draw(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int num, int flags, UINT32 priority)
5770 {
5771 tilemap_draw(bitmap,cliprect, K054157_tilemap[num], flags, priority);
5772 }
5773
K054157_is_IRQ_enabled(void)5774 int K054157_is_IRQ_enabled(void)
5775 {
5776 return K054157_regs[3] & 1;
5777 }
5778
K054157_get_lookup(int bits)5779 int K054157_get_lookup(int bits)
5780 {
5781 int res;
5782
5783 res = (K054157_regs[0x1c] >> (bits << 2)) & 0x0f;
5784
5785 if (K054157_uses_tile_banks) /* Asterix */
5786 res |= K054157_cur_tile_bank << 4;
5787
5788 return res;
5789 }
5790
K054157_set_tile_bank(int bank)5791 void K054157_set_tile_bank(int bank)
5792 {
5793 K054157_uses_tile_banks = 1;
5794
5795 if (K054157_cur_tile_bank != bank)
5796 {
5797 K054157_cur_tile_bank = bank;
5798
5799 tilemap_mark_all_tiles_dirty(K054157_tilemap[0]);
5800 tilemap_mark_all_tiles_dirty(K054157_tilemap[1]);
5801 tilemap_mark_all_tiles_dirty(K054157_tilemap[2]);
5802 tilemap_mark_all_tiles_dirty(K054157_tilemap[3]);
5803 }
5804
5805 K054157_change_rombank();
5806 }
5807
5808
5809
5810 /***************************************************************************/
5811 /* */
5812 /* 056832 */
5813 /* */
5814 /***************************************************************************/
5815
5816 #define K056832_PAGE_COLS 64
5817 #define K056832_PAGE_ROWS 32
5818 #define K056832_PAGE_HEIGHT (K056832_PAGE_ROWS*8)
5819 #define K056832_PAGE_WIDTH (K056832_PAGE_COLS*8)
5820 #define K056832_PAGE_COUNT 16
5821
5822 static struct tilemap *K056832_tilemap[K056832_PAGE_COUNT];
5823 static struct mame_bitmap *K056832_pixmap[K056832_PAGE_COUNT];
5824
5825 static data16_t K056832_regs[0x20]; /* 157/832 regs group 1*/
5826 static data16_t K056832_regsb[4]; /* 157/832 regs group 2, board dependent*/
5827
5828 static data8_t *K056832_rombase; /* pointer to tile gfx data*/
5829 data16_t *K056832_videoram;
5830 static int K056832_NumGfxBanks; /* depends on size of graphics ROMs*/
5831 static int K056832_CurGfxBank; /* cached info for K056832_regs[0x1a]*/
5832 static int K056832_gfxnum; /* graphics element index for unpacked tiles*/
5833 static int K056832_memory_region; /* memory region for tile gfx data*/
5834 static int K056832_bpp;
5835
5836 /* ROM readback involves reading 2 halves of a word*/
5837 /* from the same location in a row. Reading the*/
5838 /* RAM window resets this state so you get the first half.*/
5839 static int K056832_rom_half;
5840
5841 /* locally cached values*/
5842 static int K056832_LayerAssociatedWithPage[K056832_PAGE_COUNT];
5843 static int K056832_LayerOffset[4][2];
5844 static int K056832_LSRAMPage[4][2];
5845 static int K056832_X[4]; /* 0..3 left*/
5846 static int K056832_Y[4]; /* 0..3 top*/
5847 static int K056832_W[4]; /* 0..3 width -> 1..4 pages*/
5848 static int K056832_H[4]; /* 0..3 height -> 1..4 pages*/
5849 static int K056832_dx[4]; /* scroll*/
5850 static int K056832_dy[4]; /* scroll*/
5851 static UINT32 K056832_LineDirty[K056832_PAGE_COUNT][8];
5852 static UINT8 K056832_AllLinesDirty[K056832_PAGE_COUNT];
5853 static UINT8 K056832_PageTileMode[K056832_PAGE_COUNT];
5854 static UINT8 K056832_LayerTileMode[4];
5855 static int K056832_DefaultLayerAssociation;
5856 static int K056832_LayerAssociation;
5857 static int K056832_ActiveLayer;
5858 static int K056832_SelectedPage;
5859 static int K056832_SelectedPagex4096;
5860 static int K056832_UpdateMode;
5861 static int K056832_linemap_enabled;
5862 static int K056832_use_ext_linescroll;
5863 static int K056832_uses_tile_banks, K056832_cur_tile_bank;
5864
5865 static int K056832_djmain_hack;
5866
5867 #define K056832_mark_line_dirty(P,L) if (L<0x100) K056832_LineDirty[P][L>>5] |= 1<<(L&0x1f)
5868 #define K056832_mark_all_lines_dirty(P) K056832_AllLinesDirty[P] = 1
5869
K056832_mark_page_dirty(int page)5870 static void K056832_mark_page_dirty(int page)
5871 {
5872 if (K056832_PageTileMode[page])
5873 tilemap_mark_all_tiles_dirty(K056832_tilemap[page]);
5874 else
5875 K056832_mark_all_lines_dirty(page);
5876 }
5877
K056832_mark_plane_dirty(int layer)5878 void K056832_mark_plane_dirty(int layer)
5879 {
5880 int tilemode, i;
5881
5882 tilemode = K056832_LayerTileMode[layer];
5883
5884 for (i=0; i<K056832_PAGE_COUNT; i++)
5885 {
5886 if (K056832_LayerAssociatedWithPage[i] == layer)
5887 {
5888 K056832_PageTileMode[i] = tilemode;
5889 K056832_mark_page_dirty(i);
5890 }
5891 }
5892 }
5893
K056832_MarkAllTilemapsDirty(void)5894 void K056832_MarkAllTilemapsDirty(void)
5895 {
5896 int i;
5897
5898 for (i=0; i<K056832_PAGE_COUNT; i++)
5899 {
5900 if (K056832_LayerAssociatedWithPage[i] != -1)
5901 {
5902 K056832_PageTileMode[i] = K056832_LayerTileMode[K056832_LayerAssociatedWithPage[i]];
5903 K056832_mark_page_dirty(i);
5904 }
5905 }
5906 }
5907
K056832_UpdatePageLayout(void)5908 static void K056832_UpdatePageLayout(void)
5909 {
5910 int layer, rowstart, rowspan, colstart, colspan, r, c, pageIndex, setlayer;
5911
5912 /* enable layer association by default*/
5913 K056832_LayerAssociation = K056832_DefaultLayerAssociation;
5914
5915 /* disable association if a layer grabs the entire 4x4 map (happens in Twinbee and Dadandarn)*/
5916 for (layer=0; layer<4; layer++)
5917 {
5918 if (!K056832_Y[layer] && !K056832_X[layer] && K056832_H[layer]==3 && K056832_W[layer]==3)
5919 {
5920 K056832_LayerAssociation = 0;
5921 break;
5922 }
5923 }
5924
5925 /* disable all tilemaps*/
5926 for (pageIndex=0; pageIndex<K056832_PAGE_COUNT; pageIndex++)
5927 {
5928 K056832_LayerAssociatedWithPage[pageIndex] = -1;
5929 }
5930
5931 /* enable associated tilemaps*/
5932 for (layer=0; layer<4; layer++)
5933 {
5934 rowstart = K056832_Y[layer];
5935 colstart = K056832_X[layer];
5936 rowspan = K056832_H[layer]+1;
5937 colspan = K056832_W[layer]+1;
5938
5939 setlayer = (K056832_LayerAssociation) ? layer : K056832_ActiveLayer;
5940
5941 for (r=0; r<rowspan; r++)
5942 {
5943 for (c=0; c<colspan; c++)
5944 {
5945 pageIndex = (((rowstart + r) & 3) << 2) + ((colstart + c) & 3);
5946 if (!K056832_djmain_hack || K056832_LayerAssociatedWithPage[pageIndex] == -1)
5947 K056832_LayerAssociatedWithPage[pageIndex] = setlayer;
5948 }
5949 }
5950 }
5951
5952 /* refresh associated tilemaps*/
5953 K056832_MarkAllTilemapsDirty();
5954 }
5955
K056832_get_lookup(int bits)5956 int K056832_get_lookup(int bits)
5957 {
5958 int res;
5959
5960 res = (K056832_regs[0x1c] >> (bits << 2)) & 0x0f;
5961
5962 if (K056832_uses_tile_banks) /* Asterix */
5963 res |= K056832_cur_tile_bank << 4;
5964
5965 return res;
5966 }
5967
5968 static void (*K056832_callback)(int, int *, int *);
5969
K056832_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)5970 static INLINE UINT32 K056832_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)
5971 {
5972 return (row<<6) + col;
5973 }
5974
K056832_get_tile_info(int tile_index,int pageIndex)5975 static INLINE void K056832_get_tile_info( int tile_index, int pageIndex )
5976 {
5977 static struct K056832_SHIFTMASKS
5978 {
5979 int flips, palm1, pals2, palm2;
5980 }
5981 K056832_shiftmasks[4] = {{6,0x3f,0,0x00},{4,0x0f,2,0x30},{2,0x03,2,0x3c},{0,0x00,2,0x3f}};
5982
5983 struct K056832_SHIFTMASKS *smptr;
5984 int layer, flip, fbits, attr, code;
5985 data16_t *pMem;
5986
5987 pMem = &K056832_videoram[(pageIndex<<12)+(tile_index<<1)];
5988
5989 if (K056832_LayerAssociation)
5990 {
5991 layer = K056832_LayerAssociatedWithPage[pageIndex];
5992 if (layer == -1) layer = 0; /* use layer 0's palette info for unmapped pages*/
5993 }
5994 else
5995 layer = K056832_ActiveLayer;
5996
5997 fbits = K056832_regs[3]>>6 & 3;
5998 flip = K056832_regs[1]>>(layer<<1) & 0x3; /* tile-flip override (see p.20 3.2.2 "REG2")*/
5999 smptr = &K056832_shiftmasks[fbits];
6000 attr = pMem[0];
6001 code = pMem[1];
6002
6003 /* normalize the flip/palette flags*/
6004 /* see the tables on pages 4 and 10 of the Pt. 2-3 "VRAM" manual*/
6005 /* for a description of these bits "FBIT0" and "FBIT1"*/
6006 flip &= attr>>smptr->flips & 3;
6007 attr = (attr & smptr->palm1) | (attr>>smptr->pals2 & smptr->palm2);
6008 tile_info.flags = TILE_FLIPYX(flip);
6009
6010 (*K056832_callback)(layer, &code, &attr);
6011
6012 SET_TILE_INFO(K056832_gfxnum,
6013 code,
6014 attr,
6015 tile_info.flags)
6016 }
6017
K056832_get_tile_info0(int tile_index)6018 static void K056832_get_tile_info0(int tile_index) { K056832_get_tile_info(tile_index,0x0); }
K056832_get_tile_info1(int tile_index)6019 static void K056832_get_tile_info1(int tile_index) { K056832_get_tile_info(tile_index,0x1); }
K056832_get_tile_info2(int tile_index)6020 static void K056832_get_tile_info2(int tile_index) { K056832_get_tile_info(tile_index,0x2); }
K056832_get_tile_info3(int tile_index)6021 static void K056832_get_tile_info3(int tile_index) { K056832_get_tile_info(tile_index,0x3); }
K056832_get_tile_info4(int tile_index)6022 static void K056832_get_tile_info4(int tile_index) { K056832_get_tile_info(tile_index,0x4); }
K056832_get_tile_info5(int tile_index)6023 static void K056832_get_tile_info5(int tile_index) { K056832_get_tile_info(tile_index,0x5); }
K056832_get_tile_info6(int tile_index)6024 static void K056832_get_tile_info6(int tile_index) { K056832_get_tile_info(tile_index,0x6); }
K056832_get_tile_info7(int tile_index)6025 static void K056832_get_tile_info7(int tile_index) { K056832_get_tile_info(tile_index,0x7); }
K056832_get_tile_info8(int tile_index)6026 static void K056832_get_tile_info8(int tile_index) { K056832_get_tile_info(tile_index,0x8); }
K056832_get_tile_info9(int tile_index)6027 static void K056832_get_tile_info9(int tile_index) { K056832_get_tile_info(tile_index,0x9); }
K056832_get_tile_infoa(int tile_index)6028 static void K056832_get_tile_infoa(int tile_index) { K056832_get_tile_info(tile_index,0xa); }
K056832_get_tile_infob(int tile_index)6029 static void K056832_get_tile_infob(int tile_index) { K056832_get_tile_info(tile_index,0xb); }
K056832_get_tile_infoc(int tile_index)6030 static void K056832_get_tile_infoc(int tile_index) { K056832_get_tile_info(tile_index,0xc); }
K056832_get_tile_infod(int tile_index)6031 static void K056832_get_tile_infod(int tile_index) { K056832_get_tile_info(tile_index,0xd); }
K056832_get_tile_infoe(int tile_index)6032 static void K056832_get_tile_infoe(int tile_index) { K056832_get_tile_info(tile_index,0xe); }
K056832_get_tile_infof(int tile_index)6033 static void K056832_get_tile_infof(int tile_index) { K056832_get_tile_info(tile_index,0xf); }
6034
K056832_change_rambank(void)6035 static void K056832_change_rambank(void)
6036 {
6037 /* ------xx page col
6038 * ---xx--- page row
6039 */
6040 int bank = K056832_regs[0x19];
6041
6042 if (K056832_regs[0] & 0x02) /* external linescroll enable */
6043 {
6044 K056832_SelectedPage = K056832_PAGE_COUNT;
6045 }
6046 else
6047 {
6048 K056832_SelectedPage = ((bank>>1)&0xc)|(bank&3);
6049 }
6050 K056832_SelectedPagex4096 = K056832_SelectedPage << 12;
6051 }
6052
K056832_get_current_rambank(void)6053 int K056832_get_current_rambank(void)
6054 {
6055 int bank = K056832_regs[0x19];
6056
6057 return ((bank>>1)&0xc)|(bank&3);
6058 }
6059
K056832_change_rombank(void)6060 static void K056832_change_rombank(void)
6061 {
6062 int bank;
6063
6064 if (K056832_uses_tile_banks) /* Asterix */
6065 {
6066 bank = (K056832_regs[0x1a] >> 8) | (K056832_regs[0x1b] << 4) | (K056832_cur_tile_bank << 6);
6067 }
6068 else
6069 {
6070 bank = K056832_regs[0x1a] | (K056832_regs[0x1b] << 16);
6071 }
6072
6073 K056832_CurGfxBank = bank % K056832_NumGfxBanks;
6074 }
6075
K056832_set_tile_bank(int bank)6076 void K056832_set_tile_bank(int bank)
6077 {
6078 K056832_uses_tile_banks = 1;
6079
6080 if (K056832_cur_tile_bank != bank)
6081 {
6082 K056832_cur_tile_bank = bank;
6083
6084 K056832_mark_plane_dirty(0);
6085 K056832_mark_plane_dirty(1);
6086 K056832_mark_plane_dirty(2);
6087 K056832_mark_plane_dirty(3);
6088 }
6089
6090 K056832_change_rombank();
6091 }
6092
K056832_vh_start(int gfx_memory_region,int bpp,int big,int (* scrolld)[4][2],void (* callback)(int,int *,int *),int djmain_hack)6093 int K056832_vh_start(int gfx_memory_region, int bpp, int big, int (*scrolld)[4][2], void (*callback)(int, int *, int *), int djmain_hack)
6094 {
6095 struct tilemap *tilemap;
6096 int gfx_index;
6097 int i;
6098 struct GfxLayout charlayout8 =
6099 {
6100 8, 8,
6101 0, /* filled in later */
6102 8,
6103 { 8*7,8*3,8*5,8*1,8*6,8*2,8*4,8*0 },
6104 { 0, 1, 2, 3, 4, 5, 6, 7 },
6105 { 0, 8*8, 8*8*2, 8*8*3, 8*8*4, 8*8*5, 8*8*6, 8*8*7 },
6106 8*8*8
6107 };
6108 struct GfxLayout charlayout8le =
6109 {
6110 8, 8,
6111 0,
6112 8,
6113 /* { 0, 1, 2, 3, 0+(0x200000*8), 1+(0x200000*8), 2+(0x200000*8), 3+(0x200000*8) }, */
6114 { 0+(0x200000*8), 1+(0x200000*8), 2+(0x200000*8), 3+(0x200000*8), 0, 1, 2, 3 },
6115 { 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4 },
6116 { 0*8*4, 1*8*4, 2*8*4, 3*8*4, 4*8*4, 5*8*4, 6*8*4, 7*8*4 },
6117 8*8*4
6118 };
6119 struct GfxLayout charlayout6 =
6120 {
6121 8, 8,
6122 0, /* filled in later */
6123 6,
6124 { 40, 32, 24, 8, 16, 0 },
6125 { 0, 1, 2, 3, 4, 5, 6, 7 },
6126 { 0, 6*8, 6*8*2, 6*8*3, 6*8*4, 6*8*5, 6*8*6, 6*8*7 },
6127 8*8*6
6128 };
6129 struct GfxLayout charlayout5 =
6130 {
6131 8, 8,
6132 0, /* filled in later */
6133 5,
6134 { 32, 24, 8, 16, 0 },
6135 { 0, 1, 2, 3, 4, 5, 6, 7 },
6136 { 0, 5*8, 5*8*2, 5*8*3, 5*8*4, 5*8*5, 5*8*6, 5*8*7 },
6137 8*8*5
6138 };
6139 struct GfxLayout charlayout4 =
6140 {
6141 8, 8,
6142 0,
6143 4,
6144 { 0, 1, 2, 3 },
6145 { 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4 },
6146 { 0*8*4, 1*8*4, 2*8*4, 3*8*4, 4*8*4, 5*8*4, 6*8*4, 7*8*4 },
6147 8*8*4
6148 };
6149 static struct GfxLayout charlayout4dj =
6150 {
6151 8, 8,
6152 0, /* filled in later */
6153 4,
6154 { 8*3,8*1,8*2,8*0 },
6155 { 0, 1, 2, 3, 4, 5, 6, 7 },
6156 { 0, 8*4, 8*4*2, 8*4*3, 8*4*4, 8*4*5, 8*4*6, 8*4*7 },
6157 8*8*4
6158 };
6159
6160 K056832_bpp = bpp;
6161
6162 /* find first empty slot to decode gfx */
6163 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
6164 {
6165 if (Machine->gfx[gfx_index] == 0) break;
6166 }
6167 if (gfx_index == MAX_GFX_ELEMENTS) return 1;
6168
6169 /* handle the various graphics formats */
6170 i = (big) ? 8 : 16;
6171
6172 switch (bpp)
6173 {
6174 case K056832_BPP_4:
6175 charlayout4.total = memory_region_length(gfx_memory_region) / (i*4);
6176
6177 /* decode the graphics */
6178 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region), &charlayout4);
6179 break;
6180
6181 case K056832_BPP_5:
6182 /* tweak the structure for the number of tiles we have */
6183 charlayout5.total = memory_region_length(gfx_memory_region) / (i*5);
6184
6185 /* decode the graphics */
6186 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region), &charlayout5);
6187 break;
6188
6189 case K056832_BPP_6:
6190 /* tweak the structure for the number of tiles we have */
6191 charlayout6.total = memory_region_length(gfx_memory_region) / (i*6);
6192
6193 /* decode the graphics */
6194 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region), &charlayout6);
6195 break;
6196
6197 case K056832_BPP_8:
6198 /* tweak the structure for the number of tiles we have */
6199 charlayout8.total = memory_region_length(gfx_memory_region) / (i*8);
6200
6201 /* decode the graphics */
6202 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region), &charlayout8);
6203 break;
6204
6205 case K056832_BPP_8LE:
6206 /* tweak the structure for the number of tiles we have */
6207 charlayout8le.total = memory_region_length(gfx_memory_region) / (i*8);
6208
6209 /* decode the graphics */
6210 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region), &charlayout8le);
6211 break;
6212
6213 case K056832_BPP_4dj:
6214 charlayout4dj.total = memory_region_length(gfx_memory_region) / (i*4);
6215
6216 /* decode the graphics */
6217 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region), &charlayout4dj);
6218 break;
6219 }
6220
6221 /* make sure the decode went OK */
6222 if (!Machine->gfx[gfx_index]) return 1;
6223
6224 /* set the color information */
6225 if (Machine->drv->color_table_len)
6226 {
6227 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
6228 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
6229 }
6230 else
6231 {
6232 Machine->gfx[gfx_index]->colortable = Machine->pens;
6233 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / 16;
6234 }
6235 Machine->gfx[gfx_index]->color_granularity = 16; /* override */
6236
6237 K056832_memory_region = gfx_memory_region;
6238 K056832_gfxnum = gfx_index;
6239 K056832_callback = callback;
6240
6241 K056832_rombase = memory_region(gfx_memory_region);
6242 K056832_NumGfxBanks = memory_region_length(gfx_memory_region) / 0x2000;
6243 K056832_CurGfxBank = 0;
6244 K056832_use_ext_linescroll = 0;
6245 K056832_uses_tile_banks = 0;
6246
6247 K056832_djmain_hack = djmain_hack;
6248
6249 for (i=0; i<4; i++)
6250 {
6251 K056832_LayerOffset[i][0] = 0;
6252 K056832_LayerOffset[i][1] = 0;
6253 K056832_LSRAMPage[i][0] = i;
6254 K056832_LSRAMPage[i][1] = i << 11;
6255 K056832_X[i] = 0;
6256 K056832_Y[i] = 0;
6257 K056832_W[i] = 0;
6258 K056832_H[i] = 0;
6259 K056832_dx[i] = 0;
6260 K056832_dy[i] = 0;
6261 K056832_LayerTileMode[i] = 1;
6262 }
6263
6264 K056832_DefaultLayerAssociation = 1;
6265 K056832_ActiveLayer = 0;
6266 K056832_UpdateMode = 0;
6267 K056832_linemap_enabled = 0;
6268
6269 memset(K056832_LineDirty, 0, sizeof(UINT32) * K056832_PAGE_COUNT * 8);
6270
6271 for (i=0; i<K056832_PAGE_COUNT; i++)
6272 {
6273 K056832_AllLinesDirty[i] = 0;
6274 K056832_PageTileMode[i] = 1;
6275 }
6276
6277 if (!(K056832_videoram = auto_malloc(0x2000 * (K056832_PAGE_COUNT+1)))) return 1;
6278
6279 K056832_tilemap[0x0] = tilemap_create(K056832_get_tile_info0, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6280 K056832_tilemap[0x1] = tilemap_create(K056832_get_tile_info1, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6281 K056832_tilemap[0x2] = tilemap_create(K056832_get_tile_info2, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6282 K056832_tilemap[0x3] = tilemap_create(K056832_get_tile_info3, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6283 K056832_tilemap[0x4] = tilemap_create(K056832_get_tile_info4, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6284 K056832_tilemap[0x5] = tilemap_create(K056832_get_tile_info5, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6285 K056832_tilemap[0x6] = tilemap_create(K056832_get_tile_info6, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6286 K056832_tilemap[0x7] = tilemap_create(K056832_get_tile_info7, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6287 K056832_tilemap[0x8] = tilemap_create(K056832_get_tile_info8, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6288 K056832_tilemap[0x9] = tilemap_create(K056832_get_tile_info9, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6289 K056832_tilemap[0xa] = tilemap_create(K056832_get_tile_infoa, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6290 K056832_tilemap[0xb] = tilemap_create(K056832_get_tile_infob, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6291 K056832_tilemap[0xc] = tilemap_create(K056832_get_tile_infoc, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6292 K056832_tilemap[0xd] = tilemap_create(K056832_get_tile_infod, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6293 K056832_tilemap[0xe] = tilemap_create(K056832_get_tile_infoe, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6294 K056832_tilemap[0xf] = tilemap_create(K056832_get_tile_infof, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
6295
6296 for (i=0; i<K056832_PAGE_COUNT; i++)
6297 {
6298 if (!(tilemap = K056832_tilemap[i])) return 1;
6299
6300 K056832_pixmap[i] = tilemap_get_pixmap(tilemap);
6301
6302 tilemap_set_transparent_pen(tilemap, 0);
6303 }
6304
6305 memset(K056832_videoram, 0x00, 0x20000);
6306 memset(K056832_regs, 0x00, sizeof(K056832_regs) );
6307 memset(K056832_regsb, 0x00, sizeof(K056832_regsb) );
6308
6309 K056832_UpdatePageLayout();
6310
6311 K056832_change_rambank();
6312 K056832_change_rombank();
6313
6314 state_save_register_UINT16("K056832", 0, "memory", K056832_videoram, 0x10000);
6315 state_save_register_UINT16("K056832", 0, "registers", K056832_regs, 0x20);
6316 state_save_register_UINT16("K056832", 0, "registers b", K056832_regsb, 0x4);
6317 state_save_register_INT32 ("K056832", 0, "layerstat1", K056832_X, 0x4);
6318 state_save_register_INT32 ("K056832", 0, "layerstat2", K056832_Y, 0x4);
6319 state_save_register_INT32 ("K056832", 0, "layerstat3", K056832_W, 0x4);
6320 state_save_register_INT32 ("K056832", 0, "layerstat4", K056832_H, 0x4);
6321 state_save_register_INT32 ("K056832", 0, "layerstat5", K056832_dx, 0x4);
6322 state_save_register_INT32 ("K056832", 0, "layerstat6", K056832_dy, 0x4);
6323 state_save_register_UINT8 ("K056832", 0, "layerstat7", K056832_LayerTileMode, 4);
6324
6325 state_save_register_func_postload(K056832_UpdatePageLayout);
6326 state_save_register_func_postload(K056832_change_rambank);
6327 state_save_register_func_postload(K056832_change_rombank);
6328
6329 return 0;
6330 }
6331
6332 /* call if a game uses external linescroll */
K056832_SetExtLinescroll(void)6333 void K056832_SetExtLinescroll(void)
6334 {
6335 K056832_use_ext_linescroll = 1;
6336 }
6337
6338 /* generic helper routine for ROM checksumming */
K056832_rom_read_b(int offset,int blksize,int blksize2,int zerosec)6339 static int K056832_rom_read_b(int offset, int blksize, int blksize2, int zerosec)
6340 {
6341 data8_t *rombase;
6342 int base, ret;
6343
6344 rombase = (data8_t *)memory_region(K056832_memory_region);
6345
6346 if ((K056832_rom_half) && (zerosec))
6347 {
6348 return 0;
6349 }
6350
6351 /* add in the bank offset*/
6352 offset += (K056832_CurGfxBank * 0x2000);
6353
6354 /* figure out the base of the ROM block*/
6355 base = (offset / blksize) * blksize2;
6356
6357 /* get the starting offset of the proper word inside the block*/
6358 base += (offset % blksize) * 2;
6359
6360 if (K056832_rom_half)
6361 {
6362 ret = rombase[base+1];
6363 }
6364 else
6365 {
6366 ret = rombase[base];
6367 K056832_rom_half = 1;
6368 }
6369
6370 return ret;
6371 }
6372
READ16_HANDLER(K056832_5bpp_rom_word_r)6373 READ16_HANDLER( K056832_5bpp_rom_word_r )
6374 {
6375 if (mem_mask == 0x00ff)
6376 {
6377 return K056832_rom_read_b(offset*2, 4, 5, 0)<<8;
6378 }
6379 else if (mem_mask == 0xff00)
6380 {
6381 return K056832_rom_read_b(offset*2+1, 4, 5, 0)<<16;
6382 }
6383 else
6384 {
6385 log_cb(RETRO_LOG_DEBUG, LOGPRE "Non-byte read of tilemap ROM, PC=%x (mask=%x)\n", activecpu_get_pc(), mem_mask);
6386 }
6387 return 0;
6388 }
6389
READ32_HANDLER(K056832_5bpp_rom_long_r)6390 READ32_HANDLER( K056832_5bpp_rom_long_r )
6391 {
6392 if (mem_mask == 0x00ffffff)
6393 {
6394 return K056832_rom_read_b(offset*4, 4, 5, 0)<<24;
6395 }
6396 else if (mem_mask == 0xff00ffff)
6397 {
6398 return K056832_rom_read_b(offset*4+1, 4, 5, 0)<<16;
6399 }
6400 else if (mem_mask == 0xffff00ff)
6401 {
6402 return K056832_rom_read_b(offset*4+2, 4, 5, 0)<<8;
6403 }
6404 else if (mem_mask == 0xffffff00)
6405 {
6406 return K056832_rom_read_b(offset*4+3, 4, 5, 1);
6407 }
6408 else
6409 {
6410 log_cb(RETRO_LOG_DEBUG, LOGPRE "Non-byte read of tilemap ROM, PC=%x (mask=%x)\n", activecpu_get_pc(), mem_mask);
6411 }
6412 return 0;
6413 }
6414
READ32_HANDLER(K056832_6bpp_rom_long_r)6415 READ32_HANDLER( K056832_6bpp_rom_long_r )
6416 {
6417 if (mem_mask == 0x00ffffff)
6418 {
6419 return K056832_rom_read_b(offset*4, 4, 6, 0)<<24;
6420 }
6421 else if (mem_mask == 0xff00ffff)
6422 {
6423 return K056832_rom_read_b(offset*4+1, 4, 6, 0)<<16;
6424 }
6425 else if (mem_mask == 0xffff00ff)
6426 {
6427 return K056832_rom_read_b(offset*4+2, 4, 6, 0)<<8;
6428 }
6429 else if (mem_mask == 0xffffff00)
6430 {
6431 return K056832_rom_read_b(offset*4+3, 4, 6, 0);
6432 }
6433 else
6434 {
6435 log_cb(RETRO_LOG_DEBUG, LOGPRE "Non-byte read of tilemap ROM, PC=%x (mask=%x)\n", activecpu_get_pc(), mem_mask);
6436 }
6437 return 0;
6438 }
6439
READ16_HANDLER(K056832_rom_word_r)6440 READ16_HANDLER( K056832_rom_word_r )
6441 {
6442 int ofs16, ofs8;
6443 data8_t *rombase;
6444 int ret;
6445
6446 ofs16 = (offset / 8)*5;
6447 ofs8 = (offset / 4)*5;
6448
6449 ofs16 += (K056832_CurGfxBank*5*1024);
6450 ofs8 += (K056832_CurGfxBank*10*1024);
6451
6452 if (!K056832_rombase)
6453 {
6454 K056832_rombase = memory_region(K056832_memory_region);
6455 }
6456 rombase = (data8_t *)K056832_rombase;
6457
6458 ret = (rombase[ofs8+4]<<8);
6459 if ((offset % 8) >= 4)
6460 {
6461 ret |= (rombase[ofs16+1]<<24) | (rombase[ofs16+3]<<16);
6462 }
6463 else
6464 {
6465 ret |= (rombase[ofs16]<<24) | (rombase[ofs16+2]<<16);
6466 }
6467
6468 return ret;
6469 }
6470
READ16_HANDLER(K056832_old_rom_word_r)6471 READ16_HANDLER( K056832_old_rom_word_r )
6472 {
6473 int addr = 0x2000*K056832_CurGfxBank + 2*offset;
6474
6475 return K056832_rombase[addr+1] | (K056832_rombase[addr] << 8);
6476 }
6477
READ32_HANDLER(K056832_rom_long_r)6478 READ32_HANDLER( K056832_rom_long_r )
6479 {
6480 offset <<= 1;
6481 return (K056832_rom_word_r(offset+1, 0xffff) | (K056832_rom_word_r(offset, 0xffff)<<16));
6482 }
6483
6484 /* only one page is mapped to videoram at a time through a window */
READ16_HANDLER(K056832_ram_word_r)6485 READ16_HANDLER( K056832_ram_word_r )
6486 {
6487 /* reading from tile RAM resets the ROM readback "half" offset*/
6488 K056832_rom_half = 0;
6489
6490 return K056832_videoram[K056832_SelectedPagex4096+offset];
6491 }
6492
READ16_HANDLER(K056832_ram_half_word_r)6493 READ16_HANDLER( K056832_ram_half_word_r )
6494 {
6495 return K056832_videoram[K056832_SelectedPagex4096+(((offset << 1) & 0xffe) | ((offset >> 11) ^ 1))];
6496 }
6497
READ32_HANDLER(K056832_ram_long_r)6498 READ32_HANDLER( K056832_ram_long_r )
6499 {
6500 data16_t *pMem = &K056832_videoram[K056832_SelectedPagex4096+offset*2];
6501
6502 /* reading from tile RAM resets the ROM readback "half" offset*/
6503 K056832_rom_half = 0;
6504
6505 return(pMem[0]<<16 | pMem[1]);
6506 }
6507
6508 /* special 8-bit handlers for Lethal Enforcers */
READ_HANDLER(K056832_ram_code_lo_r)6509 READ_HANDLER( K056832_ram_code_lo_r )
6510 {
6511 data16_t *adr = &K056832_videoram[K056832_SelectedPagex4096+(offset*2)+1];
6512
6513 return *adr & 0xff;
6514 }
6515
READ_HANDLER(K056832_ram_code_hi_r)6516 READ_HANDLER( K056832_ram_code_hi_r )
6517 {
6518 data16_t *adr = &K056832_videoram[K056832_SelectedPagex4096+(offset*2)+1];
6519
6520 return *adr>>8;
6521 }
6522
READ_HANDLER(K056832_ram_attr_lo_r)6523 READ_HANDLER( K056832_ram_attr_lo_r )
6524 {
6525 data16_t *adr = &K056832_videoram[K056832_SelectedPagex4096+(offset*2)];
6526
6527 return *adr & 0xff;
6528 }
6529
READ_HANDLER(K056832_ram_attr_hi_r)6530 READ_HANDLER( K056832_ram_attr_hi_r )
6531 {
6532 data16_t *adr = &K056832_videoram[K056832_SelectedPagex4096+(offset*2)];
6533
6534 return *adr>>8;
6535 }
6536
WRITE_HANDLER(K056832_ram_code_lo_w)6537 WRITE_HANDLER( K056832_ram_code_lo_w )
6538 {
6539 data16_t *adr = &K056832_videoram[K056832_SelectedPagex4096+(offset*2)+1];
6540
6541 *adr &= 0xff00;
6542 *adr |= data;
6543
6544 if (!(K056832_regs[0] & 0x02)) /* external linescroll enable */
6545 {
6546 if (K056832_PageTileMode[K056832_SelectedPage])
6547 tilemap_mark_tile_dirty(K056832_tilemap[K056832_SelectedPage], offset);
6548 else
6549 K056832_mark_line_dirty(K056832_SelectedPage, offset);
6550 }
6551 }
6552
WRITE_HANDLER(K056832_ram_code_hi_w)6553 WRITE_HANDLER( K056832_ram_code_hi_w )
6554 {
6555 data16_t *adr = &K056832_videoram[K056832_SelectedPagex4096+(offset*2)+1];
6556
6557 *adr &= 0x00ff;
6558 *adr |= data<<8;
6559
6560 if (!(K056832_regs[0] & 0x02)) /* external linescroll enable */
6561 {
6562 if (K056832_PageTileMode[K056832_SelectedPage])
6563 tilemap_mark_tile_dirty(K056832_tilemap[K056832_SelectedPage], offset);
6564 else
6565 K056832_mark_line_dirty(K056832_SelectedPage, offset);
6566 }
6567 }
6568
WRITE_HANDLER(K056832_ram_attr_lo_w)6569 WRITE_HANDLER( K056832_ram_attr_lo_w )
6570 {
6571 data16_t *adr = &K056832_videoram[K056832_SelectedPagex4096+(offset*2)];
6572
6573 *adr &= 0xff00;
6574 *adr |= data;
6575
6576 if (!(K056832_regs[0] & 0x02)) /* external linescroll enable */
6577 {
6578 if (K056832_PageTileMode[K056832_SelectedPage])
6579 tilemap_mark_tile_dirty(K056832_tilemap[K056832_SelectedPage], offset);
6580 else
6581 K056832_mark_line_dirty(K056832_SelectedPage, offset);
6582 }
6583 }
6584
WRITE_HANDLER(K056832_ram_attr_hi_w)6585 WRITE_HANDLER( K056832_ram_attr_hi_w )
6586 {
6587 data16_t *adr = &K056832_videoram[K056832_SelectedPagex4096+(offset*2)];
6588
6589 *adr &= 0x00ff;
6590 *adr |= data<<8;
6591
6592 if (!(K056832_regs[0] & 0x02)) /* external linescroll enable */
6593 {
6594 if (K056832_PageTileMode[K056832_SelectedPage])
6595 tilemap_mark_tile_dirty(K056832_tilemap[K056832_SelectedPage], offset);
6596 else
6597 K056832_mark_line_dirty(K056832_SelectedPage, offset);
6598 }
6599 }
6600
WRITE16_HANDLER(K056832_ram_word_w)6601 WRITE16_HANDLER( K056832_ram_word_w )
6602 {
6603 data16_t *tile_ptr;
6604 data16_t old_mask, old_data;
6605
6606 tile_ptr = &K056832_videoram[K056832_SelectedPagex4096+offset];
6607 old_mask = mem_mask;
6608 mem_mask = ~mem_mask;
6609 old_data = *tile_ptr;
6610 data = (data & mem_mask) | (old_data & old_mask);
6611
6612 if(data != old_data)
6613 {
6614 offset >>= 1;
6615 *tile_ptr = data;
6616
6617 if (K056832_PageTileMode[K056832_SelectedPage])
6618 tilemap_mark_tile_dirty(K056832_tilemap[K056832_SelectedPage], offset);
6619 else
6620 K056832_mark_line_dirty(K056832_SelectedPage, offset);
6621 }
6622 }
6623
WRITE16_HANDLER(K056832_ram_half_word_w)6624 WRITE16_HANDLER( K056832_ram_half_word_w )
6625 {
6626 data16_t *adr = &K056832_videoram[K056832_SelectedPagex4096+(((offset << 1) & 0xffe) | 1)];
6627 data16_t old = *adr;
6628
6629 COMBINE_DATA(adr);
6630 if(*adr != old)
6631 {
6632 int dofs = (((offset << 1) & 0xffe) | 1);
6633
6634 dofs >>= 1;
6635
6636 if (K056832_PageTileMode[K056832_SelectedPage])
6637 tilemap_mark_tile_dirty(K056832_tilemap[K056832_SelectedPage], dofs);
6638 else
6639 K056832_mark_line_dirty(K056832_SelectedPage, dofs);
6640 }
6641 }
6642
WRITE32_HANDLER(K056832_ram_long_w)6643 WRITE32_HANDLER( K056832_ram_long_w )
6644 {
6645 data16_t *tile_ptr;
6646 data32_t old_mask, old_data;
6647
6648 tile_ptr = &K056832_videoram[K056832_SelectedPagex4096+offset*2];
6649 old_mask = mem_mask;
6650 mem_mask = ~mem_mask;
6651 old_data = (data32_t)tile_ptr[0]<<16 | (data32_t)tile_ptr[1];
6652 data = (data & mem_mask) | (old_data & old_mask);
6653
6654 if (data != old_data)
6655 {
6656 tile_ptr[0] = data>>16;
6657 tile_ptr[1] = data;
6658
6659 if (K056832_PageTileMode[K056832_SelectedPage])
6660 tilemap_mark_tile_dirty(K056832_tilemap[K056832_SelectedPage], offset);
6661 else
6662 K056832_mark_line_dirty(K056832_SelectedPage, offset);
6663 }
6664 }
6665
WRITE16_HANDLER(K056832_word_w)6666 WRITE16_HANDLER( K056832_word_w )
6667 {
6668 int layer, flip, mask, i;
6669 UINT32 old_data, new_data;
6670
6671 old_data = K056832_regs[offset];
6672 COMBINE_DATA(&K056832_regs[offset]);
6673 new_data = K056832_regs[offset];
6674
6675 if (new_data != old_data)
6676 {
6677 switch(offset)
6678 {
6679 /* -x-- ---- dotclock select: 0=8Mhz, 1=6Mhz (not used by GX)
6680 * --x- ---- screen flip y
6681 * ---x ---- screen flip x
6682 * ---- --x- external linescroll RAM page enable
6683 */
6684 case 0x00/2:
6685 if ((new_data & 0x30) != (old_data & 0x30))
6686 {
6687 flip = 0;
6688 if (new_data & 0x20) flip |= TILEMAP_FLIPY;
6689 if (new_data & 0x10) flip |= TILEMAP_FLIPX;
6690 for (i=0; i<K056832_PAGE_COUNT; i++)
6691 {
6692 tilemap_set_flip(K056832_tilemap[i], flip);
6693 }
6694 }
6695
6696 if ((new_data & 0x02) != (old_data & 0x02))
6697 {
6698 K056832_change_rambank();
6699 }
6700 break;
6701
6702 /* -------- -----xxx external irqlines enable (not used by GX)
6703 * -------- xx------ tilemap attribute config (FBIT0 and FBIT1)
6704 */
6705 /*case 0x06/2: break;*/
6706
6707 /* -------- ----DCBA tile mode: 0=512x1, 1=8x8*/
6708 /* -------- DCBA---- synchronous scroll: 0=off, 1=on*/
6709 case 0x08/2:
6710 for (layer=0; layer<4; layer++)
6711 {
6712 mask = 1<<layer;
6713 i = new_data & mask;
6714 if (i != (old_data & mask))
6715 {
6716 K056832_LayerTileMode[layer] = i;
6717 K056832_mark_plane_dirty(layer);
6718 }
6719 }
6720 break;
6721
6722 /* -------- ------xx layer A linescroll config
6723 * -------- ----xx-- layer B linescroll config
6724 * -------- --xx---- layer C linescroll config
6725 * -------- xx------ layer D linescroll config
6726 *
6727 * 0: linescroll
6728 * 2: rowscroll
6729 * 3: xy scroll
6730 */
6731 /*case 0x0a/2: break;*/
6732
6733 case 0x32/2:
6734 K056832_change_rambank();
6735 break;
6736
6737 case 0x34/2: /* ROM bank select for checksum */
6738 case 0x36/2: /* secondary ROM bank select for use with tile banking */
6739 K056832_change_rombank();
6740 break;
6741
6742 /* extended tile address*/
6743 /*case 0x38/2: break;*/
6744
6745 /* 12 bit (signed) horizontal offset if global HFLIP enabled*/
6746 /*case 0x3a/2: break;*/
6747
6748 /* 11 bit (signed) vertical offset if global VFLIP enabled*/
6749 /*case 0x3c/2: break;*/
6750
6751 default:
6752 layer = offset & 3;
6753
6754 if (offset >= 0x10/2 && offset <= 0x16/2)
6755 {
6756 K056832_Y[layer] = (new_data&0x18)>>3;
6757 K056832_H[layer] = (new_data&0x3);
6758 K056832_ActiveLayer = layer;
6759 K056832_UpdatePageLayout();
6760 } else
6761
6762 if (offset >= 0x18/2 && offset <= 0x1e/2)
6763 {
6764 K056832_X[layer] = (new_data&0x18)>>3;
6765 K056832_W[layer] = (new_data&0x03);
6766 K056832_ActiveLayer = layer;
6767 K056832_UpdatePageLayout();
6768 } else
6769
6770 if (offset >= 0x20/2 && offset <= 0x26/2)
6771 {
6772 K056832_dy[layer] = (INT16)new_data;
6773 } else
6774
6775 if (offset >= 0x28/2 && offset <= 0x2e/2)
6776 {
6777 K056832_dx[layer] = (INT16)new_data;
6778 }
6779 break;
6780 }
6781 }
6782 }
6783
WRITE32_HANDLER(K056832_long_w)6784 WRITE32_HANDLER( K056832_long_w )
6785 {
6786 /* GX does access of all 3 widths (8/16/32) so we can't do the*/
6787 /* if (ACCESSING_xxx) trick. in particular, 8-bit writes*/
6788 /* are used to the tilemap bank register.*/
6789 offset <<= 1;
6790 K056832_word_w(offset, data>>16, mem_mask >> 16);
6791 K056832_word_w(offset+1, data, mem_mask);
6792 }
6793
WRITE16_HANDLER(K056832_b_word_w)6794 WRITE16_HANDLER( K056832_b_word_w )
6795 {
6796 COMBINE_DATA( &K056832_regsb[offset] );
6797 }
6798
WRITE_HANDLER(K056832_w)6799 WRITE_HANDLER( K056832_w )
6800 {
6801 if (offset & 1)
6802 {
6803 K056832_word_w((offset>>1), data, 0xff00);
6804 }
6805 else
6806 {
6807 K056832_word_w((offset>>1), data<<8, 0x00ff);
6808 }
6809 }
6810
WRITE_HANDLER(K056832_b_w)6811 WRITE_HANDLER( K056832_b_w )
6812 {
6813 if (offset & 1)
6814 {
6815 K056832_b_word_w((offset>>1), data, 0xff00);
6816 }
6817 else
6818 {
6819 K056832_b_word_w((offset>>1), data<<8, 0x00ff);
6820 }
6821 }
6822
WRITE32_HANDLER(K056832_b_long_w)6823 WRITE32_HANDLER( K056832_b_long_w )
6824 {
6825 if (ACCESSING_MSW32)
6826 {
6827 K056832_b_word_w(offset<<1, data>>16, mem_mask >> 16);
6828 }
6829 if (ACCESSING_LSW32)
6830 {
6831 K056832_b_word_w((offset<<1)+1, data, mem_mask);
6832 }
6833 }
6834
K056832_update_linemap(struct mame_bitmap * bitmap,int page,int flags)6835 static int K056832_update_linemap(struct mame_bitmap *bitmap, int page, int flags)
6836 {
6837 #define LINE_WIDTH 512
6838
6839 #define DRAW_PIX(N) \
6840 if ((pen = src_ptr[N])) \
6841 { pen += basepen; xpr_ptr[count+N] = TILE_FLAG_FG_OPAQUE; dst_ptr[count+N] = pen; } else \
6842 { xpr_ptr[count+N] = 0; }
6843
6844 struct rectangle zerorect;
6845 struct tilemap *tilemap;
6846 struct mame_bitmap *pixmap, *xprmap;
6847 UINT8 *xprdata;
6848 const struct GfxElement *src_gfx;
6849
6850 UINT32 *dirty;
6851 int all_dirty, line;
6852 int offs, mask;
6853
6854 pen_t *pal_ptr;
6855 const UINT8 *src_base, *src_ptr;
6856 UINT8 *xpr_ptr;
6857 UINT16 *dst_ptr;
6858 UINT16 pen, basepen;
6859 int count, src_pitch, src_modulo;
6860 int dst_pitch;
6861
6862 UINT8 code_transparent, code_opaque;
6863
6864 if (K056832_PageTileMode[page]) return(0);
6865 if (!K056832_linemap_enabled) return(1);
6866
6867 tilemap = K056832_tilemap[page];
6868 pixmap = K056832_pixmap[page];
6869 xprmap = tilemap_get_transparency_bitmap(tilemap);
6870 xprdata = tilemap_get_transparency_data(tilemap);
6871
6872 dirty = K056832_LineDirty[page];
6873 all_dirty = K056832_AllLinesDirty[page];
6874
6875 if (all_dirty)
6876 {
6877 dirty[7]=dirty[6]=dirty[5]=dirty[4]=dirty[3]=dirty[2]=dirty[1]=dirty[0] = 0;
6878 K056832_AllLinesDirty[page] = 0;
6879
6880 /* force tilemap into a clean, static state*/
6881 /* *really ugly but it minimizes alteration to tilemap.c*/
6882 memset (&zerorect, 0, sizeof(struct rectangle)); /* zero dimension*/
6883 tilemap_draw(bitmap, &zerorect, tilemap, 0, 0); /* dummy call to reset tile_dirty_map*/
6884 fillbitmap(xprmap, 0, 0); /* reset pixel transparency_bitmap;*/
6885 memset(xprdata, TILE_FLAG_FG_OPAQUE, 0x800); /* reset tile transparency_data;*/
6886 }
6887 else
6888 {
6889 if (!(dirty[0]|dirty[1]|dirty[2]|dirty[3]|dirty[4]|dirty[5]|dirty[6]|dirty[7])) return(0);
6890 }
6891
6892 pal_ptr = Machine->remapped_colortable;
6893 src_gfx = Machine->gfx[K056832_gfxnum];
6894 src_base = src_gfx->gfxdata;
6895 src_pitch = src_gfx->line_modulo;
6896 src_modulo = src_gfx->char_modulo;
6897 xpr_ptr = (UINT8*)xprmap->base + LINE_WIDTH;
6898 dst_ptr = (UINT16*)pixmap->base + LINE_WIDTH;
6899 dst_pitch = pixmap->rowpixels;
6900
6901 for (line=0; line<256; xpr_ptr+=dst_pitch, dst_ptr+=dst_pitch, line++)
6902 {
6903 if (!all_dirty)
6904 {
6905 offs = line >> 5;
6906 mask = 1 << (line & 0x1f);
6907 if (!(dirty[offs] & mask)) continue;
6908 dirty[offs] ^= mask;
6909 }
6910
6911 K056832_get_tile_info(line, page);
6912 src_ptr = src_base + ((tile_info.tile_number & ~7) << 6);
6913 basepen = tile_info.pal_data - pal_ptr;
6914 code_transparent = tile_info.priority;
6915 code_opaque = code_transparent | TILE_FLAG_FG_OPAQUE;
6916 count = -LINE_WIDTH;
6917
6918 do
6919 {
6920 DRAW_PIX(0)
6921 DRAW_PIX(1)
6922 DRAW_PIX(2)
6923 DRAW_PIX(3)
6924 DRAW_PIX(4)
6925 DRAW_PIX(5)
6926 DRAW_PIX(6)
6927 DRAW_PIX(7)
6928
6929 src_ptr += 8;
6930 }
6931 while (count += 8);
6932 }
6933
6934 return(0);
6935
6936 #undef LINE_WIDTH
6937 #undef DRAW_PIX
6938 }
6939
K056832_tilemap_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int layer,int flags,UINT32 priority)6940 void K056832_tilemap_draw(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int layer, int flags, UINT32 priority)
6941 {
6942 static int last_colorbase[K056832_PAGE_COUNT];
6943
6944 UINT32 last_dx, last_visible, new_colorbase, last_active;
6945 int sx, sy, ay, tx, ty, width, height;
6946 int clipw, clipx, cliph, clipy, clipmaxy;
6947 int line_height, line_endy, line_starty, line_y;
6948 int sdat_start, sdat_walk, sdat_adv, sdat_wrapmask, sdat_offs;
6949 int pageIndex, flipx, flipy, corr, r, c;
6950 int cminy, cmaxy, cminx, cmaxx;
6951 int dminy, dmaxy, dminx, dmaxx;
6952 struct rectangle drawrect;
6953 struct tilemap *tilemap;
6954 data16_t *pScrollData;
6955 data16_t ram16[2];
6956
6957 int rowstart = K056832_Y[layer];
6958 int colstart = K056832_X[layer];
6959 int rowspan = K056832_H[layer]+1;
6960 int colspan = K056832_W[layer]+1;
6961 int dy = K056832_dy[layer];
6962 int dx = K056832_dx[layer];
6963 int scrollbank = ((K056832_regs[0x18]>>1) & 0xc) | (K056832_regs[0x18] & 3);
6964 int scrollmode = K056832_regs[0x05]>>(K056832_LSRAMPage[layer][0]<<1) & 3;
6965
6966 if (K056832_use_ext_linescroll)
6967 {
6968 scrollbank = K056832_PAGE_COUNT;
6969 }
6970
6971 height = rowspan * K056832_PAGE_HEIGHT;
6972 width = colspan * K056832_PAGE_WIDTH;
6973
6974 cminx = cliprect->min_x;
6975 cmaxx = cliprect->max_x;
6976 cminy = cliprect->min_y;
6977 cmaxy = cliprect->max_y;
6978
6979 /* flip correction registers*/
6980 if ((flipy = K056832_regs[0] & 0x20))
6981 {
6982 corr = K056832_regs[0x3c/2];
6983 if (corr & 0x400)
6984 corr |= 0xfffff800;
6985 } else corr = 0;
6986 dy += corr;
6987 ay = (unsigned)(dy - K056832_LayerOffset[layer][1]) % height;
6988
6989 if ((flipx = K056832_regs[0] & 0x10))
6990 {
6991 corr = K056832_regs[0x3a/2];
6992 if (corr & 0x800)
6993 corr |= 0xfffff000;
6994 } else corr = 0;
6995 corr -= K056832_LayerOffset[layer][0];
6996
6997 if (/*scrollmode == 0 && */(flags & TILE_LINE_DISABLED))
6998 {
6999 scrollmode = 3;
7000 flags &= ~TILE_LINE_DISABLED;
7001 }
7002
7003 switch( scrollmode )
7004 {
7005 case 0: /* linescroll*/
7006 pScrollData = &K056832_videoram[scrollbank<<12] + (K056832_LSRAMPage[layer][1]>>1);
7007 line_height = 1;
7008 sdat_wrapmask = 0x3ff;
7009 sdat_adv = 2;
7010 break;
7011 case 2: /* rowscroll*/
7012 pScrollData = &K056832_videoram[scrollbank<<12] + (K056832_LSRAMPage[layer][1]>>1);
7013 line_height = 8;
7014 sdat_wrapmask = 0x3ff;
7015 sdat_adv = 16;
7016 break;
7017 default: /* xyscroll*/
7018 pScrollData = ram16;
7019 line_height = K056832_PAGE_HEIGHT;
7020 sdat_wrapmask = 0;
7021 sdat_adv = 0;
7022 ram16[0] = 0;
7023 ram16[1] = dx;
7024 }
7025 if (flipy) sdat_adv = -sdat_adv;
7026
7027 last_active = K056832_ActiveLayer;
7028 new_colorbase = (K056832_UpdateMode) ? K055555_get_palette_index(layer) : 0;
7029
7030 for (r=0; r<rowspan; r++)
7031 {
7032 if (rowspan > 1)
7033 {
7034 sy = ay;
7035 ty = r * K056832_PAGE_HEIGHT;
7036
7037 if (!flipy)
7038 {
7039 /* handle bottom-edge wraparoundness and cull off-screen tilemaps*/
7040 if ((r == 0) && (sy > height - K056832_PAGE_HEIGHT)) sy -= height;
7041 if ((sy + K056832_PAGE_HEIGHT <= ty) || (sy - K056832_PAGE_HEIGHT >= ty)) continue;
7042
7043 /* switch frame of reference and clip y*/
7044 if ((ty -= sy) >= 0)
7045 {
7046 cliph = K056832_PAGE_HEIGHT - ty;
7047 clipy = line_starty = ty;
7048 line_endy = K056832_PAGE_HEIGHT;
7049 sdat_start = 0;
7050 }
7051 else
7052 {
7053 cliph = K056832_PAGE_HEIGHT + ty;
7054 ty = -ty;
7055 clipy = line_starty = 0;
7056 line_endy = cliph;
7057 sdat_start = ty;
7058 if (scrollmode == 2) { sdat_start &= ~7; line_starty -= ty & 7; }
7059 }
7060 }
7061 else
7062 {
7063 ty += K056832_PAGE_HEIGHT;
7064
7065 /* handle top-edge wraparoundness and cull off-screen tilemaps*/
7066 if ((r == rowspan-1) && (sy < K056832_PAGE_HEIGHT)) sy += height;
7067 if ((sy + K056832_PAGE_HEIGHT <= ty) || (sy - K056832_PAGE_HEIGHT >= ty)) continue;
7068
7069 /* switch frame of reference and clip y*/
7070 if ((ty -= sy) <= 0)
7071 {
7072 cliph = K056832_PAGE_HEIGHT + ty;
7073 clipy = line_starty = -ty;
7074 line_endy = K056832_PAGE_HEIGHT;
7075 sdat_start = K056832_PAGE_HEIGHT-1;
7076 if (scrollmode == 2) sdat_start &= ~7;
7077 }
7078 else
7079 {
7080 cliph = K056832_PAGE_HEIGHT - ty;
7081 clipy = line_starty = 0;
7082 line_endy = cliph;
7083 sdat_start = cliph-1;
7084 if (scrollmode == 2) { sdat_start &= ~7; line_starty -= ty & 7; }
7085 }
7086 }
7087 }
7088 else
7089 {
7090 cliph = line_endy = K056832_PAGE_HEIGHT;
7091 clipy = line_starty = 0;
7092
7093 if (!flipy)
7094 sdat_start = dy;
7095 else
7096 /*
7097 doesn't work with Metamorphic Force and Martial Champion (software Y-flipped) but
7098 LE2U (naturally Y-flipped) seems to expect this condition as an override.
7099
7100 sdat_start = K056832_PAGE_HEIGHT-1 -dy;
7101 */
7102 sdat_start = K056832_PAGE_HEIGHT-1;
7103
7104 if (scrollmode == 2) { sdat_start &= ~7; line_starty -= dy & 7; }
7105 }
7106
7107 sdat_start += r * K056832_PAGE_HEIGHT;
7108 sdat_start <<= 1;
7109
7110 clipmaxy = clipy + cliph - 1;
7111
7112 for (c=0; c<colspan; c++)
7113 {
7114 pageIndex = (((rowstart + r) & 3) << 2) + ((colstart + c) & 3);
7115
7116 if (K056832_LayerAssociation)
7117 {
7118 if (K056832_LayerAssociatedWithPage[pageIndex] != layer) continue;
7119 }
7120 else
7121 {
7122 if (K056832_LayerAssociatedWithPage[pageIndex] == -1) continue;
7123 K056832_ActiveLayer = layer;
7124 }
7125
7126 if (K056832_UpdateMode)
7127 {
7128 if (last_colorbase[pageIndex] != new_colorbase)
7129 {
7130 last_colorbase[pageIndex] = new_colorbase;
7131 K056832_mark_page_dirty(pageIndex);
7132 }
7133 }
7134 else
7135 if (!pageIndex) K056832_ActiveLayer = 0;
7136
7137 if (K056832_update_linemap(bitmap, pageIndex, flags)) continue;
7138
7139 tilemap = K056832_tilemap[pageIndex];
7140 tilemap_set_scrolly(tilemap, 0, ay);
7141
7142 last_dx = 0x100000;
7143 last_visible = 0;
7144
7145 for (sdat_walk=sdat_start, line_y=line_starty; line_y<line_endy; sdat_walk+=sdat_adv, line_y+=line_height)
7146 {
7147 dminy = line_y;
7148 dmaxy = line_y + line_height - 1;
7149
7150 if (dminy < clipy) dminy = clipy;
7151 if (dmaxy > clipmaxy) dmaxy = clipmaxy;
7152 if (dminy > cmaxy || dmaxy < cminy) continue;
7153
7154 sdat_offs = sdat_walk & sdat_wrapmask;
7155
7156 if(strcmp(Machine->gamedrv->name, "lethalen") == 0)
7157 {
7158 if (scrollmode==2) sdat_offs = sdat_offs + 0x1e0 + 14;
7159 }
7160
7161 drawrect.min_y = (dminy < cminy ) ? cminy : dminy;
7162 drawrect.max_y = (dmaxy > cmaxy ) ? cmaxy : dmaxy;
7163
7164 dx = ((int)pScrollData[sdat_offs]<<16 | (int)pScrollData[sdat_offs+1]) + corr;
7165
7166 if (last_dx == dx) { if (last_visible) goto LINE_SHORTCIRCUIT; continue; }
7167 last_dx = dx;
7168
7169 if (colspan > 1)
7170 {
7171 /*sx = (unsigned)dx % width;*/
7172 sx = (unsigned)dx & (width-1);
7173
7174 /*tx = c * K056832_PAGE_WIDTH;*/
7175 tx = c << 9;
7176
7177 if (!flipx)
7178 {
7179 /* handle right-edge wraparoundness and cull off-screen tilemaps*/
7180 if ((c == 0) && (sx > width - K056832_PAGE_WIDTH)) sx -= width;
7181 if ((sx + K056832_PAGE_WIDTH <= tx) || (sx - K056832_PAGE_WIDTH >= tx))
7182 { last_visible = 0; continue; }
7183
7184 /* switch frame of reference and clip x*/
7185 if ((tx -= sx) <= 0) { clipw = K056832_PAGE_WIDTH + tx; clipx = 0; }
7186 else { clipw = K056832_PAGE_WIDTH - tx; clipx = tx; }
7187 }
7188 else
7189 {
7190 tx += K056832_PAGE_WIDTH;
7191
7192 /* handle left-edge wraparoundness and cull off-screen tilemaps*/
7193 if ((c == colspan-1) && (sx < K056832_PAGE_WIDTH)) sx += width;
7194 if ((sx + K056832_PAGE_WIDTH <= tx) || (sx - K056832_PAGE_WIDTH >= tx))
7195 { last_visible = 0; continue; }
7196
7197 /* switch frame of reference and clip y*/
7198 if ((tx -= sx) >= 0) { clipw = K056832_PAGE_WIDTH - tx; clipx = 0; }
7199 else { clipw = K056832_PAGE_WIDTH + tx; clipx = -tx; }
7200 }
7201 }
7202 else { clipw = K056832_PAGE_WIDTH; clipx = 0; }
7203
7204 last_visible = 1;
7205
7206 dminx = clipx;
7207 dmaxx = clipx + clipw - 1;
7208
7209 drawrect.min_x = (dminx < cminx ) ? cminx : dminx;
7210 drawrect.max_x = (dmaxx > cmaxx ) ? cmaxx : dmaxx;
7211
7212 tilemap_set_scrollx(tilemap, 0, dx);
7213
7214 LINE_SHORTCIRCUIT:
7215 tilemap_draw(bitmap, &drawrect, tilemap, flags, priority);
7216
7217 } /* end of line loop*/
7218 } /* end of column loop*/
7219 } /* end of row loop*/
7220
7221 K056832_ActiveLayer = last_active;
7222
7223 } /* end of function*/
7224
K056832_tilemap_draw_dj(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int layer,int flags,UINT32 priority)7225 void K056832_tilemap_draw_dj(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int layer, int flags, UINT32 priority) /***/
7226 {
7227 static int last_colorbase[K056832_PAGE_COUNT];
7228
7229 UINT32 last_dx, last_visible, new_colorbase, last_active;
7230 int sx, sy, ay, tx, ty, width, height;
7231 int clipw, clipx, cliph, clipy, clipmaxy;
7232 int line_height, line_endy, line_starty, line_y;
7233 int sdat_start, sdat_walk, sdat_adv, sdat_wrapmask, sdat_offs;
7234 int pageIndex, flipx, flipy, corr, r, c;
7235 int cminy, cmaxy, cminx, cmaxx;
7236 int dminy, dmaxy, dminx, dmaxx;
7237 struct rectangle drawrect;
7238 struct tilemap *tilemap;
7239 data16_t *pScrollData;
7240 data16_t ram16[2];
7241
7242 int rowstart = K056832_Y[layer];
7243 int colstart = K056832_X[layer];
7244 int rowspan = K056832_H[layer]+1;
7245 int colspan = K056832_W[layer]+1;
7246 int dy = K056832_dy[layer];
7247 int dx = K056832_dx[layer];
7248 int scrollbank = ((K056832_regs[0x18]>>1) & 0xc) | (K056832_regs[0x18] & 3);
7249 int scrollmode = K056832_regs[0x05]>>(K056832_LSRAMPage[layer][0]<<1) & 3;
7250 int need_wrap = -1;
7251
7252 height = rowspan * K056832_PAGE_HEIGHT;
7253 width = colspan * K056832_PAGE_WIDTH;
7254
7255 cminx = cliprect->min_x;
7256 cmaxx = cliprect->max_x;
7257 cminy = cliprect->min_y;
7258 cmaxy = cliprect->max_y;
7259
7260 /* flip correction registers*/
7261 if ((flipy = K056832_regs[0] & 0x20))
7262 {
7263 corr = K056832_regs[0x3c/2];
7264 if (corr & 0x400)
7265 corr |= 0xfffff800;
7266 } else corr = 0;
7267 dy += corr;
7268 ay = (unsigned)(dy - K056832_LayerOffset[layer][1]) % height;
7269
7270 if ((flipx = K056832_regs[0] & 0x10))
7271 {
7272 corr = K056832_regs[0x3a/2];
7273 if (corr & 0x800)
7274 corr |= 0xfffff000;
7275 } else corr = 0;
7276 corr -= K056832_LayerOffset[layer][0];
7277
7278 if (/*scrollmode == 0 && */ (flags & TILE_LINE_DISABLED))
7279 {
7280 scrollmode = 3;
7281 flags &= ~TILE_LINE_DISABLED;
7282 }
7283
7284 switch( scrollmode )
7285 {
7286 case 0: /* linescroll*/
7287 pScrollData = &K056832_videoram[scrollbank<<12] + (K056832_LSRAMPage[layer][1]>>1);
7288 line_height = 1;
7289 sdat_wrapmask = 0x3ff;
7290 sdat_adv = 2;
7291 break;
7292 case 2: /* rowscroll*/
7293 pScrollData = &K056832_videoram[scrollbank<<12] + (K056832_LSRAMPage[layer][1]>>1);
7294 line_height = 8;
7295 sdat_wrapmask = 0x3ff;
7296 sdat_adv = 16;
7297 break;
7298 default: /* xyscroll*/
7299 pScrollData = ram16;
7300 line_height = K056832_PAGE_HEIGHT;
7301 sdat_wrapmask = 0;
7302 sdat_adv = 0;
7303 ram16[0] = 0;
7304 ram16[1] = dx;
7305 }
7306 if (flipy) sdat_adv = -sdat_adv;
7307
7308 last_active = K056832_ActiveLayer;
7309 new_colorbase = (K056832_UpdateMode) ? K055555_get_palette_index(layer) : 0;
7310
7311 for (r=0; r<=rowspan; r++)
7312 {
7313 sy = ay;
7314 if (r == rowspan)
7315 {
7316 if (need_wrap < 0)
7317 continue;
7318
7319 ty = need_wrap * K056832_PAGE_HEIGHT;
7320 }
7321 else
7322 {
7323 ty = r * K056832_PAGE_HEIGHT;
7324 }
7325
7326 /* cull off-screen tilemaps*/
7327 if ((sy + height <= ty) || (sy - height >= ty)) continue;
7328
7329 /* switch frame of reference*/
7330 ty -= sy;
7331
7332 /* handle top-edge wraparoundness*/
7333 if (r == rowspan)
7334 {
7335 cliph = K056832_PAGE_HEIGHT + ty;
7336 clipy = line_starty = 0;
7337 line_endy = cliph;
7338 ty = -ty;
7339 sdat_start = ty;
7340 if (scrollmode == 2) { sdat_start &= ~7; line_starty -= ty & 7; }
7341 }
7342
7343 /* clip y*/
7344 else
7345 {
7346 if (ty < 0)
7347 ty += height;
7348
7349 clipy = ty;
7350 cliph = K056832_PAGE_HEIGHT;
7351
7352 if (clipy + cliph > height)
7353 {
7354 cliph = height - clipy;
7355 need_wrap =r;
7356 }
7357
7358 line_starty = ty;
7359 line_endy = line_starty + cliph;
7360 sdat_start = 0;
7361 }
7362
7363 if (r == rowspan)
7364 sdat_start += need_wrap * K056832_PAGE_HEIGHT;
7365 else
7366 sdat_start += r * K056832_PAGE_HEIGHT;
7367 sdat_start <<= 1;
7368
7369 clipmaxy = clipy + cliph - 1;
7370
7371 for (c=0; c<colspan; c++)
7372 {
7373 if (r == rowspan)
7374 pageIndex = (((rowstart + need_wrap) & 3) << 2) + ((colstart + c) & 3);
7375 else
7376 pageIndex = (((rowstart + r) & 3) << 2) + ((colstart + c) & 3);
7377
7378 if (K056832_LayerAssociation)
7379 {
7380 if (K056832_LayerAssociatedWithPage[pageIndex] != layer) continue;
7381 }
7382 else
7383 {
7384 if (K056832_LayerAssociatedWithPage[pageIndex] == -1) continue;
7385 K056832_ActiveLayer = layer;
7386 }
7387
7388 if (K056832_UpdateMode)
7389 {
7390 if (last_colorbase[pageIndex] != new_colorbase)
7391 {
7392 last_colorbase[pageIndex] = new_colorbase;
7393 K056832_mark_page_dirty(pageIndex);
7394 }
7395 }
7396 else
7397 if (!pageIndex) K056832_ActiveLayer = 0;
7398
7399 if (K056832_update_linemap(bitmap, pageIndex, flags)) continue;
7400
7401 tilemap = K056832_tilemap[pageIndex];
7402 tilemap_set_scrolly(tilemap, 0, ay);
7403
7404 last_dx = 0x100000;
7405 last_visible = 0;
7406
7407 for (sdat_walk=sdat_start, line_y=line_starty; line_y<line_endy; sdat_walk+=sdat_adv, line_y+=line_height)
7408 {
7409 dminy = line_y;
7410 dmaxy = line_y + line_height - 1;
7411
7412 if (dminy < clipy) dminy = clipy;
7413 if (dmaxy > clipmaxy) dmaxy = clipmaxy;
7414 if (dminy > cmaxy || dmaxy < cminy) continue;
7415
7416 sdat_offs = sdat_walk & sdat_wrapmask;
7417
7418 drawrect.min_y = (dminy < cminy ) ? cminy : dminy;
7419 drawrect.max_y = (dmaxy > cmaxy ) ? cmaxy : dmaxy;
7420
7421 dx = ((int)pScrollData[sdat_offs]<<16 | (int)pScrollData[sdat_offs+1]) + corr;
7422
7423 if (last_dx == dx) { if (last_visible) goto LINE_SHORTCIRCUIT; continue; }
7424 last_dx = dx;
7425
7426 if (colspan > 1)
7427 {
7428 /*sx = (unsigned)dx % width;*/
7429 sx = (unsigned)dx & (width-1);
7430
7431 /*tx = c * K056832_PAGE_WIDTH;*/
7432 tx = c << 9;
7433
7434 if (!flipx)
7435 {
7436 /* handle right-edge wraparoundness and cull off-screen tilemaps*/
7437 if ((c == 0) && (sx > width - K056832_PAGE_WIDTH)) sx -= width;
7438 if ((sx + K056832_PAGE_WIDTH <= tx) || (sx - K056832_PAGE_WIDTH >= tx))
7439 { last_visible = 0; continue; }
7440
7441 /* switch frame of reference and clip x*/
7442 if ((tx -= sx) <= 0) { clipw = K056832_PAGE_WIDTH + tx; clipx = 0; }
7443 else { clipw = K056832_PAGE_WIDTH - tx; clipx = tx; }
7444 }
7445 else
7446 {
7447 tx += K056832_PAGE_WIDTH;
7448
7449 /* handle left-edge wraparoundness and cull off-screen tilemaps*/
7450 if ((c == colspan-1) && (sx < K056832_PAGE_WIDTH)) sx += width;
7451 if ((sx + K056832_PAGE_WIDTH <= tx) || (sx - K056832_PAGE_WIDTH >= tx))
7452 { last_visible = 0; continue; }
7453
7454 /* switch frame of reference and clip y*/
7455 if ((tx -= sx) >= 0) { clipw = K056832_PAGE_WIDTH - tx; clipx = 0; }
7456 else { clipw = K056832_PAGE_WIDTH + tx; clipx = -tx; }
7457 }
7458 }
7459 else { clipw = K056832_PAGE_WIDTH; clipx = 0; }
7460
7461 last_visible = 1;
7462
7463 dminx = clipx;
7464 dmaxx = clipx + clipw - 1;
7465
7466 drawrect.min_x = (dminx < cminx ) ? cminx : dminx;
7467 drawrect.max_x = (dmaxx > cmaxx ) ? cmaxx : dmaxx;
7468
7469 tilemap_set_scrollx(tilemap, 0, dx);
7470
7471 LINE_SHORTCIRCUIT:
7472 tilemap_draw(bitmap, &drawrect, tilemap, flags, priority);
7473
7474 } /* end of line loop*/
7475 } /* end of column loop*/
7476 } /* end of row loop*/
7477
7478 K056832_ActiveLayer = last_active;
7479
7480 } /* end of function*/
7481
K056832_set_LayerAssociation(int status)7482 void K056832_set_LayerAssociation(int status)
7483 {
7484 K056832_DefaultLayerAssociation = status;
7485 }
7486
K056832_get_LayerAssociation(void)7487 int K056832_get_LayerAssociation(void)
7488 {
7489 return(K056832_LayerAssociation);
7490 }
7491
K056832_set_LayerOffset(int layer,int offsx,int offsy)7492 void K056832_set_LayerOffset(int layer, int offsx, int offsy)
7493 {
7494 K056832_LayerOffset[layer][0] = offsx;
7495 K056832_LayerOffset[layer][1] = offsy;
7496 }
7497
K056832_set_LSRAMPage(int logical_page,int physical_page,int physical_offset)7498 void K056832_set_LSRAMPage(int logical_page, int physical_page, int physical_offset)
7499 {
7500 K056832_LSRAMPage[logical_page][0] = physical_page;
7501 K056832_LSRAMPage[logical_page][1] = physical_offset;
7502 }
7503
K056832_set_UpdateMode(int mode)7504 void K056832_set_UpdateMode(int mode)
7505 {
7506 K056832_UpdateMode = mode;
7507 }
7508
K056832_linemap_enable(int enable)7509 void K056832_linemap_enable(int enable)
7510 {
7511 K056832_linemap_enabled = enable;
7512 }
7513
K056832_is_IRQ_enabled(int irqline)7514 int K056832_is_IRQ_enabled(int irqline)
7515 {
7516 return(K056832_regs[0x06/2] & (1<<irqline & 7));
7517 }
7518
K056832_read_AVAC(int * mode,int * data)7519 void K056832_read_AVAC(int *mode, int *data)
7520 {
7521 *mode = K056832_regs[0x04/2] & 7;
7522 *data = K056832_regs[0x38/2];
7523 }
7524
K056832_read_register(int regnum)7525 int K056832_read_register(int regnum)
7526 {
7527 return(K056832_regs[regnum]);
7528 }
7529
7530
7531
7532 /***************************************************************************/
7533 /* */
7534 /* 055555 */
7535 /* */
7536 /***************************************************************************/
7537
7538 /* K055555 5-bit-per-pixel priority encoder */
7539 /* This device has 48 8-bit-wide registers */
7540
7541 static data8_t k55555_regs[128];
7542
K055555_vh_start(void)7543 void K055555_vh_start(void)
7544 {
7545 state_save_register_UINT8("K055555", 0, "registers", k55555_regs, 64);
7546
7547 memset(k55555_regs, 0, 64*sizeof(data8_t));
7548 }
7549
K055555_write_reg(data8_t regnum,data8_t regdat)7550 void K055555_write_reg(data8_t regnum, data8_t regdat)
7551 {
7552 static const char *rnames[46] =
7553 {
7554 "BGC CBLK", "BGC SET", "COLSET0", "COLSET1", "COLSET2", "COLSET3", "COLCHG ON",
7555 "A PRI 0", "A PRI 1", "A COLPRI", "B PRI 0", "B PRI 1", "B COLPRI", "C PRI", "D PRI",
7556 "OBJ PRI", "SUB1 PRI", "SUB2 PRI", "SUB3 PRI", "OBJ INPRI ON", "S1 INPRI ON", "S2 INPRI ON",
7557 "S3 INPRI ON", "A PAL", "B PAL", "C PAL", "D PAL", "OBJ PAL", "SUB1 PAL", "SUB2 PAL", "SUB3 PAL",
7558 "SUB2 PAL ON", "SUB3 PAL ON", "V INMIX", "V INMIX ON", "OS INMIX", "OS INMIX ON", "SHD PRI 1",
7559 "SHD PRI 2", "SHD PRI 3", "SHD ON", "SHD PRI SEL", "V BRI", "OS INBRI", "OS INBRI ON", "ENABLE"
7560 };
7561
7562 if (regdat != k55555_regs[regnum])
7563 {
7564 log_cb(RETRO_LOG_DEBUG, LOGPRE "5^5: %x to reg %x (%s)\n", regdat, regnum, rnames[regnum]);
7565 }
7566
7567 k55555_regs[regnum] = regdat;
7568 }
7569
WRITE32_HANDLER(K055555_long_w)7570 WRITE32_HANDLER( K055555_long_w )
7571 {
7572 data8_t regnum, regdat;
7573
7574 if (!(mem_mask & 0xff000000))
7575 {
7576 regnum = offset<<1;
7577 regdat = data>>24;
7578 }
7579 else
7580 {
7581 if (!(mem_mask & 0xff00))
7582 {
7583 regnum = (offset<<1)+1;
7584 regdat = data>>8;
7585 }
7586 else
7587 {
7588 /* log_cb(RETRO_LOG_DEBUG, LOGPRE "5^5: unknown mem_mask %08x\n", mem_mask);*/
7589 return;
7590 }
7591 }
7592
7593 K055555_write_reg(regnum, regdat);
7594 }
7595
WRITE16_HANDLER(K055555_word_w)7596 WRITE16_HANDLER( K055555_word_w )
7597 {
7598 if (mem_mask == 0xff00)
7599 {
7600 K055555_write_reg(offset, data&0xff);
7601 }
7602 else
7603 {
7604 K055555_write_reg(offset, data>>8);
7605 }
7606 }
7607
K055555_read_register(int regnum)7608 int K055555_read_register(int regnum)
7609 {
7610 return(k55555_regs[regnum]);
7611 }
7612
K055555_get_palette_index(int idx)7613 int K055555_get_palette_index(int idx)
7614 {
7615 return(k55555_regs[K55_PALBASE_A + idx]);
7616 }
7617
7618
7619
7620 /***************************************************************************/
7621 /* */
7622 /* 054338 */
7623 /* */
7624 /***************************************************************************/
7625
7626 static data16_t k54338_regs[32];
7627 static int K054338_shdRGB[9];
7628 static int K054338_alphainverted;
7629
7630
7631 /* K054338 alpha blend / final mixer (normally used with the 55555)*/
7632 /* because the implementation is vidhrdw dependant, this is just a*/
7633 /* register-handling shell.*/
K054338_vh_start(void)7634 int K054338_vh_start(void)
7635 {
7636 memset(k54338_regs, 0, sizeof(data16_t)*32);
7637 memset(K054338_shdRGB, 0, sizeof(int)*9);
7638 K054338_alphainverted = 1;
7639
7640 state_save_register_UINT16("K054338", 0, "registers", k54338_regs, 32);
7641
7642 return 0;
7643 }
7644
WRITE16_HANDLER(K054338_word_w)7645 WRITE16_HANDLER( K054338_word_w )
7646 {
7647 COMBINE_DATA(k54338_regs + offset);
7648 }
7649
WRITE32_HANDLER(K054338_long_w)7650 WRITE32_HANDLER( K054338_long_w )
7651 {
7652 offset <<= 1;
7653 K054338_word_w(offset, data>>16, mem_mask>>16);
7654 K054338_word_w(offset+1, data, mem_mask);
7655 }
7656
7657 /* returns a 16-bit '338 register*/
K054338_read_register(int reg)7658 int K054338_read_register(int reg)
7659 {
7660 return k54338_regs[reg];
7661 }
7662
K054338_update_all_shadows(void)7663 void K054338_update_all_shadows(void)
7664 {
7665 int i, d;
7666 int noclip = k54338_regs[K338_REG_CONTROL] & K338_CTL_CLIPSL;
7667
7668 for (i=0; i<9; i++)
7669 {
7670 d = k54338_regs[K338_REG_SHAD1R+i] & 0x1ff;
7671 if (d >= 0x100) d -= 0x200;
7672 K054338_shdRGB[i] = d;
7673 }
7674
7675 palette_set_shadow_dRGB32(0, K054338_shdRGB[0], K054338_shdRGB[1], K054338_shdRGB[2], noclip);
7676 palette_set_shadow_dRGB32(1, K054338_shdRGB[3], K054338_shdRGB[4], K054338_shdRGB[5], noclip);
7677 palette_set_shadow_dRGB32(2, K054338_shdRGB[6], K054338_shdRGB[7], K054338_shdRGB[8], noclip);
7678 }
7679
7680 /* K054338 BG color fill*/
K054338_fill_solid_bg(struct mame_bitmap * bitmap)7681 void K054338_fill_solid_bg(struct mame_bitmap *bitmap)
7682 {
7683 UINT32 bgcolor;
7684 UINT32 *pLine;
7685 int x, y;
7686
7687 bgcolor = (K054338_read_register(K338_REG_BGC_R)&0xff)<<16;
7688 bgcolor |= K054338_read_register(K338_REG_BGC_GB);
7689
7690 /* and fill the screen with it */
7691 for (y = 0; y < bitmap->height; y++)
7692 {
7693 pLine = (UINT32 *)bitmap->base;
7694 pLine += ((bitmap->rowbytes / 4)*y);
7695 for (x = 0; x < bitmap->width; x++)
7696 *pLine++ = bgcolor;
7697 }
7698 }
7699
7700 /* Unified K054338/K055555 BG color fill*/
K054338_fill_backcolor(struct mame_bitmap * bitmap,int mode)7701 void K054338_fill_backcolor(struct mame_bitmap *bitmap, int mode) /* (see p.67)*/
7702 {
7703 int clipx, clipy, clipw, cliph, i, dst_pitch;
7704 int BGC_CBLK, BGC_SET;
7705 UINT32 *dst_ptr, *pal_ptr;
7706 register int bgcolor;
7707
7708 clipx = Machine->visible_area.min_x & ~3;
7709 clipy = Machine->visible_area.min_y;
7710 clipw = (Machine->visible_area.max_x - clipx + 4) & ~3;
7711 cliph = Machine->visible_area.max_y - clipy + 1;
7712
7713 dst_ptr = (UINT32 *)bitmap->line[clipy];
7714 dst_pitch = bitmap->rowpixels;
7715 dst_ptr += clipx;
7716
7717 BGC_SET = 0;
7718 pal_ptr = paletteram32;
7719
7720 if (!mode)
7721 {
7722 /* single color output from CLTC*/
7723 bgcolor = (int)(k54338_regs[K338_REG_BGC_R]&0xff)<<16 | (int)k54338_regs[K338_REG_BGC_GB];
7724 }
7725 else
7726 {
7727 BGC_CBLK = K055555_read_register(0);
7728 BGC_SET = K055555_read_register(1);
7729 pal_ptr += BGC_CBLK << 9;
7730
7731 /* single color output from PCU2*/
7732 if (!(BGC_SET & 2)) { bgcolor = *pal_ptr; mode = 0; } else bgcolor = 0;
7733 }
7734
7735 if (!mode)
7736 {
7737 /* single color fill*/
7738 dst_ptr += clipw;
7739 i = clipw = -clipw;
7740 do
7741 {
7742 do { dst_ptr[i] = dst_ptr[i+1] = dst_ptr[i+2] = dst_ptr[i+3] = bgcolor; } while (i += 4);
7743 dst_ptr += dst_pitch;
7744 i = clipw;
7745 }
7746 while (--cliph);
7747 }
7748 else
7749 {
7750 if (!(BGC_SET & 1))
7751 {
7752 /* vertical gradient fill*/
7753 pal_ptr += clipy;
7754 dst_ptr += clipw;
7755 bgcolor = *pal_ptr++;
7756 i = clipw = -clipw;
7757 do
7758 {
7759 do { dst_ptr[i] = dst_ptr[i+1] = dst_ptr[i+2] = dst_ptr[i+3] = bgcolor; } while (i += 4);
7760 dst_ptr += dst_pitch;
7761 bgcolor = *pal_ptr++;
7762 i = clipw;
7763 }
7764 while (--cliph);
7765 }
7766 else
7767 {
7768 /* horizontal gradient fill*/
7769 pal_ptr += clipx;
7770 clipw <<= 2;
7771 do
7772 {
7773 memcpy(dst_ptr, pal_ptr, clipw);
7774 dst_ptr += dst_pitch;
7775 }
7776 while (--cliph);
7777 }
7778 }
7779 }
7780
7781 /* addition blending unimplemented (requires major changes to drawgfx and tilemap.c)*/
K054338_set_alpha_level(int pblend)7782 int K054338_set_alpha_level(int pblend)
7783 {
7784 data16_t *regs;
7785 int ctrl, mixpri, mixset, mixlv;
7786
7787 if (pblend <= 0 || pblend > 3)
7788 {
7789 alpha_set_level(255);
7790 return(255);
7791 }
7792
7793 regs = k54338_regs;
7794 ctrl = k54338_regs[K338_REG_CONTROL];
7795 mixpri = ctrl & K338_CTL_MIXPRI;
7796 mixset = regs[K338_REG_PBLEND + (pblend>>1 & 1)] >> (~pblend<<3 & 8);
7797 mixlv = mixset & 0x1f;
7798
7799 if (K054338_alphainverted) mixlv = 0x1f - mixlv;
7800
7801 if (!(mixset & 0x20))
7802 {
7803 mixlv = mixlv<<3 | mixlv>>2;
7804 alpha_set_level(mixlv); /* source x alpha/255 + target x (255-alpha)/255*/
7805 }
7806 else
7807 {
7808 if (!mixpri)
7809 {
7810 /* source x alpha + target (clipped at 255)*/
7811 }
7812 else
7813 {
7814 /* source + target x alpha (clipped at 255)*/
7815 }
7816
7817 /* DUMMY*/
7818 if (mixlv && mixlv<0x1f) mixlv = 0x10;
7819 mixlv = mixlv<<3 | mixlv>>2;
7820 alpha_set_level(mixlv);
7821
7822 log_cb(RETRO_LOG_DEBUG, LOGPRE "MIXSET%1d %s addition mode: %02x",pblend,(mixpri)?"dst":"src",mixset&0x1f);
7823 }
7824
7825 return(mixlv);
7826 }
7827
K054338_invert_alpha(int invert)7828 void K054338_invert_alpha(int invert)
7829 {
7830 K054338_alphainverted = invert;
7831 }
7832
K054338_export_config(int ** shdRGB)7833 void K054338_export_config(int **shdRGB)
7834 {
7835 *shdRGB = K054338_shdRGB;
7836 }
7837
7838
7839
7840 /***************************************************************************/
7841 /* */
7842 /* 053250 */
7843 /* */
7844 /***************************************************************************/
7845
7846 static struct
7847 {
7848 int chips;
7849 struct K053250_CHIPTAG
7850 {
7851 data8_t regs[8];
7852 data8_t *base;
7853 data16_t *ram, *rammax;
7854 data16_t *buffer[2];
7855 UINT32 rommask;
7856 int page[2];
7857 int frame, offsx, offsy;
7858 } chip[2];
7859 } K053250_info;
7860
K053250_set_LayerOffset(int chip,int offsx,int offsy)7861 void K053250_set_LayerOffset(int chip, int offsx, int offsy)
7862 {
7863 K053250_info.chip[chip].offsx = offsx;
7864 K053250_info.chip[chip].offsy = offsy;
7865 }
7866
7867 /* The DMA process should be instantaneous but since rendering in MAME is performed at VIDEO_UPDATE()*/
7868 /* the K053250 memory must be buffered to maintain visual integrity.*/
K053250_dma(int chip,int limiter)7869 void K053250_dma(int chip, int limiter)
7870 {
7871 struct K053250_CHIPTAG *chip_ptr;
7872 int last_frame, current_frame;
7873
7874 chip_ptr = &K053250_info.chip[chip];
7875
7876 current_frame = cpu_getcurrentframe();
7877 last_frame = chip_ptr->frame;
7878
7879 if (limiter && current_frame == last_frame) return; /* make sure we only do DMA transfer once per frame*/
7880
7881 chip_ptr->frame = current_frame;
7882 memcpy(chip_ptr->buffer[chip_ptr->page[chip]], chip_ptr->ram, 0x1000);
7883 chip_ptr->page[chip] ^= 1;
7884 }
7885
7886 /* Pixel data of the K053250 is nibble packed. It's preferable to be unpacked into byte format.*/
K053250_unpack_pixels(int region)7887 void K053250_unpack_pixels(int region)
7888 {
7889 UINT8 *src_ptr, *dst_ptr;
7890 int hi_nibble, lo_nibble, offset;
7891
7892 dst_ptr = src_ptr = memory_region(region);
7893 offset = memory_region_length(region) / 2 - 1;
7894
7895 do
7896 {
7897 lo_nibble = hi_nibble = src_ptr[offset];
7898 hi_nibble >>= 4;
7899 lo_nibble &= 0xf;
7900 dst_ptr[offset*2 ] = hi_nibble;
7901 dst_ptr[offset*2+1] = lo_nibble;
7902 }
7903 while ((--offset) >= 0);
7904 }
7905
K053250_vh_start(int chips,int * region)7906 int K053250_vh_start(int chips, int *region)
7907 {
7908 data16_t *ram;
7909 int chip;
7910
7911 K053250_info.chips = chips;
7912
7913 for(chip=0; chip<chips; chip++)
7914 {
7915 K053250_info.chip[chip].base = memory_region(region[chip]);
7916 if (!(ram = auto_malloc(0x6000))) return 1;
7917 K053250_info.chip[chip].ram = ram;
7918 K053250_info.chip[chip].rammax = ram + 0x800;
7919 K053250_info.chip[chip].buffer[0] = ram + 0x2000;
7920 K053250_info.chip[chip].buffer[1] = ram + 0x2800;
7921 memset(ram+0x2000, 0, 0x2000);
7922 K053250_info.chip[chip].rommask = memory_region_length(region[chip]);
7923 K053250_info.chip[chip].page[1] = K053250_info.chip[chip].page[0] = 0;
7924 K053250_info.chip[chip].offsy = K053250_info.chip[chip].offsx = 0;
7925 K053250_info.chip[chip].frame = -1;
7926
7927 state_save_register_UINT16("K053250", chip, "memory", K053250_info.chip[chip].ram, 0x800);
7928 state_save_register_UINT8 ("K053250", chip, "registers", K053250_info.chip[chip].regs, 8);
7929 }
7930
7931 return 0;
7932 }
7933
WRITE16_HANDLER(K053250_0_w)7934 WRITE16_HANDLER( K053250_0_w )
7935 {
7936 if (ACCESSING_LSB)
7937 {
7938 /* start LVC DMA transfer at the falling edge of control register's bit1*/
7939 if (offset == 4 && !(data & 2) && (K053250_info.chip[0].regs[4] & 2)) K053250_dma(0, 1);
7940
7941 K053250_info.chip[0].regs[offset] = data;
7942 }
7943 }
7944
READ16_HANDLER(K053250_0_r)7945 READ16_HANDLER( K053250_0_r )
7946 {
7947 return K053250_info.chip[0].regs[offset];
7948 }
7949
WRITE16_HANDLER(K053250_0_ram_w)7950 WRITE16_HANDLER( K053250_0_ram_w )
7951 {
7952 COMBINE_DATA( K053250_info.chip[0].ram + offset);
7953 }
7954
READ16_HANDLER(K053250_0_ram_r)7955 READ16_HANDLER( K053250_0_ram_r )
7956 {
7957 return K053250_info.chip[0].ram[offset];
7958 }
7959
READ16_HANDLER(K053250_0_rom_r)7960 READ16_HANDLER( K053250_0_rom_r )
7961 {
7962 /* if (!(K053250_info.chip[0].regs[5] & 1)) log_cb(RETRO_LOG_DEBUG, LOGPRE "Back: Reading rom memory with enable=0\n");*/
7963
7964 return *(K053250_info.chip[0].base + 0x80000*K053250_info.chip[0].regs[6] + 0x800*K053250_info.chip[0].regs[7] + (offset>>1));
7965 }
7966
WRITE16_HANDLER(K053250_1_w)7967 WRITE16_HANDLER( K053250_1_w )
7968 {
7969 if (ACCESSING_LSB)
7970 {
7971 /* start LVC DMA transfer at the falling edge of control register's bit1*/
7972 if (offset == 4 && !(data & 2) && (K053250_info.chip[1].regs[4] & 2)) K053250_dma(1, 1);
7973
7974 K053250_info.chip[1].regs[offset] = data;
7975 }
7976 }
7977
READ16_HANDLER(K053250_1_r)7978 READ16_HANDLER( K053250_1_r )
7979 {
7980 return K053250_info.chip[1].regs[offset];
7981 }
7982
WRITE16_HANDLER(K053250_1_ram_w)7983 WRITE16_HANDLER( K053250_1_ram_w )
7984 {
7985 COMBINE_DATA( K053250_info.chip[1].ram + offset);
7986 }
7987
READ16_HANDLER(K053250_1_ram_r)7988 READ16_HANDLER( K053250_1_ram_r )
7989 {
7990 return K053250_info.chip[1].ram[offset];
7991 }
7992
READ16_HANDLER(K053250_1_rom_r)7993 READ16_HANDLER( K053250_1_rom_r )
7994 {
7995 /* if (!(K053250_info.chip[1].regs[5] & 1)) log_cb(RETRO_LOG_DEBUG, LOGPRE "Back: Reading rom memory with enable=0\n");*/
7996
7997 return *(K053250_info.chip[1].base + 0x80000*K053250_info.chip[1].regs[6] + 0x800*K053250_info.chip[1].regs[7] + (offset>>1));
7998 }
7999
8000 #if 0
8001
8002 /* old code (for reference; do not remove)*/
8003 #define ADJUST_FOR_ORIENTATION(type, orientation, bitmapi, bitmapp, x, y) \
8004 int dy = ((type *)bitmap->line[1]) - ((type *)bitmap->line[0]); \
8005 int dyp = ((UINT8 *)bitmapp->line[1]) - ((UINT8 *)bitmapp->line[0]); \
8006 type *dsti = (type *)bitmapi->line[0] + y * dy + x; \
8007 UINT8 *dstp = (UINT8 *)bitmapp->line[0] + y * dyp + x; \
8008 int xadv = 1; \
8009 if (orientation) \
8010 { \
8011 int tx = x, ty = y, temp; \
8012 if ((orientation) & ORIENTATION_SWAP_XY) \
8013 { \
8014 temp = tx; tx = ty; ty = temp; \
8015 xadv = dy; \
8016 } \
8017 if ((orientation) & ORIENTATION_FLIP_X) \
8018 { \
8019 tx = bitmap->width - 1 - tx; \
8020 if (!((orientation) & ORIENTATION_SWAP_XY)) xadv = -xadv; \
8021 } \
8022 if ((orientation) & ORIENTATION_FLIP_Y) \
8023 { \
8024 ty = bitmap->height - 1 - ty; \
8025 if ((orientation) & ORIENTATION_SWAP_XY) xadv = -xadv; \
8026 } \
8027 /* can't lookup line because it may be negative! */ \
8028 dsti = ((type *)bitmapi->line[0]) + dy * ty + tx; \
8029 dstp = ((UINT8 *)bitmapp->line[0]) + dyp * ty + tx; \
8030 }
8031
8032 static void K053250_pdraw_scanline8(
8033 struct mame_bitmap *bitmap,int x,int y,int length,
8034 const UINT8 *src,pen_t *pens,int transparent_pen,UINT32 orient,int pri)
8035 {
8036 /* 8bpp destination */
8037 if (bitmap->depth == 8)
8038 {
8039 /* adjust in case we're oddly oriented */
8040 ADJUST_FOR_ORIENTATION(UINT8, orient, bitmap, priority_bitmap, x, y);
8041
8042 /* with pen lookups */
8043 if (pens)
8044 {
8045 if (transparent_pen == -1)
8046 while (length--)
8047 {
8048 *dsti = pens[*src++];
8049 *dstp = pri;
8050 dsti += xadv;
8051 dstp += xadv;
8052 }
8053 else
8054 while (length--)
8055 {
8056 UINT32 spixel = *src++;
8057 if (spixel != transparent_pen)
8058 {
8059 *dsti = pens[spixel];
8060 *dstp = pri;
8061 }
8062 dsti += xadv;
8063 dstp += xadv;
8064 }
8065 }
8066
8067 /* without pen lookups */
8068 else
8069 {
8070 if (transparent_pen == -1)
8071 while (length--)
8072 {
8073 *dsti = *src++;
8074 *dstp = pri;
8075 dsti += xadv;
8076 dstp += xadv;
8077 }
8078 else
8079 while (length--)
8080 {
8081 UINT32 spixel = *src++;
8082 if (spixel != transparent_pen)
8083 {
8084 *dsti = spixel;
8085 *dstp = pri;
8086 }
8087 dsti += xadv;
8088 dstp += xadv;
8089 }
8090 }
8091 }
8092
8093 /* 16bpp destination */
8094 else if(bitmap->depth == 15 || bitmap->depth == 16)
8095 {
8096 /* adjust in case we're oddly oriented */
8097 ADJUST_FOR_ORIENTATION(UINT16, orient, bitmap, priority_bitmap, x, y);
8098 /* with pen lookups */
8099 if (pens)
8100 {
8101 if (transparent_pen == -1)
8102 while (length--)
8103 {
8104 *dsti = pens[*src++];
8105 *dstp = pri;
8106 dsti += xadv;
8107 dstp += xadv;
8108 }
8109 else
8110 while (length--)
8111 {
8112 UINT32 spixel = *src++;
8113 if (spixel != transparent_pen)
8114 {
8115 *dsti = pens[spixel];
8116 *dstp = pri;
8117 }
8118 dsti += xadv;
8119 dstp += xadv;
8120 }
8121 }
8122
8123 /* without pen lookups */
8124 else
8125 {
8126 if (transparent_pen == -1)
8127 while (length--)
8128 {
8129 *dsti = *src++;
8130 *dstp = pri;
8131 dsti += xadv;
8132 dstp += xadv;
8133 }
8134 else
8135 while (length--)
8136 {
8137 UINT32 spixel = *src++;
8138 if (spixel != transparent_pen)
8139 {
8140 *dsti = spixel;
8141 *dstp = pri;
8142 }
8143 dsti += xadv;
8144 dstp += xadv;
8145 }
8146 }
8147 }
8148
8149 /* 32bpp destination */
8150 else
8151 {
8152 /* adjust in case we're oddly oriented */
8153 ADJUST_FOR_ORIENTATION(UINT32, orient, bitmap, priority_bitmap, x, y);
8154 /* with pen lookups */
8155 if (pens)
8156 {
8157 if (transparent_pen == -1)
8158 while (length--)
8159 {
8160 *dsti = pens[*src++];
8161 *dstp = pri;
8162 dsti += xadv;
8163 dstp += xadv;
8164 }
8165 else
8166 while (length--)
8167 {
8168 UINT32 spixel = *src++;
8169 if (spixel != transparent_pen)
8170 {
8171 *dsti = pens[spixel];
8172 *dstp = pri;
8173 }
8174 dsti += xadv;
8175 dstp += xadv;
8176 }
8177 }
8178
8179 /* without pen lookups */
8180 else
8181 {
8182 if (transparent_pen == -1)
8183 while (length--)
8184 {
8185 *dsti = *src++;
8186 *dstp = pri;
8187 dsti += xadv;
8188 dstp += xadv;
8189 }
8190 else
8191 while (length--)
8192 {
8193 UINT32 spixel = *src++;
8194 if (spixel != transparent_pen)
8195 {
8196 *dsti = spixel;
8197 *dstp = pri;
8198 }
8199 dsti += xadv;
8200 dstp += xadv;
8201 }
8202 }
8203 }
8204 }
8205
8206 void K053250_draw(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int chip, int colorbase, int pri)
8207 {
8208 static int pmode[2] = {-1,-1};
8209 static int kc=-1, kk=0, kxx=-105, kyy=0;
8210
8211 const struct rectangle area = Machine->visible_area;
8212 data16_t *line;
8213 int delta, dim1, dim1_max, dim2_max;
8214 UINT32 mask1, mask2;
8215 int sp;
8216 #if 1
8217 int orientation = ((K053250_info.chip[chip].regs[4] & 8) ? ORIENTATION_FLIP_X : 0)
8218 | ((K053250_info.chip[chip].regs[4] & 16) ? ORIENTATION_FLIP_Y : 0)
8219 | ((K053250_info.chip[chip].regs[4] & 1) ? 0 : ORIENTATION_SWAP_XY);
8220 #else
8221 int orientation = (!K053250_info.chip[chip].regs[4] & 8 ? ORIENTATION_FLIP_X : 0)
8222 | (K053250_info.chip[chip].regs[4] & 16 ? ORIENTATION_FLIP_Y : 0)
8223 | (!(K053250_info.chip[chip].regs[4] & 1) ? 0 : ORIENTATION_SWAP_XY);
8224 #endif
8225
8226 INT16 cur_x = (K053250_info.chip[chip].regs[0] << 8) | K053250_info.chip[chip].regs[1];
8227 INT16 cur_y = (K053250_info.chip[chip].regs[2] << 8) | K053250_info.chip[chip].regs[3];
8228
8229 if(pmode[chip] != K053250_info.chip[chip].regs[4]) {
8230 pmode[chip] = K053250_info.chip[chip].regs[4];
8231 #if 0
8232 fprintf(stderr, "NEW MODE %d %02x [%x %c%c%c%c%c]\n", chip,
8233 pmode[chip],
8234 pmode[chip] >> 5,
8235 pmode[chip] & 16 ? 'y' : '-',
8236 pmode[chip] & 8 ? 'x' : '-',
8237 pmode[chip] & 4 ? 'w' : '-',
8238 pmode[chip] & 2 ? '?' : '-',
8239 pmode[chip] & 1 ? 's' : '-');
8240 #endif
8241 }
8242
8243 colorbase <<= 4;
8244
8245 if(orientation & ORIENTATION_SWAP_XY) {
8246 dim1_max = area.max_x - area.min_x + 1;
8247 dim2_max = area.max_y - area.min_y + 1;
8248 /* -358 for level 1 boss, huh? -495*/
8249 if(orientation & ORIENTATION_FLIP_Y)
8250 delta = 238 - cur_y;
8251 else
8252 delta = kyy + cur_y;
8253 line = K053250_info.chip[chip].ram + (((area.min_x + cur_x + kxx) & 0x1ff) << 2);
8254 } else {
8255 dim1_max = area.max_y - area.min_y + 1;
8256 dim2_max = area.max_x - area.min_x + 1;
8257 delta = cur_x + 49;
8258 line = K053250_info.chip[chip].ram + (((area.min_y + cur_y + 16) & 0x1ff) << 2);
8259 }
8260
8261 if(chip && ++kk == 3) {
8262 int kx=0, kkc = 0;
8263 kk = 0;
8264 if(keyboard_pressed(KEYCODE_Y)) {
8265 kx = 1;
8266 kc--;
8267 if(kc<-1)
8268 kc = 511;
8269 }
8270 if(keyboard_pressed(KEYCODE_U)) {
8271 kx = 1;
8272 kc++;
8273 if(kc==512)
8274 kc = -1;
8275 }
8276
8277 if(keyboard_pressed(KEYCODE_T)) {
8278 kkc = 1;
8279 kyy--;
8280 }
8281 if(keyboard_pressed(KEYCODE_V)) {
8282 kkc = 1;
8283 kyy++;
8284 }
8285 if(keyboard_pressed(KEYCODE_F)) {
8286 kkc = 1;
8287 kxx--;
8288 }
8289 if(keyboard_pressed(KEYCODE_G)) {
8290 kkc = 1;
8291 kxx++;
8292 }
8293 #if 0
8294 if(kx) {
8295 UINT16 *l1 = line + ((4*kc) & 0x7ff);
8296 log_cb(RETRO_LOG_DEBUG, LOGPRE "Line %d [%02x] (%04x %04x %04x %04x)", kc,
8297 K053250_info.chip[chip].regs[4],
8298 l1[0],
8299 l1[1],
8300 l1[2],
8301 l1[3]);
8302 }
8303
8304 if(kkc)
8305 log_cb(RETRO_LOG_DEBUG, LOGPRE "(%d, %d)", kxx, kyy);
8306 #endif
8307 }
8308
8309
8310 switch(K053250_info.chip[chip].regs[4] >> 5) {
8311 case 0: /* Not sure. Warp level*/
8312 mask1 = 0xffff0000;
8313 mask2 = 0x0000ffff;
8314 sp = 0;
8315 break;
8316 case 1: /* Elaine's background*/
8317 mask1 = 0xffff8000;
8318 mask2 = 0x00007fff;
8319 sp = 0;
8320 break;
8321 case 2:
8322 mask1 = 0xffff0000;
8323 mask2 = 0x0000ffff;
8324 sp = 0;
8325 break;
8326 case 4: /* Level 1 boss, water level (planet)*/
8327 mask1 = 0xffffc000;
8328 mask2 = 0x00003fff;
8329 sp = 0;
8330 break;
8331 case 7: /* Organic level*/
8332 mask1 = 0xffff0000;
8333 mask2 = 0x0000ffff;
8334 sp = 1;
8335 break;
8336 default:
8337 /* log_cb(RETRO_LOG_DEBUG, LOGPRE "Unknown mode %02x\n", K053250_info.chip[chip].regs[4] & 0xe0);*/
8338 mask1 = 0xffff0000;
8339 mask2 = 0x0000ffff;
8340 sp = 0;
8341 break;
8342 }
8343
8344 if(K053250_info.chip[chip].regs[4] & 4)
8345 mask1 = 0;
8346
8347 for(dim1 = 0; dim1 < dim1_max; dim1++) {
8348 data16_t color = *line++;
8349 UINT16 start = *line++;
8350 data16_t inc = *line++;
8351 INT16 offset = *line++;
8352 int dim2;
8353 unsigned char *pixel;
8354 UINT32 cpos;
8355 unsigned char scanline[512];
8356 unsigned char *gbase = K053250_info.chip[chip].base + (((start & 0xff00) << 7) % K053250_info.chip[chip].rommask);
8357
8358 if(offset >= 0x500)
8359 offset -= 0x800;
8360
8361 if(line == K053250_info.chip[chip].rammax)
8362 line = K053250_info.chip[chip].ram;
8363
8364 if(!color && !start)
8365 continue;
8366
8367 pixel = scanline;
8368 start = (start & 0xff) << 7;
8369 cpos = (offset + delta)*inc;
8370 /* fprintf(stderr, "%3d %08x %04x\n", dim1, cpos, inc);*/
8371
8372 for(dim2 = 0; dim2 < dim2_max; dim2++) {
8373 int romp;
8374 UINT32 rcpos = cpos;
8375
8376 if(sp && (rcpos & mask1))
8377 rcpos += inc << 9;
8378
8379 if(rcpos & mask1) {
8380 *pixel++ = 0;
8381 cpos += inc;
8382 continue;
8383 }
8384
8385 romp = gbase[(((rcpos & mask2)>>7) + start) & 0x7fff];
8386
8387 if(rcpos & 0x40)
8388 romp &= 0xf;
8389 else
8390 romp >>= 4;
8391 *pixel++ = romp;
8392 cpos += inc;
8393 }
8394 if(orientation & ORIENTATION_SWAP_XY)
8395 K053250_pdraw_scanline8(bitmap, area.min_y, area.min_x+dim1, dim2_max, scanline,
8396 Machine->pens + ((dim1 == kc ? 0x200 : colorbase) | ((color & 0x0f) << 4)),
8397 0, orientation, pri);
8398 else
8399 K053250_pdraw_scanline8(bitmap, area.min_x, area.min_y+dim1, dim2_max, scanline,
8400 Machine->pens + ((dim1 == kc ? 0x200 : colorbase) | ((color & 0x0f) << 4)),
8401 0, orientation, pri);
8402 }
8403 }
8404
8405 #else
8406
8407 /* utility function to render a clipped scanline vertically or horizontally*/
K053250_pdraw_scanline32(struct mame_bitmap * bitmap,pen_t * palette,UINT8 * source,const struct rectangle * cliprect,int linepos,int scroll,int zoom,UINT32 clipmask,UINT32 wrapmask,UINT32 orientation,int priority)8408 static INLINE void K053250_pdraw_scanline32(struct mame_bitmap *bitmap, pen_t *palette, UINT8 *source,
8409 const struct rectangle *cliprect, int linepos, int scroll, int zoom,
8410 UINT32 clipmask, UINT32 wrapmask, UINT32 orientation, int priority)
8411 {
8412 /* a sixteen-bit fixed point resolution should be adequate to our application*/
8413 #define FIXPOINT_PRECISION 16
8414 #define FIXPOINT_PRECISION_HALF (1<<(FIXPOINT_PRECISION-1))
8415
8416 int end_pixel, flip, dst_min, dst_max, dst_start, dst_length;
8417
8418 UINT32 src_wrapmask;
8419 UINT8 *src_base;
8420 int src_x;
8421 int src_fx, src_fdx;
8422 int pix_data, dst_offset;
8423 pen_t *pal_base;
8424 UINT8 *pri_base;
8425 UINT32 *dst_base;
8426 int dst_adv;
8427 UINT8 pri;
8428
8429 /* flip X and flip Y also switch role when the X Y coordinates are swapped*/
8430 if (!(orientation & ORIENTATION_SWAP_XY))
8431 {
8432 flip = orientation & ORIENTATION_FLIP_X;
8433 dst_min = cliprect->min_x;
8434 dst_max = cliprect->max_x;
8435 }
8436 else
8437 {
8438 flip = orientation & ORIENTATION_FLIP_Y;
8439 dst_min = cliprect->min_y;
8440 dst_max = cliprect->max_y;
8441 }
8442
8443 if (clipmask)
8444 {
8445 /* reject scanlines that are outside of the target bitmap's right(bottom) clip boundary*/
8446 dst_start = -scroll;
8447 if (dst_start > dst_max) return;
8448
8449 /* calculate target length*/
8450 dst_length = clipmask + 1;
8451 if (zoom) dst_length = (dst_length << 6) / zoom;
8452
8453 /* reject scanlines that are outside of the target bitmap's left(top) clip boundary*/
8454 end_pixel = dst_start + dst_length - 1;
8455 if (end_pixel < dst_min) return;
8456
8457 /* clip scanline tail*/
8458 if ((end_pixel -= dst_max) > 0) dst_length -= end_pixel;
8459
8460 /* reject zero-length scanlines*/
8461 if (dst_length <= 0) return;
8462
8463 /* calculate zoom factor*/
8464 src_fdx = zoom << (FIXPOINT_PRECISION-6);
8465
8466 /* clip scanline head*/
8467 end_pixel = dst_min;
8468 if ((end_pixel -= dst_start) > 0)
8469 {
8470 /* chop scanline to the correct length and move target start location to the left(top) clip boundary*/
8471 dst_length -= end_pixel;
8472 dst_start = dst_min;
8473
8474 /* and skip the source for the left(top) clip region*/
8475 src_fx = end_pixel * src_fdx + FIXPOINT_PRECISION_HALF;
8476 }
8477 else
8478 /* the point five bias is to ensure even distribution of stretched or shrinked pixels*/
8479 src_fx = FIXPOINT_PRECISION_HALF;
8480
8481 /* adjust flipped source*/
8482 if (flip)
8483 {
8484 /* start from the target's clipped end if the scanline is flipped*/
8485 dst_start = dst_max + dst_min - dst_start - (dst_length-1);
8486
8487 /* and move source start location to the opposite end*/
8488 src_fx += (dst_length-1) * src_fdx - 1;
8489 src_fdx = -src_fdx;
8490 }
8491 }
8492 else
8493 {
8494 /* draw wrapped scanline at virtual bitmap boundary when source clipping is off*/
8495 dst_start = dst_min;
8496 dst_length = dst_max - dst_min + 1; /* target scanline spans the entire visible area*/
8497 src_fdx = zoom << (FIXPOINT_PRECISION-6);
8498
8499 /* pre-advance source for the clipped region*/
8500 if (!flip)
8501 src_fx = (scroll + dst_min) * src_fdx + FIXPOINT_PRECISION_HALF;
8502 else
8503 {
8504 src_fx = (scroll + dst_max) * src_fdx + FIXPOINT_PRECISION_HALF-1;
8505 src_fdx = -src_fdx;
8506 }
8507 }
8508
8509 if (!(orientation & ORIENTATION_SWAP_XY))
8510 {
8511 /* calculate target increment for horizontal scanlines which is exactly one*/
8512 dst_adv = 1;
8513 dst_offset = dst_length;
8514 pri_base = (UINT8 *)priority_bitmap->line[linepos] + dst_start + dst_offset;
8515 dst_base = (UINT32 *)bitmap->line[linepos] + dst_start + dst_length;
8516 }
8517 else
8518 {
8519 /* calculate target increment for vertical scanlines which is the bitmap's pitch value*/
8520 dst_adv = bitmap->rowpixels;
8521 dst_offset= dst_length * dst_adv;
8522 pri_base = (UINT8 *)priority_bitmap->line[dst_start] + linepos + dst_offset;
8523 dst_base = (UINT32 *)bitmap->line[dst_start] + linepos + dst_offset;
8524 }
8525
8526 #if 0
8527 /* generalized*/
8528 src_base = source;
8529 src_x = 0;
8530
8531 /* there is no need to wrap source offsets along with source clipping*/
8532 /* so we set all bits of the wrapmask to one*/
8533 src_wrapmask = (clipmask) ? ~0 : wrapmask;
8534
8535 pal_base = palette;
8536 pri = (UINT8)priority;
8537 dst_offset = -dst_offset; /* negate target offset in order to terminated draw loop at zero condition*/
8538
8539 if (pri)
8540 {
8541 /* draw scanline and update priority bitmap*/
8542 do
8543 {
8544 pix_data = src_base[(src_fx>>FIXPOINT_PRECISION) & src_wrapmask];
8545 src_fx += src_fdx;
8546
8547 if (pix_data)
8548 {
8549 pix_data = pal_base[pix_data];
8550 pri_base[dst_offset] = pri;
8551 dst_base[dst_offset] = pix_data;
8552 }
8553 }
8554 while (dst_offset += dst_adv);
8555 }
8556 else
8557 {
8558 /* draw scanline but do not update priority bitmap*/
8559 do
8560 {
8561 pix_data = src_base[(src_fx>>FIXPOINT_PRECISION) & src_wrapmask];
8562 src_fx += src_fdx;
8563
8564 if (pix_data)
8565 {
8566 dst_base[dst_offset] = pal_base[pix_data];
8567 }
8568 }
8569 while (dst_offset += dst_adv);
8570 }
8571 #else
8572 /* register efficient*/
8573 pal_base = palette;
8574 pri = (UINT8)priority;
8575 dst_offset = -dst_offset; /* negate target offset in order to terminated draw loop at zero condition*/
8576
8577 /* advance and convert source offset from fixed point to integer*/
8578 #define ADVANCE_SOURCE_OFFSET { src_x = src_fx; src_fx += src_fdx; src_x >>= FIXPOINT_PRECISION; }
8579
8580 /* draw non-zero pens and update priority bitmap*/
8581 #define DRAWPIXEL_PRIORITY { if (pix_data) { pix_data = pal_base[pix_data]; pri_base[dst_offset] = pri; dst_base[dst_offset] = pix_data; } }
8582
8583 /* draw non-zero pens but do not update priority bitmap*/
8584 #define DRAWPIXEL_NOPRIORITY { if (pix_data) dst_base[dst_offset] = pal_base[pix_data]; }
8585
8586 if (clipmask)
8587 {
8588 ADVANCE_SOURCE_OFFSET
8589 src_base = source;
8590
8591 if (dst_adv == 1)
8592 {
8593 if (pri)
8594 do { pix_data= src_base[src_x]; ADVANCE_SOURCE_OFFSET DRAWPIXEL_PRIORITY } while (++dst_offset);
8595 else
8596 do { pix_data= src_base[src_x]; ADVANCE_SOURCE_OFFSET DRAWPIXEL_NOPRIORITY } while (++dst_offset);
8597 }
8598 else
8599 {
8600 if (pri)
8601 do { pix_data= src_base[src_x]; ADVANCE_SOURCE_OFFSET DRAWPIXEL_PRIORITY } while (dst_offset += (512+32));
8602 else
8603 do { pix_data= src_base[src_x]; ADVANCE_SOURCE_OFFSET DRAWPIXEL_NOPRIORITY } while (dst_offset += (512+32));
8604 }
8605 }
8606 else
8607 {
8608 src_wrapmask = wrapmask << FIXPOINT_PRECISION | ((1<<FIXPOINT_PRECISION)-1);
8609 src_fx &= src_wrapmask;
8610 ADVANCE_SOURCE_OFFSET
8611 src_base = source;
8612 src_fx &= src_wrapmask;
8613
8614 if (dst_adv == 1)
8615 {
8616 if (pri)
8617 do { pix_data = src_base[src_x]; ADVANCE_SOURCE_OFFSET src_fx &= src_wrapmask; DRAWPIXEL_PRIORITY } while (++dst_offset);
8618 else
8619 do { pix_data = src_base[src_x]; ADVANCE_SOURCE_OFFSET src_fx &= src_wrapmask; DRAWPIXEL_NOPRIORITY } while (++dst_offset);
8620 }
8621 else
8622 {
8623 if (pri)
8624 do { pix_data = src_base[src_x]; ADVANCE_SOURCE_OFFSET src_fx &= src_wrapmask; DRAWPIXEL_PRIORITY } while (dst_offset += (512+32));
8625 else
8626 do { pix_data = src_base[src_x]; ADVANCE_SOURCE_OFFSET src_fx &= src_wrapmask; DRAWPIXEL_NOPRIORITY } while (dst_offset += (512+32));
8627 }
8628 }
8629 #endif
8630
8631 #undef FIXPOINT_PRECISION
8632 #undef FIXPOINT_PRECISION_HALF
8633 }
8634
K053250_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int chip,int colorbase,int flags,int priority)8635 void K053250_draw(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int chip, int colorbase, int flags, int priority)
8636 {
8637 struct K053250_CHIPTAG *chip_ptr;
8638 data16_t *line_ram;
8639 data8_t *pix_base, *pix_ptr, *regs;
8640 pen_t *pal_base, *pal_ptr;
8641 UINT32 rommask, src_clipmask, src_wrapmask, dst_wrapmask;
8642 int map_scrollx, map_scrolly, ctrl, orientation;
8643 int dst_minx, dst_maxx, dst_miny, dst_maxy;
8644 int linedata_offs, linedata_adv, line_pos, line_start, line_end, scroll_corr;
8645 int color, offset, zoom, scroll, passes, i, dst_height;
8646
8647 chip_ptr = &K053250_info.chip[chip]; /* pointer to chip parameters*/
8648 line_ram = chip_ptr->buffer[chip_ptr->page[chip]]; /* pointer to physical line RAM*/
8649 pix_base = chip_ptr->base; /* pointer to source pixel ROM*/
8650 rommask = chip_ptr->rommask; /* source ROM limit*/
8651 regs = chip_ptr->regs; /* pointer to registers group*/
8652
8653 map_scrollx = (short)(regs[0]<<8 | regs[1]); /* signed horizontal scroll value*/
8654 map_scrolly = (short)(regs[2]<<8 | regs[3]); /* signed vertical scroll value*/
8655 map_scrollx -= chip_ptr->offsx; /* add user X offset to horizontal scroll*/
8656 map_scrolly -= chip_ptr->offsy; /* add user Y offset to vertical scroll*/
8657 ctrl = regs[4]; /* register four is the main control register*/
8658
8659 /* copy visible boundary values to more accessible locations*/
8660 dst_minx = cliprect->min_x;
8661 dst_maxx = cliprect->max_x;
8662 dst_miny = cliprect->min_y;
8663 dst_maxy = cliprect->max_y;
8664
8665 orientation = 0; /* orientation defaults to no swapping and no flipping*/
8666 dst_height = 512; /* virtual bitmap height defaults to five hundred and twelve pixels*/
8667 linedata_adv = 4; /* line info packets are four words(eight bytes) apart*/
8668
8669 {
8670 /* switch X and Y parameters when the first bit of the control register is cleared*/
8671 if (!(ctrl & 0x01)) orientation |= ORIENTATION_SWAP_XY;
8672
8673 /* invert X parameters when the forth bit of the control register is set*/
8674 if (ctrl & 0x08) orientation |= ORIENTATION_FLIP_X;
8675
8676 /* invert Y parameters when the fifth bit of the control register is set*/
8677 if (ctrl & 0x10) orientation |= ORIENTATION_FLIP_Y;
8678
8679 switch (ctrl>>5) /* the upper four bits of the control register select source and target dimensions*/
8680 {
8681 case 0 :
8682 /* Xexex: L6 galaxies*/
8683 /* Metam: L4 forest, L5 arena, L6 tower interior, final boss*/
8684
8685 /* crop source offset between zero and two hundred and fifty-five inclusive,*/
8686 /* and set virtual bitmap height to two hundred and fifty-six pixels*/
8687 src_wrapmask = src_clipmask = 0xff;
8688 dst_height = 0x100;
8689 break;
8690 case 1 :
8691 /* Xexex: prologue, L7 nebulae*/
8692
8693 /* the source offset is cropped to zero and five hundred and eleven inclusive*/
8694 src_wrapmask = src_clipmask = 0x1ff;
8695 break;
8696 case 4 :
8697 /* Xexex: L1 sky and boss, L3 planet, L5 poly-face, L7 battle ship patches*/
8698 /* Metam: L1 summoning circle, L3 caves, L6 gargoyle towers*/
8699
8700 /* crop source offset between zero and two hundred and fifty-five inclusive,*/
8701 /* and allow source offset to wrap back at 500 hexadecimal to minus 300 hexadecimal*/
8702 src_wrapmask = src_clipmask = 0xff;
8703 flags |= K053250_WRAP500;
8704 break;
8705 /* case 2 : Xexex: title*/
8706 /* case 7 : Xexex: L4 organic stage*/
8707 default:
8708
8709 /* crop source offset between zero and one thousand and eleven inclusive,*/
8710 /* keep other dimensions to their defaults*/
8711 src_wrapmask = src_clipmask = 0x3ff;
8712 break;
8713 }
8714
8715 /* disable source clipping when the third bit of the control register is set*/
8716 if (ctrl & 0x04) src_clipmask = 0;
8717
8718 if (!(orientation & ORIENTATION_SWAP_XY)) /* normal orientaion with no X Y switching*/
8719 {
8720 line_start = dst_miny; /* the first scanline starts at the minimum Y clip location*/
8721 line_end = dst_maxy; /* the last scanline ends at the maximum Y clip location*/
8722 scroll_corr = map_scrollx; /* concentrate global X scroll*/
8723 linedata_offs = map_scrolly; /* determine where to get info for the first line*/
8724
8725 if (orientation & ORIENTATION_FLIP_X)
8726 {
8727 scroll_corr = -scroll_corr; /* X scroll adjustment should be negated in X flipped scenarioes*/
8728 }
8729
8730 if (orientation & ORIENTATION_FLIP_Y)
8731 {
8732 linedata_adv = -linedata_adv; /* traverse line RAM backward in Y flipped scenarioes*/
8733 linedata_offs += bitmap->height - 1; /* and get info for the first line from the bottom*/
8734 }
8735
8736 dst_wrapmask = ~0; /* scanlines don't seem to wrap horizontally in normal orientation*/
8737 passes = 1; /* draw scanline in a single pass*/
8738 }
8739 else /* orientaion with X and Y parameters switched*/
8740 {
8741 line_start = dst_minx; /* the first scanline starts at the minimum X clip location*/
8742 line_end = dst_maxx; /* the last scanline ends at the maximum X clip location*/
8743 scroll_corr = map_scrolly; /* concentrate global Y scroll*/
8744 linedata_offs = map_scrollx; /* determine where to get info for the first line*/
8745
8746 if (orientation & ORIENTATION_FLIP_Y)
8747 {
8748 scroll_corr = 0x100 - scroll_corr; /* apply common vertical correction*/
8749
8750 /* Y correction (ref: 1st and 5th boss)*/
8751 scroll_corr -= 2; /* apply unique vertical correction*/
8752
8753 /* X correction (ref: 1st boss, seems to undo non-rotated global X offset)*/
8754 linedata_offs -= 5; /* apply unique horizontal correction*/
8755 }
8756
8757 if (orientation & ORIENTATION_FLIP_X)
8758 {
8759 linedata_adv = -linedata_adv; /* traverse line RAM backward in X flipped scenarioes*/
8760 linedata_offs += bitmap->width - 1; /* and get info for the first line from the bottom*/
8761 }
8762
8763 if (src_clipmask)
8764 {
8765 /* determine target wrap boundary and draw scanline in two passes if the source is clipped*/
8766 dst_wrapmask = dst_height - 1;
8767 passes = 2;
8768 }
8769 else
8770 {
8771 /* otherwise disable target wraparound and draw scanline in a single pass*/
8772 dst_wrapmask = ~0;
8773 passes = 1;
8774 }
8775 }
8776 }
8777
8778 linedata_offs *= 4; /* each line info packet has four words(eight bytes)*/
8779 linedata_offs &= 0x7ff; /* and it should wrap at the four-kilobyte boundary*/
8780 linedata_offs += line_start * linedata_adv; /* pre-advance line info offset for the clipped region*/
8781
8782 /* load physical palette base*/
8783 pal_base = Machine->remapped_colortable + (colorbase << 4) % Machine->drv->total_colors;
8784
8785 /* walk the target bitmap within the visible area vertically or horizontally, one line at a time*/
8786 for (line_pos=line_start; line_pos<=line_end; linedata_offs+=linedata_adv, line_pos++)
8787 {
8788 linedata_offs &= 0x7ff; /* line info data wraps at the four-kilobyte boundary*/
8789
8790 color = line_ram[linedata_offs]; /* get scanline color code*/
8791 if (color == 0xffff) continue; /* reject scanline if color code equals minus one*/
8792
8793 offset = line_ram[linedata_offs+1]; /* get first pixel offset in ROM*/
8794 if (!(color & 0xff) && !offset) continue; /* reject scanline if both color and pixel offset are zero*/
8795
8796 /* calculate physical palette location*/
8797 /* there can be thirty-two color codes and each code represents sixteen pens*/
8798 pal_ptr = pal_base + ((color & 0x1f)<<4);
8799
8800 /* calculate physical pixel location*/
8801 /* each offset unit represents two hundred and fifty six pixels and should wrap at ROM boundary for safty*/
8802 pix_ptr = pix_base + (offset<<8) % rommask;
8803
8804 /* get scanline zoom factor*/
8805 /* For example, 0x20 doubles the length, 0x40 maintains a one-to-one length,*/
8806 /* and 0x80 halves the length. The zoom center is at the beginning of the*/
8807 /* scanline therefore it is not necessary to adjust render start position*/
8808 zoom = line_ram[linedata_offs+2];
8809
8810 scroll = (short)line_ram[linedata_offs+3]; /* get signed local scroll value for the current scanline*/
8811
8812 /* scavenged from old code; improves Xexex' first level sky*/
8813 if (flags & K053250_WRAP500 && scroll >= 0x500) scroll -= 0x800;
8814
8815 scroll += scroll_corr; /* apply final scroll correction*/
8816 scroll &= dst_wrapmask; /* wraparound scroll value if necessary*/
8817
8818 /* draw scanlines wrapped at virtual bitmap boundary in two passes*/
8819 /* this should not impose too much overhead due to clipping performed by the render code*/
8820 i = passes;
8821 do
8822 {
8823 /*
8824 Parameter descriptions:
8825
8826 bitmap : pointer to a MAME bitmap as the render target
8827 pal_ptr : pointer to the palette's physical location relative to the scanline
8828 pix_ptr : pointer to the physical start location of source pixels in ROM
8829 cliprect : pointer to a rectangle structue which describes the visible area of the target bitmap
8830 line_pos : scanline render position relative to the target bitmap
8831 should be a Y offset to the target bitmap in normal orientaion,
8832 or an X offset to the target bitmap if X,Y are swapped
8833 scroll : source scroll value of the scanline
8834 zoom : source zoom factor of the scanline
8835 src_clipmask : source offset clip mask; source pixels with offsets beyond the scope of this mask will not be drawn
8836 src_wrapmask : source offset wrap mask; wraps source offset around, no effect when src_clipmask is set
8837 orientation : flags indicating whether scanlines should be drawn horizontally, vertically, forward or backward
8838 priority : value to be written to the priority bitmap, no effect when equals zero
8839 */
8840 K053250_pdraw_scanline32(bitmap, pal_ptr, pix_ptr, cliprect,
8841 line_pos, scroll, zoom, src_clipmask, src_wrapmask, orientation, priority);
8842
8843 /* shift scanline position one virtual screen upward to render the wrapped end if necessary*/
8844 scroll -= dst_height;
8845 }
8846 while (--i);
8847 }
8848 }
8849
8850 #endif
8851
8852
8853
8854 /***************************************************************************/
8855 /* */
8856 /* 053252 */
8857 /* */
8858 /***************************************************************************/
8859
8860 /* K053252 CRT and interrupt control unit*/
8861 static data16_t K053252_regs[16];
8862
READ16_HANDLER(K053252_word_r)8863 READ16_HANDLER( K053252_word_r )
8864 {
8865 return(K053252_regs[offset]);
8866 }
8867
WRITE16_HANDLER(K053252_word_w)8868 WRITE16_HANDLER( K053252_word_w )
8869 {
8870 COMBINE_DATA(K053252_regs + offset);
8871 }
8872
WRITE32_HANDLER(K053252_long_w)8873 WRITE32_HANDLER( K053252_long_w )
8874 {
8875 offset <<= 1;
8876 K053252_word_w(offset, data>>16, mem_mask>>16);
8877 K053252_word_w(offset+1, data, mem_mask);
8878 }
8879
8880
8881
8882 /* debug handlers*/
READ16_HANDLER(K054157_word_r)8883 READ16_HANDLER( K054157_word_r ) { return(K054157_regs[offset]); } /* VACSET (legacy)*/
READ16_HANDLER(K056832_word_r)8884 READ16_HANDLER( K056832_word_r ) { return(K056832_regs[offset]); } /* VACSET*/
READ16_HANDLER(K056832_b_word_r)8885 READ16_HANDLER( K056832_b_word_r ) { return(K056832_regsb[offset]); } /* VSCCS (board dependent)*/
READ16_HANDLER(K053246_reg_word_r)8886 READ16_HANDLER( K053246_reg_word_r ) { return(K053246_regs[offset*2]<<8|K053246_regs[offset*2+1]); } /* OBJSET1*/
READ16_HANDLER(K053247_reg_word_r)8887 READ16_HANDLER( K053247_reg_word_r ) { return(K053247_regs[offset]); } /* OBJSET2*/
READ16_HANDLER(K054338_word_r)8888 READ16_HANDLER( K054338_word_r ) { return(k54338_regs[offset]); } /* CLTC*/
READ16_HANDLER(K053251_lsb_r)8889 READ16_HANDLER( K053251_lsb_r ) { return(K053251_ram[offset]); } /* PCU1*/
READ16_HANDLER(K053251_msb_r)8890 READ16_HANDLER( K053251_msb_r ) { return(K053251_ram[offset]<<8); } /* PCU1*/
READ16_HANDLER(K055555_word_r)8891 READ16_HANDLER( K055555_word_r ) { return(k55555_regs[offset]<<8); } /* PCU2*/
8892
READ32_HANDLER(K056832_long_r)8893 READ32_HANDLER( K056832_long_r )
8894 {
8895 offset <<= 1;
8896 return (K056832_word_r(offset+1, 0xffff) | K056832_word_r(offset, 0xffff)<<16);
8897 }
8898
READ32_HANDLER(K053247_reg_long_r)8899 READ32_HANDLER( K053247_reg_long_r )
8900 {
8901 offset <<= 1;
8902 return (K053247_reg_word_r(offset+1, 0xffff) | K053247_reg_word_r(offset, 0xffff)<<16);
8903 }
8904
READ32_HANDLER(K055555_long_r)8905 READ32_HANDLER( K055555_long_r )
8906 {
8907 offset <<= 1;
8908 return (K055555_word_r(offset+1, 0xffff) | K055555_word_r(offset, 0xffff)<<16);
8909 }
8910
READ16_HANDLER(K053244_reg_word_r)8911 READ16_HANDLER( K053244_reg_word_r ) { return(K053244_regs[0][offset*2]<<8|K053244_regs[0][offset*2+1]); }
8912