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 054906 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 /* helper function to join four 16-bit ROMs and form a 64-bit data stream */
konami_rom_deinterleave_4(int mem_region)1192 void konami_rom_deinterleave_4(int mem_region)
1193 {
1194 konami_rom_deinterleave_2(mem_region);
1195 konami_rom_deinterleave_2(mem_region);
1196 }
1197
1198
1199
1200
1201
1202
1203 /***************************************************************************/
1204 /* */
1205 /* 007121 */
1206 /* */
1207 /***************************************************************************/
1208
1209 /*static*/ unsigned char K007121_ctrlram[MAX_K007121][8];
1210 /*static*/ int K007121_flipscreen[MAX_K007121];
1211
1212
K007121_ctrl_w(int chip,int offset,int data)1213 void K007121_ctrl_w(int chip,int offset,int data)
1214 {
1215 switch (offset)
1216 {
1217 case 6:
1218 /* palette bank change */
1219 if ((K007121_ctrlram[chip][offset] & 0x30) != (data & 0x30))
1220 tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
1221 break;
1222 case 7:
1223 K007121_flipscreen[chip] = data & 0x08;
1224 break;
1225 }
1226
1227 K007121_ctrlram[chip][offset] = data;
1228 }
1229
WRITE_HANDLER(K007121_ctrl_0_w)1230 WRITE_HANDLER( K007121_ctrl_0_w )
1231 {
1232 K007121_ctrl_w(0,offset,data);
1233 }
1234
WRITE_HANDLER(K007121_ctrl_1_w)1235 WRITE_HANDLER( K007121_ctrl_1_w )
1236 {
1237 K007121_ctrl_w(1,offset,data);
1238 }
1239
1240
1241 /*
1242 * Sprite Format
1243 * ------------------
1244 *
1245 * There are 0x40 sprites, each one using 5 bytes. However the number of
1246 * sprites can be increased to 0x80 with a control register (Combat School
1247 * sets it on and off during the game).
1248 *
1249 * Byte | Bit(s) | Use
1250 * -----+-76543210-+----------------
1251 * 0 | xxxxxxxx | sprite code
1252 * 1 | xxxx---- | color
1253 * 1 | ----xx-- | sprite code low 2 bits for 16x8/8x8 sprites
1254 * 1 | ------xx | sprite code bank bits 1/0
1255 * 2 | xxxxxxxx | y position
1256 * 3 | xxxxxxxx | x position (low 8 bits)
1257 * 4 | xx------ | sprite code bank bits 3/2
1258 * 4 | --x----- | flip y
1259 * 4 | ---x---- | flip x
1260 * 4 | ----xxx- | sprite size 000=16x16 001=16x8 010=8x16 011=8x8 100=32x32
1261 * 4 | -------x | x position (high bit)
1262 *
1263 * Flack Attack uses a different, "wider" layout with 32 bytes per sprite,
1264 * mapped as follows, and the priority order is reversed. Maybe it is a
1265 * compatibility mode with an older custom IC. It is not known how this
1266 * alternate layout is selected.
1267 *
1268 * 0 -> e
1269 * 1 -> f
1270 * 2 -> 6
1271 * 3 -> 4
1272 * 4 -> 8
1273 *
1274 */
1275
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)1276 void K007121_sprites_draw(int chip,struct mame_bitmap *bitmap,const struct rectangle *cliprect,
1277 const unsigned char *source,int base_color,int global_x_offset,int bank_base,
1278 UINT32 pri_mask)
1279 {
1280 const struct GfxElement *gfx = Machine->gfx[chip];
1281 int flipscreen = K007121_flipscreen[chip];
1282 int i,num,inc,offs[5],trans;
1283 int is_flakatck = K007121_ctrlram[chip][0x06] & 0x04; /* WRONG!!!! */
1284
1285 #if 0
1286 usrintf_showmessage("%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
1287 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],
1288 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]);
1289
1290 if (keyboard_pressed(KEYCODE_D))
1291 {
1292 FILE *fp;
1293 fp=fopen(chip?"SPRITE1.DMP":"SPRITE0.DMP", "w+b");
1294 if (fp)
1295 {
1296 fwrite(source, 0x800, 1, fp);
1297 usrintf_showmessage("saved");
1298 fclose(fp);
1299 }
1300 }
1301 #endif
1302
1303 if (is_flakatck)
1304 {
1305 num = 0x40;
1306 inc = -0x20;
1307 source += 0x3f*0x20;
1308 offs[0] = 0x0e;
1309 offs[1] = 0x0f;
1310 offs[2] = 0x06;
1311 offs[3] = 0x04;
1312 offs[4] = 0x08;
1313 /* Flak Attack doesn't use a lookup PROM, it maps the color code directly */
1314 /* to a palette entry */
1315 trans = TRANSPARENCY_PEN;
1316 }
1317 else /* all others */
1318 {
1319 //num = (K007121_ctrlram[chip][0x03] & 0x40) ? 0x80 : 0x40; /* WRONG!!! (needed by combasc) */
1320 num = 0x40; // Combasc writes 70 sprites to VRAM at peak but the chip only processes the first 64.
1321
1322 inc = 5;
1323 offs[0] = 0x00;
1324 offs[1] = 0x01;
1325 offs[2] = 0x02;
1326 offs[3] = 0x03;
1327 offs[4] = 0x04;
1328 trans = TRANSPARENCY_COLOR;
1329 /* when using priority buffer, draw front to back */
1330 if (pri_mask != -1)
1331 {
1332 source += (num-1)*inc;
1333 inc = -inc;
1334 }
1335 }
1336
1337 for (i = 0;i < num;i++)
1338 {
1339 int number = source[offs[0]]; /* sprite number */
1340 int sprite_bank = source[offs[1]] & 0x0f; /* sprite bank */
1341 int sx = source[offs[3]]; /* vertical position */
1342 int sy = source[offs[2]]; /* horizontal position */
1343 int attr = source[offs[4]]; /* attributes */
1344 int xflip = source[offs[4]] & 0x10; /* flip x */
1345 int yflip = source[offs[4]] & 0x20; /* flip y */
1346 int color = base_color + ((source[offs[1]] & 0xf0) >> 4);
1347 int width,height;
1348 static int x_offset[4] = {0x0,0x1,0x4,0x5};
1349 static int y_offset[4] = {0x0,0x2,0x8,0xa};
1350 int x,y, ex, ey;
1351
1352 if (attr & 0x01) sx -= 256;
1353 if (sy >= 240) sy -= 256;
1354
1355 number += ((sprite_bank & 0x3) << 8) + ((attr & 0xc0) << 4);
1356 number = number << 2;
1357 number += (sprite_bank >> 2) & 3;
1358
1359 if (!is_flakatck || source[0x00]) /* Flak Attack needs this */
1360 {
1361 number += bank_base;
1362
1363 switch( attr&0xe )
1364 {
1365 case 0x06: width = height = 1; break;
1366 case 0x04: width = 1; height = 2; number &= (~2); break;
1367 case 0x02: width = 2; height = 1; number &= (~1); break;
1368 case 0x00: width = height = 2; number &= (~3); break;
1369 case 0x08: width = height = 4; number &= (~3); break;
1370 default: width = 1; height = 1;
1371 // logerror("Unknown sprite size %02x\n",attr&0xe);
1372 // usrintf_showmessage("Unknown sprite size %02x\n",attr&0xe);
1373 }
1374
1375 for (y = 0;y < height;y++)
1376 {
1377 for (x = 0;x < width;x++)
1378 {
1379 ex = xflip ? (width-1-x) : x;
1380 ey = yflip ? (height-1-y) : y;
1381
1382 if (flipscreen)
1383 {
1384 if (pri_mask != -1)
1385 pdrawgfx(bitmap,gfx,
1386 number + x_offset[ex] + y_offset[ey],
1387 color,
1388 !xflip,!yflip,
1389 248-(sx+x*8),248-(sy+y*8),
1390 cliprect,trans,0,
1391 pri_mask);
1392 else
1393 drawgfx(bitmap,gfx,
1394 number + x_offset[ex] + y_offset[ey],
1395 color,
1396 !xflip,!yflip,
1397 248-(sx+x*8),248-(sy+y*8),
1398 cliprect,trans,0);
1399 }
1400 else
1401 {
1402 if (pri_mask != -1)
1403 pdrawgfx(bitmap,gfx,
1404 number + x_offset[ex] + y_offset[ey],
1405 color,
1406 xflip,yflip,
1407 global_x_offset+sx+x*8,sy+y*8,
1408 cliprect,trans,0,
1409 pri_mask);
1410 else
1411 drawgfx(bitmap,gfx,
1412 number + x_offset[ex] + y_offset[ey],
1413 color,
1414 xflip,yflip,
1415 global_x_offset+sx+x*8,sy+y*8,
1416 cliprect,trans,0);
1417 }
1418 }
1419 }
1420 }
1421
1422 source += inc;
1423 }
1424 }
1425
1426
1427
1428 /***************************************************************************/
1429 /* */
1430 /* 007342 */
1431 /* */
1432 /***************************************************************************/
1433
1434 static unsigned char *K007342_ram,*K007342_scroll_ram;
1435 static int K007342_gfxnum;
1436 static int K007342_int_enabled;
1437 static int K007342_flipscreen;
1438 static int K007342_scrollx[2];
1439 static int K007342_scrolly[2];
1440 static unsigned char *K007342_videoram_0,*K007342_colorram_0;
1441 static unsigned char *K007342_videoram_1,*K007342_colorram_1;
1442 static int K007342_regs[8];
1443 static void (*K007342_callback)(int tilemap, int bank, int *code, int *color);
1444 static struct tilemap *K007342_tilemap[2];
1445
1446 /***************************************************************************
1447
1448 Callbacks for the TileMap code
1449
1450 ***************************************************************************/
1451
1452 /*
1453 data format:
1454 video RAM xxxxxxxx tile number (bits 0-7)
1455 color RAM x------- tiles with priority over the sprites
1456 color RAM -x------ depends on external conections
1457 color RAM --x----- flip Y
1458 color RAM ---x---- flip X
1459 color RAM ----xxxx depends on external connections (usually color and banking)
1460 */
1461
K007342_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)1462 static UINT32 K007342_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)
1463 {
1464 /* logical (col,row) -> memory offset */
1465 return (col & 0x1f) + ((row & 0x1f) << 5) + ((col & 0x20) << 5);
1466 }
1467
K007342_get_tile_info(int tile_index,int layer,data8_t * cram,data8_t * vram)1468 static INLINE void K007342_get_tile_info(int tile_index,int layer,data8_t *cram,data8_t *vram)
1469 {
1470 int color, code;
1471
1472 color = cram[tile_index];
1473 code = vram[tile_index];
1474
1475 tile_info.flags = TILE_FLIPYX((color & 0x30) >> 4);
1476 tile_info.priority = (color & 0x80) >> 7;
1477
1478 (*K007342_callback)(layer, K007342_regs[1], &code, &color);
1479
1480 SET_TILE_INFO(
1481 K007342_gfxnum,
1482 code,
1483 color,
1484 tile_info.flags)
1485 }
1486
K007342_get_tile_info0(int tile_index)1487 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)1488 static void K007342_get_tile_info1(int tile_index) { K007342_get_tile_info(tile_index,1,K007342_colorram_1,K007342_videoram_1); }
1489
1490
1491
K007342_vh_start(int gfx_index,void (* callback)(int tilemap,int bank,int * code,int * color))1492 int K007342_vh_start(int gfx_index, void (*callback)(int tilemap, int bank, int *code, int *color))
1493 {
1494 K007342_gfxnum = gfx_index;
1495 K007342_callback = callback;
1496
1497 K007342_tilemap[0] = tilemap_create(K007342_get_tile_info0,K007342_scan,TILEMAP_TRANSPARENT,8,8,64,32);
1498 K007342_tilemap[1] = tilemap_create(K007342_get_tile_info1,K007342_scan,TILEMAP_TRANSPARENT,8,8,64,32);
1499
1500 K007342_ram = auto_malloc(0x2000);
1501 K007342_scroll_ram = auto_malloc(0x0200);
1502
1503 if (!K007342_ram || !K007342_scroll_ram || !K007342_tilemap[0] || !K007342_tilemap[1])
1504 return 1;
1505
1506 memset(K007342_ram,0,0x2000);
1507
1508 K007342_colorram_0 = &K007342_ram[0x0000];
1509 K007342_colorram_1 = &K007342_ram[0x1000];
1510 K007342_videoram_0 = &K007342_ram[0x0800];
1511 K007342_videoram_1 = &K007342_ram[0x1800];
1512
1513 tilemap_set_transparent_pen(K007342_tilemap[0],0);
1514 tilemap_set_transparent_pen(K007342_tilemap[1],0);
1515
1516 return 0;
1517 }
1518
READ_HANDLER(K007342_r)1519 READ_HANDLER( K007342_r )
1520 {
1521 return K007342_ram[offset];
1522 }
1523
WRITE_HANDLER(K007342_w)1524 WRITE_HANDLER( K007342_w )
1525 {
1526 if (offset < 0x1000)
1527 { /* layer 0 */
1528 if (K007342_ram[offset] != data)
1529 {
1530 K007342_ram[offset] = data;
1531 tilemap_mark_tile_dirty(K007342_tilemap[0],offset & 0x7ff);
1532 }
1533 }
1534 else
1535 { /* layer 1 */
1536 if (K007342_ram[offset] != data)
1537 {
1538 K007342_ram[offset] = data;
1539 tilemap_mark_tile_dirty(K007342_tilemap[1],offset & 0x7ff);
1540 }
1541 }
1542 }
1543
READ_HANDLER(K007342_scroll_r)1544 READ_HANDLER( K007342_scroll_r )
1545 {
1546 return K007342_scroll_ram[offset];
1547 }
1548
WRITE_HANDLER(K007342_scroll_w)1549 WRITE_HANDLER( K007342_scroll_w )
1550 {
1551 K007342_scroll_ram[offset] = data;
1552 }
1553
WRITE_HANDLER(K007342_vreg_w)1554 WRITE_HANDLER( K007342_vreg_w )
1555 {
1556 switch(offset)
1557 {
1558 case 0x00:
1559 /* bit 1: INT control */
1560 K007342_int_enabled = data & 0x02;
1561 K007342_flipscreen = data & 0x10;
1562 tilemap_set_flip(K007342_tilemap[0],K007342_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
1563 tilemap_set_flip(K007342_tilemap[1],K007342_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
1564 break;
1565 case 0x01: /* used for banking in Rock'n'Rage */
1566 if (data != K007342_regs[1])
1567 tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
1568 case 0x02:
1569 K007342_scrollx[0] = (K007342_scrollx[0] & 0xff) | ((data & 0x01) << 8);
1570 K007342_scrollx[1] = (K007342_scrollx[1] & 0xff) | ((data & 0x02) << 7);
1571 break;
1572 case 0x03: /* scroll x (register 0) */
1573 K007342_scrollx[0] = (K007342_scrollx[0] & 0x100) | data;
1574 break;
1575 case 0x04: /* scroll y (register 0) */
1576 K007342_scrolly[0] = data;
1577 break;
1578 case 0x05: /* scroll x (register 1) */
1579 K007342_scrollx[1] = (K007342_scrollx[1] & 0x100) | data;
1580 break;
1581 case 0x06: /* scroll y (register 1) */
1582 K007342_scrolly[1] = data;
1583 case 0x07: /* unused */
1584 break;
1585 }
1586 K007342_regs[offset] = data;
1587 }
1588
K007342_tilemap_update(void)1589 void K007342_tilemap_update(void)
1590 {
1591 int offs;
1592
1593
1594 /* update scroll */
1595 switch (K007342_regs[2] & 0x1c)
1596 {
1597 case 0x00:
1598 case 0x08: /* unknown, blades of steel shootout between periods */
1599 tilemap_set_scroll_rows(K007342_tilemap[0],1);
1600 tilemap_set_scroll_cols(K007342_tilemap[0],1);
1601 tilemap_set_scrollx(K007342_tilemap[0],0,K007342_scrollx[0]);
1602 tilemap_set_scrolly(K007342_tilemap[0],0,K007342_scrolly[0]);
1603 break;
1604
1605 case 0x0c: /* 32 columns */
1606 tilemap_set_scroll_rows(K007342_tilemap[0],1);
1607 tilemap_set_scroll_cols(K007342_tilemap[0],512);
1608 tilemap_set_scrollx(K007342_tilemap[0],0,K007342_scrollx[0]);
1609 for (offs = 0;offs < 256;offs++)
1610 tilemap_set_scrolly(K007342_tilemap[0],(offs + K007342_scrollx[0]) & 0x1ff,
1611 K007342_scroll_ram[2*(offs/8)] + 256 * K007342_scroll_ram[2*(offs/8)+1]);
1612 break;
1613
1614 case 0x14: /* 256 rows */
1615 tilemap_set_scroll_rows(K007342_tilemap[0],256);
1616 tilemap_set_scroll_cols(K007342_tilemap[0],1);
1617 tilemap_set_scrolly(K007342_tilemap[0],0,K007342_scrolly[0]);
1618 for (offs = 0;offs < 256;offs++)
1619 tilemap_set_scrollx(K007342_tilemap[0],(offs + K007342_scrolly[0]) & 0xff,
1620 K007342_scroll_ram[2*offs] + 256 * K007342_scroll_ram[2*offs+1]);
1621 break;
1622
1623 default:
1624 // usrintf_showmessage("unknown scroll ctrl %02x",K007342_regs[2] & 0x1c);
1625 break;
1626 }
1627
1628 tilemap_set_scrollx(K007342_tilemap[1],0,K007342_scrollx[1]);
1629 tilemap_set_scrolly(K007342_tilemap[1],0,K007342_scrolly[1]);
1630
1631 #if 0
1632 {
1633 static int current_layer = 0;
1634
1635 if (keyboard_pressed_memory(KEYCODE_Z)) current_layer = !current_layer;
1636 tilemap_set_enable(K007342_tilemap[current_layer], 1);
1637 tilemap_set_enable(K007342_tilemap[!current_layer], 0);
1638
1639 usrintf_showmessage("regs:%02x %02x %02x %02x-%02x %02x %02x %02x:%02x",
1640 K007342_regs[0], K007342_regs[1], K007342_regs[2], K007342_regs[3],
1641 K007342_regs[4], K007342_regs[5], K007342_regs[6], K007342_regs[7],
1642 current_layer);
1643 }
1644 #endif
1645 }
1646
K007342_tilemap_set_enable(int tilemap,int enable)1647 void K007342_tilemap_set_enable(int tilemap, int enable)
1648 {
1649 tilemap_set_enable(K007342_tilemap[tilemap], enable);
1650 }
1651
K007342_tilemap_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int num,int flags,UINT32 priority)1652 void K007342_tilemap_draw(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int num,int flags,UINT32 priority)
1653 {
1654 tilemap_draw(bitmap,cliprect,K007342_tilemap[num],flags,priority);
1655 }
1656
K007342_is_INT_enabled(void)1657 int K007342_is_INT_enabled(void)
1658 {
1659 return K007342_int_enabled;
1660 }
1661
1662
1663
1664 /***************************************************************************/
1665 /* */
1666 /* 007420 */
1667 /* */
1668 /***************************************************************************/
1669
1670 static struct GfxElement *K007420_gfx;
1671 static void (*K007420_callback)(int *code,int *color);
1672 static unsigned char *K007420_ram;
1673 static int K007420_banklimit;
1674
K007420_vh_start(int gfxnum,void (* callback)(int * code,int * color))1675 int K007420_vh_start(int gfxnum, void (*callback)(int *code,int *color))
1676 {
1677 K007420_gfx = Machine->gfx[gfxnum];
1678 K007420_callback = callback;
1679 K007420_ram = auto_malloc(0x200);
1680 if (!K007420_ram) return 1;
1681
1682 memset(K007420_ram,0,0x200);
1683
1684 K007420_banklimit = -1;
1685
1686 return 0;
1687 }
1688
READ_HANDLER(K007420_r)1689 READ_HANDLER( K007420_r )
1690 {
1691 return K007420_ram[offset];
1692 }
1693
WRITE_HANDLER(K007420_w)1694 WRITE_HANDLER( K007420_w )
1695 {
1696 K007420_ram[offset] = data;
1697 }
1698
1699 /*
1700 * Sprite Format
1701 * ------------------
1702 *
1703 * Byte | Bit(s) | Use
1704 * -----+-76543210-+----------------
1705 * 0 | xxxxxxxx | y position
1706 * 1 | xxxxxxxx | sprite code (low 8 bits)
1707 * 2 | xxxxxxxx | depends on external conections. Usually banking
1708 * 3 | xxxxxxxx | x position (low 8 bits)
1709 * 4 | x------- | x position (high bit)
1710 * 4 | -xxx---- | sprite size 000=16x16 001=8x16 010=16x8 011=8x8 100=32x32
1711 * 4 | ----x--- | flip y
1712 * 4 | -----x-- | flip x
1713 * 4 | ------xx | zoom (bits 8 & 9)
1714 * 5 | xxxxxxxx | zoom (low 8 bits) 0x080 = normal, < 0x80 enlarge, > 0x80 reduce
1715 * 6 | xxxxxxxx | unused
1716 * 7 | xxxxxxxx | unused
1717 */
1718
K007420_sprites_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect)1719 void K007420_sprites_draw(struct mame_bitmap *bitmap,const struct rectangle *cliprect)
1720 {
1721 #define K007420_SPRITERAM_SIZE 0x200
1722 int offs;
1723 int codemask = K007420_banklimit;
1724 int bankmask = ~K007420_banklimit;
1725
1726 for (offs = K007420_SPRITERAM_SIZE - 8; offs >= 0; offs -= 8)
1727 {
1728 int ox,oy,code,color,flipx,flipy,zoom,w,h,x,y,bank;
1729 static int xoffset[4] = { 0, 1, 4, 5 };
1730 static int yoffset[4] = { 0, 2, 8, 10 };
1731
1732 code = K007420_ram[offs+1];
1733 color = K007420_ram[offs+2];
1734 ox = K007420_ram[offs+3] - ((K007420_ram[offs+4] & 0x80) << 1);
1735 oy = 256 - K007420_ram[offs+0];
1736 flipx = K007420_ram[offs+4] & 0x04;
1737 flipy = K007420_ram[offs+4] & 0x08;
1738
1739 (*K007420_callback)(&code,&color);
1740
1741 bank = code & bankmask;
1742 code &= codemask;
1743
1744 /* 0x080 = normal scale, 0x040 = double size, 0x100 half size */
1745 zoom = K007420_ram[offs+5] | ((K007420_ram[offs+4] & 0x03) << 8);
1746 if (!zoom) continue;
1747 zoom = 0x10000 * 128 / zoom;
1748
1749 switch (K007420_ram[offs+4] & 0x70)
1750 {
1751 case 0x30: w = h = 1; break;
1752 case 0x20: w = 2; h = 1; code &= (~1); break;
1753 case 0x10: w = 1; h = 2; code &= (~2); break;
1754 case 0x00: w = h = 2; code &= (~3); break;
1755 case 0x40: w = h = 4; code &= (~3); break;
1756 default: w = 1; h = 1;
1757 //logerror("Unknown sprite size %02x\n",(K007420_ram[offs+4] & 0x70)>>4);
1758 }
1759
1760 if (K007342_flipscreen)
1761 {
1762 ox = 256 - ox - ((zoom * w + (1<<12)) >> 13);
1763 oy = 256 - oy - ((zoom * h + (1<<12)) >> 13);
1764 flipx = !flipx;
1765 flipy = !flipy;
1766 }
1767
1768 if (zoom == 0x10000)
1769 {
1770 int sx,sy;
1771
1772 for (y = 0;y < h;y++)
1773 {
1774 sy = oy + 8 * y;
1775
1776 for (x = 0;x < w;x++)
1777 {
1778 int c = code;
1779
1780 sx = ox + 8 * x;
1781 if (flipx) c += xoffset[(w-1-x)];
1782 else c += xoffset[x];
1783 if (flipy) c += yoffset[(h-1-y)];
1784 else c += yoffset[y];
1785
1786 if (c & bankmask) continue; else c += bank;
1787
1788 drawgfx(bitmap,K007420_gfx,
1789 c,
1790 color,
1791 flipx,flipy,
1792 sx,sy,
1793 cliprect,TRANSPARENCY_PEN,0);
1794
1795 if (K007342_regs[2] & 0x80)
1796 drawgfx(bitmap,K007420_gfx,
1797 c,
1798 color,
1799 flipx,flipy,
1800 sx,sy-256,
1801 cliprect,TRANSPARENCY_PEN,0);
1802 }
1803 }
1804 }
1805 else
1806 {
1807 int sx,sy,zw,zh;
1808 for (y = 0;y < h;y++)
1809 {
1810 sy = oy + ((zoom * y + (1<<12)) >> 13);
1811 zh = (oy + ((zoom * (y+1) + (1<<12)) >> 13)) - sy;
1812
1813 for (x = 0;x < w;x++)
1814 {
1815 int c = code;
1816
1817 sx = ox + ((zoom * x + (1<<12)) >> 13);
1818 zw = (ox + ((zoom * (x+1) + (1<<12)) >> 13)) - sx;
1819 if (flipx) c += xoffset[(w-1-x)];
1820 else c += xoffset[x];
1821 if (flipy) c += yoffset[(h-1-y)];
1822 else c += yoffset[y];
1823
1824 if (c & bankmask) continue; else c += bank;
1825
1826 drawgfxzoom(bitmap,K007420_gfx,
1827 c,
1828 color,
1829 flipx,flipy,
1830 sx,sy,
1831 cliprect,TRANSPARENCY_PEN,0,
1832 (zw << 16) / 8,(zh << 16) / 8);
1833
1834 if (K007342_regs[2] & 0x80)
1835 drawgfxzoom(bitmap,K007420_gfx,
1836 c,
1837 color,
1838 flipx,flipy,
1839 sx,sy-256,
1840 cliprect,TRANSPARENCY_PEN,0,
1841 (zw << 16) / 8,(zh << 16) / 8);
1842 }
1843 }
1844 }
1845 }
1846 #if 0
1847 {
1848 static int current_sprite = 0;
1849
1850 if (keyboard_pressed_memory(KEYCODE_Z)) current_sprite = (current_sprite+1) & ((K007420_SPRITERAM_SIZE/8)-1);
1851 if (keyboard_pressed_memory(KEYCODE_X)) current_sprite = (current_sprite-1) & ((K007420_SPRITERAM_SIZE/8)-1);
1852
1853 usrintf_showmessage("%02x:%02x %02x %02x %02x %02x %02x %02x %02x", current_sprite,
1854 K007420_ram[(current_sprite*8)+0], K007420_ram[(current_sprite*8)+1],
1855 K007420_ram[(current_sprite*8)+2], K007420_ram[(current_sprite*8)+3],
1856 K007420_ram[(current_sprite*8)+4], K007420_ram[(current_sprite*8)+5],
1857 K007420_ram[(current_sprite*8)+6], K007420_ram[(current_sprite*8)+7]);
1858 }
1859 #endif
1860 }
1861
K007420_set_banklimit(int limit)1862 void K007420_set_banklimit(int limit)
1863 {
1864 K007420_banklimit = limit;
1865 }
1866
1867
1868
1869 /***************************************************************************/
1870 /* */
1871 /* 052109 */
1872 /* */
1873 /***************************************************************************/
1874
1875 static int K052109_memory_region;
1876 static int K052109_gfxnum;
1877 static void (*K052109_callback)(int tilemap,int bank,int *code,int *color);
1878 static unsigned char *K052109_ram;
1879 static unsigned char *K052109_videoram_F,*K052109_videoram2_F,*K052109_colorram_F;
1880 static unsigned char *K052109_videoram_A,*K052109_videoram2_A,*K052109_colorram_A;
1881 static unsigned char *K052109_videoram_B,*K052109_videoram2_B,*K052109_colorram_B;
1882 static unsigned char K052109_charrombank[4];
1883 static int has_extra_video_ram;
1884 static int K052109_RMRD_line;
1885 static int K052109_tileflip_enable;
1886 static int K052109_irq_enabled;
1887 static unsigned char K052109_romsubbank,K052109_scrollctrl;
1888 struct tilemap *K052109_tilemap[3];
1889
1890
1891
1892 /***************************************************************************
1893
1894 Callbacks for the TileMap code
1895
1896 ***************************************************************************/
1897
1898 /*
1899 data format:
1900 video RAM xxxxxxxx tile number (low 8 bits)
1901 color RAM xxxx---- depends on external connections (usually color and banking)
1902 color RAM ----xx-- bank select (0-3): these bits are replaced with the 2
1903 bottom bits of the bank register before being placed on
1904 the output pins. The other two bits of the bank register are
1905 placed on the CAB1 and CAB2 output pins.
1906 color RAM ------xx depends on external connections (usually banking, flip)
1907 */
1908
K052109_get_tile_info(int tile_index,int layer,data8_t * cram,data8_t * vram1,data8_t * vram2)1909 static INLINE void K052109_get_tile_info(int tile_index,int layer,data8_t *cram,data8_t *vram1,data8_t *vram2)
1910 {
1911 int flipy = 0;
1912 int code = vram1[tile_index] + 256 * vram2[tile_index];
1913 int color = cram[tile_index];
1914 int bank = K052109_charrombank[(color & 0x0c) >> 2];
1915 if (has_extra_video_ram) bank = (color & 0x0c) >> 2; /* kludge for X-Men */
1916 color = (color & 0xf3) | ((bank & 0x03) << 2);
1917 bank >>= 2;
1918
1919 flipy = color & 0x02;
1920
1921 tile_info.flags = 0;
1922
1923 (*K052109_callback)(layer,bank,&code,&color);
1924
1925 SET_TILE_INFO(
1926 K052109_gfxnum,
1927 code,
1928 color,
1929 tile_info.flags);
1930
1931 /* if the callback set flip X but it is not enabled, turn it off */
1932 if (!(K052109_tileflip_enable & 1)) tile_info.flags &= ~TILE_FLIPX;
1933
1934 /* if flip Y is enabled and the attribute but is set, turn it on */
1935 if (flipy && (K052109_tileflip_enable & 2)) tile_info.flags |= TILE_FLIPY;
1936 }
1937
K052109_get_tile_info0(int tile_index)1938 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)1939 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)1940 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); }
1941
1942
K052109_tileflip_reset(void)1943 static void K052109_tileflip_reset(void)
1944 {
1945 int data = K052109_ram[0x1e80];
1946 tilemap_set_flip(K052109_tilemap[0],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
1947 tilemap_set_flip(K052109_tilemap[1],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
1948 tilemap_set_flip(K052109_tilemap[2],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
1949 K052109_tileflip_enable = ((data & 0x06) >> 1);
1950 }
1951
1952
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))1953 int K052109_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,
1954 void (*callback)(int tilemap,int bank,int *code,int *color))
1955 {
1956 int gfx_index;
1957 static struct GfxLayout charlayout =
1958 {
1959 8,8,
1960 0, /* filled in later */
1961 4,
1962 { 0, 0, 0, 0 }, /* filled in later */
1963 { 0, 1, 2, 3, 4, 5, 6, 7 },
1964 { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
1965 32*8
1966 };
1967
1968
1969 /* find first empty slot to decode gfx */
1970 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
1971 if (Machine->gfx[gfx_index] == 0)
1972 break;
1973 if (gfx_index == MAX_GFX_ELEMENTS)
1974 return 1;
1975
1976 /* tweak the structure for the number of tiles we have */
1977 charlayout.total = memory_region_length(gfx_memory_region) / 32;
1978 charlayout.planeoffset[0] = plane3 * 8;
1979 charlayout.planeoffset[1] = plane2 * 8;
1980 charlayout.planeoffset[2] = plane1 * 8;
1981 charlayout.planeoffset[3] = plane0 * 8;
1982
1983 /* decode the graphics */
1984 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&charlayout);
1985 if (!Machine->gfx[gfx_index])
1986 return 1;
1987
1988 /* set the color information */
1989 if (Machine->drv->color_table_len)
1990 {
1991 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
1992 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
1993 }
1994 else
1995 {
1996 Machine->gfx[gfx_index]->colortable = Machine->pens;
1997 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / 16;
1998 }
1999
2000 K052109_memory_region = gfx_memory_region;
2001 K052109_gfxnum = gfx_index;
2002 K052109_callback = callback;
2003 K052109_RMRD_line = CLEAR_LINE;
2004 K052109_irq_enabled = 0;
2005
2006 has_extra_video_ram = 0;
2007
2008 K052109_tilemap[0] = tilemap_create(K052109_get_tile_info0,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,64,32);
2009 K052109_tilemap[1] = tilemap_create(K052109_get_tile_info1,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,64,32);
2010 K052109_tilemap[2] = tilemap_create(K052109_get_tile_info2,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,64,32);
2011
2012 K052109_ram = auto_malloc(0x6000);
2013
2014 if (!K052109_ram || !K052109_tilemap[0] || !K052109_tilemap[1] || !K052109_tilemap[2])
2015 return 1;
2016
2017 memset(K052109_ram,0,0x6000);
2018
2019 K052109_colorram_F = &K052109_ram[0x0000];
2020 K052109_colorram_A = &K052109_ram[0x0800];
2021 K052109_colorram_B = &K052109_ram[0x1000];
2022 K052109_videoram_F = &K052109_ram[0x2000];
2023 K052109_videoram_A = &K052109_ram[0x2800];
2024 K052109_videoram_B = &K052109_ram[0x3000];
2025 K052109_videoram2_F = &K052109_ram[0x4000];
2026 K052109_videoram2_A = &K052109_ram[0x4800];
2027 K052109_videoram2_B = &K052109_ram[0x5000];
2028
2029 tilemap_set_transparent_pen(K052109_tilemap[0],0);
2030 tilemap_set_transparent_pen(K052109_tilemap[1],0);
2031 tilemap_set_transparent_pen(K052109_tilemap[2],0);
2032
2033 state_save_register_UINT8("k052109", 0, "ram", K052109_ram, 0x6000);
2034 state_save_register_int ("k052109", 0, "rmrd", &K052109_RMRD_line);
2035 state_save_register_UINT8("k052109", 0, "romsubbank", &K052109_romsubbank, 1);
2036 state_save_register_UINT8("k052109", 0, "scrollctrl", &K052109_scrollctrl, 1);
2037 state_save_register_int ("k052109", 0, "irqen", &K052109_irq_enabled);
2038 state_save_register_UINT8("k052109", 0, "charbank", K052109_charrombank, 4);
2039 state_save_register_int ("k052109", 0, "extra", &has_extra_video_ram);
2040
2041 state_save_register_func_postload(K052109_tileflip_reset);
2042 return 0;
2043 }
2044
2045
2046
READ_HANDLER(K052109_r)2047 READ_HANDLER( K052109_r )
2048 {
2049 if (K052109_RMRD_line == CLEAR_LINE)
2050 {
2051 if ((offset & 0x1fff) >= 0x1800)
2052 {
2053 if (offset >= 0x180c && offset < 0x1834)
2054 { /* A y scroll */ }
2055 else if (offset >= 0x1a00 && offset < 0x1c00)
2056 { /* A x scroll */ }
2057 else if (offset == 0x1d00)
2058 { /* read for bitwise operations before writing */ }
2059 else if (offset >= 0x380c && offset < 0x3834)
2060 { /* B y scroll */ }
2061 else if (offset >= 0x3a00 && offset < 0x3c00)
2062 { /* B x scroll */ }
2063 // else
2064 //logerror("%04x: read from unknown 052109 address %04x\n",activecpu_get_pc(),offset);
2065 }
2066
2067 return K052109_ram[offset];
2068 }
2069 else /* Punk Shot and TMNT read from 0000-1fff, Aliens from 2000-3fff */
2070 {
2071 int code = (offset & 0x1fff) >> 5;
2072 int color = K052109_romsubbank;
2073 int bank = K052109_charrombank[(color & 0x0c) >> 2] >> 2; /* discard low bits (TMNT) */
2074 int addr;
2075
2076 if (has_extra_video_ram) code |= color << 8; /* kludge for X-Men */
2077 else
2078 (*K052109_callback)(0,bank,&code,&color);
2079
2080 addr = (code << 5) + (offset & 0x1f);
2081 addr &= memory_region_length(K052109_memory_region)-1;
2082
2083 // usrintf_showmessage("%04x: off%04x sub%02x (bnk%x) adr%06x",activecpu_get_pc(),offset,K052109_romsubbank,bank,addr);
2084
2085 return memory_region(K052109_memory_region)[addr];
2086 }
2087 }
2088
WRITE_HANDLER(K052109_w)2089 WRITE_HANDLER( K052109_w )
2090 {
2091 if ((offset & 0x1fff) < 0x1800) /* tilemap RAM */
2092 {
2093 if (K052109_ram[offset] != data)
2094 {
2095 if (offset >= 0x4000) has_extra_video_ram = 1; /* kludge for X-Men */
2096 K052109_ram[offset] = data;
2097 tilemap_mark_tile_dirty(K052109_tilemap[(offset & 0x1800) >> 11],offset & 0x7ff);
2098 }
2099 }
2100 else /* control registers */
2101 {
2102 K052109_ram[offset] = data;
2103
2104 if (offset >= 0x180c && offset < 0x1834)
2105 { /* A y scroll */ }
2106 else if (offset >= 0x1a00 && offset < 0x1c00)
2107 { /* A x scroll */ }
2108 else if (offset == 0x1c80)
2109 {
2110 if (K052109_scrollctrl != data)
2111 {
2112 //usrintf_showmessage("scrollcontrol = %02x",data);
2113 //logerror("%04x: rowscrollcontrol = %02x\n",activecpu_get_pc(),data);
2114 K052109_scrollctrl = data;
2115 }
2116 }
2117 else if (offset == 0x1d00)
2118 {
2119 //logerror("%04x: 052109 register 1d00 = %02x\n",activecpu_get_pc(),data);
2120 /* bit 2 = irq enable */
2121 /* the custom chip can also generate NMI and FIRQ, for use with a 6809 */
2122 K052109_irq_enabled = data & 0x04;
2123 }
2124 else if (offset == 0x1d80)
2125 {
2126 int dirty = 0;
2127
2128 if (K052109_charrombank[0] != (data & 0x0f)) dirty |= 1;
2129 if (K052109_charrombank[1] != ((data >> 4) & 0x0f)) dirty |= 2;
2130 if (dirty)
2131 {
2132 int i;
2133
2134 K052109_charrombank[0] = data & 0x0f;
2135 K052109_charrombank[1] = (data >> 4) & 0x0f;
2136
2137 for (i = 0;i < 0x1800;i++)
2138 {
2139 int bank = (K052109_ram[i]&0x0c) >> 2;
2140 if ((bank == 0 && (dirty & 1)) || (bank == 1 && dirty & 2))
2141 {
2142 tilemap_mark_tile_dirty(K052109_tilemap[(i & 0x1800) >> 11],i & 0x7ff);
2143 }
2144 }
2145 }
2146 }
2147 else if (offset == 0x1e00)
2148 {
2149 //logerror("%04x: 052109 register 1e00 = %02x\n",activecpu_get_pc(),data);
2150 K052109_romsubbank = data;
2151 }
2152 else if (offset == 0x1e80)
2153 {
2154 //if ((data & 0xfe)) logerror("%04x: 052109 register 1e80 = %02x\n",activecpu_get_pc(),data);
2155 tilemap_set_flip(K052109_tilemap[0],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
2156 tilemap_set_flip(K052109_tilemap[1],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
2157 tilemap_set_flip(K052109_tilemap[2],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
2158 if (K052109_tileflip_enable != ((data & 0x06) >> 1))
2159 {
2160 K052109_tileflip_enable = ((data & 0x06) >> 1);
2161
2162 tilemap_mark_all_tiles_dirty(K052109_tilemap[0]);
2163 tilemap_mark_all_tiles_dirty(K052109_tilemap[1]);
2164 tilemap_mark_all_tiles_dirty(K052109_tilemap[2]);
2165 }
2166 }
2167 else if (offset == 0x1f00)
2168 {
2169 int dirty = 0;
2170
2171 if (K052109_charrombank[2] != (data & 0x0f)) dirty |= 1;
2172 if (K052109_charrombank[3] != ((data >> 4) & 0x0f)) dirty |= 2;
2173 if (dirty)
2174 {
2175 int i;
2176
2177 K052109_charrombank[2] = data & 0x0f;
2178 K052109_charrombank[3] = (data >> 4) & 0x0f;
2179
2180 for (i = 0;i < 0x1800;i++)
2181 {
2182 int bank = (K052109_ram[i] & 0x0c) >> 2;
2183 if ((bank == 2 && (dirty & 1)) || (bank == 3 && dirty & 2))
2184 tilemap_mark_tile_dirty(K052109_tilemap[(i & 0x1800) >> 11],i & 0x7ff);
2185 }
2186 }
2187 }
2188 else if (offset >= 0x380c && offset < 0x3834)
2189 { /* B y scroll */ }
2190 else if (offset >= 0x3a00 && offset < 0x3c00)
2191 { /* B x scroll */ }
2192 // else
2193 //logerror("%04x: write %02x to unknown 052109 address %04x\n",activecpu_get_pc(),data,offset);
2194 }
2195 }
2196
READ16_HANDLER(K052109_word_r)2197 READ16_HANDLER( K052109_word_r )
2198 {
2199 return K052109_r(offset + 0x2000) | (K052109_r(offset) << 8);
2200 }
2201
WRITE16_HANDLER(K052109_word_w)2202 WRITE16_HANDLER( K052109_word_w )
2203 {
2204 if (ACCESSING_MSB)
2205 K052109_w(offset,(data >> 8) & 0xff);
2206 if (ACCESSING_LSB)
2207 K052109_w(offset + 0x2000,data & 0xff);
2208 }
2209
READ16_HANDLER(K052109_lsb_r)2210 READ16_HANDLER(K052109_lsb_r)
2211 {
2212 return K052109_r(offset);
2213 }
2214
WRITE16_HANDLER(K052109_lsb_w)2215 WRITE16_HANDLER(K052109_lsb_w)
2216 {
2217 if(ACCESSING_LSB)
2218 K052109_w(offset, data & 0xff);
2219 }
2220
K052109_set_RMRD_line(int state)2221 void K052109_set_RMRD_line(int state)
2222 {
2223 K052109_RMRD_line = state;
2224 }
2225
2226
K052109_tilemap_update(void)2227 void K052109_tilemap_update(void)
2228 {
2229 #if 0
2230 {
2231 usrintf_showmessage("%x %x %x %x",
2232 K052109_charrombank[0],
2233 K052109_charrombank[1],
2234 K052109_charrombank[2],
2235 K052109_charrombank[3]);
2236 }
2237 #endif
2238 if ((K052109_scrollctrl & 0x03) == 0x02)
2239 {
2240 int xscroll,yscroll,offs;
2241 unsigned char *scrollram = &K052109_ram[0x1a00];
2242
2243
2244 tilemap_set_scroll_rows(K052109_tilemap[1],256);
2245 tilemap_set_scroll_cols(K052109_tilemap[1],1);
2246 yscroll = K052109_ram[0x180c];
2247 tilemap_set_scrolly(K052109_tilemap[1],0,yscroll);
2248 for (offs = 0;offs < 256;offs++)
2249 {
2250 xscroll = scrollram[2*(offs&0xfff8)+0] + 256 * scrollram[2*(offs&0xfff8)+1];
2251 xscroll -= 6;
2252 tilemap_set_scrollx(K052109_tilemap[1],(offs+yscroll)&0xff,xscroll);
2253 }
2254 }
2255 else if ((K052109_scrollctrl & 0x03) == 0x03)
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);
2265 for (offs = 0;offs < 256;offs++)
2266 {
2267 xscroll = scrollram[2*offs+0] + 256 * scrollram[2*offs+1];
2268 xscroll -= 6;
2269 tilemap_set_scrollx(K052109_tilemap[1],(offs+yscroll)&0xff,xscroll);
2270 }
2271 }
2272 else if ((K052109_scrollctrl & 0x04) == 0x04)
2273 {
2274 int xscroll,yscroll,offs;
2275 unsigned char *scrollram = &K052109_ram[0x1800];
2276
2277
2278 tilemap_set_scroll_rows(K052109_tilemap[1],1);
2279 tilemap_set_scroll_cols(K052109_tilemap[1],512);
2280 xscroll = K052109_ram[0x1a00] + 256 * K052109_ram[0x1a01];
2281 xscroll -= 6;
2282 tilemap_set_scrollx(K052109_tilemap[1],0,xscroll);
2283 for (offs = 0;offs < 512;offs++)
2284 {
2285 yscroll = scrollram[offs/8];
2286 tilemap_set_scrolly(K052109_tilemap[1],(offs+xscroll)&0x1ff,yscroll);
2287 }
2288 }
2289 else
2290 {
2291 int xscroll,yscroll;
2292 unsigned char *scrollram = &K052109_ram[0x1a00];
2293
2294
2295 tilemap_set_scroll_rows(K052109_tilemap[1],1);
2296 tilemap_set_scroll_cols(K052109_tilemap[1],1);
2297 xscroll = scrollram[0] + 256 * scrollram[1];
2298 xscroll -= 6;
2299 yscroll = K052109_ram[0x180c];
2300 tilemap_set_scrollx(K052109_tilemap[1],0,xscroll);
2301 tilemap_set_scrolly(K052109_tilemap[1],0,yscroll);
2302 }
2303
2304 if ((K052109_scrollctrl & 0x18) == 0x10)
2305 {
2306 int xscroll,yscroll,offs;
2307 unsigned char *scrollram = &K052109_ram[0x3a00];
2308
2309
2310 tilemap_set_scroll_rows(K052109_tilemap[2],256);
2311 tilemap_set_scroll_cols(K052109_tilemap[2],1);
2312 yscroll = K052109_ram[0x380c];
2313 tilemap_set_scrolly(K052109_tilemap[2],0,yscroll);
2314 for (offs = 0;offs < 256;offs++)
2315 {
2316 xscroll = scrollram[2*(offs&0xfff8)+0] + 256 * scrollram[2*(offs&0xfff8)+1];
2317 xscroll -= 6;
2318 tilemap_set_scrollx(K052109_tilemap[2],(offs+yscroll)&0xff,xscroll);
2319 }
2320 }
2321 else if ((K052109_scrollctrl & 0x18) == 0x18)
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);
2331 for (offs = 0;offs < 256;offs++)
2332 {
2333 xscroll = scrollram[2*offs+0] + 256 * scrollram[2*offs+1];
2334 xscroll -= 6;
2335 tilemap_set_scrollx(K052109_tilemap[2],(offs+yscroll)&0xff,xscroll);
2336 }
2337 }
2338 else if ((K052109_scrollctrl & 0x20) == 0x20)
2339 {
2340 int xscroll,yscroll,offs;
2341 unsigned char *scrollram = &K052109_ram[0x3800];
2342
2343
2344 tilemap_set_scroll_rows(K052109_tilemap[2],1);
2345 tilemap_set_scroll_cols(K052109_tilemap[2],512);
2346 xscroll = K052109_ram[0x3a00] + 256 * K052109_ram[0x3a01];
2347 xscroll -= 6;
2348 tilemap_set_scrollx(K052109_tilemap[2],0,xscroll);
2349 for (offs = 0;offs < 512;offs++)
2350 {
2351 yscroll = scrollram[offs/8];
2352 tilemap_set_scrolly(K052109_tilemap[2],(offs+xscroll)&0x1ff,yscroll);
2353 }
2354 }
2355 else
2356 {
2357 int xscroll,yscroll;
2358 unsigned char *scrollram = &K052109_ram[0x3a00];
2359
2360
2361 tilemap_set_scroll_rows(K052109_tilemap[2],1);
2362 tilemap_set_scroll_cols(K052109_tilemap[2],1);
2363 xscroll = scrollram[0] + 256 * scrollram[1];
2364 xscroll -= 6;
2365 yscroll = K052109_ram[0x380c];
2366 tilemap_set_scrollx(K052109_tilemap[2],0,xscroll);
2367 tilemap_set_scrolly(K052109_tilemap[2],0,yscroll);
2368 }
2369
2370 #if 0
2371 if ((K052109_scrollctrl & 0x03) == 0x01 ||
2372 (K052109_scrollctrl & 0x18) == 0x08 ||
2373 ((K052109_scrollctrl & 0x04) && (K052109_scrollctrl & 0x03)) ||
2374 ((K052109_scrollctrl & 0x20) && (K052109_scrollctrl & 0x18)) ||
2375 (K052109_scrollctrl & 0xc0) != 0)
2376 usrintf_showmessage("scrollcontrol = %02x",K052109_scrollctrl);
2377
2378 if (keyboard_pressed(KEYCODE_F))
2379 {
2380 FILE *fp;
2381 fp=fopen("TILE.DMP", "w+b");
2382 if (fp)
2383 {
2384 fwrite(K052109_ram, 0x6000, 1, fp);
2385 usrintf_showmessage("saved");
2386 fclose(fp);
2387 }
2388 }
2389 #endif
2390 }
2391
K052109_is_IRQ_enabled(void)2392 int K052109_is_IRQ_enabled(void)
2393 {
2394 return K052109_irq_enabled;
2395 }
2396
2397
2398
2399 /***************************************************************************/
2400 /* */
2401 /* 051960 */
2402 /* */
2403 /***************************************************************************/
2404
2405 static int K051960_memory_region;
2406 static struct GfxElement *K051960_gfx;
2407 static void (*K051960_callback)(int *code,int *color,int *priority,int *shadow);
2408 static int K051960_romoffset;
2409 static int K051960_spriteflip,K051960_readroms;
2410 static unsigned char K051960_spriterombank[3];
2411 static unsigned char *K051960_ram;
2412 static int K051960_irq_enabled, K051960_nmi_enabled;
2413
2414
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))2415 int K051960_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,
2416 void (*callback)(int *code,int *color,int *priority,int *shadow))
2417 {
2418 int gfx_index,i;
2419 static struct GfxLayout spritelayout =
2420 {
2421 16,16,
2422 0, /* filled in later */
2423 4,
2424 { 0, 0, 0, 0 }, /* filled in later */
2425 { 0, 1, 2, 3, 4, 5, 6, 7,
2426 8*32+0, 8*32+1, 8*32+2, 8*32+3, 8*32+4, 8*32+5, 8*32+6, 8*32+7 },
2427 { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32,
2428 16*32, 17*32, 18*32, 19*32, 20*32, 21*32, 22*32, 23*32 },
2429 128*8
2430 };
2431
2432
2433 /* find first empty slot to decode gfx */
2434 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
2435 if (Machine->gfx[gfx_index] == 0)
2436 break;
2437 if (gfx_index == MAX_GFX_ELEMENTS)
2438 return 1;
2439
2440 /* tweak the structure for the number of tiles we have */
2441 spritelayout.total = memory_region_length(gfx_memory_region) / 128;
2442 spritelayout.planeoffset[0] = plane0 * 8;
2443 spritelayout.planeoffset[1] = plane1 * 8;
2444 spritelayout.planeoffset[2] = plane2 * 8;
2445 spritelayout.planeoffset[3] = plane3 * 8;
2446
2447 /* decode the graphics */
2448 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&spritelayout);
2449 if (!Machine->gfx[gfx_index])
2450 return 1;
2451
2452 /* set the color information */
2453 if (Machine->drv->color_table_len)
2454 {
2455 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
2456 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
2457 }
2458 else
2459 {
2460 Machine->gfx[gfx_index]->colortable = Machine->pens;
2461 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / 16;
2462 }
2463
2464 #if VERBOSE
2465 if (!(Machine->drv->video_attributes & VIDEO_HAS_SHADOWS))
2466 usrintf_showmessage("driver should use VIDEO_HAS_SHADOWS");
2467 #endif
2468
2469 /* prepare shadow draw table */
2470 gfx_drawmode_table[0] = DRAWMODE_NONE;
2471 for (i = 1;i < 15;i++)
2472 gfx_drawmode_table[i] = DRAWMODE_SOURCE;
2473 gfx_drawmode_table[15] = DRAWMODE_SHADOW;
2474
2475 K051960_memory_region = gfx_memory_region;
2476 K051960_gfx = Machine->gfx[gfx_index];
2477 K051960_callback = callback;
2478 K051960_ram = auto_malloc(0x400);
2479 if (!K051960_ram) return 1;
2480 memset(K051960_ram,0,0x400);
2481
2482 return 0;
2483 }
2484
2485
K051960_fetchromdata(int byte)2486 static int K051960_fetchromdata(int byte)
2487 {
2488 int code,color,pri,shadow,off1,addr;
2489
2490
2491 addr = K051960_romoffset + (K051960_spriterombank[0] << 8) +
2492 ((K051960_spriterombank[1] & 0x03) << 16);
2493 code = (addr & 0x3ffe0) >> 5;
2494 off1 = addr & 0x1f;
2495 color = ((K051960_spriterombank[1] & 0xfc) >> 2) + ((K051960_spriterombank[2] & 0x03) << 6);
2496 pri = 0;
2497 shadow = color & 0x80;
2498 (*K051960_callback)(&code,&color,&pri,&shadow);
2499
2500 addr = (code << 7) | (off1 << 2) | byte;
2501 addr &= memory_region_length(K051960_memory_region)-1;
2502
2503 // usrintf_showmessage("%04x: addr %06x",activecpu_get_pc(),addr);
2504
2505 return memory_region(K051960_memory_region)[addr];
2506 }
2507
READ_HANDLER(K051960_r)2508 READ_HANDLER( K051960_r )
2509 {
2510 if (K051960_readroms)
2511 {
2512 /* the 051960 remembers the last address read and uses it when reading the sprite ROMs */
2513 K051960_romoffset = (offset & 0x3fc) >> 2;
2514 return K051960_fetchromdata(offset & 3); /* only 88 Games reads the ROMs from here */
2515 }
2516 else
2517 return K051960_ram[offset];
2518 }
2519
WRITE_HANDLER(K051960_w)2520 WRITE_HANDLER( K051960_w )
2521 {
2522 K051960_ram[offset] = data;
2523 }
2524
READ16_HANDLER(K051960_word_r)2525 READ16_HANDLER( K051960_word_r )
2526 {
2527 return K051960_r(offset*2 + 1) | (K051960_r(offset*2) << 8);
2528 }
2529
WRITE16_HANDLER(K051960_word_w)2530 WRITE16_HANDLER( K051960_word_w )
2531 {
2532 if (ACCESSING_MSB)
2533 K051960_w(offset*2,(data >> 8) & 0xff);
2534 if (ACCESSING_LSB)
2535 K051960_w(offset*2 + 1,data & 0xff);
2536 }
2537
READ_HANDLER(K051937_r)2538 READ_HANDLER( K051937_r )
2539 {
2540 if (K051960_readroms && offset >= 4 && offset < 8)
2541 {
2542 return K051960_fetchromdata(offset & 3);
2543 }
2544 else
2545 {
2546 if (offset == 0)
2547 {
2548 static int counter;
2549
2550 /* some games need bit 0 to pulse */
2551 return (counter++) & 1;
2552 }
2553 //logerror("%04x: read unknown 051937 address %x\n",activecpu_get_pc(),offset);
2554 return 0;
2555 }
2556 }
2557
WRITE_HANDLER(K051937_w)2558 WRITE_HANDLER( K051937_w )
2559 {
2560 if (offset == 0)
2561 {
2562
2563 //if (data & 0xc2) usrintf_showmessage("051937 reg 00 = %02x",data);
2564
2565 /* bit 0 is IRQ enable */
2566 K051960_irq_enabled = (data & 0x01);
2567
2568 /* bit 1: probably FIRQ enable */
2569
2570 /* bit 2 is NMI enable */
2571 K051960_nmi_enabled = (data & 0x04);
2572
2573 /* bit 3 = flip screen */
2574 K051960_spriteflip = data & 0x08;
2575
2576 /* bit 4 used by Devastators and TMNT, unknown */
2577
2578 /* bit 5 = enable gfx ROM reading */
2579 K051960_readroms = data & 0x20;
2580 //logerror("%04x: write %02x to 051937 address %x\n",activecpu_get_pc(),data,offset);
2581 }
2582 else if (offset == 1)
2583 {
2584 // usrintf_showmessage("%04x: write %02x to 051937 address %x",activecpu_get_pc(),data,offset);
2585 //logerror("%04x: write %02x to unknown 051937 address %x\n",activecpu_get_pc(),data,offset);
2586 }
2587 else if (offset >= 2 && offset < 5)
2588 {
2589 K051960_spriterombank[offset - 2] = data;
2590 }
2591 else
2592 {
2593 // usrintf_showmessage("%04x: write %02x to 051937 address %x",activecpu_get_pc(),data,offset);
2594 //logerror("%04x: write %02x to unknown 051937 address %x\n",activecpu_get_pc(),data,offset);
2595 }
2596 }
2597
READ16_HANDLER(K051937_word_r)2598 READ16_HANDLER( K051937_word_r )
2599 {
2600 return K051937_r(offset*2 + 1) | (K051937_r(offset*2) << 8);
2601 }
2602
WRITE16_HANDLER(K051937_word_w)2603 WRITE16_HANDLER( K051937_word_w )
2604 {
2605 if (ACCESSING_MSB)
2606 K051937_w(offset*2,(data >> 8) & 0xff);
2607 if (ACCESSING_LSB)
2608 K051937_w(offset*2 + 1,data & 0xff);
2609 }
2610
2611
2612 /*
2613 * Sprite Format
2614 * ------------------
2615 *
2616 * Byte | Bit(s) | Use
2617 * -----+-76543210-+----------------
2618 * 0 | x------- | active (show this sprite)
2619 * 0 | -xxxxxxx | priority order
2620 * 1 | xxx----- | sprite size (see below)
2621 * 1 | ---xxxxx | sprite code (high 5 bits)
2622 * 2 | xxxxxxxx | sprite code (low 8 bits)
2623 * 3 | xxxxxxxx | "color", but depends on external connections (see below)
2624 * 4 | xxxxxx-- | zoom y (0 = normal, >0 = shrink)
2625 * 4 | ------x- | flip y
2626 * 4 | -------x | y position (high bit)
2627 * 5 | xxxxxxxx | y position (low 8 bits)
2628 * 6 | xxxxxx-- | zoom x (0 = normal, >0 = shrink)
2629 * 6 | ------x- | flip x
2630 * 6 | -------x | x position (high bit)
2631 * 7 | xxxxxxxx | x position (low 8 bits)
2632 *
2633 * Example of "color" field for Punk Shot:
2634 * 3 | x------- | shadow
2635 * 3 | -xx----- | priority
2636 * 3 | ---x---- | use second gfx ROM bank
2637 * 3 | ----xxxx | color code
2638 *
2639 * shadow enables transparent shadows. Note that it applies to pen 0x0f ONLY.
2640 * The rest of the sprite remains normal.
2641 * Note that Aliens also uses the shadow bit to select the second sprite bank.
2642 */
2643
K051960_sprites_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int min_priority,int max_priority)2644 void K051960_sprites_draw(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int min_priority,int max_priority)
2645 {
2646 #define NUM_SPRITES 128
2647 int offs,pri_code;
2648 int sortedlist[NUM_SPRITES];
2649
2650 for (offs = 0;offs < NUM_SPRITES;offs++)
2651 sortedlist[offs] = -1;
2652
2653 /* prebuild a sorted table */
2654 for (offs = 0;offs < 0x400;offs += 8)
2655 {
2656 if (K051960_ram[offs] & 0x80)
2657 {
2658 if (max_priority == -1) /* draw front to back when using priority buffer */
2659 sortedlist[(K051960_ram[offs] & 0x7f) ^ 0x7f] = offs;
2660 else
2661 sortedlist[K051960_ram[offs] & 0x7f] = offs;
2662 }
2663 }
2664
2665 for (pri_code = 0;pri_code < NUM_SPRITES;pri_code++)
2666 {
2667 int ox,oy,code,color,pri,shadow,size,w,h,x,y,flipx,flipy,zoomx,zoomy;
2668 /* sprites can be grouped up to 8x8. The draw order is
2669 0 1 4 5 16 17 20 21
2670 2 3 6 7 18 19 22 23
2671 8 9 12 13 24 25 28 29
2672 10 11 14 15 26 27 30 31
2673 32 33 36 37 48 49 52 53
2674 34 35 38 39 50 51 54 55
2675 40 41 44 45 56 57 60 61
2676 42 43 46 47 58 59 62 63
2677 */
2678 static int xoffset[8] = { 0, 1, 4, 5, 16, 17, 20, 21 };
2679 static int yoffset[8] = { 0, 2, 8, 10, 32, 34, 40, 42 };
2680 static int width[8] = { 1, 2, 1, 2, 4, 2, 4, 8 };
2681 static int height[8] = { 1, 1, 2, 2, 2, 4, 4, 8 };
2682
2683
2684 offs = sortedlist[pri_code];
2685 if (offs == -1) continue;
2686
2687 code = K051960_ram[offs+2] + ((K051960_ram[offs+1] & 0x1f) << 8);
2688 color = K051960_ram[offs+3] & 0xff;
2689 pri = 0;
2690 shadow = color & 0x80;
2691 (*K051960_callback)(&code,&color,&pri,&shadow);
2692
2693 if (max_priority != -1)
2694 if (pri < min_priority || pri > max_priority) continue;
2695
2696 size = (K051960_ram[offs+1] & 0xe0) >> 5;
2697 w = width[size];
2698 h = height[size];
2699
2700 if (w >= 2) code &= ~0x01;
2701 if (h >= 2) code &= ~0x02;
2702 if (w >= 4) code &= ~0x04;
2703 if (h >= 4) code &= ~0x08;
2704 if (w >= 8) code &= ~0x10;
2705 if (h >= 8) code &= ~0x20;
2706
2707 ox = (256 * K051960_ram[offs+6] + K051960_ram[offs+7]) & 0x01ff;
2708 oy = 256 - ((256 * K051960_ram[offs+4] + K051960_ram[offs+5]) & 0x01ff);
2709 flipx = K051960_ram[offs+6] & 0x02;
2710 flipy = K051960_ram[offs+4] & 0x02;
2711 zoomx = (K051960_ram[offs+6] & 0xfc) >> 2;
2712 zoomy = (K051960_ram[offs+4] & 0xfc) >> 2;
2713 zoomx = 0x10000 / 128 * (128 - zoomx);
2714 zoomy = 0x10000 / 128 * (128 - zoomy);
2715
2716 if (K051960_spriteflip)
2717 {
2718 ox = 512 - (zoomx * w >> 12) - ox;
2719 oy = 256 - (zoomy * h >> 12) - oy;
2720 flipx = !flipx;
2721 flipy = !flipy;
2722 }
2723
2724 if (zoomx == 0x10000 && zoomy == 0x10000)
2725 {
2726 int sx,sy;
2727
2728 for (y = 0;y < h;y++)
2729 {
2730 sy = oy + 16 * y;
2731
2732 for (x = 0;x < w;x++)
2733 {
2734 int c = code;
2735
2736 sx = ox + 16 * x;
2737 if (flipx) c += xoffset[(w-1-x)];
2738 else c += xoffset[x];
2739 if (flipy) c += yoffset[(h-1-y)];
2740 else c += yoffset[y];
2741
2742 if (max_priority == -1)
2743 pdrawgfx(bitmap,K051960_gfx,
2744 c,
2745 color,
2746 flipx,flipy,
2747 sx & 0x1ff,sy,
2748 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,pri);
2749 else
2750 drawgfx(bitmap,K051960_gfx,
2751 c,
2752 color,
2753 flipx,flipy,
2754 sx & 0x1ff,sy,
2755 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0);
2756 }
2757 }
2758 }
2759 else
2760 {
2761 int sx,sy,zw,zh;
2762
2763 for (y = 0;y < h;y++)
2764 {
2765 sy = oy + ((zoomy * y + (1<<11)) >> 12);
2766 zh = (oy + ((zoomy * (y+1) + (1<<11)) >> 12)) - sy;
2767
2768 for (x = 0;x < w;x++)
2769 {
2770 int c = code;
2771
2772 sx = ox + ((zoomx * x + (1<<11)) >> 12);
2773 zw = (ox + ((zoomx * (x+1) + (1<<11)) >> 12)) - sx;
2774 if (flipx) c += xoffset[(w-1-x)];
2775 else c += xoffset[x];
2776 if (flipy) c += yoffset[(h-1-y)];
2777 else c += yoffset[y];
2778
2779 if (max_priority == -1)
2780 pdrawgfxzoom(bitmap,K051960_gfx,
2781 c,
2782 color,
2783 flipx,flipy,
2784 sx & 0x1ff,sy,
2785 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,
2786 (zw << 16) / 16,(zh << 16) / 16,pri);
2787 else
2788 drawgfxzoom(bitmap,K051960_gfx,
2789 c,
2790 color,
2791 flipx,flipy,
2792 sx & 0x1ff,sy,
2793 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,
2794 (zw << 16) / 16,(zh << 16) / 16);
2795 }
2796 }
2797 }
2798 }
2799 #if 0
2800 if (keyboard_pressed(KEYCODE_D))
2801 {
2802 FILE *fp;
2803 fp=fopen("SPRITE.DMP", "w+b");
2804 if (fp)
2805 {
2806 fwrite(K051960_ram, 0x400, 1, fp);
2807 usrintf_showmessage("saved");
2808 fclose(fp);
2809 }
2810 }
2811 #endif
2812 #undef NUM_SPRITES
2813 }
2814
K051960_is_IRQ_enabled(void)2815 int K051960_is_IRQ_enabled(void)
2816 {
2817 return K051960_irq_enabled;
2818 }
2819
K051960_is_NMI_enabled(void)2820 int K051960_is_NMI_enabled(void)
2821 {
2822 return K051960_nmi_enabled;
2823 }
2824
2825
2826
2827
READ_HANDLER(K052109_051960_r)2828 READ_HANDLER( K052109_051960_r )
2829 {
2830 if (K052109_RMRD_line == CLEAR_LINE)
2831 {
2832 if (offset >= 0x3800 && offset < 0x3808)
2833 return K051937_r(offset - 0x3800);
2834 else if (offset < 0x3c00)
2835 return K052109_r(offset);
2836 else
2837 return K051960_r(offset - 0x3c00);
2838 }
2839 else return K052109_r(offset);
2840 }
2841
WRITE_HANDLER(K052109_051960_w)2842 WRITE_HANDLER( K052109_051960_w )
2843 {
2844 if (offset >= 0x3800 && offset < 0x3808)
2845 K051937_w(offset - 0x3800,data);
2846 else if (offset < 0x3c00)
2847 K052109_w(offset,data);
2848 else
2849 K051960_w(offset - 0x3c00,data);
2850 }
2851
2852
2853
2854 /***************************************************************************/
2855 /* */
2856 /* 05324x Family Sprite Generators */
2857 /* */
2858 /***************************************************************************/
2859
2860 static int K05324x_z_rejection = -1;
2861
2862 /*
2863 In a K053247+K055555 setup objects with Z-code 0x00 should be ignored
2864 when PRFLIP is cleared, while objects with Z-code 0xff should be
2865 ignored when PRFLIP is set.
2866
2867 These behaviors can also be seen in older K053245(6)+K053251 setups.
2868 Bucky'O Hare, The Simpsons and Sunset Riders rely on their implications
2869 to prepare and retire sprites. They probably apply to many other Konami
2870 games but it's hard to tell because most artifacts have been filtered
2871 by exclusion sort.
2872
2873 A driver may call K05324x_set_z_rejection() to set which zcode to ignore.
2874 Parameter:
2875 -1 = accept all(default)
2876 0x00-0xff = zcode to ignore
2877 */
K05324x_set_z_rejection(int zcode)2878 void K05324x_set_z_rejection(int zcode)
2879 {
2880 K05324x_z_rejection = zcode;
2881 }
2882
2883
2884
2885 /***************************************************************************/
2886 /* */
2887 /* 053245 */
2888 /* */
2889 /***************************************************************************/
2890
2891 static int K053245_memory_region=2;
2892 static struct GfxElement *K053245_gfx;
2893 static void (*K053245_callback)(int *code,int *color,int *priority);
2894 static int K053244_rombank;
2895 static int K053245_ramsize;
2896 static data16_t *K053245_ram, *K053245_buffer;
2897 static data8_t K053244_regs[0x10];
2898
K053245_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,void (* callback)(int * code,int * color,int * priority))2899 int K053245_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,
2900 void (*callback)(int *code,int *color,int *priority))
2901 {
2902 int gfx_index,i;
2903 static struct GfxLayout spritelayout =
2904 {
2905 16,16,
2906 0, /* filled in later */
2907 4,
2908 { 0, 0, 0, 0 }, /* filled in later */
2909 { 0, 1, 2, 3, 4, 5, 6, 7,
2910 8*32+0, 8*32+1, 8*32+2, 8*32+3, 8*32+4, 8*32+5, 8*32+6, 8*32+7 },
2911 { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32,
2912 16*32, 17*32, 18*32, 19*32, 20*32, 21*32, 22*32, 23*32 },
2913 128*8
2914 };
2915
2916
2917 /* find first empty slot to decode gfx */
2918 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
2919 if (Machine->gfx[gfx_index] == 0)
2920 break;
2921 if (gfx_index == MAX_GFX_ELEMENTS)
2922 return 1;
2923
2924 /* tweak the structure for the number of tiles we have */
2925 spritelayout.total = memory_region_length(gfx_memory_region) / 128;
2926 spritelayout.planeoffset[0] = plane3 * 8;
2927 spritelayout.planeoffset[1] = plane2 * 8;
2928 spritelayout.planeoffset[2] = plane1 * 8;
2929 spritelayout.planeoffset[3] = plane0 * 8;
2930
2931 /* decode the graphics */
2932 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&spritelayout);
2933 if (!Machine->gfx[gfx_index])
2934 return 1;
2935
2936 /* set the color information */
2937 if (Machine->drv->color_table_len)
2938 {
2939 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
2940 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
2941 }
2942 else
2943 {
2944 Machine->gfx[gfx_index]->colortable = Machine->pens;
2945 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / 16;
2946 }
2947
2948 #if VERBOSE
2949 if (!(Machine->drv->video_attributes & VIDEO_HAS_SHADOWS))
2950 usrintf_showmessage("driver should use VIDEO_HAS_SHADOWS");
2951 #endif
2952
2953 /* prepare shadow draw table */
2954 gfx_drawmode_table[0] = DRAWMODE_NONE;
2955 for (i = 1;i < 15;i++)
2956 gfx_drawmode_table[i] = DRAWMODE_SOURCE;
2957 gfx_drawmode_table[15] = DRAWMODE_SHADOW;
2958 K05324x_z_rejection = -1;
2959 K053245_memory_region = gfx_memory_region;
2960 K053245_gfx = Machine->gfx[gfx_index];
2961 K053245_callback = callback;
2962 K053244_rombank = 0;
2963 K053245_ramsize = 0x800;
2964 K053245_ram = auto_malloc(K053245_ramsize);
2965 if (!K053245_ram) return 1;
2966
2967 K053245_buffer = auto_malloc(K053245_ramsize);
2968 if (!K053245_buffer)
2969 return 1;
2970
2971 memset(K053245_ram,0,K053245_ramsize);
2972 memset(K053245_buffer,0,K053245_ramsize);
2973
2974 return 0;
2975 }
2976
READ16_HANDLER(K053245_word_r)2977 READ16_HANDLER( K053245_word_r )
2978 {
2979 return K053245_ram[offset];
2980 }
2981
WRITE16_HANDLER(K053245_word_w)2982 WRITE16_HANDLER( K053245_word_w )
2983 {
2984 COMBINE_DATA(K053245_ram+offset);
2985 }
2986
READ_HANDLER(K053245_r)2987 READ_HANDLER( K053245_r )
2988 {
2989 if(offset & 1)
2990 return K053245_ram[offset>>1] & 0xff;
2991 else
2992 return (K053245_ram[offset>>1]>>8) & 0xff;
2993 }
2994
WRITE_HANDLER(K053245_w)2995 WRITE_HANDLER( K053245_w )
2996 {
2997 if(offset & 1)
2998 K053245_ram[offset>>1] = (K053245_ram[offset>>1] & 0xff00) | data;
2999 else
3000 K053245_ram[offset>>1] = (K053245_ram[offset>>1] & 0x00ff) | (data<<8);
3001 }
3002
K053245_clear_buffer(void)3003 void K053245_clear_buffer(void)
3004 {
3005 int i, e;
3006 for (e=K053245_ramsize/2, i=0; i<e; i+=8) K053245_buffer[i] = 0;
3007 }
3008
K053245_update_buffer(void)3009 static INLINE void K053245_update_buffer( void )
3010 {
3011 memcpy(K053245_buffer, K053245_ram, K053245_ramsize);
3012 }
3013
READ_HANDLER(K053244_r)3014 READ_HANDLER( K053244_r )
3015 {
3016 if ((K053244_regs[5] & 0x10) && offset >= 0x0c && offset < 0x10)
3017 {
3018 int addr;
3019
3020 addr = (K053244_rombank << 19) | ((K053244_regs[11] & 0x7) << 18)
3021 | (K053244_regs[8] << 10) | (K053244_regs[9] << 2)
3022 | ((offset & 3) ^ 1);
3023 addr &= memory_region_length(K053245_memory_region)-1;
3024
3025 // usrintf_showmessage("%04x: offset %02x addr %06x",activecpu_get_pc(),offset&3,addr);
3026
3027 return memory_region(K053245_memory_region)[addr];
3028 }
3029 else if (offset == 0x06)
3030 {
3031 K053245_update_buffer();
3032 return 0;
3033 }
3034 else
3035 {
3036 //logerror("%04x: read from unknown 053244 address %x\n",activecpu_get_pc(),offset);
3037 return 0;
3038 }
3039 }
3040
WRITE_HANDLER(K053244_w)3041 WRITE_HANDLER( K053244_w )
3042 {
3043 K053244_regs[offset] = data;
3044
3045 switch(offset) {
3046 case 0x05: {
3047 // if (data & 0xc8)
3048 // usrintf_showmessage("053244 reg 05 = %02x",data);
3049 /* bit 2 = unknown, Parodius uses it */
3050 /* bit 5 = unknown, Rollergames uses it */
3051 // logerror("%04x: write %02x to 053244 address 5\n",activecpu_get_pc(),data);
3052 break;
3053 }
3054 case 0x06:
3055 K053245_update_buffer();
3056 break;
3057 }
3058 }
3059
READ16_HANDLER(K053244_lsb_r)3060 READ16_HANDLER( K053244_lsb_r )
3061 {
3062 return K053244_r(offset);
3063 }
3064
WRITE16_HANDLER(K053244_lsb_w)3065 WRITE16_HANDLER( K053244_lsb_w )
3066 {
3067 if (ACCESSING_LSB)
3068 K053244_w(offset, data & 0xff);
3069 }
3070
READ16_HANDLER(K053244_word_r)3071 READ16_HANDLER( K053244_word_r )
3072 {
3073 return (K053244_r(offset*2)<<8)|K053244_r(offset*2+1);
3074 }
3075
WRITE16_HANDLER(K053244_word_w)3076 WRITE16_HANDLER( K053244_word_w )
3077 {
3078 if (ACCESSING_MSB)
3079 K053244_w(offset*2, (data >> 8) & 0xff);
3080 if (ACCESSING_LSB)
3081 K053244_w(offset*2+1, data & 0xff);
3082 }
3083
K053244_bankselect(int bank)3084 void K053244_bankselect(int bank)
3085 {
3086 K053244_rombank = bank;
3087 }
3088
3089 /*
3090 * Sprite Format
3091 * ------------------
3092 *
3093 * Word | Bit(s) | Use
3094 * -----+-fedcba9876543210-+----------------
3095 * 0 | x--------------- | active (show this sprite)
3096 * 0 | -x-------------- | maintain aspect ratio (when set, zoom y acts on both axis)
3097 * 0 | --x------------- | flip y
3098 * 0 | ---x------------ | flip x
3099 * 0 | ----xxxx-------- | sprite size (see below)
3100 * 0 | ---------xxxxxxx | priority order
3101 * 1 | --xxxxxxxxxxxxxx | sprite code. We use an additional bit in TMNT2, but this is
3102 * probably not accurate (protection related so we can't verify)
3103 * 2 | ------xxxxxxxxxx | y position
3104 * 3 | ------xxxxxxxxxx | x position
3105 * 4 | xxxxxxxxxxxxxxxx | zoom y (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
3106 * 5 | xxxxxxxxxxxxxxxx | zoom x (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
3107 * 6 | ------x--------- | mirror y (top half is drawn as mirror image of the bottom)
3108 * 6 | -------x-------- | mirror x (right half is drawn as mirror image of the left)
3109 * 6 | --------x------- | shadow
3110 * 6 | ---------xxxxxxx | "color", but depends on external connections
3111 * 7 | ---------------- |
3112 *
3113 * shadow enables transparent shadows. Note that it applies to pen 0x0f ONLY.
3114 * The rest of the sprite remains normal.
3115 */
3116
K053245_sprites_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect)3117 void K053245_sprites_draw(struct mame_bitmap *bitmap,const struct rectangle *cliprect) //*
3118 {
3119 #define NUM_SPRITES 128
3120 int offs,pri_code,i;
3121 int sortedlist[NUM_SPRITES];
3122 int flipscreenX, flipscreenY, spriteoffsX, spriteoffsY;
3123
3124 flipscreenX = K053244_regs[5] & 0x01;
3125 flipscreenY = K053244_regs[5] & 0x02;
3126 spriteoffsX = (K053244_regs[0] << 8) | K053244_regs[1];
3127 spriteoffsY = (K053244_regs[2] << 8) | K053244_regs[3];
3128
3129 for (offs = 0;offs < NUM_SPRITES;offs++)
3130 sortedlist[offs] = -1;
3131
3132 /* prebuild a sorted table */
3133 for (i=K053245_ramsize/2, offs=0; offs<i; offs+=8)
3134 {
3135 pri_code = K053245_buffer[offs];
3136 if (pri_code & 0x8000)
3137 {
3138 pri_code &= 0x007f;
3139
3140 if (offs && pri_code == K05324x_z_rejection) continue;
3141
3142 if (sortedlist[pri_code] == -1) sortedlist[pri_code] = offs;
3143 }
3144 }
3145
3146 for (pri_code = NUM_SPRITES-1;pri_code >= 0;pri_code--)
3147 {
3148 int ox,oy,color,code,size,w,h,x,y,flipx,flipy,mirrorx,mirrory,shadow,zoomx,zoomy,pri;
3149
3150 offs = sortedlist[pri_code];
3151 if (offs == -1) continue;
3152
3153 /* the following changes the sprite draw order from
3154 0 1 4 5 16 17 20 21
3155 2 3 6 7 18 19 22 23
3156 8 9 12 13 24 25 28 29
3157 10 11 14 15 26 27 30 31
3158 32 33 36 37 48 49 52 53
3159 34 35 38 39 50 51 54 55
3160 40 41 44 45 56 57 60 61
3161 42 43 46 47 58 59 62 63
3162
3163 to
3164
3165 0 1 2 3 4 5 6 7
3166 8 9 10 11 12 13 14 15
3167 16 17 18 19 20 21 22 23
3168 24 25 26 27 28 29 30 31
3169 32 33 34 35 36 37 38 39
3170 40 41 42 43 44 45 46 47
3171 48 49 50 51 52 53 54 55
3172 56 57 58 59 60 61 62 63
3173 */
3174
3175 /* NOTE: from the schematics, it looks like the top 2 bits should be ignored */
3176 /* (there are not output pins for them), and probably taken from the "color" */
3177 /* field to do bank switching. However this applies only to TMNT2, with its */
3178 /* protection mcu creating the sprite table, so we don't know where to fetch */
3179 /* the bits from. */
3180 code = K053245_buffer[offs+1];
3181 code = ((code & 0xffe1) + ((code & 0x0010) >> 2) + ((code & 0x0008) << 1)
3182 + ((code & 0x0004) >> 1) + ((code & 0x0002) << 2));
3183 color = K053245_buffer[offs+6] & 0x00ff;
3184 pri = 0;
3185
3186 (*K053245_callback)(&code,&color,&pri);
3187
3188 size = (K053245_buffer[offs] & 0x0f00) >> 8;
3189
3190 w = 1 << (size & 0x03);
3191 h = 1 << ((size >> 2) & 0x03);
3192
3193 /* zoom control:
3194 0x40 = normal scale
3195 <0x40 enlarge (0x20 = double size)
3196 >0x40 reduce (0x80 = half size)
3197 */
3198 zoomy = K053245_buffer[offs+4];
3199 if (zoomy > 0x2000) continue;
3200 if (zoomy) zoomy = (0x400000+zoomy/2) / zoomy;
3201 else zoomy = 2 * 0x400000;
3202 if ((K053245_buffer[offs] & 0x4000) == 0)
3203 {
3204 zoomx = K053245_buffer[offs+5];
3205 if (zoomx > 0x2000) continue;
3206 if (zoomx) zoomx = (0x400000+zoomx/2) / zoomx;
3207 else zoomx = 2 * 0x400000;
3208 // else zoomx = zoomy; /* workaround for TMNT2 */
3209 }
3210 else zoomx = zoomy;
3211
3212 ox = K053245_buffer[offs+3] + spriteoffsX;
3213 oy = K053245_buffer[offs+2];
3214
3215 flipx = K053245_buffer[offs] & 0x1000;
3216 flipy = K053245_buffer[offs] & 0x2000;
3217 mirrorx = K053245_buffer[offs+6] & 0x0100;
3218 if (mirrorx) flipx = 0; // documented and confirmed
3219 mirrory = K053245_buffer[offs+6] & 0x0200;
3220 shadow = K053245_buffer[offs+6] & 0x0080;
3221
3222 if (flipscreenX)
3223 {
3224 ox = 512 - ox;
3225 if (!mirrorx) flipx = !flipx;
3226 }
3227 if (flipscreenY)
3228 {
3229 oy = -oy;
3230 if (!mirrory) flipy = !flipy;
3231 }
3232
3233 ox = (ox + 0x5d) & 0x3ff;
3234 if (ox >= 768) ox -= 1024;
3235 oy = (-(oy + spriteoffsY + 0x07)) & 0x3ff;
3236 if (oy >= 640) oy -= 1024;
3237
3238 /* the coordinates given are for the *center* of the sprite */
3239 ox -= (zoomx * w) >> 13;
3240 oy -= (zoomy * h) >> 13;
3241
3242 for (y = 0;y < h;y++)
3243 {
3244 int sx,sy,zw,zh;
3245
3246 sy = oy + ((zoomy * y + (1<<11)) >> 12);
3247 zh = (oy + ((zoomy * (y+1) + (1<<11)) >> 12)) - sy;
3248
3249 for (x = 0;x < w;x++)
3250 {
3251 int c,fx,fy;
3252
3253 sx = ox + ((zoomx * x + (1<<11)) >> 12);
3254 zw = (ox + ((zoomx * (x+1) + (1<<11)) >> 12)) - sx;
3255 c = code;
3256 if (mirrorx)
3257 {
3258 if ((flipx == 0) ^ (2*x < w))
3259 {
3260 /* mirror left/right */
3261 c += (w-x-1);
3262 fx = 1;
3263 }
3264 else
3265 {
3266 c += x;
3267 fx = 0;
3268 }
3269 }
3270 else
3271 {
3272 if (flipx) c += w-1-x;
3273 else c += x;
3274 fx = flipx;
3275 }
3276 if (mirrory)
3277 {
3278 if ((flipy == 0) ^ (2*y >= h))
3279 {
3280 /* mirror top/bottom */
3281 c += 8*(h-y-1);
3282 fy = 1;
3283 }
3284 else
3285 {
3286 c += 8*y;
3287 fy = 0;
3288 }
3289 }
3290 else
3291 {
3292 if (flipy) c += 8*(h-1-y);
3293 else c += 8*y;
3294 fy = flipy;
3295 }
3296
3297 /* the sprite can start at any point in the 8x8 grid, but it must stay */
3298 /* in a 64 entries window, wrapping around at the edges. The animation */
3299 /* at the end of the saloon level in Sunset Riders breaks otherwise. */
3300 c = (c & 0x3f) | (code & ~0x3f);
3301
3302 if (zoomx == 0x10000 && zoomy == 0x10000)
3303 {
3304 pdrawgfx(bitmap,K053245_gfx,
3305 c,
3306 color,
3307 fx,fy,
3308 sx,sy,
3309 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,pri);
3310 }
3311 else
3312 {
3313 pdrawgfxzoom(bitmap,K053245_gfx,
3314 c,
3315 color,
3316 fx,fy,
3317 sx,sy,
3318 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,
3319 (zw << 16) / 16,(zh << 16) / 16,pri);
3320 }
3321 }
3322 }
3323 }
3324 #if 0
3325 if (keyboard_pressed(KEYCODE_D))
3326 {
3327 FILE *fp;
3328 fp=fopen("SPRITE.DMP", "w+b");
3329 if (fp)
3330 {
3331 fwrite(K053245_buffer, 0x800, 1, fp);
3332 usrintf_showmessage("saved");
3333 fclose(fp);
3334 }
3335 }
3336 #endif
3337 #undef NUM_SPRITES
3338 }
3339
3340
3341
3342 /***************************************************************************/
3343 /* */
3344 /* 053246/053247 */
3345 /* */
3346 /***************************************************************************/
3347
3348 static int K053247_memory_region, K053247_dx, K053247_dy, K053247_wraparound;
3349 static data8_t K053246_regs[8];
3350 static data16_t K053247_regs[16];
3351 static data16_t *K053247_ram=0;
3352 static struct GfxElement *K053247_gfx;
3353 static void (*K053247_callback)(int *code,int *color,int *priority);
3354 static int K053246_OBJCHA_line;
3355
K053247_export_config(data16_t ** ram,struct GfxElement ** gfx,void ** callback,int * dx,int * dy)3356 void K053247_export_config(data16_t **ram, struct GfxElement **gfx, void **callback, int *dx, int *dy)
3357 {
3358 *ram = K053247_ram;
3359 *gfx = K053247_gfx;
3360 *callback = (void*)K053247_callback;
3361 *dx = K053247_dx;
3362 *dy = K053247_dy;
3363 }
3364
K053246_read_register(int regnum)3365 int K053246_read_register(int regnum) { return(K053246_regs[regnum]); }
K053247_read_register(int regnum)3366 int K053247_read_register(int regnum) { return(K053247_regs[regnum]); }
3367
K053247_set_SpriteOffset(int offsx,int offsy)3368 void K053247_set_SpriteOffset(int offsx, int offsy)
3369 {
3370 K053247_dx = offsx;
3371 K053247_dy = offsy;
3372 }
3373
K053247_wraparound_enable(int status)3374 void K053247_wraparound_enable(int status)
3375 {
3376 K053247_wraparound = status;
3377 }
3378
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))3379 int K053247_vh_start(int gfx_memory_region, int dx, int dy, int plane0,int plane1,int plane2,int plane3,
3380 void (*callback)(int *code,int *color,int *priority))
3381 {
3382 int gfx_index,i;
3383 static struct GfxLayout spritelayout =
3384 {
3385 16,16,
3386 0, /* filled in later */
3387 4,
3388 { 0, 0, 0, 0 }, /* filled in later */
3389 { 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4,
3390 10*4, 11*4, 8*4, 9*4, 14*4, 15*4, 12*4, 13*4 },
3391 { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64,
3392 8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 },
3393 128*8
3394 };
3395
3396
3397 /* find first empty slot to decode gfx */
3398 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
3399 if (Machine->gfx[gfx_index] == 0)
3400 break;
3401 if (gfx_index == MAX_GFX_ELEMENTS)
3402 return 1;
3403
3404 /* tweak the structure for the number of tiles we have */
3405 spritelayout.total = memory_region_length(gfx_memory_region) / 128;
3406 spritelayout.planeoffset[0] = plane0;
3407 spritelayout.planeoffset[1] = plane1;
3408 spritelayout.planeoffset[2] = plane2;
3409 spritelayout.planeoffset[3] = plane3;
3410
3411 /* decode the graphics */
3412 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&spritelayout);
3413 if (!Machine->gfx[gfx_index])
3414 return 1;
3415
3416 /* set the color information */
3417 if (Machine->drv->color_table_len)
3418 {
3419 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
3420 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
3421 }
3422 else
3423 {
3424 Machine->gfx[gfx_index]->colortable = Machine->pens;
3425 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / 16;
3426 }
3427
3428 #if VERBOSE
3429 if (Machine->color_depth == 32)
3430 {
3431 if ((Machine->drv->video_attributes & (VIDEO_HAS_SHADOWS|VIDEO_HAS_HIGHLIGHTS)) != VIDEO_HAS_SHADOWS+VIDEO_HAS_HIGHLIGHTS)
3432 usrintf_showmessage("driver missing SHADOWS or HIGHLIGHTS flag");
3433 }
3434 else
3435 {
3436 if (!(Machine->drv->video_attributes & VIDEO_HAS_SHADOWS))
3437 usrintf_showmessage("driver should use VIDEO_HAS_SHADOWS");
3438 }
3439 #endif
3440
3441 /* prepare shadow draw table */
3442 gfx_drawmode_table[0] = DRAWMODE_NONE;
3443 for (i = 1;i < 15;i++)
3444 gfx_drawmode_table[i] = DRAWMODE_SOURCE;
3445 gfx_drawmode_table[15] = DRAWMODE_SHADOW;
3446
3447 K053247_dx = dx;
3448 K053247_dy = dy;
3449 K053247_wraparound = 1;
3450 K05324x_z_rejection = -1;
3451 K053247_memory_region = gfx_memory_region;
3452 K053247_gfx = Machine->gfx[gfx_index];
3453 K053247_callback = callback;
3454 K053246_OBJCHA_line = CLEAR_LINE;
3455 K053247_ram = auto_malloc(0x1000);
3456 if (!K053247_ram) return 1;
3457
3458 memset(K053247_ram, 0, 0x1000);
3459 memset(K053246_regs, 0, 8);
3460 memset(K053247_regs, 0, 32);
3461
3462 state_save_register_UINT16("K053246", 0, "memory", K053247_ram, 0x800);
3463 state_save_register_UINT8 ("K053246", 0, "registers", K053246_regs, 8);
3464 state_save_register_UINT16("K053246", 0, "registers2",K053247_regs, 16);
3465 state_save_register_int ("K053246", 0, "objcha", &K053246_OBJCHA_line);
3466
3467 return 0;
3468 }
3469
3470 /* 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))3471 int K055673_vh_start(int gfx_memory_region, int layout, int dx, int dy, void (*callback)(int *code,int *color,int *priority))
3472 {
3473 int gfx_index;
3474
3475 static struct GfxLayout spritelayout = /* System GX sprite layout */
3476 {
3477 16,16,
3478 32768, /* filled in later */
3479 5,
3480 { 32, 24, 16, 8, 0 },
3481 { 0, 1, 2, 3, 4, 5, 6, 7, 40, 41, 42, 43, 44, 45, 46, 47 },
3482 { 0, 10*8, 10*8*2, 10*8*3, 10*8*4, 10*8*5, 10*8*6, 10*8*7, 10*8*8,
3483 10*8*9, 10*8*10, 10*8*11, 10*8*12, 10*8*13, 10*8*14, 10*8*15 },
3484 16*16*5
3485 };
3486 static struct GfxLayout spritelayout2 = /* Run and Gun sprite layout */
3487 {
3488 16,16,
3489 32768, /* filled in later */
3490 4,
3491 { 24, 16, 8, 0 },
3492 { 0, 1, 2, 3, 4, 5, 6, 7, 32, 33, 34, 35, 36, 37, 38, 39 },
3493 { 0, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960 },
3494 16*16*4
3495 };
3496 static struct GfxLayout spritelayout3 = /* Lethal Enforcers II sprite layout */
3497 {
3498 16,16,
3499 32768, /* filled in later */
3500 8,
3501 { 8*1,8*0,8*3,8*2,8*5,8*4,8*7,8*6 },
3502 { 0,1,2,3,4,5,6,7,64+0,64+1,64+2,64+3,64+4,64+5,64+6,64+7 },
3503 { 128*0, 128*1, 128*2, 128*3, 128*4, 128*5, 128*6, 128*7,
3504 128*8, 128*9, 128*10, 128*11, 128*12, 128*13, 128*14, 128*15 },
3505 128*16
3506 };
3507 static struct GfxLayout spritelayout4 = /* System GX 6bpp sprite layout */
3508 {
3509 16,16,
3510 32768, /* filled in later */
3511 6,
3512 { 40, 32, 24, 16, 8, 0 },
3513 { 0, 1, 2, 3, 4, 5, 6, 7, 48, 49, 50, 51, 52, 53, 54, 55 },
3514 { 0, 12*8, 12*8*2, 12*8*3, 12*8*4, 12*8*5, 12*8*6, 12*8*7, 12*8*8,
3515 12*8*9, 12*8*10, 12*8*11, 12*8*12, 12*8*13, 12*8*14, 12*8*15 },
3516 16*16*6
3517 };
3518 unsigned char *s1, *s2, *d;
3519 long i, c;
3520 data16_t *K055673_rom;
3521
3522 /* find first empty slot to decode gfx */
3523 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
3524 if (Machine->gfx[gfx_index] == 0)
3525 break;
3526 if (gfx_index == MAX_GFX_ELEMENTS)
3527 return 1;
3528
3529 switch(layout) {
3530 case K055673_LAYOUT_GX:
3531 {
3532 int size4 = (memory_region_length(gfx_memory_region)/(1024*1024))/5;
3533 size4 *= 4*1024*1024;
3534 /* set the # of tiles based on the 4bpp section */
3535 spritelayout.total = size4 / 128;
3536 if (!(K055673_rom = (data16_t *)auto_malloc(size4 * 5))) return 1;
3537 d = (data8_t *)K055673_rom;
3538 // now combine the graphics together to form 5bpp
3539 s1 = memory_region(gfx_memory_region); // 4bpp area
3540 s2 = s1 + (size4); // 1bpp area
3541 for (i = 0; i < size4; i+= 4)
3542 {
3543 *d++ = *s1++;
3544 *d++ = *s1++;
3545 *d++ = *s1++;
3546 *d++ = *s1++;
3547 *d++ = *s2++;
3548 }
3549 /* decode the graphics */
3550 Machine->gfx[gfx_index] = decodegfx((data8_t *)K055673_rom, &spritelayout);
3551 break;
3552 }
3553 case K055673_LAYOUT_RNG:
3554 K055673_rom = (data16_t *)memory_region(gfx_memory_region);
3555 spritelayout2.total = memory_region_length(gfx_memory_region) / (16*16/2);
3556
3557 /* decode the graphics */
3558 Machine->gfx[gfx_index] = decodegfx((data8_t *)K055673_rom, &spritelayout2);
3559 break;
3560 case K055673_LAYOUT_LE2:
3561 K055673_rom = (data16_t *)memory_region(gfx_memory_region);
3562 spritelayout3.total = memory_region_length(gfx_memory_region) / (16*16);
3563
3564 /* decode the graphics */
3565 Machine->gfx[gfx_index] = decodegfx((data8_t *)K055673_rom, &spritelayout3);
3566 break;
3567 case K055673_LAYOUT_GX6:
3568 K055673_rom = (data16_t *)memory_region(gfx_memory_region);
3569 spritelayout4.total = memory_region_length(gfx_memory_region) / (16*16*6/8);
3570
3571 /* decode the graphics */
3572 Machine->gfx[gfx_index] = decodegfx((data8_t *)K055673_rom, &spritelayout4);
3573 break;
3574 }
3575
3576 if (!Machine->gfx[gfx_index])
3577 return 1;
3578
3579 /* set the color information */
3580 if (Machine->drv->color_table_len)
3581 {
3582 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
3583 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
3584 }
3585 else
3586 {
3587 Machine->gfx[gfx_index]->colortable = Machine->pens;
3588 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / 16;
3589 }
3590
3591 #if VERBOSE
3592 if (!(Machine->drv->video_attributes & VIDEO_HAS_SHADOWS))
3593 usrintf_showmessage("driver should use VIDEO_HAS_SHADOWS");
3594 #endif
3595
3596 /* prepare shadow draw table */
3597 c = Machine->gfx[gfx_index]->color_granularity-1;
3598 gfx_drawmode_table[0] = DRAWMODE_NONE;
3599 for (i = 1;i < c;i++)
3600 gfx_drawmode_table[i] = DRAWMODE_SOURCE;
3601 gfx_drawmode_table[c] = DRAWMODE_SHADOW;
3602
3603 K053247_dx = dx;
3604 K053247_dy = dy;
3605 K053247_wraparound = 1;
3606 K05324x_z_rejection = -1;
3607 K053247_memory_region = gfx_memory_region;
3608 K053247_gfx = Machine->gfx[gfx_index];
3609 K053247_callback = callback;
3610 K053246_OBJCHA_line = CLEAR_LINE;
3611 K053247_ram = auto_malloc(0x1000);
3612 if (!K053247_ram) return 1;
3613
3614 memset(K053247_ram, 0, 0x1000);
3615 memset(K053246_regs, 0, 8);
3616 memset(K053247_regs, 0, 32);
3617
3618 state_save_register_UINT16("K053246", 0, "memory", K053247_ram, 0x800);
3619 state_save_register_UINT8 ("K053246", 0, "registers", K053246_regs, 8);
3620 state_save_register_UINT16("K053246", 0, "registers2",K053247_regs, 16);
3621 state_save_register_int ("K053246", 0, "objcha", &K053246_OBJCHA_line);
3622
3623 return 0;
3624 }
3625
WRITE16_HANDLER(K053247_reg_word_w)3626 WRITE16_HANDLER( K053247_reg_word_w ) // write-only OBJSET2 registers (see p.43 table 6.1)
3627 {
3628 COMBINE_DATA(K053247_regs + offset);
3629 }
3630
WRITE32_HANDLER(K053247_reg_long_w)3631 WRITE32_HANDLER( K053247_reg_long_w )
3632 {
3633 offset <<= 1;
3634 COMBINE_DATA(K053247_regs + offset + 1);
3635 mem_mask >>= 16;
3636 data >>= 16;
3637 COMBINE_DATA(K053247_regs + offset);
3638 }
3639
READ16_HANDLER(K053247_word_r)3640 READ16_HANDLER( K053247_word_r )
3641 {
3642 return K053247_ram[offset];
3643 }
3644
WRITE16_HANDLER(K053247_word_w)3645 WRITE16_HANDLER( K053247_word_w )
3646 {
3647 COMBINE_DATA(K053247_ram + offset);
3648 }
3649
READ32_HANDLER(K053247_long_r)3650 READ32_HANDLER( K053247_long_r )
3651 {
3652 return K053247_ram[offset*2+1] | (K053247_ram[offset*2]<<16);
3653 }
3654
WRITE32_HANDLER(K053247_long_w)3655 WRITE32_HANDLER( K053247_long_w )
3656 {
3657 offset <<= 1;
3658 COMBINE_DATA(K053247_ram + offset + 1);
3659 mem_mask >>= 16;
3660 data >>= 16;
3661 COMBINE_DATA(K053247_ram + offset);
3662 }
3663
READ_HANDLER(K053247_r)3664 READ_HANDLER( K053247_r )
3665 {
3666 int offs = offset >> 1;
3667
3668 if (offset & 1)
3669 return(K053247_ram[offs] & 0xff);
3670 else
3671 return(K053247_ram[offs] >> 8);
3672 }
3673
WRITE_HANDLER(K053247_w)3674 WRITE_HANDLER( K053247_w )
3675 {
3676 int offs = offset >> 1;
3677
3678 if (offset & 1)
3679 K053247_ram[offs] = (K053247_ram[offs] & 0xff00) | data;
3680 else
3681 K053247_ram[offs] = (K053247_ram[offs] & 0x00ff) | (data<<8);
3682 }
3683
3684 // Mystic Warriors hardware games support a non-OBJCHA based ROM readback
3685 // write the address to the 246 as usual, but there's a completely separate ROM
3686 // window that works without needing an OBJCHA line.
3687 // in this window, +0 = 32 bits from one set of ROMs, and +8 = 32 bits from another set
READ16_HANDLER(K055673_rom_word_r)3688 READ16_HANDLER( K055673_rom_word_r ) // 5bpp
3689 {
3690 data8_t *ROM8 = (data8_t *)memory_region(K053247_memory_region);
3691 data16_t *ROM = (data16_t *)memory_region(K053247_memory_region);
3692 int size4 = (memory_region_length(K053247_memory_region)/(1024*1024))/5;
3693 int romofs;
3694
3695 size4 *= 4*1024*1024; // get offset to 5th bit
3696 ROM8 += size4;
3697
3698 romofs = K053246_regs[6]<<16 | K053246_regs[7]<<8 | K053246_regs[4];
3699
3700 switch (offset)
3701 {
3702 case 0: // 20k / 36u
3703 return ROM[romofs+2];
3704 break;
3705 case 1: // 17k / 36y
3706 return ROM[romofs+3];
3707 break;
3708 case 2: // 10k / 32y
3709 case 3:
3710 romofs /= 2;
3711 return ROM8[romofs+1];
3712 break;
3713 case 4: // 22k / 34u
3714 return ROM[romofs];
3715 break;
3716 case 5: // 19k / 34y
3717 return ROM[romofs+1];
3718 break;
3719 case 6: // 12k / 29y
3720 case 7:
3721 romofs /= 2;
3722 return ROM8[romofs];
3723 break;
3724 default:
3725 #if VERBOSE
3726 logerror("55673_rom_word_r: Unknown read offset %x\n", offset);
3727 #endif
3728 break;
3729 }
3730
3731 return 0;
3732 }
3733
READ16_HANDLER(K055673_GX6bpp_rom_word_r)3734 READ16_HANDLER( K055673_GX6bpp_rom_word_r )
3735 {
3736 data16_t *ROM = (data16_t *)memory_region(K053247_memory_region);
3737 int romofs;
3738
3739 romofs = K053246_regs[6]<<16 | K053246_regs[7]<<8 | K053246_regs[4];
3740
3741 romofs /= 4; // romofs increments 4 at a time
3742 romofs *= 12/2; // each increment of romofs = 12 new bytes (6 new words)
3743
3744 switch (offset)
3745 {
3746 case 0:
3747 return ROM[romofs+3];
3748 break;
3749 case 1:
3750 return ROM[romofs+4];
3751 break;
3752 case 2:
3753 case 3:
3754 return ROM[romofs+5];
3755 break;
3756 case 4:
3757 return ROM[romofs];
3758 break;
3759 case 5:
3760 return ROM[romofs+1];
3761 break;
3762 case 6:
3763 case 7:
3764 return ROM[romofs+2];
3765 break;
3766 default:
3767 #if VERBOSE
3768 logerror("55673_rom_word_r: Unknown read offset %x (PC=%x)\n", offset, activecpu_get_pc());
3769 #endif
3770 break;
3771 }
3772
3773 return 0;
3774 }
3775
READ_HANDLER(K053246_r)3776 READ_HANDLER( K053246_r )
3777 {
3778 if (K053246_OBJCHA_line == ASSERT_LINE)
3779 {
3780 int addr;
3781
3782 addr = (K053246_regs[6] << 17) | (K053246_regs[7] << 9) | (K053246_regs[4] << 1) | ((offset & 1) ^ 1);
3783 addr &= memory_region_length(K053247_memory_region)-1;
3784 #if VERBOSE
3785 usrintf_showmessage("%04x: offset %02x addr %06x",activecpu_get_pc(),offset,addr);
3786 #endif
3787 return memory_region(K053247_memory_region)[addr];
3788 }
3789 else
3790 {
3791 #if VERBOSE
3792 logerror("%04x: read from unknown 053246 address %x\n",activecpu_get_pc(),offset);
3793 #endif
3794 return 0;
3795 }
3796 }
3797
WRITE_HANDLER(K053246_w)3798 WRITE_HANDLER( K053246_w )
3799 {
3800 K053246_regs[offset] = data;
3801 }
3802
READ16_HANDLER(K053246_word_r)3803 READ16_HANDLER( K053246_word_r )
3804 {
3805 offset <<= 1;
3806 return K053246_r(offset + 1) | (K053246_r(offset) << 8);
3807 }
3808
WRITE16_HANDLER(K053246_word_w)3809 WRITE16_HANDLER( K053246_word_w )
3810 {
3811 if (ACCESSING_MSB)
3812 K053246_w(offset<<1,(data >> 8) & 0xff);
3813 if (ACCESSING_LSB)
3814 K053246_w((offset<<1) + 1,data & 0xff);
3815 }
3816
READ32_HANDLER(K053246_long_r)3817 READ32_HANDLER( K053246_long_r )
3818 {
3819 offset <<= 1;
3820 return (K053246_word_r(offset+1, 0xffff) | K053246_word_r(offset, 0xffff)<<16);
3821 }
3822
WRITE32_HANDLER(K053246_long_w)3823 WRITE32_HANDLER( K053246_long_w )
3824 {
3825 offset <<= 1;
3826 K053246_word_w(offset, data>>16, mem_mask >> 16);
3827 K053246_word_w(offset+1, data, mem_mask);
3828 }
3829
K053246_set_OBJCHA_line(int state)3830 void K053246_set_OBJCHA_line(int state)
3831 {
3832 K053246_OBJCHA_line = state;
3833 }
3834
K053246_is_IRQ_enabled(void)3835 int K053246_is_IRQ_enabled(void)
3836 {
3837 // This bit enables obj DMA rather than obj IRQ even though the two functions usually coincide.
3838 return K053246_regs[5] & 0x10;
3839 }
3840
3841 /*
3842 * Sprite Format
3843 * ------------------
3844 *
3845 * Word | Bit(s) | Use
3846 * -----+-fedcba9876543210-+----------------
3847 * 0 | x--------------- | active (show this sprite)
3848 * 0 | -x-------------- | maintain aspect ratio (when set, zoom y acts on both axis)
3849 * 0 | --x------------- | flip y
3850 * 0 | ---x------------ | flip x
3851 * 0 | ----xxxx-------- | sprite size (see below)
3852 * 0 | --------xxxxxxxx | zcode
3853 * 1 | xxxxxxxxxxxxxxxx | sprite code
3854 * 2 | ------xxxxxxxxxx | y position
3855 * 3 | ------xxxxxxxxxx | x position
3856 * 4 | xxxxxxxxxxxxxxxx | zoom y (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
3857 * 5 | xxxxxxxxxxxxxxxx | zoom x (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
3858 * 6 | x--------------- | mirror y (top half is drawn as mirror image of the bottom)
3859 * 6 | -x-------------- | mirror x (right half is drawn as mirror image of the left)
3860 * 6 | --xx------------ | reserved (sprites with these two bits set don't seem to be graphics data at all)
3861 * 6 | ----xx---------- | shadow code: 0=off, 0x400=preset1, 0x800=preset2, 0xc00=preset3
3862 * 6 | ------xx-------- | effect code: flicker, upper palette, full shadow...etc. (game dependent)
3863 * 6 | --------xxxxxxxx | "color", but depends on external connections (implies priority)
3864 * 7 | xxxxxxxxxxxxxxxx | game dependent
3865 *
3866 * shadow enables transparent shadows. Note that it applies to the last sprite pen ONLY.
3867 * The rest of the sprite remains normal.
3868 */
3869
K053247_sprites_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect)3870 void K053247_sprites_draw(struct mame_bitmap *bitmap,const struct rectangle *cliprect) //*
3871 {
3872 #define NUM_SPRITES 256
3873
3874 /* sprites can be grouped up to 8x8. The draw order is
3875 0 1 4 5 16 17 20 21
3876 2 3 6 7 18 19 22 23
3877 8 9 12 13 24 25 28 29
3878 10 11 14 15 26 27 30 31
3879 32 33 36 37 48 49 52 53
3880 34 35 38 39 50 51 54 55
3881 40 41 44 45 56 57 60 61
3882 42 43 46 47 58 59 62 63
3883 */
3884 static int xoffset[8] = { 0, 1, 4, 5, 16, 17, 20, 21 };
3885 static int yoffset[8] = { 0, 2, 8, 10, 32, 34, 40, 42 };
3886
3887 int sortedlist[NUM_SPRITES];
3888 int offs,zcode;
3889 int ox,oy,color,code,size,w,h,x,y,xa,ya,flipx,flipy,mirrorx,mirrory,shadow,zoomx,zoomy,primask;
3890 int shdmask,nozoom,count,temp;
3891
3892 int flipscreenx = K053246_regs[5] & 0x01;
3893 int flipscreeny = K053246_regs[5] & 0x02;
3894 int offx = (short)((K053246_regs[0] << 8) | K053246_regs[1]);
3895 int offy = (short)((K053246_regs[2] << 8) | K053246_regs[3]);
3896
3897 int solidpens = K053247_gfx->color_granularity - 1;
3898 int screen_width = Machine->drv->screen_width;
3899
3900 /*
3901 safeguard older drivers missing any of the following video attributes:
3902
3903 VIDEO_NEEDS_6BITS_PER_GUN | VIDEO_RGB_DIRECT | VIDEO_HAS_SHADOWS | VIDEO_HAS_HIGHLIGHTS
3904 */
3905 if (Machine->drv->video_attributes & VIDEO_HAS_SHADOWS)
3906 {
3907 if (Machine->color_depth == 32 && (Machine->drv->video_attributes & VIDEO_HAS_HIGHLIGHTS))
3908 shdmask = 3; // enable all shadows and highlights
3909 else
3910 shdmask = 0; // enable default shadows
3911 }
3912 else
3913 shdmask = -1; // disable everything
3914
3915 /*
3916 The K053247 does not draw pixels on top of those with equal or smaller Z-values
3917 regardless of priority. Embedded shadows inherit Z-values from their host sprites
3918 but do not assume host priorities unless explicitly told. In other words shadows
3919 can have priorities different from that of normal pens in the same sprite,
3920 in addition to the ability of masking themselves from specific layers or pixels
3921 on the other sprites.
3922
3923 In front-to-back rendering, sprites cannot sandwich between alpha blended layers
3924 or the draw code will have to figure out the percentage opacities of what is on
3925 top and beneath each sprite pixel and blend the target accordingly. The process
3926 is overly demanding for realtime software and is thus another shortcoming of
3927 pdrawgfx and pixel based mixers. Even mahjong games with straight forward video
3928 subsystems are feeling the impact by which the girls cannot appear under
3929 translucent dialogue boxes.
3930
3931 These are a small part of the K053247's feature set but many games expect them
3932 to be the minimum compliances. The specification will undoubtedly require
3933 redesigning the priority system from the ground up. Drawgfx.c and tilemap.c must
3934 also undergo heavy facelifts but in the end the changes could hurt simpler games
3935 more than they help complex systems; therefore the new engine should remain
3936 completely stand alone and self-contained. Implementation details are being
3937 hammered down but too early to make propositions.
3938 */
3939
3940 // Prebuild a sorted table by descending Z-order.
3941 zcode = K05324x_z_rejection;
3942 offs = count = 0;
3943
3944 if (zcode == -1)
3945 {
3946 for (; offs<0x800; offs+=8)
3947 if (K053247_ram[offs] & 0x8000) sortedlist[count++] = offs;
3948 }
3949 else
3950 {
3951 for (; offs<0x800; offs+=8)
3952 if ((K053247_ram[offs] & 0x8000) && ((K053247_ram[offs] & 0xff) != zcode)) sortedlist[count++] = offs;
3953 }
3954
3955 w = count;
3956 count--;
3957 h = count;
3958
3959 if (!(K053247_regs[0xc/2] & 0x10))
3960 {
3961 // sort objects in decending order(smaller z closer) when OPSET PRI is clear
3962 for (y=0; y<h; y++)
3963 {
3964 offs = sortedlist[y];
3965 zcode = K053247_ram[offs] & 0xff;
3966 for (x=y+1; x<w; x++)
3967 {
3968 temp = sortedlist[x];
3969 code = K053247_ram[temp] & 0xff;
3970 if (zcode <= code) { zcode = code; sortedlist[x] = offs; sortedlist[y] = offs = temp; }
3971 }
3972 }
3973 }
3974 else
3975 {
3976 // sort objects in ascending order(bigger z closer) when OPSET PRI is set
3977 for (y=0; y<h; y++)
3978 {
3979 offs = sortedlist[y];
3980 zcode = K053247_ram[offs] & 0xff;
3981 for (x=y+1; x<w; x++)
3982 {
3983 temp = sortedlist[x];
3984 code = K053247_ram[temp] & 0xff;
3985 if (zcode >= code) { zcode = code; sortedlist[x] = offs; sortedlist[y] = offs = temp; }
3986 }
3987 }
3988 }
3989
3990 for (; count>=0; count--)
3991 {
3992 offs = sortedlist[count];
3993
3994 code = K053247_ram[offs+1];
3995 shadow = color = K053247_ram[offs+6];
3996 primask = 0;
3997
3998 (*K053247_callback)(&code,&color,&primask);
3999
4000 temp = K053247_ram[offs];
4001
4002 size = (temp & 0x0f00) >> 8;
4003 w = 1 << (size & 0x03);
4004 h = 1 << ((size >> 2) & 0x03);
4005
4006 /* the sprite can start at any point in the 8x8 grid. We have to */
4007 /* adjust the offsets to draw it correctly. Simpsons does this all the time. */
4008 xa = 0;
4009 ya = 0;
4010 if (code & 0x01) xa += 1;
4011 if (code & 0x02) ya += 1;
4012 if (code & 0x04) xa += 2;
4013 if (code & 0x08) ya += 2;
4014 if (code & 0x10) xa += 4;
4015 if (code & 0x20) ya += 4;
4016 code &= ~0x3f;
4017
4018 oy = (short)K053247_ram[offs+2];
4019 ox = (short)K053247_ram[offs+3];
4020
4021 if (K053247_wraparound)
4022 {
4023 offx &= 0x3ff;
4024 offy &= 0x3ff;
4025 oy &= 0x3ff;
4026 ox &= 0x3ff;
4027 }
4028
4029 /* zoom control:
4030 0x40 = normal scale
4031 <0x40 enlarge (0x20 = double size)
4032 >0x40 reduce (0x80 = half size)
4033 */
4034 y = zoomy = K053247_ram[offs+4] & 0x3ff;
4035 if (zoomy) zoomy = (0x400000+(zoomy>>1)) / zoomy; else zoomy = 0x800000;
4036 if (!(temp & 0x4000))
4037 {
4038 x = zoomx = K053247_ram[offs+5] & 0x3ff;
4039 if (zoomx) zoomx = (0x400000+(zoomx>>1)) / zoomx;
4040 else zoomx = 0x800000;
4041 }
4042 else { zoomx = zoomy; x = y; }
4043
4044 // ************************************************************************************
4045 // for Escape Kids (GX975)
4046 // ************************************************************************************
4047 // Escape Kids use 053246 #5 register's UNKNOWN Bit #5, #3 and #2.
4048 // Bit #5, #3, #2 always set "1".
4049 // Maybe, Bit #5 or #3 or #2 or combination means "FIX SPRITE WIDTH TO HALF" ?????
4050 // Below 7 lines supports this 053246's(???) function.
4051 // Don't rely on it, Please. But, Escape Kids works correctly!
4052 // ************************************************************************************
4053 if ( K053246_regs[5] & 0x08 ) // Check only "Bit #3 is '1'?" (NOTE: good guess)
4054 {
4055 zoomx >>= 1; // Fix sprite width to HALF size
4056 ox = (ox >> 1) + 1; // Fix sprite draw position
4057 if (flipscreenx) ox += screen_width;
4058 nozoom = 0;
4059 }
4060 else
4061 nozoom = (x == 0x40 && y == 0x40);
4062
4063 flipx = temp & 0x1000;
4064 flipy = temp & 0x2000;
4065 mirrorx = shadow & 0x4000;
4066 if (mirrorx) flipx = 0; // documented and confirmed
4067 mirrory = shadow & 0x8000;
4068
4069 if (color == -1)
4070 {
4071 // drop the entire sprite to shadow unconditionally
4072 if (shdmask < 0) continue;
4073 color = 0;
4074 shadow = -1;
4075 for (temp=1; temp<solidpens; temp++) gfx_drawmode_table[temp] = DRAWMODE_SHADOW;
4076 palette_set_shadow_mode(0);
4077 }
4078 else
4079 {
4080 if (shdmask >= 0)
4081 {
4082 shadow = (color & K053247_CUSTOMSHADOW) ? (color>>K053247_SHDSHIFT) : (shadow>>10);
4083 if (shadow &= 3) palette_set_shadow_mode((shadow-1) & shdmask);
4084 }
4085 else
4086 shadow = 0;
4087 }
4088
4089 color &= 0xffff; // strip attribute flags
4090
4091
4092 // ************************************************************************************
4093 // for Escape Kids (GX975)
4094 // ************************************************************************************
4095 // Escape Kids use 053246 #5 register's UNKNOWN Bit #5, #3 and #2.
4096 // Bit #5, #3, #2 always set "1".
4097 // Maybe, Bit #5 or #3 or #2 or combination means "FIX SPRITE WIDTH TO HALF" ?????
4098 // Below 7 lines supports this 053246's(???) function.
4099 // Don't rely on it, Please. But, Escape Kids works correctly!
4100 // ************************************************************************************
4101 if ( K053246_regs[5] & 0x08 ) // Check only "Bit #3 is '1'?"
4102 {
4103 zoomx = zoomx >> 1; // Fix sprite width to HALF size
4104 ox = (ox >> 1) + 1; // Fix sprite draw position
4105
4106 if (flipscreenx)
4107 ox = ox + screen_width;
4108 }
4109
4110
4111 if (flipscreenx)
4112 {
4113 ox = -ox;
4114 if (!mirrorx) flipx = !flipx;
4115 }
4116 if (flipscreeny)
4117 {
4118 oy = -oy;
4119 if (!mirrory) flipy = !flipy;
4120 }
4121
4122 // apply wrapping and global offsets
4123 if (K053247_wraparound)
4124 {
4125 ox = ( ox - offx) & 0x3ff;
4126 oy = (-oy - offy) & 0x3ff;
4127 if (ox >= 0x300) ox -= 0x400;
4128 if (oy >= 0x280) oy -= 0x400;
4129 }
4130 else
4131 {
4132 ox = ox - offx;
4133 oy = -oy - offy;
4134 }
4135 ox += K053247_dx;
4136 oy -= K053247_dy;
4137
4138 // apply global and display window offsets
4139
4140 /* the coordinates given are for the *center* of the sprite */
4141 ox -= (zoomx * w) >> 13;
4142 oy -= (zoomy * h) >> 13;
4143
4144 for (y = 0;y < h;y++)
4145 {
4146 int sx,sy,zw,zh;
4147
4148 sy = oy + ((zoomy * y + (1<<11)) >> 12);
4149 zh = (oy + ((zoomy * (y+1) + (1<<11)) >> 12)) - sy;
4150
4151 for (x = 0;x < w;x++)
4152 {
4153 int c,fx,fy;
4154
4155 sx = ox + ((zoomx * x + (1<<11)) >> 12);
4156 zw = (ox + ((zoomx * (x+1) + (1<<11)) >> 12)) - sx;
4157 c = code;
4158 if (mirrorx)
4159 {
4160 if ((flipx == 0) ^ ((x<<1) < w))
4161 {
4162 /* mirror left/right */
4163 c += xoffset[(w-1-x+xa)&7];
4164 fx = 1;
4165 }
4166 else
4167 {
4168 c += xoffset[(x+xa)&7];
4169 fx = 0;
4170 }
4171 }
4172 else
4173 {
4174 if (flipx) c += xoffset[(w-1-x+xa)&7];
4175 else c += xoffset[(x+xa)&7];
4176 fx = flipx;
4177 }
4178 if (mirrory)
4179 {
4180 if ((flipy == 0) ^ ((y<<1) >= h))
4181 {
4182 /* mirror top/bottom */
4183 c += yoffset[(h-1-y+ya)&7];
4184 fy = 1;
4185 }
4186 else
4187 {
4188 c += yoffset[(y+ya)&7];
4189 fy = 0;
4190 }
4191 }
4192 else
4193 {
4194 if (flipy) c += yoffset[(h-1-y+ya)&7];
4195 else c += yoffset[(y+ya)&7];
4196 fy = flipy;
4197 }
4198
4199 if (nozoom)
4200 {
4201 pdrawgfx(bitmap,K053247_gfx,
4202 c,
4203 color,
4204 fx,fy,
4205 sx,sy,
4206 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,primask);
4207 }
4208 else
4209 {
4210 pdrawgfxzoom(bitmap,K053247_gfx,
4211 c,
4212 color,
4213 fx,fy,
4214 sx,sy,
4215 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,
4216 (zw << 16) >> 4,(zh << 16) >> 4,primask);
4217 }
4218
4219 if (mirrory && h == 1) /* Simpsons shadows */
4220 {
4221 if (nozoom)
4222 {
4223 pdrawgfx(bitmap,K053247_gfx,
4224 c,
4225 color,
4226 fx,!fy,
4227 sx,sy,
4228 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,primask);
4229 }
4230 else
4231 {
4232 pdrawgfxzoom(bitmap,K053247_gfx,
4233 c,
4234 color,
4235 fx,!fy,
4236 sx,sy,
4237 cliprect,shadow ? TRANSPARENCY_PEN_TABLE : TRANSPARENCY_PEN,0,
4238 (zw << 16) >> 4,(zh << 16) >> 4,primask);
4239 }
4240 }
4241 } // end of X loop
4242 } // end of Y loop
4243
4244 // reset drawmode_table
4245 if (shadow == -1) for (temp=1; temp<solidpens; temp++) gfx_drawmode_table[temp] = DRAWMODE_SOURCE;
4246
4247 } // end of sprite-list loop
4248 #undef NUM_SPRITES
4249 }
4250
4251
4252
4253 /***************************************************************************/
4254 /* */
4255 /* 051316 */
4256 /* */
4257 /***************************************************************************/
4258
4259 #define MAX_K051316 3
4260
4261 static int K051316_memory_region[MAX_K051316];
4262 static int K051316_gfxnum[MAX_K051316];
4263 static int K051316_wraparound[MAX_K051316];
4264 static int K051316_offset[MAX_K051316][2];
4265 static int K051316_bpp[MAX_K051316];
4266 static void (*K051316_callback[MAX_K051316])(int *code,int *color);
4267 static unsigned char *K051316_ram[MAX_K051316];
4268 static unsigned char K051316_ctrlram[MAX_K051316][16];
4269 static struct tilemap *K051316_tilemap[MAX_K051316];
4270
4271 /***************************************************************************
4272
4273 Callbacks for the TileMap code
4274
4275 ***************************************************************************/
4276
K051316_get_tile_info(int tile_index,int chip)4277 static INLINE void K051316_get_tile_info(int tile_index,int chip)
4278 {
4279 int code = K051316_ram[chip][tile_index];
4280 int color = K051316_ram[chip][tile_index + 0x400];
4281
4282 tile_info.flags = 0;
4283
4284 (*K051316_callback[chip])(&code,&color);
4285
4286 SET_TILE_INFO(
4287 K051316_gfxnum[chip],
4288 code,
4289 color,
4290 tile_info.flags)
4291 }
4292
K051316_get_tile_info0(int tile_index)4293 static void K051316_get_tile_info0(int tile_index) { K051316_get_tile_info(tile_index,0); }
K051316_get_tile_info1(int tile_index)4294 static void K051316_get_tile_info1(int tile_index) { K051316_get_tile_info(tile_index,1); }
K051316_get_tile_info2(int tile_index)4295 static void K051316_get_tile_info2(int tile_index) { K051316_get_tile_info(tile_index,2); }
4296
4297
K051316_vh_start(int chip,int gfx_memory_region,int bpp,int tilemap_type,int transparent_pen,void (* callback)(int * code,int * color))4298 int K051316_vh_start(int chip, int gfx_memory_region,int bpp,
4299 int tilemap_type,int transparent_pen,
4300 void (*callback)(int *code,int *color))
4301 {
4302 int gfx_index;
4303 static void (*get_tile_info[3])(int tile_index) = { K051316_get_tile_info0,K051316_get_tile_info1,K051316_get_tile_info2 };
4304
4305 /* find first empty slot to decode gfx */
4306 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
4307 if (Machine->gfx[gfx_index] == 0)
4308 break;
4309 if (gfx_index == MAX_GFX_ELEMENTS)
4310 return 1;
4311
4312 if (bpp == 4)
4313 {
4314 static struct GfxLayout charlayout =
4315 {
4316 16,16,
4317 0, /* filled in later */
4318 4,
4319 { 0, 1, 2, 3 },
4320 { 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4,
4321 8*4, 9*4, 10*4, 11*4, 12*4, 13*4, 14*4, 15*4 },
4322 { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64,
4323 8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 },
4324 128*8
4325 };
4326
4327
4328 /* tweak the structure for the number of tiles we have */
4329 charlayout.total = memory_region_length(gfx_memory_region) / 128;
4330
4331 /* decode the graphics */
4332 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&charlayout);
4333 }
4334 else if (bpp == 7 || bpp == 8)
4335 {
4336 static struct GfxLayout charlayout =
4337 {
4338 16,16,
4339 0, /* filled in later */
4340 0, /* filled in later */
4341 { 0 }, /* filled in later */
4342 { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8,
4343 8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 },
4344 { 0*128, 1*128, 2*128, 3*128, 4*128, 5*128, 6*128, 7*128,
4345 8*128, 9*128, 10*128, 11*128, 12*128, 13*128, 14*128, 15*128 },
4346 256*8
4347 };
4348 int i;
4349
4350
4351 /* tweak the structure for the number of tiles we have */
4352 charlayout.total = memory_region_length(gfx_memory_region) / 256;
4353 charlayout.planes = bpp;
4354 if (bpp == 7) for (i = 0;i < 7;i++) charlayout.planeoffset[i] = i+1;
4355 else for (i = 0;i < 8;i++) charlayout.planeoffset[i] = i;
4356
4357 /* decode the graphics */
4358 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&charlayout);
4359 }
4360 else
4361 {
4362 //logerror("K051316_vh_start supports only 4, 7 and 8 bpp\n");
4363 return 1;
4364 }
4365
4366 if (!Machine->gfx[gfx_index])
4367 return 1;
4368
4369 /* set the color information */
4370 if (Machine->drv->color_table_len)
4371 {
4372 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
4373 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / (1 << bpp);
4374 }
4375 else
4376 {
4377 Machine->gfx[gfx_index]->colortable = Machine->pens;
4378 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / (1 << bpp);
4379 }
4380
4381 K051316_memory_region[chip] = gfx_memory_region;
4382 K051316_gfxnum[chip] = gfx_index;
4383 K051316_bpp[chip] = bpp;
4384 K051316_callback[chip] = callback;
4385
4386 K051316_tilemap[chip] = tilemap_create(get_tile_info[chip],tilemap_scan_rows,tilemap_type,16,16,32,32);
4387
4388 K051316_ram[chip] = auto_malloc(0x800);
4389
4390 if (!K051316_ram[chip] || !K051316_tilemap[chip])
4391 return 1;
4392
4393 tilemap_set_transparent_pen(K051316_tilemap[chip],transparent_pen);
4394
4395 K051316_wraparound[chip] = 0; /* default = no wraparound */
4396 K051316_offset[chip][0] = K051316_offset[chip][1] = 0;
4397
4398 return 0;
4399 }
4400
K051316_vh_start_0(int gfx_memory_region,int bpp,int tilemap_type,int transparent_pen,void (* callback)(int * code,int * color))4401 int K051316_vh_start_0(int gfx_memory_region,int bpp,
4402 int tilemap_type,int transparent_pen,
4403 void (*callback)(int *code,int *color))
4404 {
4405 return K051316_vh_start(0,gfx_memory_region,bpp,tilemap_type,transparent_pen,callback);
4406 }
4407
K051316_vh_start_1(int gfx_memory_region,int bpp,int tilemap_type,int transparent_pen,void (* callback)(int * code,int * color))4408 int K051316_vh_start_1(int gfx_memory_region,int bpp,
4409 int tilemap_type,int transparent_pen,
4410 void (*callback)(int *code,int *color))
4411 {
4412 return K051316_vh_start(1,gfx_memory_region,bpp,tilemap_type,transparent_pen,callback);
4413 }
4414
K051316_vh_start_2(int gfx_memory_region,int bpp,int tilemap_type,int transparent_pen,void (* callback)(int * code,int * color))4415 int K051316_vh_start_2(int gfx_memory_region,int bpp,
4416 int tilemap_type,int transparent_pen,
4417 void (*callback)(int *code,int *color))
4418 {
4419 return K051316_vh_start(2,gfx_memory_region,bpp,tilemap_type,transparent_pen,callback);
4420 }
4421
4422
K051316_r(int chip,int offset)4423 int K051316_r(int chip, int offset)
4424 {
4425 return K051316_ram[chip][offset];
4426 }
4427
READ_HANDLER(K051316_0_r)4428 READ_HANDLER( K051316_0_r )
4429 {
4430 return K051316_r(0, offset);
4431 }
4432
READ_HANDLER(K051316_1_r)4433 READ_HANDLER( K051316_1_r )
4434 {
4435 return K051316_r(1, offset);
4436 }
4437
READ_HANDLER(K051316_2_r)4438 READ_HANDLER( K051316_2_r )
4439 {
4440 return K051316_r(2, offset);
4441 }
4442
4443
K051316_w(int chip,int offset,int data)4444 void K051316_w(int chip,int offset,int data)
4445 {
4446 if (K051316_ram[chip][offset] != data)
4447 {
4448 K051316_ram[chip][offset] = data;
4449 tilemap_mark_tile_dirty(K051316_tilemap[chip],offset & 0x3ff);
4450 }
4451 }
4452
WRITE_HANDLER(K051316_0_w)4453 WRITE_HANDLER( K051316_0_w )
4454 {
4455 K051316_w(0,offset,data);
4456 }
4457
WRITE_HANDLER(K051316_1_w)4458 WRITE_HANDLER( K051316_1_w )
4459 {
4460 K051316_w(1,offset,data);
4461 }
4462
WRITE_HANDLER(K051316_2_w)4463 WRITE_HANDLER( K051316_2_w )
4464 {
4465 K051316_w(2,offset,data);
4466 }
4467
4468
K051316_rom_r(int chip,int offset)4469 int K051316_rom_r(int chip, int offset)
4470 {
4471 if ((K051316_ctrlram[chip][0x0e] & 0x01) == 0)
4472 {
4473 int addr;
4474
4475 addr = offset + (K051316_ctrlram[chip][0x0c] << 11) + (K051316_ctrlram[chip][0x0d] << 19);
4476 if (K051316_bpp[chip] <= 4) addr /= 2;
4477 addr &= memory_region_length(K051316_memory_region[chip])-1;
4478
4479 // usrintf_showmessage("%04x: offset %04x addr %04x",activecpu_get_pc(),offset,addr);
4480
4481 return memory_region(K051316_memory_region[chip])[addr];
4482 }
4483 else
4484 {
4485 //logerror("%04x: read 051316 ROM offset %04x but reg 0x0c bit 0 not clear\n",activecpu_get_pc(),offset);
4486 return 0;
4487 }
4488 }
4489
READ_HANDLER(K051316_rom_0_r)4490 READ_HANDLER( K051316_rom_0_r )
4491 {
4492 return K051316_rom_r(0,offset);
4493 }
4494
READ_HANDLER(K051316_rom_1_r)4495 READ_HANDLER( K051316_rom_1_r )
4496 {
4497 return K051316_rom_r(1,offset);
4498 }
4499
READ_HANDLER(K051316_rom_2_r)4500 READ_HANDLER( K051316_rom_2_r )
4501 {
4502 return K051316_rom_r(2,offset);
4503 }
4504
4505
4506
K051316_ctrl_w(int chip,int offset,int data)4507 void K051316_ctrl_w(int chip,int offset,int data)
4508 {
4509 K051316_ctrlram[chip][offset] = data;
4510 //if (offset >= 0x0c) logerror("%04x: write %02x to 051316 reg %x\n",activecpu_get_pc(),data,offset);
4511 }
4512
WRITE_HANDLER(K051316_ctrl_0_w)4513 WRITE_HANDLER( K051316_ctrl_0_w )
4514 {
4515 K051316_ctrl_w(0,offset,data);
4516 }
4517
WRITE_HANDLER(K051316_ctrl_1_w)4518 WRITE_HANDLER( K051316_ctrl_1_w )
4519 {
4520 K051316_ctrl_w(1,offset,data);
4521 }
4522
WRITE_HANDLER(K051316_ctrl_2_w)4523 WRITE_HANDLER( K051316_ctrl_2_w )
4524 {
4525 K051316_ctrl_w(2,offset,data);
4526 }
4527
K051316_wraparound_enable(int chip,int status)4528 void K051316_wraparound_enable(int chip, int status)
4529 {
4530 K051316_wraparound[chip] = status;
4531 }
4532
K051316_set_offset(int chip,int xoffs,int yoffs)4533 void K051316_set_offset(int chip, int xoffs, int yoffs)
4534 {
4535 K051316_offset[chip][0] = xoffs;
4536 K051316_offset[chip][1] = yoffs;
4537 }
4538
4539
K051316_zoom_draw(int chip,struct mame_bitmap * bitmap,const struct rectangle * cliprect,int flags,UINT32 priority)4540 void K051316_zoom_draw(int chip, struct mame_bitmap *bitmap,const struct rectangle *cliprect,int flags,UINT32 priority)
4541 {
4542 UINT32 startx,starty;
4543 int incxx,incxy,incyx,incyy;
4544
4545 startx = 256 * ((INT16)(256 * K051316_ctrlram[chip][0x00] + K051316_ctrlram[chip][0x01]));
4546 incxx = (INT16)(256 * K051316_ctrlram[chip][0x02] + K051316_ctrlram[chip][0x03]);
4547 incyx = (INT16)(256 * K051316_ctrlram[chip][0x04] + K051316_ctrlram[chip][0x05]);
4548 starty = 256 * ((INT16)(256 * K051316_ctrlram[chip][0x06] + K051316_ctrlram[chip][0x07]));
4549 incxy = (INT16)(256 * K051316_ctrlram[chip][0x08] + K051316_ctrlram[chip][0x09]);
4550 incyy = (INT16)(256 * K051316_ctrlram[chip][0x0a] + K051316_ctrlram[chip][0x0b]);
4551
4552 startx -= (16 + K051316_offset[chip][1]) * incyx;
4553 starty -= (16 + K051316_offset[chip][1]) * incyy;
4554
4555 startx -= (89 + K051316_offset[chip][0]) * incxx;
4556 starty -= (89 + K051316_offset[chip][0]) * incxy;
4557
4558 tilemap_draw_roz(bitmap,cliprect,K051316_tilemap[chip],startx << 5,starty << 5,
4559 incxx << 5,incxy << 5,incyx << 5,incyy << 5,
4560 K051316_wraparound[chip],
4561 flags,priority);
4562
4563 #if 0
4564 usrintf_showmessage("%02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x",
4565 K051316_ctrlram[chip][0x00],
4566 K051316_ctrlram[chip][0x01],
4567 K051316_ctrlram[chip][0x02],
4568 K051316_ctrlram[chip][0x03],
4569 K051316_ctrlram[chip][0x04],
4570 K051316_ctrlram[chip][0x05],
4571 K051316_ctrlram[chip][0x06],
4572 K051316_ctrlram[chip][0x07],
4573 K051316_ctrlram[chip][0x08],
4574 K051316_ctrlram[chip][0x09],
4575 K051316_ctrlram[chip][0x0a],
4576 K051316_ctrlram[chip][0x0b],
4577 K051316_ctrlram[chip][0x0c], /* bank for ROM testing */
4578 K051316_ctrlram[chip][0x0d],
4579 K051316_ctrlram[chip][0x0e], /* 0 = test ROMs */
4580 K051316_ctrlram[chip][0x0f]);
4581 #endif
4582 }
4583
K051316_zoom_draw_0(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int flags,UINT32 priority)4584 void K051316_zoom_draw_0(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int flags,UINT32 priority)
4585 {
4586 K051316_zoom_draw(0,bitmap,cliprect,flags,priority);
4587 }
4588
K051316_zoom_draw_1(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int flags,UINT32 priority)4589 void K051316_zoom_draw_1(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int flags,UINT32 priority)
4590 {
4591 K051316_zoom_draw(1,bitmap,cliprect,flags,priority);
4592 }
4593
K051316_zoom_draw_2(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int flags,UINT32 priority)4594 void K051316_zoom_draw_2(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int flags,UINT32 priority)
4595 {
4596 K051316_zoom_draw(2,bitmap,cliprect,flags,priority);
4597 }
4598
4599
4600
4601 /***************************************************************************/
4602 /* */
4603 /* 053936 */
4604 /* */
4605 /***************************************************************************/
4606
4607 #define K053936_MAX_CHIPS 2
4608
4609 data16_t *K053936_0_ctrl,*K053936_0_linectrl;
4610 data16_t *K053936_1_ctrl,*K053936_1_linectrl;
4611 static int K053936_offset[K053936_MAX_CHIPS][2];
4612 static int K053936_wraparound[K053936_MAX_CHIPS];
4613
4614
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)4615 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)
4616 {
4617 if (ctrl[0x07] & 0x0040) /* "super" mode */
4618 {
4619 UINT32 startx,starty;
4620 int incxx,incxy;
4621 struct rectangle my_clip;
4622 int y,maxy;
4623
4624 if ((ctrl[0x07] & 0x0002) && ctrl[0x09]) /* wrong, but fixes glfgreat */
4625 {
4626 my_clip.min_x = ctrl[0x08] + K053936_offset[chip][0]+2;
4627 my_clip.max_x = ctrl[0x09] + K053936_offset[chip][0]+2 - 1;
4628 if (my_clip.min_x < cliprect->min_x)
4629 my_clip.min_x = cliprect->min_x;
4630 if (my_clip.max_x > cliprect->max_x)
4631 my_clip.max_x = cliprect->max_x;
4632
4633 y = ctrl[0x0a] + K053936_offset[chip][1]-2;
4634 if (y < cliprect->min_y)
4635 y = cliprect->min_y;
4636 maxy = ctrl[0x0b] + K053936_offset[chip][1]-2 - 1;
4637 if (maxy > cliprect->max_y)
4638 maxy = cliprect->max_y;
4639 }
4640 else
4641 {
4642 my_clip.min_x = cliprect->min_x;
4643 my_clip.max_x = cliprect->max_x;
4644
4645 y = cliprect->min_y;
4646 maxy = cliprect->max_y;
4647 }
4648
4649 while (y <= maxy)
4650 {
4651 data16_t *lineaddr = linectrl + 4*((y - K053936_offset[chip][1]) & 0x1ff);
4652 my_clip.min_y = my_clip.max_y = y;
4653
4654 startx = 256 * (INT16)(lineaddr[0] + ctrl[0x00]);
4655 starty = 256 * (INT16)(lineaddr[1] + ctrl[0x01]);
4656 incxx = (INT16)(lineaddr[2]);
4657 incxy = (INT16)(lineaddr[3]);
4658
4659 if (ctrl[0x06] & 0x8000) incxx *= 256;
4660 if (ctrl[0x06] & 0x0080) incxy *= 256;
4661
4662 startx -= K053936_offset[chip][0] * incxx;
4663 starty -= K053936_offset[chip][0] * incxy;
4664
4665 tilemap_draw_roz(bitmap,&my_clip,tilemap,startx << 5,starty << 5,
4666 incxx << 5,incxy << 5,0,0,
4667 K053936_wraparound[chip],
4668 flags,priority);
4669
4670 y++;
4671 }
4672 }
4673 else /* "simple" mode */
4674 {
4675 UINT32 startx,starty;
4676 int incxx,incxy,incyx,incyy;
4677
4678 startx = 256 * (INT16)(ctrl[0x00]);
4679 starty = 256 * (INT16)(ctrl[0x01]);
4680 incyx = (INT16)(ctrl[0x02]);
4681 incyy = (INT16)(ctrl[0x03]);
4682 incxx = (INT16)(ctrl[0x04]);
4683 incxy = (INT16)(ctrl[0x05]);
4684
4685 if (ctrl[0x06] & 0x4000) { incyx *= 256; incyy *= 256; }
4686 if (ctrl[0x06] & 0x0040) { incxx *= 256; incxy *= 256; }
4687
4688 startx -= K053936_offset[chip][1] * incyx;
4689 starty -= K053936_offset[chip][1] * incyy;
4690
4691 startx -= K053936_offset[chip][0] * incxx;
4692 starty -= K053936_offset[chip][0] * incxy;
4693
4694 tilemap_draw_roz(bitmap,cliprect,tilemap,startx << 5,starty << 5,
4695 incxx << 5,incxy << 5,incyx << 5,incyy << 5,
4696 K053936_wraparound[chip],
4697 flags,priority);
4698 }
4699
4700 #if 0
4701 if (keyboard_pressed(KEYCODE_D))
4702 usrintf_showmessage("%04x %04x %04x %04x\n%04x %04x %04x %04x\n%04x %04x %04x %04x\n%04x %04x %04x %04x",
4703 ctrl[0x00],
4704 ctrl[0x01],
4705 ctrl[0x02],
4706 ctrl[0x03],
4707 ctrl[0x04],
4708 ctrl[0x05],
4709 ctrl[0x06],
4710 ctrl[0x07],
4711 ctrl[0x08],
4712 ctrl[0x09],
4713 ctrl[0x0a],
4714 ctrl[0x0b],
4715 ctrl[0x0c],
4716 ctrl[0x0d],
4717 ctrl[0x0e],
4718 ctrl[0x0f]);
4719 #endif
4720 }
4721
4722
K053936_0_zoom_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect,struct tilemap * tilemap,int flags,UINT32 priority)4723 void K053936_0_zoom_draw(struct mame_bitmap *bitmap,const struct rectangle *cliprect,struct tilemap *tilemap,int flags,UINT32 priority)
4724 {
4725 K053936_zoom_draw(0,K053936_0_ctrl,K053936_0_linectrl,bitmap,cliprect,tilemap,flags,priority);
4726 }
4727
K053936_1_zoom_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect,struct tilemap * tilemap,int flags,UINT32 priority)4728 void K053936_1_zoom_draw(struct mame_bitmap *bitmap,const struct rectangle *cliprect,struct tilemap *tilemap,int flags,UINT32 priority)
4729 {
4730 K053936_zoom_draw(1,K053936_1_ctrl,K053936_1_linectrl,bitmap,cliprect,tilemap,flags,priority);
4731 }
4732
4733
K053936_wraparound_enable(int chip,int status)4734 void K053936_wraparound_enable(int chip, int status)
4735 {
4736 K053936_wraparound[chip] = status;
4737 }
4738
4739
K053936_set_offset(int chip,int xoffs,int yoffs)4740 void K053936_set_offset(int chip, int xoffs, int yoffs)
4741 {
4742 K053936_offset[chip][0] = xoffs;
4743 K053936_offset[chip][1] = yoffs;
4744 }
4745
4746
4747
4748 /***************************************************************************/
4749 /* */
4750 /* 053251 */
4751 /* */
4752 /***************************************************************************/
4753
4754 static unsigned char K053251_ram[16];
4755 static int K053251_palette_index[5];
4756 static struct tilemap *K053251_tilemaps[5];
4757 static int K053251_tilemaps_set;
4758
K053251_reset_indexes(void)4759 static void K053251_reset_indexes(void)
4760 {
4761 K053251_palette_index[0] = 32 * ((K053251_ram[9] >> 0) & 0x03);
4762 K053251_palette_index[1] = 32 * ((K053251_ram[9] >> 2) & 0x03);
4763 K053251_palette_index[2] = 32 * ((K053251_ram[9] >> 4) & 0x03);
4764 K053251_palette_index[3] = 16 * ((K053251_ram[10] >> 0) & 0x07);
4765 K053251_palette_index[4] = 16 * ((K053251_ram[10] >> 3) & 0x07);
4766 }
4767
K053251_vh_start(void)4768 int K053251_vh_start(void)
4769 {
4770 K053251_set_tilemaps(NULL,NULL,NULL,NULL,NULL);
4771
4772 state_save_register_UINT8("K053251", 0, "registers", K053251_ram, 16);
4773 state_save_register_func_postload(K053251_reset_indexes);
4774
4775 return 0;
4776 }
4777
K053251_set_tilemaps(struct tilemap * ci0,struct tilemap * ci1,struct tilemap * ci2,struct tilemap * ci3,struct tilemap * ci4)4778 void K053251_set_tilemaps(struct tilemap *ci0,struct tilemap *ci1,struct tilemap *ci2,struct tilemap *ci3,struct tilemap *ci4)
4779 {
4780 K053251_tilemaps[0] = ci0;
4781 K053251_tilemaps[1] = ci1;
4782 K053251_tilemaps[2] = ci2;
4783 K053251_tilemaps[3] = ci3;
4784 K053251_tilemaps[4] = ci4;
4785
4786 K053251_tilemaps_set = (ci0 || ci1 || ci2 || ci3 || ci4) ? 1 : 0;
4787 }
4788
WRITE_HANDLER(K053251_w)4789 WRITE_HANDLER( K053251_w )
4790 {
4791 int i,newind;
4792
4793 data &= 0x3f;
4794
4795 if (K053251_ram[offset] != data)
4796 {
4797 K053251_ram[offset] = data;
4798 if (offset == 9)
4799 {
4800 /* palette base index */
4801 for (i = 0;i < 3;i++)
4802 {
4803 newind = 32 * ((data >> 2*i) & 0x03);
4804 if (K053251_palette_index[i] != newind)
4805 {
4806 K053251_palette_index[i] = newind;
4807 if (K053251_tilemaps[i])
4808 tilemap_mark_all_tiles_dirty(K053251_tilemaps[i]);
4809
4810 }
4811 }
4812
4813 if (!K053251_tilemaps_set)
4814 tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
4815 }
4816 else if (offset == 10)
4817 {
4818 /* palette base index */
4819 for (i = 0;i < 2;i++)
4820 {
4821 newind = 16 * ((data >> 3*i) & 0x07);
4822 if (K053251_palette_index[3+i] != newind)
4823 {
4824 K053251_palette_index[3+i] = newind;
4825 if (K053251_tilemaps[3+i])
4826 tilemap_mark_all_tiles_dirty(K053251_tilemaps[3+i]);
4827
4828 }
4829 }
4830
4831 if (!K053251_tilemaps_set)
4832 tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
4833 }
4834 }
4835 }
4836
WRITE16_HANDLER(K053251_lsb_w)4837 WRITE16_HANDLER( K053251_lsb_w )
4838 {
4839 if (ACCESSING_LSB)
4840 K053251_w(offset, data & 0xff);
4841 }
4842
WRITE16_HANDLER(K053251_msb_w)4843 WRITE16_HANDLER( K053251_msb_w )
4844 {
4845 if (ACCESSING_MSB)
4846 K053251_w(offset, (data >> 8) & 0xff);
4847 }
4848
K053251_get_priority(int ci)4849 int K053251_get_priority(int ci)
4850 {
4851 return K053251_ram[ci];
4852 }
4853
K053251_get_palette_index(int ci)4854 int K053251_get_palette_index(int ci)
4855 {
4856 return K053251_palette_index[ci];
4857 }
4858
4859
4860
4861 /***************************************************************************/
4862 /* */
4863 /* 054000 */
4864 /* */
4865 /***************************************************************************/
4866
4867 static unsigned char K054000_ram[0x20];
4868
WRITE_HANDLER(K054000_w)4869 WRITE_HANDLER( K054000_w )
4870 {
4871 //logerror("%04x: write %02x to 054000 address %02x\n",activecpu_get_pc(),data,offset);
4872
4873 K054000_ram[offset] = data;
4874 }
4875
READ_HANDLER(K054000_r)4876 READ_HANDLER( K054000_r )
4877 {
4878 int Acx,Acy,Aax,Aay;
4879 int Bcx,Bcy,Bax,Bay;
4880
4881 //logerror("%04x: read 054000 address %02x\n",activecpu_get_pc(),offset);
4882
4883 if (offset != 0x18) return 0;
4884
4885 Acx = (K054000_ram[0x01] << 16) | (K054000_ram[0x02] << 8) | K054000_ram[0x03];
4886 Acy = (K054000_ram[0x09] << 16) | (K054000_ram[0x0a] << 8) | K054000_ram[0x0b];
4887 /* TODO: this is a hack to make thndrx2 pass the startup check. It is certainly wrong. */
4888 if (K054000_ram[0x04] == 0xff) Acx+=3;
4889 if (K054000_ram[0x0c] == 0xff) Acy+=3;
4890 Aax = K054000_ram[0x06] + 1;
4891 Aay = K054000_ram[0x07] + 1;
4892
4893 Bcx = (K054000_ram[0x15] << 16) | (K054000_ram[0x16] << 8) | K054000_ram[0x17];
4894 Bcy = (K054000_ram[0x11] << 16) | (K054000_ram[0x12] << 8) | K054000_ram[0x13];
4895 Bax = K054000_ram[0x0e] + 1;
4896 Bay = K054000_ram[0x0f] + 1;
4897
4898 if (Acx + Aax < Bcx - Bax)
4899 return 1;
4900
4901 if (Bcx + Bax < Acx - Aax)
4902 return 1;
4903
4904 if (Acy + Aay < Bcy - Bay)
4905 return 1;
4906
4907 if (Bcy + Bay < Acy - Aay)
4908 return 1;
4909
4910 return 0;
4911 }
4912
READ16_HANDLER(K054000_lsb_r)4913 READ16_HANDLER( K054000_lsb_r )
4914 {
4915 return K054000_r(offset);
4916 }
4917
WRITE16_HANDLER(K054000_lsb_w)4918 WRITE16_HANDLER( K054000_lsb_w )
4919 {
4920 if (ACCESSING_LSB)
4921 K054000_w(offset, data & 0xff);
4922 }
4923
4924
4925
4926 /***************************************************************************/
4927 /* */
4928 /* 051733 */
4929 /* */
4930 /***************************************************************************/
4931
4932 static unsigned char K051733_ram[0x20];
4933
WRITE_HANDLER(K051733_w)4934 WRITE_HANDLER( K051733_w )
4935 {
4936 //logerror("%04x: write %02x to 051733 address %02x\n",activecpu_get_pc(),data,offset);
4937
4938 K051733_ram[offset] = data;
4939 }
4940
4941
int_sqrt(UINT32 op)4942 static int int_sqrt(UINT32 op)
4943 {
4944 UINT32 i,step;
4945
4946 i = 0x8000;
4947 step = 0x4000;
4948 while (step)
4949 {
4950 if (i*i == op) return i;
4951 else if (i*i > op) i -= step;
4952 else i += step;
4953 step >>= 1;
4954 }
4955 return i;
4956 }
4957
READ_HANDLER(K051733_r)4958 READ_HANDLER( K051733_r )
4959 {
4960 int op1 = (K051733_ram[0x00] << 8) | K051733_ram[0x01];
4961 int op2 = (K051733_ram[0x02] << 8) | K051733_ram[0x03];
4962 int op3 = (K051733_ram[0x04] << 8) | K051733_ram[0x05];
4963
4964 int rad = (K051733_ram[0x06] << 8) | K051733_ram[0x07];
4965 int yobj1c = (K051733_ram[0x08] << 8) | K051733_ram[0x09];
4966 int xobj1c = (K051733_ram[0x0a] << 8) | K051733_ram[0x0b];
4967 int yobj2c = (K051733_ram[0x0c] << 8) | K051733_ram[0x0d];
4968 int xobj2c = (K051733_ram[0x0e] << 8) | K051733_ram[0x0f];
4969
4970 //logerror("%04x: read 051733 address %02x\n",activecpu_get_pc(),offset);
4971
4972 switch(offset){
4973 case 0x00:
4974 if (op2) return (op1 / op2) >> 8;
4975 else return 0xff;
4976 case 0x01:
4977 if (op2) return (op1 / op2) & 0xff;
4978 else return 0xff;
4979
4980 /* this is completely unverified */
4981 case 0x02:
4982 if (op2) return (op1 % op2) >> 8;
4983 else return 0xff;
4984 case 0x03:
4985 if (op2) return (op1 % op2) & 0xff;
4986 else return 0xff;
4987
4988 case 0x04:
4989 return int_sqrt(op3<<16) >> 8;
4990
4991 case 0x05:
4992 return int_sqrt(op3<<16) & 0xff;
4993
4994 case 0x07:{
4995 if (xobj1c + rad < xobj2c)
4996 return 0x80;
4997
4998 if (xobj2c + rad < xobj1c)
4999 return 0x80;
5000
5001 if (yobj1c + rad < yobj2c)
5002 return 0x80;
5003
5004 if (yobj2c + rad < yobj1c)
5005 return 0x80;
5006
5007 return 0;
5008 }
5009 case 0x0e:
5010 return ~K051733_ram[offset];
5011 case 0x0f:
5012 return ~K051733_ram[offset];
5013 default:
5014 return K051733_ram[offset];
5015 }
5016 }
5017
5018
5019
5020 /***************************************************************************/
5021 /* */
5022 /* 054157 */
5023 /* */
5024 /***************************************************************************/
5025
5026 static struct tilemap *K054157_tilemap[4], *K054157_cur_tilemap;
5027 static struct tilemap *K054157_tilemapb[4], *K054157_tilemaps[4];
5028
5029 static data16_t K054157_regs[0x20], K054157_regsb[4];
5030 static void (*K054157_linescroll_updater[4])(int layer);
5031
5032 static int K054157_cur_rombank, K054157_romnbbanks;
5033 static int K054157_uses_tile_banks, K054157_cur_tile_bank;
5034 static int K054157_gfxnum, K054157_memory_region;
5035 static int K054157_cur_offset;
5036 static data16_t *K054157_rambase, *K054157_cur_spbase, *K054157_cur_rambase;
5037 static data8_t *K054157_rombase;
5038 static data16_t *K054157_rambasel[8];
5039 static int K054157_tilemapl[8], K054157_offsetl[8];
5040
5041 static void (*K054157_callback)(int, int *, int *);
5042
K054157_get_tile_info(int tile_index,int layer)5043 static INLINE void K054157_get_tile_info(int tile_index,int layer)
5044 {
5045 data16_t *addr;
5046 int attr, code;
5047 data16_t *lbase = K054157_rambase + 0x2000*layer;
5048 if(tile_index < 64*32)
5049 addr = lbase + (tile_index<<1);
5050 else
5051 addr = lbase + (tile_index<<1) + 0x1000 - 64*32*2;
5052
5053 attr = addr[0];
5054 code = addr[1];
5055 tile_info.flags = 0;
5056
5057 (*K054157_callback)(layer, &code, &attr);
5058 SET_TILE_INFO(K054157_gfxnum,
5059 code,
5060 attr,
5061 tile_info.flags)
5062 }
5063
K054157_get_tile_info0(int tile_index)5064 static void K054157_get_tile_info0(int tile_index) { K054157_get_tile_info(tile_index,0); }
K054157_get_tile_info1(int tile_index)5065 static void K054157_get_tile_info1(int tile_index) { K054157_get_tile_info(tile_index,1); }
K054157_get_tile_info2(int tile_index)5066 static void K054157_get_tile_info2(int tile_index) { K054157_get_tile_info(tile_index,2); }
K054157_get_tile_info3(int tile_index)5067 static void K054157_get_tile_info3(int tile_index) { K054157_get_tile_info(tile_index,3); }
5068
5069
K054157_lsu_1_256(int layer)5070 static void K054157_lsu_1_256(int layer)
5071 {
5072 int y;
5073 int basey = K054157_regs[0x10|layer];
5074
5075 data16_t *baseram = K054157_cur_spbase + layer*0x400;
5076 for(y=0; y<256; y++) {
5077 int offset = (((basey + y) & 0x1ff) << 1) | 1;
5078 tilemap_set_scrollx(K054157_tilemap[layer], y, baseram[offset]);
5079 }
5080 }
5081
K054157_lsu_1_512(int layer)5082 static void K054157_lsu_1_512(int layer)
5083 {
5084 int y;
5085 int basey = K054157_regs[0x10|layer];
5086
5087 data16_t *baseram = K054157_cur_spbase + layer*0x400;
5088 for(y=0; y<512; y++) {
5089 int offset = (((basey + y) & 0x1ff) << 1) | 1;
5090 tilemap_set_scrollx(K054157_tilemap[layer], y, baseram[offset]);
5091 }
5092 }
5093
K054157_lsu_8_256(int layer)5094 static void K054157_lsu_8_256(int layer)
5095 {
5096 int y;
5097 int basey = K054157_regs[0x10|layer];
5098
5099 data16_t *baseram = K054157_cur_spbase + layer*0x400;
5100 for(y=0; y<256; y++) {
5101 int offset = (((basey + y) & 0x1f8) << 1) | 1;
5102 tilemap_set_scrollx(K054157_tilemap[layer], y, baseram[offset]);
5103 }
5104 }
5105
K054157_lsu_8_512(int layer)5106 static void K054157_lsu_8_512(int layer)
5107 {
5108 int y;
5109 int basey = K054157_regs[0x10|layer];
5110
5111 data16_t *baseram = K054157_cur_spbase + layer*0x400;
5112 for(y=0; y<512; y++) {
5113 int offset = (((basey + y) & 0x1f8) << 1) | 1;
5114 tilemap_set_scrollx(K054157_tilemap[layer], y, baseram[offset]);
5115 }
5116 }
5117
K054157_lsu_full(int layer)5118 static void K054157_lsu_full(int layer)
5119 {
5120 tilemap_set_scrollx(K054157_tilemap[layer], 0, K054157_regs[0x14|layer]);
5121 }
5122
K054157_reset_linescroll(void)5123 static void K054157_reset_linescroll(void)
5124 {
5125 int layer;
5126 int mode = K054157_regs[5];
5127 for(layer=0; layer < 4; layer++) {
5128 int lmode = (mode >> (layer << 1)) & 3;
5129 switch(lmode) {
5130 case 0:
5131 if(K054157_tilemap[layer] == K054157_tilemaps[layer]) {
5132 K054157_linescroll_updater[layer] = K054157_lsu_1_256;
5133 tilemap_set_scroll_rows(K054157_tilemap[layer], 256);
5134 } else {
5135 K054157_linescroll_updater[layer] = K054157_lsu_1_512;
5136 tilemap_set_scroll_rows(K054157_tilemap[layer], 512);
5137 }
5138 break;
5139 case 1:
5140 // logerror("LS mode layer %d unknown (%d)\n", layer, lmode);
5141 goto rhaaa_lovely;
5142 case 2:
5143 if(K054157_tilemap[layer] == K054157_tilemaps[layer]) {
5144 K054157_linescroll_updater[layer] = K054157_lsu_8_256;
5145 tilemap_set_scroll_rows(K054157_tilemap[layer], 256);
5146 } else {
5147 K054157_linescroll_updater[layer] = K054157_lsu_8_512;
5148 tilemap_set_scroll_rows(K054157_tilemap[layer], 512);
5149 }
5150 break;
5151 case 3:
5152 rhaaa_lovely:
5153 K054157_linescroll_updater[layer] = K054157_lsu_full;
5154 tilemap_set_scroll_rows(K054157_tilemap[layer], 1);
5155 break;
5156 }
5157 }
5158 }
5159
K054157_change_tilemap(int layer)5160 static void K054157_change_tilemap(int layer)
5161 {
5162 int flip = 0;
5163 if(K054157_regs[8|layer] & 1) {
5164 tilemap_set_enable(K054157_tilemapb[layer], 1);
5165 tilemap_set_enable(K054157_tilemaps[layer], 0);
5166 K054157_tilemap[layer] = K054157_tilemapb[layer];
5167 } else {
5168 tilemap_set_enable(K054157_tilemapb[layer], 0);
5169 tilemap_set_enable(K054157_tilemaps[layer], 1);
5170 K054157_tilemap[layer] = K054157_tilemaps[layer];
5171 }
5172 tilemap_mark_all_tiles_dirty(K054157_tilemap[layer]);
5173
5174 if(K054157_regs[0] & 0x20)
5175 flip |= TILEMAP_FLIPY;
5176 if(K054157_regs[0] & 0x10)
5177 flip |= TILEMAP_FLIPX;
5178
5179 tilemap_set_flip(K054157_tilemap[layer], flip);
5180
5181 K054157_reset_linescroll();
5182 }
5183
K054157_reset_tilemaps(void)5184 static void K054157_reset_tilemaps(void)
5185 {
5186 int i;
5187 // To avoid crashes in K054157_reset_linescroll()
5188 for(i=0; i<4; i++)
5189 K054157_tilemap[i] = K054157_tilemaps[i];
5190 for(i=0; i<4; i++)
5191 K054157_change_tilemap(i);
5192 }
5193
K054157_change_flip(void)5194 static void K054157_change_flip(void)
5195 {
5196 int flip = 0;
5197
5198 if(K054157_regs[0] & 0x20)
5199 flip |= TILEMAP_FLIPY;
5200 if(K054157_regs[0] & 0x10)
5201 flip |= TILEMAP_FLIPX;
5202 tilemap_set_flip(K054157_tilemap[0], flip);
5203 tilemap_set_flip(K054157_tilemap[1], flip);
5204 tilemap_set_flip(K054157_tilemap[2], flip);
5205 tilemap_set_flip(K054157_tilemap[3], flip);
5206 }
5207
K054157_change_rambank(void)5208 static void K054157_change_rambank(void)
5209 {
5210 int bank = ((K054157_regs[0x19]>>2) & 6) | (K054157_regs[0x19] & 1);
5211
5212 K054157_cur_rambase = K054157_rambasel[bank];
5213 K054157_cur_tilemap = K054157_tilemap[K054157_tilemapl[bank]];
5214 K054157_cur_offset = K054157_offsetl[bank];
5215 }
5216
K054157_change_splayer(void)5217 static void K054157_change_splayer(void)
5218 {
5219 int bank = ((K054157_regs[0x18]>>2) & 6) | (K054157_regs[0x18] & 1);
5220 K054157_cur_spbase = K054157_rambasel[bank];
5221 }
5222
K054157_change_rombank(void)5223 static void K054157_change_rombank(void)
5224 {
5225 int bank;
5226
5227 if (K054157_uses_tile_banks) /* asterix */
5228 bank = (K054157_regs[0x1a] >> 8) | (K054157_regs[0x1b] << 4) | (K054157_cur_tile_bank << 6);
5229 else /* everything else */
5230 bank = K054157_regs[0x1a] | (K054157_regs[0x1b] << 16);
5231
5232 K054157_cur_rombank = bank % K054157_romnbbanks;
5233 //usrintf_showmessage("%04x: %04x %04x %04x",activecpu_get_pc(),K054157_regs[0x1a],K054157_regs[0x1b],K054157_cur_rombank);
5234 }
5235
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 *))5236 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 *))
5237 {
5238 int gfx_index;
5239 int i;
5240 static struct GfxLayout charlayout =
5241 {
5242 8, 8,
5243 0, /* filled in later */
5244 4,
5245 { 0, 0, 0, 0 }, /* filled in later */
5246 { 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4 },
5247 { 0*8*4, 1*8*4, 2*8*4, 3*8*4, 4*8*4, 5*8*4, 6*8*4, 7*8*4 },
5248 8*8*4
5249 };
5250
5251 /* find first empty slot to decode gfx */
5252 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
5253 if (Machine->gfx[gfx_index] == 0)
5254 break;
5255 if (gfx_index == MAX_GFX_ELEMENTS)
5256 return 1;
5257
5258 /* tweak the structure for the number of tiles we have */
5259 charlayout.total = memory_region_length(gfx_memory_region) / (8*4);
5260 charlayout.planeoffset[0] = plane0;
5261 charlayout.planeoffset[1] = plane1;
5262 charlayout.planeoffset[2] = plane2;
5263 charlayout.planeoffset[3] = plane3;
5264
5265 /* decode the graphics */
5266 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region), &charlayout);
5267 if (!Machine->gfx[gfx_index])
5268 return 1;
5269
5270 /* set the color information */
5271 if (Machine->drv->color_table_len)
5272 {
5273 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
5274 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
5275 }
5276 else
5277 {
5278 Machine->gfx[gfx_index]->colortable = Machine->pens;
5279 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / 16;
5280 }
5281
5282 K054157_memory_region = gfx_memory_region;
5283 K054157_gfxnum = gfx_index;
5284 K054157_callback = callback;
5285
5286 K054157_rombase = memory_region(gfx_memory_region);
5287 K054157_romnbbanks = memory_region_length(gfx_memory_region)/0x2000;
5288 K054157_cur_rombank = 0;
5289 K054157_uses_tile_banks = 0;
5290
5291 K054157_tilemapb[0] = tilemap_create(K054157_get_tile_info0, tilemap_scan_rows,
5292 TILEMAP_TRANSPARENT, 8, 8, 64, 64);
5293 K054157_tilemapb[1] = tilemap_create(K054157_get_tile_info1, tilemap_scan_rows,
5294 TILEMAP_TRANSPARENT, 8, 8, 64, 64);
5295 K054157_tilemapb[2] = tilemap_create(K054157_get_tile_info2, tilemap_scan_rows,
5296 TILEMAP_TRANSPARENT, 8, 8, 64, 64);
5297 K054157_tilemapb[3] = tilemap_create(K054157_get_tile_info3, tilemap_scan_rows,
5298 TILEMAP_TRANSPARENT, 8, 8, 64, 64);
5299 K054157_tilemaps[0] = tilemap_create(K054157_get_tile_info0, tilemap_scan_rows,
5300 TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5301 K054157_tilemaps[1] = tilemap_create(K054157_get_tile_info1, tilemap_scan_rows,
5302 TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5303 K054157_tilemaps[2] = tilemap_create(K054157_get_tile_info2, tilemap_scan_rows,
5304 TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5305 K054157_tilemaps[3] = tilemap_create(K054157_get_tile_info3, tilemap_scan_rows,
5306 TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5307
5308 K054157_rambase = auto_malloc(0x14000);
5309
5310 if(!K054157_rambase
5311 || !K054157_tilemapb[0] || !K054157_tilemapb[1] || !K054157_tilemapb[2] || !K054157_tilemapb[3]
5312 || !K054157_tilemaps[0] || !K054157_tilemaps[1] || !K054157_tilemaps[2] || !K054157_tilemaps[3])
5313 return 1;
5314
5315 if(big) {
5316 K054157_rambasel[0] = K054157_rambase + 0x2000;
5317 K054157_rambasel[1] = K054157_rambase + 0x6000;
5318 K054157_rambasel[2] = K054157_rambase + 0x3000;
5319 K054157_rambasel[3] = K054157_rambase + 0x7000;
5320 K054157_rambasel[4] = K054157_rambase + 0x4000;
5321 K054157_rambasel[5] = K054157_rambase + 0x0000;
5322 K054157_rambasel[6] = K054157_rambase + 0x5000;
5323 K054157_rambasel[7] = K054157_rambase + 0x1000;
5324 } else {
5325 K054157_rambasel[0] = K054157_rambase + 0x0000;
5326 K054157_rambasel[1] = K054157_rambase + 0x2000;
5327 K054157_rambasel[2] = K054157_rambase + 0x4000;
5328 K054157_rambasel[3] = K054157_rambase + 0x6000;
5329 K054157_rambasel[4] = 0;
5330 K054157_rambasel[5] = 0;
5331 K054157_rambasel[6] = 0;
5332 K054157_rambasel[7] = 0;
5333 }
5334
5335 for(i=0; i<8; i++) {
5336 if(K054157_rambasel[i]) {
5337 int delta = K054157_rambasel[i] - K054157_rambase;
5338 K054157_tilemapl[i] = delta >> 13;
5339 K054157_offsetl [i] = (delta & 0x1000) ? 64*32 : 0;
5340 } else {
5341 K054157_tilemapl[i] = 0;
5342 K054157_offsetl [i] = 0;
5343 }
5344 }
5345
5346 memset(K054157_rambase, 0, 0x10000);
5347 memset(K054157_regs, 0, 0x40);
5348 memset(K054157_regsb, 0, 8);
5349
5350 for(i=0; i<4; i++) {
5351 tilemap_set_transparent_pen(K054157_tilemapb[i],0);
5352 tilemap_set_scrolldx(K054157_tilemapb[i], -scrolld[0][i][0], -scrolld[1][i][0]);
5353 tilemap_set_scrolldy(K054157_tilemapb[i], -scrolld[0][i][1], -scrolld[1][i][1]);
5354
5355 tilemap_set_transparent_pen(K054157_tilemaps[i],0);
5356 tilemap_set_scrolldx(K054157_tilemaps[i], -scrolld[0][i][0], -scrolld[1][i][0]);
5357 tilemap_set_scrolldy(K054157_tilemaps[i], -scrolld[0][i][1], -scrolld[1][i][1]);
5358 }
5359
5360 K054157_reset_tilemaps();
5361 K054157_change_rambank();
5362 K054157_change_rombank();
5363 K054157_change_splayer();
5364
5365 state_save_register_UINT16("K054157", 0, "memory", K054157_rambase, 0x8000);
5366 state_save_register_UINT16("K054157", 0, "registers", K054157_regs, 0x20);
5367 state_save_register_UINT16("K054157", 0, "registers b", K054157_regsb, 0x4);
5368
5369 state_save_register_func_postload(K054157_reset_tilemaps);
5370 state_save_register_func_postload(K054157_change_rambank);
5371 state_save_register_func_postload(K054157_change_rombank);
5372
5373 return 0;
5374 }
5375
5376
READ16_HANDLER(K054157_ram_word_r)5377 READ16_HANDLER( K054157_ram_word_r )
5378 {
5379 return K054157_cur_rambase[offset];
5380 }
5381
READ16_HANDLER(K054157_ram_half_word_r)5382 READ16_HANDLER( K054157_ram_half_word_r )
5383 {
5384 return K054157_cur_rambase[((offset << 1) & 0xffe) | ((offset >> 11) ^ 1)];
5385 }
5386
READ16_HANDLER(K054157_rom_word_r)5387 READ16_HANDLER( K054157_rom_word_r )
5388 {
5389 int addr = 0x2000*K054157_cur_rombank + 2*offset;
5390
5391 // usrintf_showmessage("%04x: addr %06x",activecpu_get_pc(),addr);
5392
5393 return K054157_rombase[addr+1] | (K054157_rombase[addr] << 8);
5394 }
5395
READ16_HANDLER(K054157_rom_word_8000_r)5396 READ16_HANDLER( K054157_rom_word_8000_r )
5397 {
5398 int addr = 0x8000*K054157_cur_rombank + 2*offset;
5399
5400 // usrintf_showmessage("%04x: addr %06x",activecpu_get_pc(),addr);
5401
5402 // printf("rd @ %x (bank %x, final %x)\n", offset*2, K054157_cur_rombank, addr);
5403
5404 return K054157_rombase[addr+1] | (K054157_rombase[addr] << 8);
5405 }
5406
WRITE16_HANDLER(K054157_ram_word_w)5407 WRITE16_HANDLER( K054157_ram_word_w )
5408 {
5409 data16_t *adr = K054157_cur_rambase + offset;
5410 data16_t old = *adr;
5411
5412 COMBINE_DATA(adr);
5413 if(*adr != old && K054157_cur_tilemap)
5414 tilemap_mark_tile_dirty(K054157_cur_tilemap, offset/2 + K054157_cur_offset);
5415 }
5416
WRITE16_HANDLER(K054157_ram_half_word_w)5417 WRITE16_HANDLER( K054157_ram_half_word_w )
5418 {
5419 data16_t *adr = K054157_cur_rambase + (((offset << 1) & 0xffe) | 1);
5420 data16_t old = *adr;
5421
5422 COMBINE_DATA(adr);
5423 if(*adr != old)
5424 tilemap_mark_tile_dirty(K054157_cur_tilemap, (offset & 0x7ff) + K054157_cur_offset);
5425 }
5426
WRITE16_HANDLER(K054157_word_w)5427 WRITE16_HANDLER( K054157_word_w )
5428 {
5429 UINT16 old = K054157_regs[offset];
5430 COMBINE_DATA (K054157_regs + offset);
5431
5432 if(K054157_regs[offset] != old)
5433 {
5434 switch(offset) {
5435 case 0x00:
5436 if((K054157_regs[0] & 0x30) != (old & 0x30))
5437 K054157_change_flip();
5438 break;
5439 case 0x05:
5440 K054157_reset_linescroll();
5441 break;
5442 case 0x08:
5443 case 0x09:
5444 case 0x0a:
5445 case 0x0b:
5446 if((K054157_regs[offset] & 1) ^ (K054157_tilemap[offset & 3] == K054157_tilemapb[offset & 3]))
5447 K054157_change_tilemap(offset & 3);
5448 break;
5449 case 0x18:
5450 K054157_change_splayer();
5451 break;
5452 case 0x19:
5453 K054157_change_rambank();
5454 break;
5455 case 0x1a:
5456 case 0x1b:
5457 K054157_change_rombank();
5458 break;
5459 case 0x1c:
5460 tilemap_mark_all_tiles_dirty(K054157_tilemapb[0]);
5461 tilemap_mark_all_tiles_dirty(K054157_tilemapb[1]);
5462 tilemap_mark_all_tiles_dirty(K054157_tilemapb[2]);
5463 tilemap_mark_all_tiles_dirty(K054157_tilemapb[3]);
5464 tilemap_mark_all_tiles_dirty(K054157_tilemaps[0]);
5465 tilemap_mark_all_tiles_dirty(K054157_tilemaps[1]);
5466 tilemap_mark_all_tiles_dirty(K054157_tilemaps[2]);
5467 tilemap_mark_all_tiles_dirty(K054157_tilemaps[3]);
5468 break;
5469 }
5470 }
5471 }
5472
WRITE16_HANDLER(K054157_b_word_w)5473 WRITE16_HANDLER( K054157_b_word_w )
5474 {
5475 COMBINE_DATA (K054157_regsb + offset);
5476 }
5477
K054157_tilemap_update(void)5478 void K054157_tilemap_update(void)
5479 {
5480 int layer;
5481
5482 for(layer=0; layer<4; layer++)
5483 {
5484 K054157_linescroll_updater[layer](layer);
5485 tilemap_set_scrolly(K054157_tilemap[layer], 0, K054157_regs[0x10|layer]);
5486 }
5487 }
5488
K054157_tilemap_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int num,int flags,UINT32 priority)5489 void K054157_tilemap_draw(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int num, int flags, UINT32 priority)
5490 {
5491 tilemap_draw(bitmap,cliprect, K054157_tilemap[num], flags, priority);
5492 }
5493
K054157_is_IRQ_enabled(void)5494 int K054157_is_IRQ_enabled(void)
5495 {
5496 return K054157_regs[3] & 1;
5497 }
5498
K054157_get_lookup(int bits)5499 int K054157_get_lookup(int bits)
5500 {
5501 int res;
5502
5503 res = (K054157_regs[0x1c] >> (bits << 2)) & 0x0f;
5504
5505 if (K054157_uses_tile_banks) /* Asterix */
5506 res |= K054157_cur_tile_bank << 4;
5507
5508 return res;
5509 }
5510
K054157_set_tile_bank(int bank)5511 void K054157_set_tile_bank(int bank)
5512 {
5513 K054157_uses_tile_banks = 1;
5514
5515 if (K054157_cur_tile_bank != bank)
5516 {
5517 K054157_cur_tile_bank = bank;
5518
5519 tilemap_mark_all_tiles_dirty(K054157_tilemap[0]);
5520 tilemap_mark_all_tiles_dirty(K054157_tilemap[1]);
5521 tilemap_mark_all_tiles_dirty(K054157_tilemap[2]);
5522 tilemap_mark_all_tiles_dirty(K054157_tilemap[3]);
5523 }
5524
5525 K054157_change_rombank();
5526 }
5527
5528
5529
5530 /***************************************************************************/
5531 /* */
5532 /* 056832 */
5533 /* */
5534 /***************************************************************************/
5535
5536 #define K056832_PAGE_COLS 64
5537 #define K056832_PAGE_ROWS 32
5538 #define K056832_PAGE_HEIGHT (K056832_PAGE_ROWS*8)
5539 #define K056832_PAGE_WIDTH (K056832_PAGE_COLS*8)
5540 #define K056832_PAGE_COUNT 16
5541
5542 static struct tilemap *K056832_tilemap[K056832_PAGE_COUNT];
5543 static struct mame_bitmap *K056832_pixmap[K056832_PAGE_COUNT];
5544
5545 static data16_t K056832_regs[0x20]; // 157/832 regs group 1
5546 static data16_t K056832_regsb[4]; // 157/832 regs group 2, board dependent
5547
5548 static data8_t *K056832_rombase; // pointer to tile gfx data
5549 static data16_t *K056832_videoram;
5550 static int K056832_NumGfxBanks; // depends on size of graphics ROMs
5551 static int K056832_CurGfxBank; // cached info for K056832_regs[0x1a]
5552 static int K056832_gfxnum; // graphics element index for unpacked tiles
5553 static int K056832_memory_region; // memory region for tile gfx data
5554 static int K056832_bpp;
5555
5556 // ROM readback involves reading 2 halves of a word
5557 // from the same location in a row. Reading the
5558 // RAM window resets this state so you get the first half.
5559 static int K056832_rom_half;
5560
5561 // locally cached values
5562 static int K056832_LayerAssociatedWithPage[K056832_PAGE_COUNT];
5563 static int K056832_LayerOffset[4][2];
5564 static int K056832_LSRAMPage[4][2];
5565 static int K056832_X[4]; // 0..3 left
5566 static int K056832_Y[4]; // 0..3 top
5567 static int K056832_W[4]; // 0..3 width -> 1..4 pages
5568 static int K056832_H[4]; // 0..3 height -> 1..4 pages
5569 static int K056832_dx[4]; // scroll
5570 static int K056832_dy[4]; // scroll
5571 static UINT32 K056832_LineDirty[K056832_PAGE_COUNT][8];
5572 static UINT8 K056832_AllLinesDirty[K056832_PAGE_COUNT];
5573 static UINT8 K056832_PageTileMode[K056832_PAGE_COUNT];
5574 static UINT8 K056832_LayerTileMode[4];
5575 static int K056832_DefaultLayerAssociation;
5576 static int K056832_LayerAssociation;
5577 static int K056832_ActiveLayer;
5578 static int K056832_SelectedPage;
5579 static int K056832_SelectedPagex4096;
5580 static int K056832_UpdateMode;
5581 static int K056832_linemap_enabled;
5582
5583 #define K056832_mark_line_dirty(P,L) if (L<0x100) K056832_LineDirty[P][L>>5] |= 1<<(L&0x1f)
5584 #define K056832_mark_all_lines_dirty(P) K056832_AllLinesDirty[P] = 1
5585
K056832_mark_page_dirty(int page)5586 static void K056832_mark_page_dirty(int page)
5587 {
5588 if (K056832_PageTileMode[page])
5589 tilemap_mark_all_tiles_dirty(K056832_tilemap[page]);
5590 else
5591 K056832_mark_all_lines_dirty(page);
5592 }
5593
K056832_mark_plane_dirty(int layer)5594 void K056832_mark_plane_dirty(int layer)
5595 {
5596 int tilemode, i;
5597
5598 tilemode = K056832_LayerTileMode[layer];
5599
5600 for (i=0; i<K056832_PAGE_COUNT; i++)
5601 {
5602 if (K056832_LayerAssociatedWithPage[i] == layer)
5603 {
5604 K056832_PageTileMode[i] = tilemode;
5605 K056832_mark_page_dirty(i);
5606 }
5607 }
5608 }
5609
K056832_MarkAllTilemapsDirty(void)5610 void K056832_MarkAllTilemapsDirty(void)
5611 {
5612 int i;
5613
5614 for (i=0; i<K056832_PAGE_COUNT; i++)
5615 {
5616 if (K056832_LayerAssociatedWithPage[i] != -1)
5617 {
5618 K056832_PageTileMode[i] = K056832_LayerTileMode[K056832_LayerAssociatedWithPage[i]];
5619 K056832_mark_page_dirty(i);
5620 }
5621 }
5622 }
5623
K056832_UpdatePageLayout(void)5624 static void K056832_UpdatePageLayout(void)
5625 {
5626 int layer, rowstart, rowspan, colstart, colspan, r, c, pageIndex, setlayer;
5627
5628 // enable layer association by default
5629 K056832_LayerAssociation = K056832_DefaultLayerAssociation;
5630
5631 // disable association if a layer grabs the entire 4x4 map (happens in Twinbee and Dadandarn)
5632 for (layer=0; layer<4; layer++)
5633 {
5634 if (!K056832_Y[layer] && !K056832_X[layer] && K056832_H[layer]==3 && K056832_W[layer]==3)
5635 {
5636 K056832_LayerAssociation = 0;
5637 break;
5638 }
5639 }
5640
5641 // disable all tilemaps
5642 for (pageIndex=0; pageIndex<K056832_PAGE_COUNT; pageIndex++)
5643 {
5644 K056832_LayerAssociatedWithPage[pageIndex] = -1;
5645 }
5646
5647 // enable associated tilemaps
5648 for (layer=0; layer<4; layer++)
5649 {
5650 rowstart = K056832_Y[layer];
5651 colstart = K056832_X[layer];
5652 rowspan = K056832_H[layer]+1;
5653 colspan = K056832_W[layer]+1;
5654
5655 setlayer = (K056832_LayerAssociation) ? layer : K056832_ActiveLayer;
5656
5657 for (r=0; r<rowspan; r++)
5658 {
5659 for (c=0; c<colspan; c++)
5660 {
5661 pageIndex = (((rowstart + r) & 3) << 2) + ((colstart + c) & 3);
5662 if (strcasecmp(Machine->gamedrv->source_file+12, "djmain.c") || K056832_LayerAssociatedWithPage[pageIndex] == -1) //*
5663 K056832_LayerAssociatedWithPage[pageIndex] = setlayer;
5664 }
5665 }
5666 }
5667
5668 // refresh associated tilemaps
5669 K056832_MarkAllTilemapsDirty();
5670 }
5671
5672 static void (*K056832_callback)(int, int *, int *);
5673
K056832_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)5674 static INLINE UINT32 K056832_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)
5675 {
5676 return (row<<6) + col;
5677 }
5678
K056832_get_tile_info(int tile_index,int pageIndex)5679 static INLINE void K056832_get_tile_info( int tile_index, int pageIndex )
5680 {
5681 static struct K056832_SHIFTMASKS
5682 {
5683 int flips, palm1, pals2, palm2;
5684 }
5685 K056832_shiftmasks[4] = {{6,0x3f,0,0x00},{4,0x0f,2,0x30},{2,0x03,2,0x3c},{0,0x00,2,0x3f}};
5686
5687 struct K056832_SHIFTMASKS *smptr;
5688 int layer, flip, fbits, attr, code;
5689 data16_t *pMem;
5690
5691 pMem = &K056832_videoram[(pageIndex<<12)+(tile_index<<1)];
5692
5693 if (K056832_LayerAssociation)
5694 {
5695 layer = K056832_LayerAssociatedWithPage[pageIndex];
5696 if (layer == -1) layer = 0; // use layer 0's palette info for unmapped pages
5697 }
5698 else
5699 layer = K056832_ActiveLayer;
5700
5701 fbits = K056832_regs[3]>>6 & 3;
5702 flip = K056832_regs[1]>>(layer<<1) & 0x3; // tile-flip override (see p.20 3.2.2 "REG2")
5703 smptr = &K056832_shiftmasks[fbits];
5704 attr = pMem[0];
5705 code = pMem[1];
5706
5707 // normalize the flip/palette flags
5708 // see the tables on pages 4 and 10 of the Pt. 2-3 "VRAM" manual
5709 // for a description of these bits "FBIT0" and "FBIT1"
5710 flip &= attr>>smptr->flips & 3;
5711 attr = (attr & smptr->palm1) | (attr>>smptr->pals2 & smptr->palm2);
5712 tile_info.flags = TILE_FLIPYX(flip);
5713
5714 (*K056832_callback)(layer, &code, &attr);
5715
5716 SET_TILE_INFO(K056832_gfxnum,
5717 code,
5718 attr,
5719 tile_info.flags)
5720 }
5721
K056832_get_tile_info0(int tile_index)5722 static void K056832_get_tile_info0(int tile_index) { K056832_get_tile_info(tile_index,0x0); }
K056832_get_tile_info1(int tile_index)5723 static void K056832_get_tile_info1(int tile_index) { K056832_get_tile_info(tile_index,0x1); }
K056832_get_tile_info2(int tile_index)5724 static void K056832_get_tile_info2(int tile_index) { K056832_get_tile_info(tile_index,0x2); }
K056832_get_tile_info3(int tile_index)5725 static void K056832_get_tile_info3(int tile_index) { K056832_get_tile_info(tile_index,0x3); }
K056832_get_tile_info4(int tile_index)5726 static void K056832_get_tile_info4(int tile_index) { K056832_get_tile_info(tile_index,0x4); }
K056832_get_tile_info5(int tile_index)5727 static void K056832_get_tile_info5(int tile_index) { K056832_get_tile_info(tile_index,0x5); }
K056832_get_tile_info6(int tile_index)5728 static void K056832_get_tile_info6(int tile_index) { K056832_get_tile_info(tile_index,0x6); }
K056832_get_tile_info7(int tile_index)5729 static void K056832_get_tile_info7(int tile_index) { K056832_get_tile_info(tile_index,0x7); }
K056832_get_tile_info8(int tile_index)5730 static void K056832_get_tile_info8(int tile_index) { K056832_get_tile_info(tile_index,0x8); }
K056832_get_tile_info9(int tile_index)5731 static void K056832_get_tile_info9(int tile_index) { K056832_get_tile_info(tile_index,0x9); }
K056832_get_tile_infoa(int tile_index)5732 static void K056832_get_tile_infoa(int tile_index) { K056832_get_tile_info(tile_index,0xa); }
K056832_get_tile_infob(int tile_index)5733 static void K056832_get_tile_infob(int tile_index) { K056832_get_tile_info(tile_index,0xb); }
K056832_get_tile_infoc(int tile_index)5734 static void K056832_get_tile_infoc(int tile_index) { K056832_get_tile_info(tile_index,0xc); }
K056832_get_tile_infod(int tile_index)5735 static void K056832_get_tile_infod(int tile_index) { K056832_get_tile_info(tile_index,0xd); }
K056832_get_tile_infoe(int tile_index)5736 static void K056832_get_tile_infoe(int tile_index) { K056832_get_tile_info(tile_index,0xe); }
K056832_get_tile_infof(int tile_index)5737 static void K056832_get_tile_infof(int tile_index) { K056832_get_tile_info(tile_index,0xf); }
5738
K056832_change_rambank(void)5739 static void K056832_change_rambank(void)
5740 {
5741 /* ------xx page col
5742 * ---xx--- page row
5743 */
5744 int bank = K056832_regs[0x19];
5745 K056832_SelectedPage = ((bank>>1)&0xc)|(bank&3);
5746 K056832_SelectedPagex4096 = K056832_SelectedPage << 12;
5747 }
5748
K056832_change_rombank(void)5749 static void K056832_change_rombank(void)
5750 {
5751 int bank = K056832_regs[0x1a] | (K056832_regs[0x1b] << 16);
5752 K056832_CurGfxBank = bank % K056832_NumGfxBanks;
5753 }
5754
K056832_vh_start(int gfx_memory_region,int bpp,int big,int (* scrolld)[4][2],void (* callback)(int,int *,int *))5755 int K056832_vh_start(int gfx_memory_region, int bpp, int big, int (*scrolld)[4][2], void (*callback)(int, int *, int *))
5756 {
5757 struct tilemap *tilemap;
5758 int gfx_index;
5759 int i;
5760 struct GfxLayout charlayout8 =
5761 {
5762 8, 8,
5763 0, /* filled in later */
5764 8,
5765 { 8*7,8*3,8*5,8*1,8*6,8*2,8*4,8*0 },
5766 { 0, 1, 2, 3, 4, 5, 6, 7 },
5767 { 0, 8*8, 8*8*2, 8*8*3, 8*8*4, 8*8*5, 8*8*6, 8*8*7 },
5768 8*8*8
5769 };
5770 struct GfxLayout charlayout6 =
5771 {
5772 8, 8,
5773 0, /* filled in later */
5774 6,
5775 { 40, 32, 24, 8, 16, 0 },
5776 { 0, 1, 2, 3, 4, 5, 6, 7 },
5777 { 0, 6*8, 6*8*2, 6*8*3, 6*8*4, 6*8*5, 6*8*6, 6*8*7 },
5778 8*8*6
5779 };
5780 struct GfxLayout charlayout5 =
5781 {
5782 8, 8,
5783 0, /* filled in later */
5784 5,
5785 { 32, 24, 8, 16, 0 },
5786 { 0, 1, 2, 3, 4, 5, 6, 7 },
5787 { 0, 5*8, 5*8*2, 5*8*3, 5*8*4, 5*8*5, 5*8*6, 5*8*7 },
5788 8*8*5
5789 };
5790 struct GfxLayout charlayout4 =
5791 {
5792 8, 8,
5793 0, /* filled in later */
5794 4,
5795 { 0, 1, 2, 3 },
5796 { 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4 },
5797 { 0*8*4, 1*8*4, 2*8*4, 3*8*4, 4*8*4, 5*8*4, 6*8*4, 7*8*4 },
5798 8*8*4
5799 };
5800 static struct GfxLayout charlayout4dj =
5801 {
5802 8, 8,
5803 0, /* filled in later */
5804 4,
5805 { 8*3,8*1,8*2,8*0 },
5806 { 0, 1, 2, 3, 4, 5, 6, 7 },
5807 { 0, 8*4, 8*4*2, 8*4*3, 8*4*4, 8*4*5, 8*4*6, 8*4*7 },
5808 8*8*4
5809 };
5810
5811 K056832_bpp = bpp;
5812
5813 /* find first empty slot to decode gfx */
5814 for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
5815 {
5816 if (Machine->gfx[gfx_index] == 0) break;
5817 }
5818 if (gfx_index == MAX_GFX_ELEMENTS) return 1;
5819
5820 /* handle the various graphics formats */
5821 i = (big) ? 8 : 16;
5822
5823 switch (bpp)
5824 {
5825 case K056832_BPP_4:
5826 charlayout4.total = memory_region_length(gfx_memory_region) / (i*4);
5827
5828 /* decode the graphics */
5829 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region), &charlayout4);
5830 break;
5831
5832 case K056832_BPP_5:
5833 /* tweak the structure for the number of tiles we have */
5834 charlayout5.total = memory_region_length(gfx_memory_region) / (i*5);
5835
5836 /* decode the graphics */
5837 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region), &charlayout5);
5838 break;
5839
5840 case K056832_BPP_6:
5841 /* tweak the structure for the number of tiles we have */
5842 charlayout6.total = memory_region_length(gfx_memory_region) / (i*6);
5843
5844 /* decode the graphics */
5845 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region), &charlayout6);
5846 break;
5847
5848 case K056832_BPP_8:
5849 /* tweak the structure for the number of tiles we have */
5850 charlayout8.total = memory_region_length(gfx_memory_region) / (i*8);
5851
5852 /* decode the graphics */
5853 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region), &charlayout8);
5854 break;
5855
5856 case K056832_BPP_4dj:
5857 charlayout4dj.total = memory_region_length(gfx_memory_region) / (i*4);
5858
5859 /* decode the graphics */
5860 Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region), &charlayout4dj);
5861 break;
5862 }
5863
5864 /* make sure the decode went OK */
5865 if (!Machine->gfx[gfx_index]) return 1;
5866
5867 /* set the color information */
5868 if (Machine->drv->color_table_len)
5869 {
5870 Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
5871 Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
5872 }
5873 else
5874 {
5875 Machine->gfx[gfx_index]->colortable = Machine->pens;
5876 Machine->gfx[gfx_index]->total_colors = Machine->drv->total_colors / 16;
5877 }
5878 Machine->gfx[gfx_index]->color_granularity = 16; /* override */
5879
5880 K056832_memory_region = gfx_memory_region;
5881 K056832_gfxnum = gfx_index;
5882 K056832_callback = callback;
5883
5884 K056832_rombase = memory_region(gfx_memory_region);
5885 K056832_NumGfxBanks = memory_region_length(gfx_memory_region) / 0x2000;
5886 K056832_CurGfxBank = 0;
5887
5888 for (i=0; i<4; i++)
5889 {
5890 K056832_LayerOffset[i][0] = 0;
5891 K056832_LayerOffset[i][1] = 0;
5892 K056832_LSRAMPage[i][0] = i;
5893 K056832_LSRAMPage[i][1] = i << 11;
5894 K056832_X[i] = 0;
5895 K056832_Y[i] = 0;
5896 K056832_W[i] = 0;
5897 K056832_H[i] = 0;
5898 K056832_dx[i] = 0;
5899 K056832_dy[i] = 0;
5900 K056832_LayerTileMode[i] = 1;
5901 }
5902
5903 K056832_DefaultLayerAssociation = 1;
5904 K056832_ActiveLayer = 0;
5905 K056832_UpdateMode = 0;
5906 K056832_linemap_enabled = 0;
5907
5908 memset(K056832_LineDirty, 0, sizeof(UINT32) * K056832_PAGE_COUNT * 8);
5909
5910 for (i=0; i<K056832_PAGE_COUNT; i++)
5911 {
5912 K056832_AllLinesDirty[i] = 0;
5913 K056832_PageTileMode[i] = 1;
5914 }
5915
5916 if (!(K056832_videoram = auto_malloc(0x2000 * K056832_PAGE_COUNT))) return 1;
5917
5918 K056832_tilemap[0x0] = tilemap_create(K056832_get_tile_info0, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5919 K056832_tilemap[0x1] = tilemap_create(K056832_get_tile_info1, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5920 K056832_tilemap[0x2] = tilemap_create(K056832_get_tile_info2, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5921 K056832_tilemap[0x3] = tilemap_create(K056832_get_tile_info3, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5922 K056832_tilemap[0x4] = tilemap_create(K056832_get_tile_info4, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5923 K056832_tilemap[0x5] = tilemap_create(K056832_get_tile_info5, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5924 K056832_tilemap[0x6] = tilemap_create(K056832_get_tile_info6, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5925 K056832_tilemap[0x7] = tilemap_create(K056832_get_tile_info7, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5926 K056832_tilemap[0x8] = tilemap_create(K056832_get_tile_info8, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5927 K056832_tilemap[0x9] = tilemap_create(K056832_get_tile_info9, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5928 K056832_tilemap[0xa] = tilemap_create(K056832_get_tile_infoa, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5929 K056832_tilemap[0xb] = tilemap_create(K056832_get_tile_infob, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5930 K056832_tilemap[0xc] = tilemap_create(K056832_get_tile_infoc, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5931 K056832_tilemap[0xd] = tilemap_create(K056832_get_tile_infod, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5932 K056832_tilemap[0xe] = tilemap_create(K056832_get_tile_infoe, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5933 K056832_tilemap[0xf] = tilemap_create(K056832_get_tile_infof, K056832_scan, TILEMAP_TRANSPARENT, 8, 8, 64, 32);
5934
5935 for (i=0; i<K056832_PAGE_COUNT; i++)
5936 {
5937 if (!(tilemap = K056832_tilemap[i])) return 1;
5938
5939 K056832_pixmap[i] = tilemap_get_pixmap(tilemap);
5940
5941 tilemap_set_transparent_pen(tilemap, 0);
5942 }
5943
5944 memset(K056832_videoram, 0x00, 0x20000);
5945 memset(K056832_regs, 0x00, sizeof(K056832_regs) );
5946 memset(K056832_regsb, 0x00, sizeof(K056832_regsb) );
5947
5948 K056832_UpdatePageLayout();
5949
5950 K056832_change_rambank();
5951 K056832_change_rombank();
5952
5953 state_save_register_UINT16("K056832", 0, "memory", K056832_videoram, 0x10000);
5954 state_save_register_UINT16("K056832", 0, "registers", K056832_regs, 0x20);
5955 state_save_register_UINT16("K056832", 0, "registers b", K056832_regsb, 0x4);
5956 state_save_register_INT32 ("K056832", 0, "layerstat1", K056832_X, 0x4);
5957 state_save_register_INT32 ("K056832", 0, "layerstat2", K056832_Y, 0x4);
5958 state_save_register_INT32 ("K056832", 0, "layerstat3", K056832_W, 0x4);
5959 state_save_register_INT32 ("K056832", 0, "layerstat4", K056832_H, 0x4);
5960 state_save_register_INT32 ("K056832", 0, "layerstat5", K056832_dx, 0x4);
5961 state_save_register_INT32 ("K056832", 0, "layerstat6", K056832_dy, 0x4);
5962 state_save_register_UINT8 ("K056832", 0, "layerstat7", K056832_LayerTileMode, 4);
5963
5964 state_save_register_func_postload(K056832_UpdatePageLayout);
5965 state_save_register_func_postload(K056832_change_rambank);
5966 state_save_register_func_postload(K056832_change_rombank);
5967
5968 return 0;
5969 }
5970
5971 /* generic helper routine for ROM checksumming */
K056832_rom_read_b(int offset,int blksize,int blksize2,int zerosec)5972 static int K056832_rom_read_b(int offset, int blksize, int blksize2, int zerosec)
5973 {
5974 data8_t *rombase;
5975 int base, ret;
5976
5977 rombase = (data8_t *)memory_region(K056832_memory_region);
5978
5979 if ((K056832_rom_half) && (zerosec))
5980 {
5981 return 0;
5982 }
5983
5984 // add in the bank offset
5985 offset += (K056832_CurGfxBank * 0x2000);
5986
5987 // figure out the base of the ROM block
5988 base = (offset / blksize) * blksize2;
5989
5990 // get the starting offset of the proper word inside the block
5991 base += (offset % blksize) * 2;
5992
5993 if (K056832_rom_half)
5994 {
5995 ret = rombase[base+1];
5996 }
5997 else
5998 {
5999 ret = rombase[base];
6000 K056832_rom_half = 1;
6001 }
6002
6003 return ret;
6004 }
6005
READ16_HANDLER(K056832_5bpp_rom_word_r)6006 READ16_HANDLER( K056832_5bpp_rom_word_r )
6007 {
6008 if (mem_mask == 0x00ff)
6009 {
6010 return K056832_rom_read_b(offset*2, 4, 5, 0)<<8;
6011 }
6012 else if (mem_mask == 0xff00)
6013 {
6014 return K056832_rom_read_b(offset*2+1, 4, 5, 0)<<16;
6015 }
6016 else
6017 {
6018 #if VERBOSE
6019 logerror("Non-byte read of tilemap ROM, PC=%x (mask=%x)\n", activecpu_get_pc(), mem_mask);
6020 #endif
6021 }
6022 return 0;
6023 }
6024
READ32_HANDLER(K056832_5bpp_rom_long_r)6025 READ32_HANDLER( K056832_5bpp_rom_long_r )
6026 {
6027 if (mem_mask == 0x00ffffff)
6028 {
6029 return K056832_rom_read_b(offset*4, 4, 5, 0)<<24;
6030 }
6031 else if (mem_mask == 0xff00ffff)
6032 {
6033 return K056832_rom_read_b(offset*4+1, 4, 5, 0)<<16;
6034 }
6035 else if (mem_mask == 0xffff00ff)
6036 {
6037 return K056832_rom_read_b(offset*4+2, 4, 5, 0)<<8;
6038 }
6039 else if (mem_mask == 0xffffff00)
6040 {
6041 return K056832_rom_read_b(offset*4+3, 4, 5, 1);
6042 }
6043 else
6044 {
6045 #if VERBOSE
6046 logerror("Non-byte read of tilemap ROM, PC=%x (mask=%x)\n", activecpu_get_pc(), mem_mask);
6047 #endif
6048 }
6049 return 0;
6050 }
6051
READ32_HANDLER(K056832_6bpp_rom_long_r)6052 READ32_HANDLER( K056832_6bpp_rom_long_r )
6053 {
6054 if (mem_mask == 0x00ffffff)
6055 {
6056 return K056832_rom_read_b(offset*4, 4, 6, 0)<<24;
6057 }
6058 else if (mem_mask == 0xff00ffff)
6059 {
6060 return K056832_rom_read_b(offset*4+1, 4, 6, 0)<<16;
6061 }
6062 else if (mem_mask == 0xffff00ff)
6063 {
6064 return K056832_rom_read_b(offset*4+2, 4, 6, 0)<<8;
6065 }
6066 else if (mem_mask == 0xffffff00)
6067 {
6068 return K056832_rom_read_b(offset*4+3, 4, 6, 0);
6069 }
6070 else
6071 {
6072 #if VERBOSE
6073 logerror("Non-byte read of tilemap ROM, PC=%x (mask=%x)\n", activecpu_get_pc(), mem_mask);
6074 #endif
6075 }
6076 return 0;
6077 }
6078
READ16_HANDLER(K056832_rom_word_r)6079 READ16_HANDLER( K056832_rom_word_r )
6080 {
6081 int ofs16, ofs8;
6082 data8_t *rombase;
6083 int ret;
6084
6085 ofs16 = (offset / 8)*5;
6086 ofs8 = (offset / 4)*5;
6087
6088 ofs16 += (K056832_CurGfxBank*5*1024);
6089 ofs8 += (K056832_CurGfxBank*10*1024);
6090
6091 // if (!offset)
6092 // printf("CurGfxBank = %x\n", K056832_CurGfxBank);
6093
6094 if (!K056832_rombase)
6095 {
6096 K056832_rombase = memory_region(K056832_memory_region);
6097 }
6098 rombase = (data8_t *)K056832_rombase;
6099
6100 ret = (rombase[ofs8+4]<<8);
6101 if ((offset % 8) >= 4)
6102 {
6103 ret |= (rombase[ofs16+1]<<24) | (rombase[ofs16+3]<<16);
6104 }
6105 else
6106 {
6107 ret |= (rombase[ofs16]<<24) | (rombase[ofs16+2]<<16);
6108 }
6109
6110 return ret;
6111 }
6112
READ32_HANDLER(K056832_rom_long_r)6113 READ32_HANDLER( K056832_rom_long_r )
6114 {
6115 offset <<= 1;
6116 return (K056832_rom_word_r(offset+1, 0xffff) | (K056832_rom_word_r(offset, 0xffff)<<16));
6117 }
6118
6119 /* only one page is mapped to videoram at a time through a window */
READ16_HANDLER(K056832_ram_word_r)6120 READ16_HANDLER( K056832_ram_word_r )
6121 {
6122 // reading from tile RAM resets the ROM readback "half" offset
6123 K056832_rom_half = 0;
6124
6125 return K056832_videoram[K056832_SelectedPagex4096+offset];
6126 }
6127
READ32_HANDLER(K056832_ram_long_r)6128 READ32_HANDLER( K056832_ram_long_r )
6129 {
6130 data16_t *pMem = &K056832_videoram[K056832_SelectedPagex4096+offset*2];
6131
6132 // reading from tile RAM resets the ROM readback "half" offset
6133 K056832_rom_half = 0;
6134
6135 return(pMem[0]<<16 | pMem[1]);
6136 }
6137
WRITE16_HANDLER(K056832_ram_word_w)6138 WRITE16_HANDLER( K056832_ram_word_w )
6139 {
6140 data16_t *tile_ptr;
6141 data16_t old_mask, old_data;
6142
6143 tile_ptr = &K056832_videoram[K056832_SelectedPagex4096+offset];
6144 old_mask = mem_mask;
6145 mem_mask = ~mem_mask;
6146 old_data = *tile_ptr;
6147 data = (data & mem_mask) | (old_data & old_mask);
6148
6149 if(data != old_data)
6150 {
6151 offset >>= 1;
6152 *tile_ptr = data;
6153
6154 if (K056832_PageTileMode[K056832_SelectedPage])
6155 tilemap_mark_tile_dirty(K056832_tilemap[K056832_SelectedPage], offset);
6156 else
6157 K056832_mark_line_dirty(K056832_SelectedPage, offset);
6158 }
6159 }
6160
WRITE32_HANDLER(K056832_ram_long_w)6161 WRITE32_HANDLER( K056832_ram_long_w )
6162 {
6163 data16_t *tile_ptr;
6164 data32_t old_mask, old_data;
6165
6166 tile_ptr = &K056832_videoram[K056832_SelectedPagex4096+offset*2];
6167 old_mask = mem_mask;
6168 mem_mask = ~mem_mask;
6169 old_data = (data32_t)tile_ptr[0]<<16 | (data32_t)tile_ptr[1];
6170 data = (data & mem_mask) | (old_data & old_mask);
6171
6172 if (data != old_data)
6173 {
6174 tile_ptr[0] = data>>16;
6175 tile_ptr[1] = data;
6176
6177 if (K056832_PageTileMode[K056832_SelectedPage])
6178 tilemap_mark_tile_dirty(K056832_tilemap[K056832_SelectedPage], offset);
6179 else
6180 K056832_mark_line_dirty(K056832_SelectedPage, offset);
6181 }
6182 }
6183
WRITE16_HANDLER(K056832_word_w)6184 WRITE16_HANDLER( K056832_word_w )
6185 {
6186 int layer, flip, mask, i;
6187 UINT32 old_data, new_data;
6188
6189 old_data = K056832_regs[offset];
6190 COMBINE_DATA(&K056832_regs[offset]);
6191 new_data = K056832_regs[offset];
6192
6193 if (new_data != old_data)
6194 {
6195 switch(offset)
6196 {
6197 /* -x-- ---- dotclock select: 0=8Mhz, 1=6Mhz (not used by GX)
6198 * --x- ---- screen flip y
6199 * ---x ---- screen flip x
6200 */
6201 case 0x00/2:
6202 if ((new_data & 0x30) != (old_data & 0x30))
6203 {
6204 flip = 0;
6205 if (new_data & 0x20) flip |= TILEMAP_FLIPY;
6206 if (new_data & 0x10) flip |= TILEMAP_FLIPX;
6207 for (i=0; i<K056832_PAGE_COUNT; i++)
6208 {
6209 tilemap_set_flip(K056832_tilemap[i], flip);
6210 }
6211 }
6212 break;
6213
6214 /* -------- -----xxx external irqlines enable (not used by GX)
6215 * -------- xx------ tilemap attribute config (FBIT0 and FBIT1)
6216 */
6217 //case 0x06/2: break;
6218
6219 // -------- ----DCBA tile mode: 0=512x1, 1=8x8
6220 // -------- DCBA---- synchronous scroll: 0=off, 1=on
6221 case 0x08/2:
6222 for (layer=0; layer<4; layer++)
6223 {
6224 mask = 1<<layer;
6225 i = new_data & mask;
6226 if (i != (old_data & mask))
6227 {
6228 K056832_LayerTileMode[layer] = i;
6229 K056832_mark_plane_dirty(layer);
6230 }
6231 }
6232 break;
6233
6234 /* -------- ------xx layer A linescroll config
6235 * -------- ----xx-- layer B linescroll config
6236 * -------- --xx---- layer C linescroll config
6237 * -------- xx------ layer D linescroll config
6238 *
6239 * 0: linescroll
6240 * 2: rowscroll
6241 * 3: xy scroll
6242 */
6243 //case 0x0a/2: break;
6244
6245 case 0x32/2:
6246 K056832_change_rambank();
6247 break;
6248
6249 case 0x34/2: /* ROM bank select for checksum */
6250 case 0x36/2: /* secondary ROM bank select for use with tile banking */
6251 K056832_change_rombank();
6252 break;
6253
6254 // extended tile address
6255 //case 0x38/2: break;
6256
6257 // 12 bit (signed) horizontal offset if global HFLIP enabled
6258 //case 0x3a/2: break;
6259
6260 // 11 bit (signed) vertical offset if global VFLIP enabled
6261 //case 0x3c/2: break;
6262
6263 default:
6264 layer = offset & 3;
6265
6266 if (offset >= 0x10/2 && offset <= 0x16/2)
6267 {
6268 K056832_Y[layer] = (new_data&0x18)>>3;
6269 K056832_H[layer] = (new_data&0x3);
6270 K056832_ActiveLayer = layer;
6271 K056832_UpdatePageLayout();
6272 } else
6273
6274 if (offset >= 0x18/2 && offset <= 0x1e/2)
6275 {
6276 K056832_X[layer] = (new_data&0x18)>>3;
6277 K056832_W[layer] = (new_data&0x03);
6278 K056832_ActiveLayer = layer;
6279 K056832_UpdatePageLayout();
6280 } else
6281
6282 if (offset >= 0x20/2 && offset <= 0x26/2)
6283 {
6284 K056832_dy[layer] = (INT16)data;
6285 } else
6286
6287 if (offset >= 0x28/2 && offset <= 0x2e/2)
6288 {
6289 K056832_dx[layer] = (INT16)data;
6290 }
6291 break;
6292 }
6293 }
6294 }
6295
WRITE32_HANDLER(K056832_long_w)6296 WRITE32_HANDLER( K056832_long_w )
6297 {
6298 // GX does access of all 3 widths (8/16/32) so we can't do the
6299 // if (ACCESSING_xxx) trick. in particular, 8-bit writes
6300 // are used to the tilemap bank register.
6301 offset <<= 1;
6302 K056832_word_w(offset, data>>16, mem_mask >> 16);
6303 K056832_word_w(offset+1, data, mem_mask);
6304 }
6305
WRITE16_HANDLER(K056832_b_word_w)6306 WRITE16_HANDLER( K056832_b_word_w )
6307 {
6308 COMBINE_DATA( &K056832_regsb[offset] );
6309 }
6310
WRITE32_HANDLER(K056832_b_long_w)6311 WRITE32_HANDLER( K056832_b_long_w )
6312 {
6313 if (ACCESSING_MSW32)
6314 {
6315 K056832_b_word_w(offset<<1, data>>16, mem_mask >> 16);
6316 }
6317 if (ACCESSING_LSW32)
6318 {
6319 K056832_b_word_w((offset<<1)+1, data, mem_mask);
6320 }
6321 }
6322
K056832_update_linemap(struct mame_bitmap * bitmap,int page,int flags)6323 static int K056832_update_linemap(struct mame_bitmap *bitmap, int page, int flags)
6324 {
6325 #define LINE_WIDTH 512
6326
6327 #define DRAW_PIX(N) \
6328 if ((pen = src_ptr[N])) \
6329 { pen += basepen; xpr_ptr[count+N] = TILE_FLAG_FG_OPAQUE; dst_ptr[count+N] = pen; } else \
6330 { xpr_ptr[count+N] = 0; }
6331
6332 struct rectangle zerorect;
6333 struct tilemap *tilemap;
6334 struct mame_bitmap *pixmap, *xprmap;
6335 UINT8 *xprdata;
6336 const struct GfxElement *src_gfx;
6337
6338 UINT32 *dirty;
6339 int all_dirty, line;
6340 int offs, mask;
6341
6342 pen_t *pal_ptr;
6343 const UINT8 *src_base, *src_ptr;
6344 UINT8 *xpr_ptr;
6345 UINT16 *dst_ptr;
6346 UINT16 pen, basepen;
6347 int count, src_pitch, src_modulo;
6348 int dst_pitch;
6349
6350 UINT8 code_transparent, code_opaque;
6351
6352 if (K056832_PageTileMode[page]) return(0);
6353 if (!K056832_linemap_enabled) return(1);
6354
6355 tilemap = K056832_tilemap[page];
6356 pixmap = K056832_pixmap[page];
6357 xprmap = tilemap_get_transparency_bitmap(tilemap);
6358 xprdata = tilemap_get_transparency_data(tilemap);
6359
6360 dirty = K056832_LineDirty[page];
6361 all_dirty = K056832_AllLinesDirty[page];
6362
6363 if (all_dirty)
6364 {
6365 dirty[7]=dirty[6]=dirty[5]=dirty[4]=dirty[3]=dirty[2]=dirty[1]=dirty[0] = 0;
6366 K056832_AllLinesDirty[page] = 0;
6367
6368 // force tilemap into a clean, static state
6369 // *really ugly but it minimizes alteration to tilemap.c
6370 memset (&zerorect, 0, sizeof(struct rectangle)); // zero dimension
6371 tilemap_draw(bitmap, &zerorect, tilemap, 0, 0); // dummy call to reset tile_dirty_map
6372 fillbitmap(xprmap, 0, 0); // reset pixel transparency_bitmap;
6373 memset(xprdata, TILE_FLAG_FG_OPAQUE, 0x800); // reset tile transparency_data;
6374 }
6375 else
6376 {
6377 if (!(dirty[0]|dirty[1]|dirty[2]|dirty[3]|dirty[4]|dirty[5]|dirty[6]|dirty[7])) return(0);
6378 }
6379
6380 pal_ptr = Machine->remapped_colortable;
6381 src_gfx = Machine->gfx[K056832_gfxnum];
6382 src_base = src_gfx->gfxdata;
6383 src_pitch = src_gfx->line_modulo;
6384 src_modulo = src_gfx->char_modulo;
6385 xpr_ptr = (UINT8*)xprmap->base + LINE_WIDTH;
6386 dst_ptr = (UINT16*)pixmap->base + LINE_WIDTH;
6387 dst_pitch = pixmap->rowpixels;
6388
6389 for (line=0; line<256; xpr_ptr+=dst_pitch, dst_ptr+=dst_pitch, line++)
6390 {
6391 if (!all_dirty)
6392 {
6393 offs = line >> 5;
6394 mask = 1 << (line & 0x1f);
6395 if (!(dirty[offs] & mask)) continue;
6396 dirty[offs] ^= mask;
6397 }
6398
6399 K056832_get_tile_info(line, page);
6400 src_ptr = src_base + ((tile_info.tile_number & ~7) << 6);
6401 basepen = tile_info.pal_data - pal_ptr;
6402 code_transparent = tile_info.priority;
6403 code_opaque = code_transparent | TILE_FLAG_FG_OPAQUE;
6404 count = -LINE_WIDTH;
6405
6406 do
6407 {
6408 DRAW_PIX(0)
6409 DRAW_PIX(1)
6410 DRAW_PIX(2)
6411 DRAW_PIX(3)
6412 DRAW_PIX(4)
6413 DRAW_PIX(5)
6414 DRAW_PIX(6)
6415 DRAW_PIX(7)
6416
6417 src_ptr += 8;
6418 }
6419 while (count += 8);
6420 }
6421
6422 return(0);
6423
6424 #undef LINE_WIDTH
6425 #undef DRAW_PIX
6426 }
6427
K056832_tilemap_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int layer,int flags,UINT32 priority)6428 void K056832_tilemap_draw(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int layer, int flags, UINT32 priority)
6429 {
6430 static int last_colorbase[K056832_PAGE_COUNT];
6431
6432 UINT32 last_dx, last_visible, new_colorbase, last_active;
6433 int sx, sy, ay, tx, ty, width, height;
6434 int clipw, clipx, cliph, clipy, clipmaxy;
6435 int line_height, line_endy, line_starty, line_y;
6436 int sdat_start, sdat_walk, sdat_adv, sdat_wrapmask, sdat_offs;
6437 int pageIndex, flipx, flipy, corr, r, c;
6438 int cminy, cmaxy, cminx, cmaxx;
6439 int dminy, dmaxy, dminx, dmaxx;
6440 struct rectangle drawrect;
6441 struct tilemap *tilemap;
6442 data16_t *pScrollData;
6443 data16_t ram16[2];
6444
6445 int rowstart = K056832_Y[layer];
6446 int colstart = K056832_X[layer];
6447 int rowspan = K056832_H[layer]+1;
6448 int colspan = K056832_W[layer]+1;
6449 int dy = K056832_dy[layer];
6450 int dx = K056832_dx[layer];
6451 int scrollbank = ((K056832_regs[0x18]>>1) & 0xc) | (K056832_regs[0x18] & 3);
6452 int scrollmode = K056832_regs[0x05]>>(K056832_LSRAMPage[layer][0]<<1) & 3;
6453
6454 height = rowspan * K056832_PAGE_HEIGHT;
6455 width = colspan * K056832_PAGE_WIDTH;
6456
6457 cminx = cliprect->min_x;
6458 cmaxx = cliprect->max_x;
6459 cminy = cliprect->min_y;
6460 cmaxy = cliprect->max_y;
6461
6462 // flip correction registers
6463 if ((flipy = K056832_regs[0] & 0x20))
6464 {
6465 corr = K056832_regs[0x3c/2];
6466 if (corr & 0x400)
6467 corr |= 0xfffff800;
6468 } else corr = 0;
6469 dy += corr;
6470 ay = (unsigned)(dy - K056832_LayerOffset[layer][1]) % height;
6471
6472 if ((flipx = K056832_regs[0] & 0x10))
6473 {
6474 corr = K056832_regs[0x3a/2];
6475 if (corr & 0x800)
6476 corr |= 0xfffff000;
6477 } else corr = 0;
6478 corr -= K056832_LayerOffset[layer][0];
6479
6480 if (scrollmode == 0 && (flags & TILE_LINE_DISABLED))
6481 {
6482 scrollmode = 3;
6483 flags &= ~TILE_LINE_DISABLED;
6484 }
6485
6486 switch( scrollmode )
6487 {
6488 case 0: // linescroll
6489 pScrollData = &K056832_videoram[scrollbank<<12] + (K056832_LSRAMPage[layer][1]>>1);
6490 line_height = 1;
6491 sdat_wrapmask = 0x3ff;
6492 sdat_adv = 2;
6493 break;
6494 case 2: // rowscroll
6495 pScrollData = &K056832_videoram[scrollbank<<12] + (K056832_LSRAMPage[layer][1]>>1);
6496 line_height = 8;
6497 sdat_wrapmask = 0x3ff;
6498 sdat_adv = 16;
6499 break;
6500 default: // xyscroll
6501 pScrollData = ram16;
6502 line_height = K056832_PAGE_HEIGHT;
6503 sdat_wrapmask = 0;
6504 sdat_adv = 0;
6505 ram16[0] = 0;
6506 ram16[1] = dx;
6507 }
6508 if (flipy) sdat_adv = -sdat_adv;
6509
6510 last_active = K056832_ActiveLayer;
6511 new_colorbase = (K056832_UpdateMode) ? K055555_get_palette_index(layer) : 0;
6512
6513 for (r=0; r<rowspan; r++)
6514 {
6515 if (rowspan > 1)
6516 {
6517 sy = ay;
6518 ty = r * K056832_PAGE_HEIGHT;
6519
6520 if (!flipy)
6521 {
6522 // handle bottom-edge wraparoundness and cull off-screen tilemaps
6523 if ((r == 0) && (sy > height - K056832_PAGE_HEIGHT)) sy -= height;
6524 if ((sy + K056832_PAGE_HEIGHT <= ty) || (sy - K056832_PAGE_HEIGHT >= ty)) continue;
6525
6526 // switch frame of reference and clip y
6527 if ((ty -= sy) >= 0)
6528 {
6529 cliph = K056832_PAGE_HEIGHT - ty;
6530 clipy = line_starty = ty;
6531 line_endy = K056832_PAGE_HEIGHT;
6532 sdat_start = 0;
6533 }
6534 else
6535 {
6536 cliph = K056832_PAGE_HEIGHT + ty;
6537 ty = -ty;
6538 clipy = line_starty = 0;
6539 line_endy = cliph;
6540 sdat_start = ty;
6541 if (scrollmode == 2) { sdat_start &= ~7; line_starty -= ty & 7; }
6542 }
6543 }
6544 else
6545 {
6546 ty += K056832_PAGE_HEIGHT;
6547
6548 // handle top-edge wraparoundness and cull off-screen tilemaps
6549 if ((r == rowspan-1) && (sy < K056832_PAGE_HEIGHT)) sy += height;
6550 if ((sy + K056832_PAGE_HEIGHT <= ty) || (sy - K056832_PAGE_HEIGHT >= ty)) continue;
6551
6552 // switch frame of reference and clip y
6553 if ((ty -= sy) <= 0)
6554 {
6555 cliph = K056832_PAGE_HEIGHT + ty;
6556 clipy = line_starty = -ty;
6557 line_endy = K056832_PAGE_HEIGHT;
6558 sdat_start = K056832_PAGE_HEIGHT-1;
6559 if (scrollmode == 2) sdat_start &= ~7;
6560 }
6561 else
6562 {
6563 cliph = K056832_PAGE_HEIGHT - ty;
6564 clipy = line_starty = 0;
6565 line_endy = cliph;
6566 sdat_start = cliph-1;
6567 if (scrollmode == 2) { sdat_start &= ~7; line_starty -= ty & 7; }
6568 }
6569 }
6570 }
6571 else
6572 {
6573 cliph = line_endy = K056832_PAGE_HEIGHT;
6574 clipy = line_starty = 0;
6575
6576 if (!flipy)
6577 sdat_start = dy;
6578 else
6579 /*
6580 doesn't work with Metamorphic Force and Martial Champion (software Y-flipped) but
6581 LE2U (naturally Y-flipped) seems to expect this condition as an override.
6582
6583 sdat_start = K056832_PAGE_HEIGHT-1 -dy;
6584 */
6585 sdat_start = K056832_PAGE_HEIGHT-1;
6586
6587 if (scrollmode == 2) { sdat_start &= ~7; line_starty -= dy & 7; }
6588 }
6589
6590 sdat_start += r * K056832_PAGE_HEIGHT;
6591 sdat_start <<= 1;
6592
6593 clipmaxy = clipy + cliph - 1;
6594
6595 for (c=0; c<colspan; c++)
6596 {
6597 pageIndex = (((rowstart + r) & 3) << 2) + ((colstart + c) & 3);
6598
6599 if (K056832_LayerAssociation)
6600 {
6601 if (K056832_LayerAssociatedWithPage[pageIndex] != layer) continue;
6602 }
6603 else
6604 {
6605 if (K056832_LayerAssociatedWithPage[pageIndex] == -1) continue;
6606 K056832_ActiveLayer = layer;
6607 }
6608
6609 if (K056832_UpdateMode)
6610 {
6611 if (last_colorbase[pageIndex] != new_colorbase)
6612 {
6613 last_colorbase[pageIndex] = new_colorbase;
6614 K056832_mark_page_dirty(pageIndex);
6615 }
6616 }
6617 else
6618 if (!pageIndex) K056832_ActiveLayer = 0;
6619
6620 if (K056832_update_linemap(bitmap, pageIndex, flags)) continue;
6621
6622 tilemap = K056832_tilemap[pageIndex];
6623 tilemap_set_scrolly(tilemap, 0, ay);
6624
6625 last_dx = 0x100000;
6626 last_visible = 0;
6627
6628 for (sdat_walk=sdat_start, line_y=line_starty; line_y<line_endy; sdat_walk+=sdat_adv, line_y+=line_height)
6629 {
6630 dminy = line_y;
6631 dmaxy = line_y + line_height - 1;
6632
6633 if (dminy < clipy) dminy = clipy;
6634 if (dmaxy > clipmaxy) dmaxy = clipmaxy;
6635 if (dminy > cmaxy || dmaxy < cminy) continue;
6636
6637 sdat_offs = sdat_walk & sdat_wrapmask;
6638
6639 drawrect.min_y = (dminy < cminy ) ? cminy : dminy;
6640 drawrect.max_y = (dmaxy > cmaxy ) ? cmaxy : dmaxy;
6641
6642 dx = ((int)pScrollData[sdat_offs]<<16 | (int)pScrollData[sdat_offs+1]) + corr;
6643
6644 if (last_dx == dx) { if (last_visible) goto LINE_SHORTCIRCUIT; continue; }
6645 last_dx = dx;
6646
6647 if (colspan > 1)
6648 {
6649 //sx = (unsigned)dx % width;
6650 sx = (unsigned)dx & (width-1);
6651
6652 //tx = c * K056832_PAGE_WIDTH;
6653 tx = c << 9;
6654
6655 if (!flipx)
6656 {
6657 // handle right-edge wraparoundness and cull off-screen tilemaps
6658 if ((c == 0) && (sx > width - K056832_PAGE_WIDTH)) sx -= width;
6659 if ((sx + K056832_PAGE_WIDTH <= tx) || (sx - K056832_PAGE_WIDTH >= tx))
6660 { last_visible = 0; continue; }
6661
6662 // switch frame of reference and clip x
6663 if ((tx -= sx) <= 0) { clipw = K056832_PAGE_WIDTH + tx; clipx = 0; }
6664 else { clipw = K056832_PAGE_WIDTH - tx; clipx = tx; }
6665 }
6666 else
6667 {
6668 tx += K056832_PAGE_WIDTH;
6669
6670 // handle left-edge wraparoundness and cull off-screen tilemaps
6671 if ((c == colspan-1) && (sx < K056832_PAGE_WIDTH)) sx += width;
6672 if ((sx + K056832_PAGE_WIDTH <= tx) || (sx - K056832_PAGE_WIDTH >= tx))
6673 { last_visible = 0; continue; }
6674
6675 // switch frame of reference and clip y
6676 if ((tx -= sx) >= 0) { clipw = K056832_PAGE_WIDTH - tx; clipx = 0; }
6677 else { clipw = K056832_PAGE_WIDTH + tx; clipx = -tx; }
6678 }
6679 }
6680 else { clipw = K056832_PAGE_WIDTH; clipx = 0; }
6681
6682 last_visible = 1;
6683
6684 dminx = clipx;
6685 dmaxx = clipx + clipw - 1;
6686
6687 drawrect.min_x = (dminx < cminx ) ? cminx : dminx;
6688 drawrect.max_x = (dmaxx > cmaxx ) ? cmaxx : dmaxx;
6689
6690 tilemap_set_scrollx(tilemap, 0, dx);
6691
6692 LINE_SHORTCIRCUIT:
6693 tilemap_draw(bitmap, &drawrect, tilemap, flags, priority);
6694
6695 } // end of line loop
6696 } // end of column loop
6697 } // end of row loop
6698
6699 K056832_ActiveLayer = last_active;
6700
6701 } // end of function
6702
K056832_tilemap_draw_dj(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int layer,int flags,UINT32 priority)6703 void K056832_tilemap_draw_dj(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int layer, int flags, UINT32 priority) //*
6704 {
6705 static int last_colorbase[K056832_PAGE_COUNT];
6706
6707 UINT32 last_dx, last_visible, new_colorbase, last_active;
6708 int sx, sy, ay, tx, ty, width, height;
6709 int clipw, clipx, cliph, clipy, clipmaxy;
6710 int line_height, line_endy, line_starty, line_y;
6711 int sdat_start, sdat_walk, sdat_adv, sdat_wrapmask, sdat_offs;
6712 int pageIndex, flipx, flipy, corr, r, c;
6713 int cminy, cmaxy, cminx, cmaxx;
6714 int dminy, dmaxy, dminx, dmaxx;
6715 struct rectangle drawrect;
6716 struct tilemap *tilemap;
6717 data16_t *pScrollData;
6718 data16_t ram16[2];
6719
6720 int rowstart = K056832_Y[layer];
6721 int colstart = K056832_X[layer];
6722 int rowspan = K056832_H[layer]+1;
6723 int colspan = K056832_W[layer]+1;
6724 int dy = K056832_dy[layer];
6725 int dx = K056832_dx[layer];
6726 int scrollbank = ((K056832_regs[0x18]>>1) & 0xc) | (K056832_regs[0x18] & 3);
6727 int scrollmode = K056832_regs[0x05]>>(K056832_LSRAMPage[layer][0]<<1) & 3;
6728 int need_wrap = -1;
6729
6730 height = rowspan * K056832_PAGE_HEIGHT;
6731 width = colspan * K056832_PAGE_WIDTH;
6732
6733 cminx = cliprect->min_x;
6734 cmaxx = cliprect->max_x;
6735 cminy = cliprect->min_y;
6736 cmaxy = cliprect->max_y;
6737
6738 // flip correction registers
6739 if ((flipy = K056832_regs[0] & 0x20))
6740 {
6741 corr = K056832_regs[0x3c/2];
6742 if (corr & 0x400)
6743 corr |= 0xfffff800;
6744 } else corr = 0;
6745 dy += corr;
6746 ay = (unsigned)(dy - K056832_LayerOffset[layer][1]) % height;
6747
6748 if ((flipx = K056832_regs[0] & 0x10))
6749 {
6750 corr = K056832_regs[0x3a/2];
6751 if (corr & 0x800)
6752 corr |= 0xfffff000;
6753 } else corr = 0;
6754 corr -= K056832_LayerOffset[layer][0];
6755
6756 if (scrollmode == 0 && (flags & TILE_LINE_DISABLED))
6757 {
6758 scrollmode = 3;
6759 flags &= ~TILE_LINE_DISABLED;
6760 }
6761
6762 switch( scrollmode )
6763 {
6764 case 0: // linescroll
6765 pScrollData = &K056832_videoram[scrollbank<<12] + (K056832_LSRAMPage[layer][1]>>1);
6766 line_height = 1;
6767 sdat_wrapmask = 0x3ff;
6768 sdat_adv = 2;
6769 break;
6770 case 2: // rowscroll
6771 pScrollData = &K056832_videoram[scrollbank<<12] + (K056832_LSRAMPage[layer][1]>>1);
6772 line_height = 8;
6773 sdat_wrapmask = 0x3ff;
6774 sdat_adv = 16;
6775 break;
6776 default: // xyscroll
6777 pScrollData = ram16;
6778 line_height = K056832_PAGE_HEIGHT;
6779 sdat_wrapmask = 0;
6780 sdat_adv = 0;
6781 ram16[0] = 0;
6782 ram16[1] = dx;
6783 }
6784 if (flipy) sdat_adv = -sdat_adv;
6785
6786 last_active = K056832_ActiveLayer;
6787 new_colorbase = (K056832_UpdateMode) ? K055555_get_palette_index(layer) : 0;
6788
6789 for (r=0; r<=rowspan; r++)
6790 {
6791 sy = ay;
6792 if (r == rowspan)
6793 {
6794 if (need_wrap < 0)
6795 continue;
6796
6797 ty = need_wrap * K056832_PAGE_HEIGHT;
6798 }
6799 else
6800 {
6801 ty = r * K056832_PAGE_HEIGHT;
6802 }
6803
6804 // cull off-screen tilemaps
6805 if ((sy + height <= ty) || (sy - height >= ty)) continue;
6806
6807 // switch frame of reference
6808 ty -= sy;
6809
6810 // handle top-edge wraparoundness
6811 if (r == rowspan)
6812 {
6813 cliph = K056832_PAGE_HEIGHT + ty;
6814 clipy = line_starty = 0;
6815 line_endy = cliph;
6816 ty = -ty;
6817 sdat_start = ty;
6818 if (scrollmode == 2) { sdat_start &= ~7; line_starty -= ty & 7; }
6819 }
6820
6821 // clip y
6822 else
6823 {
6824 if (ty < 0)
6825 ty += height;
6826
6827 clipy = ty;
6828 cliph = K056832_PAGE_HEIGHT;
6829
6830 if (clipy + cliph > height)
6831 {
6832 cliph = height - clipy;
6833 need_wrap =r;
6834 }
6835
6836 line_starty = ty;
6837 line_endy = line_starty + cliph;
6838 sdat_start = 0;
6839 }
6840
6841 if (r == rowspan)
6842 sdat_start += need_wrap * K056832_PAGE_HEIGHT;
6843 else
6844 sdat_start += r * K056832_PAGE_HEIGHT;
6845 sdat_start <<= 1;
6846
6847 clipmaxy = clipy + cliph - 1;
6848
6849 for (c=0; c<colspan; c++)
6850 {
6851 if (r == rowspan)
6852 pageIndex = (((rowstart + need_wrap) & 3) << 2) + ((colstart + c) & 3);
6853 else
6854 pageIndex = (((rowstart + r) & 3) << 2) + ((colstart + c) & 3);
6855
6856 if (K056832_LayerAssociation)
6857 {
6858 if (K056832_LayerAssociatedWithPage[pageIndex] != layer) continue;
6859 }
6860 else
6861 {
6862 if (K056832_LayerAssociatedWithPage[pageIndex] == -1) continue;
6863 K056832_ActiveLayer = layer;
6864 }
6865
6866 if (K056832_UpdateMode)
6867 {
6868 if (last_colorbase[pageIndex] != new_colorbase)
6869 {
6870 last_colorbase[pageIndex] = new_colorbase;
6871 K056832_mark_page_dirty(pageIndex);
6872 }
6873 }
6874 else
6875 if (!pageIndex) K056832_ActiveLayer = 0;
6876
6877 if (K056832_update_linemap(bitmap, pageIndex, flags)) continue;
6878
6879 tilemap = K056832_tilemap[pageIndex];
6880 tilemap_set_scrolly(tilemap, 0, ay);
6881
6882 last_dx = 0x100000;
6883 last_visible = 0;
6884
6885 for (sdat_walk=sdat_start, line_y=line_starty; line_y<line_endy; sdat_walk+=sdat_adv, line_y+=line_height)
6886 {
6887 dminy = line_y;
6888 dmaxy = line_y + line_height - 1;
6889
6890 if (dminy < clipy) dminy = clipy;
6891 if (dmaxy > clipmaxy) dmaxy = clipmaxy;
6892 if (dminy > cmaxy || dmaxy < cminy) continue;
6893
6894 sdat_offs = sdat_walk & sdat_wrapmask;
6895
6896 drawrect.min_y = (dminy < cminy ) ? cminy : dminy;
6897 drawrect.max_y = (dmaxy > cmaxy ) ? cmaxy : dmaxy;
6898
6899 dx = ((int)pScrollData[sdat_offs]<<16 | (int)pScrollData[sdat_offs+1]) + corr;
6900
6901 if (last_dx == dx) { if (last_visible) goto LINE_SHORTCIRCUIT; continue; }
6902 last_dx = dx;
6903
6904 if (colspan > 1)
6905 {
6906 //sx = (unsigned)dx % width;
6907 sx = (unsigned)dx & (width-1);
6908
6909 //tx = c * K056832_PAGE_WIDTH;
6910 tx = c << 9;
6911
6912 if (!flipx)
6913 {
6914 // handle right-edge wraparoundness and cull off-screen tilemaps
6915 if ((c == 0) && (sx > width - K056832_PAGE_WIDTH)) sx -= width;
6916 if ((sx + K056832_PAGE_WIDTH <= tx) || (sx - K056832_PAGE_WIDTH >= tx))
6917 { last_visible = 0; continue; }
6918
6919 // switch frame of reference and clip x
6920 if ((tx -= sx) <= 0) { clipw = K056832_PAGE_WIDTH + tx; clipx = 0; }
6921 else { clipw = K056832_PAGE_WIDTH - tx; clipx = tx; }
6922 }
6923 else
6924 {
6925 tx += K056832_PAGE_WIDTH;
6926
6927 // handle left-edge wraparoundness and cull off-screen tilemaps
6928 if ((c == colspan-1) && (sx < K056832_PAGE_WIDTH)) sx += width;
6929 if ((sx + K056832_PAGE_WIDTH <= tx) || (sx - K056832_PAGE_WIDTH >= tx))
6930 { last_visible = 0; continue; }
6931
6932 // switch frame of reference and clip y
6933 if ((tx -= sx) >= 0) { clipw = K056832_PAGE_WIDTH - tx; clipx = 0; }
6934 else { clipw = K056832_PAGE_WIDTH + tx; clipx = -tx; }
6935 }
6936 }
6937 else { clipw = K056832_PAGE_WIDTH; clipx = 0; }
6938
6939 last_visible = 1;
6940
6941 dminx = clipx;
6942 dmaxx = clipx + clipw - 1;
6943
6944 drawrect.min_x = (dminx < cminx ) ? cminx : dminx;
6945 drawrect.max_x = (dmaxx > cmaxx ) ? cmaxx : dmaxx;
6946
6947 tilemap_set_scrollx(tilemap, 0, dx);
6948
6949 LINE_SHORTCIRCUIT:
6950 tilemap_draw(bitmap, &drawrect, tilemap, flags, priority);
6951
6952 } // end of line loop
6953 } // end of column loop
6954 } // end of row loop
6955
6956 K056832_ActiveLayer = last_active;
6957
6958 } // end of function
6959
K056832_set_LayerAssociation(int status)6960 void K056832_set_LayerAssociation(int status)
6961 {
6962 K056832_DefaultLayerAssociation = status;
6963 }
6964
K056832_get_LayerAssociation(void)6965 int K056832_get_LayerAssociation(void)
6966 {
6967 return(K056832_LayerAssociation);
6968 }
6969
K056832_set_LayerOffset(int layer,int offsx,int offsy)6970 void K056832_set_LayerOffset(int layer, int offsx, int offsy)
6971 {
6972 K056832_LayerOffset[layer][0] = offsx;
6973 K056832_LayerOffset[layer][1] = offsy;
6974 }
6975
K056832_set_LSRAMPage(int logical_page,int physical_page,int physical_offset)6976 void K056832_set_LSRAMPage(int logical_page, int physical_page, int physical_offset)
6977 {
6978 K056832_LSRAMPage[logical_page][0] = physical_page;
6979 K056832_LSRAMPage[logical_page][1] = physical_offset;
6980 }
6981
K056832_set_UpdateMode(int mode)6982 void K056832_set_UpdateMode(int mode)
6983 {
6984 K056832_UpdateMode = mode;
6985 }
6986
K056832_linemap_enable(int enable)6987 void K056832_linemap_enable(int enable)
6988 {
6989 K056832_linemap_enabled = enable;
6990 }
6991
K056832_is_IRQ_enabled(int irqline)6992 int K056832_is_IRQ_enabled(int irqline)
6993 {
6994 return(K056832_regs[0x06/2] & (1<<irqline & 7));
6995 }
6996
K056832_read_AVAC(int * mode,int * data)6997 void K056832_read_AVAC(int *mode, int *data)
6998 {
6999 *mode = K056832_regs[0x04/2] & 7;
7000 *data = K056832_regs[0x38/2];
7001 }
7002
K056832_read_register(int regnum)7003 int K056832_read_register(int regnum)
7004 {
7005 return(K056832_regs[regnum]);
7006 }
7007
7008
7009
7010 /***************************************************************************/
7011 /* */
7012 /* 055555 */
7013 /* */
7014 /***************************************************************************/
7015
7016 /* K055555 5-bit-per-pixel priority encoder */
7017 /* This device has 48 8-bit-wide registers */
7018
7019 static data8_t k55555_regs[128];
7020
K055555_vh_start(void)7021 void K055555_vh_start(void)
7022 {
7023 state_save_register_UINT8("K055555", 0, "registers", k55555_regs, 64);
7024
7025 memset(k55555_regs, 0, 64*sizeof(data8_t));
7026 }
7027
K055555_write_reg(data8_t regnum,data8_t regdat)7028 void K055555_write_reg(data8_t regnum, data8_t regdat)
7029 {
7030 #if VERBOSE
7031 static const char *rnames[46] =
7032 {
7033 "BGC CBLK", "BGC SET", "COLSET0", "COLSET1", "COLSET2", "COLSET3", "COLCHG ON",
7034 "A PRI 0", "A PRI 1", "A COLPRI", "B PRI 0", "B PRI 1", "B COLPRI", "C PRI", "D PRI",
7035 "OBJ PRI", "SUB1 PRI", "SUB2 PRI", "SUB3 PRI", "OBJ INPRI ON", "S1 INPRI ON", "S2 INPRI ON",
7036 "S3 INPRI ON", "A PAL", "B PAL", "C PAL", "D PAL", "OBJ PAL", "SUB1 PAL", "SUB2 PAL", "SUB3 PAL",
7037 "SUB2 PAL ON", "SUB3 PAL ON", "V INMIX", "V INMIX ON", "OS INMIX", "OS INMIX ON", "SHD PRI 1",
7038 "SHD PRI 2", "SHD PRI 3", "SHD ON", "SHD PRI SEL", "V BRI", "OS INBRI", "OS INBRI ON", "ENABLE"
7039 };
7040
7041 if (regdat != k55555_regs[regnum])
7042 {
7043 logerror("5^5: %x to reg %x (%s)\n", regdat, regnum, rnames[regnum]);
7044 }
7045 #endif
7046
7047 k55555_regs[regnum] = regdat;
7048 }
7049
WRITE32_HANDLER(K055555_long_w)7050 WRITE32_HANDLER( K055555_long_w )
7051 {
7052 data8_t regnum, regdat;
7053
7054 if (!(mem_mask & 0xff000000))
7055 {
7056 regnum = offset<<1;
7057 regdat = data>>24;
7058 }
7059 else
7060 {
7061 if (!(mem_mask & 0xff00))
7062 {
7063 regnum = (offset<<1)+1;
7064 regdat = data>>8;
7065 }
7066 else
7067 {
7068 // logerror("5^5: unknown mem_mask %08x\n", mem_mask);
7069 return;
7070 }
7071 }
7072
7073 K055555_write_reg(regnum, regdat);
7074 }
7075
WRITE16_HANDLER(K055555_word_w)7076 WRITE16_HANDLER( K055555_word_w )
7077 {
7078 if (mem_mask == 0xff00)
7079 {
7080 K055555_write_reg(offset, data&0xff);
7081 }
7082 else
7083 {
7084 K055555_write_reg(offset, data>>8);
7085 }
7086 }
7087
K055555_read_register(int regnum)7088 int K055555_read_register(int regnum)
7089 {
7090 return(k55555_regs[regnum]);
7091 }
7092
K055555_get_palette_index(int idx)7093 int K055555_get_palette_index(int idx)
7094 {
7095 return(k55555_regs[K55_PALBASE_A + idx]);
7096 }
7097
7098
7099
7100 /***************************************************************************/
7101 /* */
7102 /* 054338 */
7103 /* */
7104 /***************************************************************************/
7105
7106 static data16_t k54338_regs[32];
7107 static int K054338_shdRGB[9];
7108 static int K054338_alphainverted;
7109
7110
7111 // K054338 alpha blend / final mixer (normally used with the 55555)
7112 // because the implementation is vidhrdw dependant, this is just a
7113 // register-handling shell.
K054338_vh_start(void)7114 int K054338_vh_start(void)
7115 {
7116 memset(k54338_regs, 0, sizeof(data16_t)*32);
7117 memset(K054338_shdRGB, 0, sizeof(int)*9);
7118 K054338_alphainverted = 1;
7119
7120 state_save_register_UINT16("K054338", 0, "registers", k54338_regs, 32);
7121
7122 return 0;
7123 }
7124
WRITE16_HANDLER(K054338_word_w)7125 WRITE16_HANDLER( K054338_word_w )
7126 {
7127 COMBINE_DATA(k54338_regs + offset);
7128 }
7129
WRITE32_HANDLER(K054338_long_w)7130 WRITE32_HANDLER( K054338_long_w )
7131 {
7132 offset <<= 1;
7133 K054338_word_w(offset, data>>16, mem_mask>>16);
7134 K054338_word_w(offset+1, data, mem_mask);
7135 }
7136
7137 // returns a 16-bit '338 register
K054338_read_register(int reg)7138 int K054338_read_register(int reg)
7139 {
7140 return k54338_regs[reg];
7141 }
7142
K054338_update_all_shadows(void)7143 void K054338_update_all_shadows(void)
7144 {
7145 int i, d;
7146 int noclip = k54338_regs[K338_REG_CONTROL] & K338_CTL_CLIPSL;
7147
7148 for (i=0; i<9; i++)
7149 {
7150 d = k54338_regs[K338_REG_SHAD1R+i] & 0x1ff;
7151 if (d >= 0x100) d -= 0x200;
7152 K054338_shdRGB[i] = d;
7153 }
7154
7155 palette_set_shadow_dRGB32(0, K054338_shdRGB[0], K054338_shdRGB[1], K054338_shdRGB[2], noclip);
7156 palette_set_shadow_dRGB32(1, K054338_shdRGB[3], K054338_shdRGB[4], K054338_shdRGB[5], noclip);
7157 palette_set_shadow_dRGB32(2, K054338_shdRGB[6], K054338_shdRGB[7], K054338_shdRGB[8], noclip);
7158 }
7159
7160 // K054338 BG color fill
K054338_fill_solid_bg(struct mame_bitmap * bitmap)7161 void K054338_fill_solid_bg(struct mame_bitmap *bitmap)
7162 {
7163 UINT32 bgcolor;
7164 UINT32 *pLine;
7165 int x, y;
7166
7167 bgcolor = (K054338_read_register(K338_REG_BGC_R)&0xff)<<16;
7168 bgcolor |= K054338_read_register(K338_REG_BGC_GB);
7169
7170 /* and fill the screen with it */
7171 for (y = 0; y < bitmap->height; y++)
7172 {
7173 pLine = (UINT32 *)bitmap->base;
7174 pLine += ((bitmap->rowbytes / 4)*y);
7175 for (x = 0; x < bitmap->width; x++)
7176 *pLine++ = bgcolor;
7177 }
7178 }
7179
7180 // Unified K054338/K055555 BG color fill
K054338_fill_backcolor(struct mame_bitmap * bitmap,int mode)7181 void K054338_fill_backcolor(struct mame_bitmap *bitmap, int mode) // (see p.67)
7182 {
7183 int clipx, clipy, clipw, cliph, i, dst_pitch;
7184 int BGC_CBLK, BGC_SET;
7185 UINT32 *dst_ptr, *pal_ptr;
7186 register int bgcolor;
7187
7188 clipx = Machine->visible_area.min_x & ~3;
7189 clipy = Machine->visible_area.min_y;
7190 clipw = (Machine->visible_area.max_x - clipx + 4) & ~3;
7191 cliph = Machine->visible_area.max_y - clipy + 1;
7192
7193 dst_ptr = (UINT32 *)bitmap->line[clipy];
7194 dst_pitch = bitmap->rowpixels;
7195 dst_ptr += clipx;
7196
7197 BGC_SET = 0;
7198 pal_ptr = paletteram32;
7199
7200 if (!mode)
7201 {
7202 // single color output from CLTC
7203 bgcolor = (int)(k54338_regs[K338_REG_BGC_R]&0xff)<<16 | (int)k54338_regs[K338_REG_BGC_GB];
7204 }
7205 else
7206 {
7207 BGC_CBLK = K055555_read_register(0);
7208 BGC_SET = K055555_read_register(1);
7209 pal_ptr += BGC_CBLK << 9;
7210
7211 // single color output from PCU2
7212 if (!(BGC_SET & 2)) { bgcolor = *pal_ptr; mode = 0; } else bgcolor = 0;
7213 }
7214
7215 if (!mode)
7216 {
7217 // single color fill
7218 dst_ptr += clipw;
7219 i = clipw = -clipw;
7220 do
7221 {
7222 do { dst_ptr[i] = dst_ptr[i+1] = dst_ptr[i+2] = dst_ptr[i+3] = bgcolor; } while (i += 4);
7223 dst_ptr += dst_pitch;
7224 i = clipw;
7225 }
7226 while (--cliph);
7227 }
7228 else
7229 {
7230 if (!(BGC_SET & 1))
7231 {
7232 // vertical gradient fill
7233 pal_ptr += clipy;
7234 dst_ptr += clipw;
7235 bgcolor = *pal_ptr++;
7236 i = clipw = -clipw;
7237 do
7238 {
7239 do { dst_ptr[i] = dst_ptr[i+1] = dst_ptr[i+2] = dst_ptr[i+3] = bgcolor; } while (i += 4);
7240 dst_ptr += dst_pitch;
7241 bgcolor = *pal_ptr++;
7242 i = clipw;
7243 }
7244 while (--cliph);
7245 }
7246 else
7247 {
7248 // horizontal gradient fill
7249 pal_ptr += clipx;
7250 clipw <<= 2;
7251 do
7252 {
7253 memcpy(dst_ptr, pal_ptr, clipw);
7254 dst_ptr += dst_pitch;
7255 }
7256 while (--cliph);
7257 }
7258 }
7259 }
7260
7261 // addition blending unimplemented (requires major changes to drawgfx and tilemap.c)
K054338_set_alpha_level(int pblend)7262 int K054338_set_alpha_level(int pblend)
7263 {
7264 data16_t *regs;
7265 int ctrl, mixpri, mixset, mixlv;
7266
7267 if (pblend <= 0 || pblend > 3)
7268 {
7269 alpha_set_level(255);
7270 return(255);
7271 }
7272
7273 regs = k54338_regs;
7274 ctrl = k54338_regs[K338_REG_CONTROL];
7275 mixpri = ctrl & K338_CTL_MIXPRI;
7276 mixset = regs[K338_REG_PBLEND + (pblend>>1 & 1)] >> (~pblend<<3 & 8);
7277 mixlv = mixset & 0x1f;
7278
7279 if (K054338_alphainverted) mixlv = 0x1f - mixlv;
7280
7281 if (!(mixset & 0x20))
7282 {
7283 mixlv = mixlv<<3 | mixlv>>2;
7284 alpha_set_level(mixlv); // source x alpha/255 + target x (255-alpha)/255
7285 }
7286 else
7287 {
7288 if (!mixpri)
7289 {
7290 // source x alpha + target (clipped at 255)
7291 }
7292 else
7293 {
7294 // source + target x alpha (clipped at 255)
7295 }
7296
7297 // DUMMY
7298 if (mixlv && mixlv<0x1f) mixlv = 0x10;
7299 mixlv = mixlv<<3 | mixlv>>2;
7300 alpha_set_level(mixlv);
7301
7302 #if VERBOSE
7303 usrintf_showmessage("MIXSET%1d %s addition mode: %02x",pblend,(mixpri)?"dst":"src",mixset&0x1f);
7304 #endif
7305 }
7306
7307 return(mixlv);
7308 }
7309
K054338_invert_alpha(int invert)7310 void K054338_invert_alpha(int invert)
7311 {
7312 K054338_alphainverted = invert;
7313 }
7314
K054338_export_config(int ** shdRGB)7315 void K054338_export_config(int **shdRGB)
7316 {
7317 *shdRGB = K054338_shdRGB;
7318 }
7319
7320
7321
7322 /***************************************************************************/
7323 /* */
7324 /* 053250 */
7325 /* */
7326 /***************************************************************************/
7327
7328 static struct
7329 {
7330 int chips;
7331 struct K053250_CHIPTAG
7332 {
7333 data8_t regs[8];
7334 data8_t *base;
7335 data16_t *ram, *rammax;
7336 data16_t *buffer[2];
7337 UINT32 rommask;
7338 int page[2];
7339 int frame, offsx, offsy;
7340 } chip[2];
7341 } K053250_info;
7342
K053250_set_LayerOffset(int chip,int offsx,int offsy)7343 void K053250_set_LayerOffset(int chip, int offsx, int offsy)
7344 {
7345 K053250_info.chip[chip].offsx = offsx;
7346 K053250_info.chip[chip].offsy = offsy;
7347 }
7348
7349 // The DMA process should be instantaneous but since rendering in MAME is performed at VIDEO_UPDATE()
7350 // the K053250 memory must be buffered to maintain visual integrity.
K053250_dma(int chip,int limiter)7351 void K053250_dma(int chip, int limiter)
7352 {
7353 struct K053250_CHIPTAG *chip_ptr;
7354 int last_frame, current_frame;
7355
7356 chip_ptr = &K053250_info.chip[chip];
7357
7358 current_frame = cpu_getcurrentframe();
7359 last_frame = chip_ptr->frame;
7360
7361 if (limiter && current_frame == last_frame) return; // make sure we only do DMA transfer once per frame
7362
7363 chip_ptr->frame = current_frame;
7364 memcpy(chip_ptr->buffer[chip_ptr->page[chip]], chip_ptr->ram, 0x1000);
7365 chip_ptr->page[chip] ^= 1;
7366 }
7367
7368 // Pixel data of the K053250 is nibble packed. It's preferable to be unpacked into byte format.
K053250_unpack_pixels(int region)7369 void K053250_unpack_pixels(int region)
7370 {
7371 UINT8 *src_ptr, *dst_ptr;
7372 int hi_nibble, lo_nibble, offset;
7373
7374 dst_ptr = src_ptr = memory_region(region);
7375 offset = memory_region_length(region) / 2 - 1;
7376
7377 do
7378 {
7379 lo_nibble = hi_nibble = src_ptr[offset];
7380 hi_nibble >>= 4;
7381 lo_nibble &= 0xf;
7382 dst_ptr[offset*2 ] = hi_nibble;
7383 dst_ptr[offset*2+1] = lo_nibble;
7384 }
7385 while ((--offset) >= 0);
7386 }
7387
K053250_vh_start(int chips,int * region)7388 int K053250_vh_start(int chips, int *region)
7389 {
7390 data16_t *ram;
7391 int chip;
7392
7393 K053250_info.chips = chips;
7394
7395 for(chip=0; chip<chips; chip++)
7396 {
7397 K053250_info.chip[chip].base = memory_region(region[chip]);
7398 if (!(ram = auto_malloc(0x6000))) return 1;
7399 K053250_info.chip[chip].ram = ram;
7400 K053250_info.chip[chip].rammax = ram + 0x800;
7401 K053250_info.chip[chip].buffer[0] = ram + 0x2000;
7402 K053250_info.chip[chip].buffer[1] = ram + 0x2800;
7403 memset(ram+0x2000, 0, 0x2000);
7404 K053250_info.chip[chip].rommask = memory_region_length(region[chip]);
7405 K053250_info.chip[chip].page[1] = K053250_info.chip[chip].page[0] = 0;
7406 K053250_info.chip[chip].offsy = K053250_info.chip[chip].offsx = 0;
7407 K053250_info.chip[chip].frame = -1;
7408
7409 state_save_register_UINT16("K053250", chip, "memory", K053250_info.chip[chip].ram, 0x800);
7410 state_save_register_UINT8 ("K053250", chip, "registers", K053250_info.chip[chip].regs, 8);
7411 }
7412
7413 return 0;
7414 }
7415
WRITE16_HANDLER(K053250_0_w)7416 WRITE16_HANDLER( K053250_0_w )
7417 {
7418 if (ACCESSING_LSB)
7419 {
7420 // start LVC DMA transfer at the falling edge of control register's bit1
7421 if (offset == 4 && !(data & 2) && (K053250_info.chip[0].regs[4] & 2)) K053250_dma(0, 1);
7422
7423 K053250_info.chip[0].regs[offset] = data;
7424 }
7425 }
7426
READ16_HANDLER(K053250_0_r)7427 READ16_HANDLER( K053250_0_r )
7428 {
7429 return K053250_info.chip[0].regs[offset];
7430 }
7431
WRITE16_HANDLER(K053250_0_ram_w)7432 WRITE16_HANDLER( K053250_0_ram_w )
7433 {
7434 COMBINE_DATA( K053250_info.chip[0].ram + offset);
7435 }
7436
READ16_HANDLER(K053250_0_ram_r)7437 READ16_HANDLER( K053250_0_ram_r )
7438 {
7439 return K053250_info.chip[0].ram[offset];
7440 }
7441
READ16_HANDLER(K053250_0_rom_r)7442 READ16_HANDLER( K053250_0_rom_r )
7443 {
7444 // if (!(K053250_info.chip[0].regs[5] & 1)) logerror("Back: Reading rom memory with enable=0\n");
7445
7446 return *(K053250_info.chip[0].base + 0x80000*K053250_info.chip[0].regs[6] + 0x800*K053250_info.chip[0].regs[7] + (offset>>1));
7447 }
7448
WRITE16_HANDLER(K053250_1_w)7449 WRITE16_HANDLER( K053250_1_w )
7450 {
7451 if (ACCESSING_LSB)
7452 {
7453 // start LVC DMA transfer at the falling edge of control register's bit1
7454 if (offset == 4 && !(data & 2) && (K053250_info.chip[1].regs[4] & 2)) K053250_dma(1, 1);
7455
7456 K053250_info.chip[1].regs[offset] = data;
7457 }
7458 }
7459
READ16_HANDLER(K053250_1_r)7460 READ16_HANDLER( K053250_1_r )
7461 {
7462 return K053250_info.chip[1].regs[offset];
7463 }
7464
WRITE16_HANDLER(K053250_1_ram_w)7465 WRITE16_HANDLER( K053250_1_ram_w )
7466 {
7467 COMBINE_DATA( K053250_info.chip[1].ram + offset);
7468 }
7469
READ16_HANDLER(K053250_1_ram_r)7470 READ16_HANDLER( K053250_1_ram_r )
7471 {
7472 return K053250_info.chip[1].ram[offset];
7473 }
7474
READ16_HANDLER(K053250_1_rom_r)7475 READ16_HANDLER( K053250_1_rom_r )
7476 {
7477 // if (!(K053250_info.chip[1].regs[5] & 1)) logerror("Back: Reading rom memory with enable=0\n");
7478
7479 return *(K053250_info.chip[1].base + 0x80000*K053250_info.chip[1].regs[6] + 0x800*K053250_info.chip[1].regs[7] + (offset>>1));
7480 }
7481
7482 #if 0
7483
7484 // old code (for reference; do not remove)
7485 #define ADJUST_FOR_ORIENTATION(type, orientation, bitmapi, bitmapp, x, y) \
7486 int dy = ((type *)bitmap->line[1]) - ((type *)bitmap->line[0]); \
7487 int dyp = ((UINT8 *)bitmapp->line[1]) - ((UINT8 *)bitmapp->line[0]); \
7488 type *dsti = (type *)bitmapi->line[0] + y * dy + x; \
7489 UINT8 *dstp = (UINT8 *)bitmapp->line[0] + y * dyp + x; \
7490 int xadv = 1; \
7491 if (orientation) \
7492 { \
7493 int tx = x, ty = y, temp; \
7494 if ((orientation) & ORIENTATION_SWAP_XY) \
7495 { \
7496 temp = tx; tx = ty; ty = temp; \
7497 xadv = dy; \
7498 } \
7499 if ((orientation) & ORIENTATION_FLIP_X) \
7500 { \
7501 tx = bitmap->width - 1 - tx; \
7502 if (!((orientation) & ORIENTATION_SWAP_XY)) xadv = -xadv; \
7503 } \
7504 if ((orientation) & ORIENTATION_FLIP_Y) \
7505 { \
7506 ty = bitmap->height - 1 - ty; \
7507 if ((orientation) & ORIENTATION_SWAP_XY) xadv = -xadv; \
7508 } \
7509 /* can't lookup line because it may be negative! */ \
7510 dsti = ((type *)bitmapi->line[0]) + dy * ty + tx; \
7511 dstp = ((UINT8 *)bitmapp->line[0]) + dyp * ty + tx; \
7512 }
7513
7514 static void K053250_pdraw_scanline8(
7515 struct mame_bitmap *bitmap,int x,int y,int length,
7516 const UINT8 *src,pen_t *pens,int transparent_pen,UINT32 orient,int pri)
7517 {
7518 /* 8bpp destination */
7519 if (bitmap->depth == 8)
7520 {
7521 /* adjust in case we're oddly oriented */
7522 ADJUST_FOR_ORIENTATION(UINT8, orient, bitmap, priority_bitmap, x, y);
7523
7524 /* with pen lookups */
7525 if (pens)
7526 {
7527 if (transparent_pen == -1)
7528 while (length--)
7529 {
7530 *dsti = pens[*src++];
7531 *dstp = pri;
7532 dsti += xadv;
7533 dstp += xadv;
7534 }
7535 else
7536 while (length--)
7537 {
7538 UINT32 spixel = *src++;
7539 if (spixel != transparent_pen)
7540 {
7541 *dsti = pens[spixel];
7542 *dstp = pri;
7543 }
7544 dsti += xadv;
7545 dstp += xadv;
7546 }
7547 }
7548
7549 /* without pen lookups */
7550 else
7551 {
7552 if (transparent_pen == -1)
7553 while (length--)
7554 {
7555 *dsti = *src++;
7556 *dstp = pri;
7557 dsti += xadv;
7558 dstp += xadv;
7559 }
7560 else
7561 while (length--)
7562 {
7563 UINT32 spixel = *src++;
7564 if (spixel != transparent_pen)
7565 {
7566 *dsti = spixel;
7567 *dstp = pri;
7568 }
7569 dsti += xadv;
7570 dstp += xadv;
7571 }
7572 }
7573 }
7574
7575 /* 16bpp destination */
7576 else if(bitmap->depth == 15 || bitmap->depth == 16)
7577 {
7578 /* adjust in case we're oddly oriented */
7579 ADJUST_FOR_ORIENTATION(UINT16, orient, bitmap, priority_bitmap, x, y);
7580 /* with pen lookups */
7581 if (pens)
7582 {
7583 if (transparent_pen == -1)
7584 while (length--)
7585 {
7586 *dsti = pens[*src++];
7587 *dstp = pri;
7588 dsti += xadv;
7589 dstp += xadv;
7590 }
7591 else
7592 while (length--)
7593 {
7594 UINT32 spixel = *src++;
7595 if (spixel != transparent_pen)
7596 {
7597 *dsti = pens[spixel];
7598 *dstp = pri;
7599 }
7600 dsti += xadv;
7601 dstp += xadv;
7602 }
7603 }
7604
7605 /* without pen lookups */
7606 else
7607 {
7608 if (transparent_pen == -1)
7609 while (length--)
7610 {
7611 *dsti = *src++;
7612 *dstp = pri;
7613 dsti += xadv;
7614 dstp += xadv;
7615 }
7616 else
7617 while (length--)
7618 {
7619 UINT32 spixel = *src++;
7620 if (spixel != transparent_pen)
7621 {
7622 *dsti = spixel;
7623 *dstp = pri;
7624 }
7625 dsti += xadv;
7626 dstp += xadv;
7627 }
7628 }
7629 }
7630
7631 /* 32bpp destination */
7632 else
7633 {
7634 /* adjust in case we're oddly oriented */
7635 ADJUST_FOR_ORIENTATION(UINT32, orient, bitmap, priority_bitmap, x, y);
7636 /* with pen lookups */
7637 if (pens)
7638 {
7639 if (transparent_pen == -1)
7640 while (length--)
7641 {
7642 *dsti = pens[*src++];
7643 *dstp = pri;
7644 dsti += xadv;
7645 dstp += xadv;
7646 }
7647 else
7648 while (length--)
7649 {
7650 UINT32 spixel = *src++;
7651 if (spixel != transparent_pen)
7652 {
7653 *dsti = pens[spixel];
7654 *dstp = pri;
7655 }
7656 dsti += xadv;
7657 dstp += xadv;
7658 }
7659 }
7660
7661 /* without pen lookups */
7662 else
7663 {
7664 if (transparent_pen == -1)
7665 while (length--)
7666 {
7667 *dsti = *src++;
7668 *dstp = pri;
7669 dsti += xadv;
7670 dstp += xadv;
7671 }
7672 else
7673 while (length--)
7674 {
7675 UINT32 spixel = *src++;
7676 if (spixel != transparent_pen)
7677 {
7678 *dsti = spixel;
7679 *dstp = pri;
7680 }
7681 dsti += xadv;
7682 dstp += xadv;
7683 }
7684 }
7685 }
7686 }
7687
7688 void K053250_draw(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int chip, int colorbase, int pri)
7689 {
7690 static int pmode[2] = {-1,-1};
7691 static int kc=-1, kk=0, kxx=-105, kyy=0;
7692
7693 const struct rectangle area = Machine->visible_area;
7694 data16_t *line;
7695 int delta, dim1, dim1_max, dim2_max;
7696 UINT32 mask1, mask2;
7697 int sp;
7698 #if 1
7699 int orientation = ((K053250_info.chip[chip].regs[4] & 8) ? ORIENTATION_FLIP_X : 0)
7700 | ((K053250_info.chip[chip].regs[4] & 16) ? ORIENTATION_FLIP_Y : 0)
7701 | ((K053250_info.chip[chip].regs[4] & 1) ? 0 : ORIENTATION_SWAP_XY);
7702 #else
7703 int orientation = (!K053250_info.chip[chip].regs[4] & 8 ? ORIENTATION_FLIP_X : 0)
7704 | (K053250_info.chip[chip].regs[4] & 16 ? ORIENTATION_FLIP_Y : 0)
7705 | (!(K053250_info.chip[chip].regs[4] & 1) ? 0 : ORIENTATION_SWAP_XY);
7706 #endif
7707
7708 INT16 cur_x = (K053250_info.chip[chip].regs[0] << 8) | K053250_info.chip[chip].regs[1];
7709 INT16 cur_y = (K053250_info.chip[chip].regs[2] << 8) | K053250_info.chip[chip].regs[3];
7710
7711 if(pmode[chip] != K053250_info.chip[chip].regs[4]) {
7712 pmode[chip] = K053250_info.chip[chip].regs[4];
7713 #if 0
7714 fprintf(stderr, "NEW MODE %d %02x [%x %c%c%c%c%c]\n", chip,
7715 pmode[chip],
7716 pmode[chip] >> 5,
7717 pmode[chip] & 16 ? 'y' : '-',
7718 pmode[chip] & 8 ? 'x' : '-',
7719 pmode[chip] & 4 ? 'w' : '-',
7720 pmode[chip] & 2 ? '?' : '-',
7721 pmode[chip] & 1 ? 's' : '-');
7722 #endif
7723 }
7724
7725 colorbase <<= 4;
7726
7727 if(orientation & ORIENTATION_SWAP_XY) {
7728 dim1_max = area.max_x - area.min_x + 1;
7729 dim2_max = area.max_y - area.min_y + 1;
7730 // -358 for level 1 boss, huh? -495
7731 if(orientation & ORIENTATION_FLIP_Y)
7732 delta = 238 - cur_y;
7733 else
7734 delta = kyy + cur_y;
7735 line = K053250_info.chip[chip].ram + (((area.min_x + cur_x + kxx) & 0x1ff) << 2);
7736 } else {
7737 dim1_max = area.max_y - area.min_y + 1;
7738 dim2_max = area.max_x - area.min_x + 1;
7739 delta = cur_x + 49;
7740 line = K053250_info.chip[chip].ram + (((area.min_y + cur_y + 16) & 0x1ff) << 2);
7741 }
7742
7743 if(chip && ++kk == 3) {
7744 int kx=0, kkc = 0;
7745 kk = 0;
7746 if(keyboard_pressed(KEYCODE_Y)) {
7747 kx = 1;
7748 kc--;
7749 if(kc<-1)
7750 kc = 511;
7751 }
7752 if(keyboard_pressed(KEYCODE_U)) {
7753 kx = 1;
7754 kc++;
7755 if(kc==512)
7756 kc = -1;
7757 }
7758
7759 if(keyboard_pressed(KEYCODE_T)) {
7760 kkc = 1;
7761 kyy--;
7762 }
7763 if(keyboard_pressed(KEYCODE_V)) {
7764 kkc = 1;
7765 kyy++;
7766 }
7767 if(keyboard_pressed(KEYCODE_F)) {
7768 kkc = 1;
7769 kxx--;
7770 }
7771 if(keyboard_pressed(KEYCODE_G)) {
7772 kkc = 1;
7773 kxx++;
7774 }
7775 #if 0
7776 if(kx) {
7777 UINT16 *l1 = line + ((4*kc) & 0x7ff);
7778 usrintf_showmessage("Line %d [%02x] (%04x %04x %04x %04x)", kc,
7779 K053250_info.chip[chip].regs[4],
7780 l1[0],
7781 l1[1],
7782 l1[2],
7783 l1[3]);
7784 }
7785
7786 if(kkc)
7787 usrintf_showmessage("(%d, %d)", kxx, kyy);
7788 #endif
7789 }
7790
7791
7792 switch(K053250_info.chip[chip].regs[4] >> 5) {
7793 case 0: // Not sure. Warp level
7794 mask1 = 0xffff0000;
7795 mask2 = 0x0000ffff;
7796 sp = 0;
7797 break;
7798 case 1: // Elaine's background
7799 mask1 = 0xffff8000;
7800 mask2 = 0x00007fff;
7801 sp = 0;
7802 break;
7803 case 2:
7804 mask1 = 0xffff0000;
7805 mask2 = 0x0000ffff;
7806 sp = 0;
7807 break;
7808 case 4: // Level 1 boss, water level (planet)
7809 mask1 = 0xffffc000;
7810 mask2 = 0x00003fff;
7811 sp = 0;
7812 break;
7813 case 7: // Organic level
7814 mask1 = 0xffff0000;
7815 mask2 = 0x0000ffff;
7816 sp = 1;
7817 break;
7818 default:
7819 // logerror("Unknown mode %02x\n", K053250_info.chip[chip].regs[4] & 0xe0);
7820 mask1 = 0xffff0000;
7821 mask2 = 0x0000ffff;
7822 sp = 0;
7823 break;
7824 }
7825
7826 if(K053250_info.chip[chip].regs[4] & 4)
7827 mask1 = 0;
7828
7829 for(dim1 = 0; dim1 < dim1_max; dim1++) {
7830 data16_t color = *line++;
7831 UINT16 start = *line++;
7832 data16_t inc = *line++;
7833 INT16 offset = *line++;
7834 int dim2;
7835 unsigned char *pixel;
7836 UINT32 cpos;
7837 unsigned char scanline[512];
7838 unsigned char *gbase = K053250_info.chip[chip].base + (((start & 0xff00) << 7) % K053250_info.chip[chip].rommask);
7839
7840 if(offset >= 0x500)
7841 offset -= 0x800;
7842
7843 if(line == K053250_info.chip[chip].rammax)
7844 line = K053250_info.chip[chip].ram;
7845
7846 if(!color && !start)
7847 continue;
7848
7849 pixel = scanline;
7850 start = (start & 0xff) << 7;
7851 cpos = (offset + delta)*inc;
7852 // fprintf(stderr, "%3d %08x %04x\n", dim1, cpos, inc);
7853
7854 for(dim2 = 0; dim2 < dim2_max; dim2++) {
7855 int romp;
7856 UINT32 rcpos = cpos;
7857
7858 if(sp && (rcpos & mask1))
7859 rcpos += inc << 9;
7860
7861 if(rcpos & mask1) {
7862 *pixel++ = 0;
7863 cpos += inc;
7864 continue;
7865 }
7866
7867 romp = gbase[(((rcpos & mask2)>>7) + start) & 0x7fff];
7868
7869 if(rcpos & 0x40)
7870 romp &= 0xf;
7871 else
7872 romp >>= 4;
7873 *pixel++ = romp;
7874 cpos += inc;
7875 }
7876 if(orientation & ORIENTATION_SWAP_XY)
7877 K053250_pdraw_scanline8(bitmap, area.min_y, area.min_x+dim1, dim2_max, scanline,
7878 Machine->pens + ((dim1 == kc ? 0x200 : colorbase) | ((color & 0x0f) << 4)),
7879 0, orientation, pri);
7880 else
7881 K053250_pdraw_scanline8(bitmap, area.min_x, area.min_y+dim1, dim2_max, scanline,
7882 Machine->pens + ((dim1 == kc ? 0x200 : colorbase) | ((color & 0x0f) << 4)),
7883 0, orientation, pri);
7884 }
7885 }
7886
7887 #else
7888
7889 // 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)7890 static INLINE void K053250_pdraw_scanline32(struct mame_bitmap *bitmap, pen_t *palette, UINT8 *source,
7891 const struct rectangle *cliprect, int linepos, int scroll, int zoom,
7892 UINT32 clipmask, UINT32 wrapmask, UINT32 orientation, int priority)
7893 {
7894 // a sixteen-bit fixed point resolution should be adequate to our application
7895 #define FIXPOINT_PRECISION 16
7896 #define FIXPOINT_PRECISION_HALF (1<<(FIXPOINT_PRECISION-1))
7897
7898 int end_pixel, flip, dst_min, dst_max, dst_start, dst_length;
7899
7900 UINT32 src_wrapmask;
7901 UINT8 *src_base;
7902 int src_x;
7903 int src_fx, src_fdx;
7904 int pix_data, dst_offset;
7905 pen_t *pal_base;
7906 UINT8 *pri_base;
7907 UINT32 *dst_base;
7908 int dst_adv;
7909 UINT8 pri;
7910
7911 // flip X and flip Y also switch role when the X Y coordinates are swapped
7912 if (!(orientation & ORIENTATION_SWAP_XY))
7913 {
7914 flip = orientation & ORIENTATION_FLIP_X;
7915 dst_min = cliprect->min_x;
7916 dst_max = cliprect->max_x;
7917 }
7918 else
7919 {
7920 flip = orientation & ORIENTATION_FLIP_Y;
7921 dst_min = cliprect->min_y;
7922 dst_max = cliprect->max_y;
7923 }
7924
7925 if (clipmask)
7926 {
7927 // reject scanlines that are outside of the target bitmap's right(bottom) clip boundary
7928 dst_start = -scroll;
7929 if (dst_start > dst_max) return;
7930
7931 // calculate target length
7932 dst_length = clipmask + 1;
7933 if (zoom) dst_length = (dst_length << 6) / zoom;
7934
7935 // reject scanlines that are outside of the target bitmap's left(top) clip boundary
7936 end_pixel = dst_start + dst_length - 1;
7937 if (end_pixel < dst_min) return;
7938
7939 // clip scanline tail
7940 if ((end_pixel -= dst_max) > 0) dst_length -= end_pixel;
7941
7942 // reject zero-length scanlines
7943 if (dst_length <= 0) return;
7944
7945 // calculate zoom factor
7946 src_fdx = zoom << (FIXPOINT_PRECISION-6);
7947
7948 // clip scanline head
7949 end_pixel = dst_min;
7950 if ((end_pixel -= dst_start) > 0)
7951 {
7952 // chop scanline to the correct length and move target start location to the left(top) clip boundary
7953 dst_length -= end_pixel;
7954 dst_start = dst_min;
7955
7956 // and skip the source for the left(top) clip region
7957 src_fx = end_pixel * src_fdx + FIXPOINT_PRECISION_HALF;
7958 }
7959 else
7960 // the point five bias is to ensure even distribution of stretched or shrinked pixels
7961 src_fx = FIXPOINT_PRECISION_HALF;
7962
7963 // adjust flipped source
7964 if (flip)
7965 {
7966 // start from the target's clipped end if the scanline is flipped
7967 dst_start = dst_max + dst_min - dst_start - (dst_length-1);
7968
7969 // and move source start location to the opposite end
7970 src_fx += (dst_length-1) * src_fdx - 1;
7971 src_fdx = -src_fdx;
7972 }
7973 }
7974 else
7975 {
7976 // draw wrapped scanline at virtual bitmap boundary when source clipping is off
7977 dst_start = dst_min;
7978 dst_length = dst_max - dst_min + 1; // target scanline spans the entire visible area
7979 src_fdx = zoom << (FIXPOINT_PRECISION-6);
7980
7981 // pre-advance source for the clipped region
7982 if (!flip)
7983 src_fx = (scroll + dst_min) * src_fdx + FIXPOINT_PRECISION_HALF;
7984 else
7985 {
7986 src_fx = (scroll + dst_max) * src_fdx + FIXPOINT_PRECISION_HALF-1;
7987 src_fdx = -src_fdx;
7988 }
7989 }
7990
7991 if (!(orientation & ORIENTATION_SWAP_XY))
7992 {
7993 // calculate target increment for horizontal scanlines which is exactly one
7994 dst_adv = 1;
7995 dst_offset = dst_length;
7996 pri_base = (UINT8 *)priority_bitmap->line[linepos] + dst_start + dst_offset;
7997 dst_base = (UINT32 *)bitmap->line[linepos] + dst_start + dst_length;
7998 }
7999 else
8000 {
8001 // calculate target increment for vertical scanlines which is the bitmap's pitch value
8002 dst_adv = bitmap->rowpixels;
8003 dst_offset= dst_length * dst_adv;
8004 pri_base = (UINT8 *)priority_bitmap->line[dst_start] + linepos + dst_offset;
8005 dst_base = (UINT32 *)bitmap->line[dst_start] + linepos + dst_offset;
8006 }
8007
8008 #if 0
8009 // generalized
8010 src_base = source;
8011 src_x = 0;
8012
8013 // there is no need to wrap source offsets along with source clipping
8014 // so we set all bits of the wrapmask to one
8015 src_wrapmask = (clipmask) ? ~0 : wrapmask;
8016
8017 pal_base = palette;
8018 pri = (UINT8)priority;
8019 dst_offset = -dst_offset; // negate target offset in order to terminated draw loop at zero condition
8020
8021 if (pri)
8022 {
8023 // draw scanline and update priority bitmap
8024 do
8025 {
8026 pix_data = src_base[(src_fx>>FIXPOINT_PRECISION) & src_wrapmask];
8027 src_fx += src_fdx;
8028
8029 if (pix_data)
8030 {
8031 pix_data = pal_base[pix_data];
8032 pri_base[dst_offset] = pri;
8033 dst_base[dst_offset] = pix_data;
8034 }
8035 }
8036 while (dst_offset += dst_adv);
8037 }
8038 else
8039 {
8040 // draw scanline but do not update priority bitmap
8041 do
8042 {
8043 pix_data = src_base[(src_fx>>FIXPOINT_PRECISION) & src_wrapmask];
8044 src_fx += src_fdx;
8045
8046 if (pix_data)
8047 {
8048 dst_base[dst_offset] = pal_base[pix_data];
8049 }
8050 }
8051 while (dst_offset += dst_adv);
8052 }
8053 #else
8054 // register efficient
8055 pal_base = palette;
8056 pri = (UINT8)priority;
8057 dst_offset = -dst_offset; // negate target offset in order to terminated draw loop at zero condition
8058
8059 // advance and convert source offset from fixed point to integer
8060 #define ADVANCE_SOURCE_OFFSET { src_x = src_fx; src_fx += src_fdx; src_x >>= FIXPOINT_PRECISION; }
8061
8062 // draw non-zero pens and update priority bitmap
8063 #define DRAWPIXEL_PRIORITY { if (pix_data) { pix_data = pal_base[pix_data]; pri_base[dst_offset] = pri; dst_base[dst_offset] = pix_data; } }
8064
8065 // draw non-zero pens but do not update priority bitmap
8066 #define DRAWPIXEL_NOPRIORITY { if (pix_data) dst_base[dst_offset] = pal_base[pix_data]; }
8067
8068 if (clipmask)
8069 {
8070 ADVANCE_SOURCE_OFFSET
8071 src_base = source;
8072
8073 if (dst_adv == 1)
8074 {
8075 if (pri)
8076 do { pix_data= src_base[src_x]; ADVANCE_SOURCE_OFFSET DRAWPIXEL_PRIORITY } while (++dst_offset);
8077 else
8078 do { pix_data= src_base[src_x]; ADVANCE_SOURCE_OFFSET DRAWPIXEL_NOPRIORITY } while (++dst_offset);
8079 }
8080 else
8081 {
8082 if (pri)
8083 do { pix_data= src_base[src_x]; ADVANCE_SOURCE_OFFSET DRAWPIXEL_PRIORITY } while (dst_offset += (512+32));
8084 else
8085 do { pix_data= src_base[src_x]; ADVANCE_SOURCE_OFFSET DRAWPIXEL_NOPRIORITY } while (dst_offset += (512+32));
8086 }
8087 }
8088 else
8089 {
8090 src_wrapmask = wrapmask << FIXPOINT_PRECISION | ((1<<FIXPOINT_PRECISION)-1);
8091 src_fx &= src_wrapmask;
8092 ADVANCE_SOURCE_OFFSET
8093 src_base = source;
8094 src_fx &= src_wrapmask;
8095
8096 if (dst_adv == 1)
8097 {
8098 if (pri)
8099 do { pix_data = src_base[src_x]; ADVANCE_SOURCE_OFFSET src_fx &= src_wrapmask; DRAWPIXEL_PRIORITY } while (++dst_offset);
8100 else
8101 do { pix_data = src_base[src_x]; ADVANCE_SOURCE_OFFSET src_fx &= src_wrapmask; DRAWPIXEL_NOPRIORITY } while (++dst_offset);
8102 }
8103 else
8104 {
8105 if (pri)
8106 do { pix_data = src_base[src_x]; ADVANCE_SOURCE_OFFSET src_fx &= src_wrapmask; DRAWPIXEL_PRIORITY } while (dst_offset += (512+32));
8107 else
8108 do { pix_data = src_base[src_x]; ADVANCE_SOURCE_OFFSET src_fx &= src_wrapmask; DRAWPIXEL_NOPRIORITY } while (dst_offset += (512+32));
8109 }
8110 }
8111 #endif
8112
8113 #undef FIXPOINT_PRECISION
8114 #undef FIXPOINT_PRECISION_HALF
8115 }
8116
K053250_draw(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int chip,int colorbase,int flags,int priority)8117 void K053250_draw(struct mame_bitmap *bitmap, const struct rectangle *cliprect, int chip, int colorbase, int flags, int priority)
8118 {
8119 struct K053250_CHIPTAG *chip_ptr;
8120 data16_t *line_ram;
8121 data8_t *pix_base, *pix_ptr, *regs;
8122 pen_t *pal_base, *pal_ptr;
8123 UINT32 rommask, src_clipmask, src_wrapmask, dst_wrapmask;
8124 int map_scrollx, map_scrolly, ctrl, orientation;
8125 int dst_minx, dst_maxx, dst_miny, dst_maxy;
8126 int linedata_offs, linedata_adv, line_pos, line_start, line_end, scroll_corr;
8127 int color, offset, zoom, scroll, passes, i, dst_height;
8128
8129 chip_ptr = &K053250_info.chip[chip]; // pointer to chip parameters
8130 line_ram = chip_ptr->buffer[chip_ptr->page[chip]]; // pointer to physical line RAM
8131 pix_base = chip_ptr->base; // pointer to source pixel ROM
8132 rommask = chip_ptr->rommask; // source ROM limit
8133 regs = chip_ptr->regs; // pointer to registers group
8134
8135 map_scrollx = (short)(regs[0]<<8 | regs[1]); // signed horizontal scroll value
8136 map_scrolly = (short)(regs[2]<<8 | regs[3]); // signed vertical scroll value
8137 map_scrollx -= chip_ptr->offsx; // add user X offset to horizontal scroll
8138 map_scrolly -= chip_ptr->offsy; // add user Y offset to vertical scroll
8139 ctrl = regs[4]; // register four is the main control register
8140
8141 // copy visible boundary values to more accessible locations
8142 dst_minx = cliprect->min_x;
8143 dst_maxx = cliprect->max_x;
8144 dst_miny = cliprect->min_y;
8145 dst_maxy = cliprect->max_y;
8146
8147 orientation = 0; // orientation defaults to no swapping and no flipping
8148 dst_height = 512; // virtual bitmap height defaults to five hundred and twelve pixels
8149 linedata_adv = 4; // line info packets are four words(eight bytes) apart
8150
8151 {
8152 // switch X and Y parameters when the first bit of the control register is cleared
8153 if (!(ctrl & 0x01)) orientation |= ORIENTATION_SWAP_XY;
8154
8155 // invert X parameters when the forth bit of the control register is set
8156 if (ctrl & 0x08) orientation |= ORIENTATION_FLIP_X;
8157
8158 // invert Y parameters when the fifth bit of the control register is set
8159 if (ctrl & 0x10) orientation |= ORIENTATION_FLIP_Y;
8160
8161 switch (ctrl>>5) // the upper four bits of the control register select source and target dimensions
8162 {
8163 case 0 :
8164 // Xexex: L6 galaxies
8165 // Metam: L4 forest, L5 arena, L6 tower interior, final boss
8166
8167 // crop source offset between zero and two hundred and fifty-five inclusive,
8168 // and set virtual bitmap height to two hundred and fifty-six pixels
8169 src_wrapmask = src_clipmask = 0xff;
8170 dst_height = 0x100;
8171 break;
8172 case 1 :
8173 // Xexex: prologue, L7 nebulae
8174
8175 // the source offset is cropped to zero and five hundred and eleven inclusive
8176 src_wrapmask = src_clipmask = 0x1ff;
8177 break;
8178 case 4 :
8179 // Xexex: L1 sky and boss, L3 planet, L5 poly-face, L7 battle ship patches
8180 // Metam: L1 summoning circle, L3 caves, L6 gargoyle towers
8181
8182 // crop source offset between zero and two hundred and fifty-five inclusive,
8183 // and allow source offset to wrap back at 500 hexadecimal to minus 300 hexadecimal
8184 src_wrapmask = src_clipmask = 0xff;
8185 flags |= K053250_WRAP500;
8186 break;
8187 // case 2 : // Xexex: title
8188 // case 7 : // Xexex: L4 organic stage
8189 default:
8190
8191 // crop source offset between zero and one thousand and eleven inclusive,
8192 // keep other dimensions to their defaults
8193 src_wrapmask = src_clipmask = 0x3ff;
8194 break;
8195 }
8196
8197 // disable source clipping when the third bit of the control register is set
8198 if (ctrl & 0x04) src_clipmask = 0;
8199
8200 if (!(orientation & ORIENTATION_SWAP_XY)) // normal orientaion with no X Y switching
8201 {
8202 line_start = dst_miny; // the first scanline starts at the minimum Y clip location
8203 line_end = dst_maxy; // the last scanline ends at the maximum Y clip location
8204 scroll_corr = map_scrollx; // concentrate global X scroll
8205 linedata_offs = map_scrolly; // determine where to get info for the first line
8206
8207 if (orientation & ORIENTATION_FLIP_X)
8208 {
8209 scroll_corr = -scroll_corr; // X scroll adjustment should be negated in X flipped scenarioes
8210 }
8211
8212 if (orientation & ORIENTATION_FLIP_Y)
8213 {
8214 linedata_adv = -linedata_adv; // traverse line RAM backward in Y flipped scenarioes
8215 linedata_offs += bitmap->height - 1; // and get info for the first line from the bottom
8216 }
8217
8218 dst_wrapmask = ~0; // scanlines don't seem to wrap horizontally in normal orientation
8219 passes = 1; // draw scanline in a single pass
8220 }
8221 else // orientaion with X and Y parameters switched
8222 {
8223 line_start = dst_minx; // the first scanline starts at the minimum X clip location
8224 line_end = dst_maxx; // the last scanline ends at the maximum X clip location
8225 scroll_corr = map_scrolly; // concentrate global Y scroll
8226 linedata_offs = map_scrollx; // determine where to get info for the first line
8227
8228 if (orientation & ORIENTATION_FLIP_Y)
8229 {
8230 scroll_corr = 0x100 - scroll_corr; // apply common vertical correction
8231
8232 // Y correction (ref: 1st and 5th boss)
8233 scroll_corr -= 2; // apply unique vertical correction
8234
8235 // X correction (ref: 1st boss, seems to undo non-rotated global X offset)
8236 linedata_offs -= 5; // apply unique horizontal correction
8237 }
8238
8239 if (orientation & ORIENTATION_FLIP_X)
8240 {
8241 linedata_adv = -linedata_adv; // traverse line RAM backward in X flipped scenarioes
8242 linedata_offs += bitmap->width - 1; // and get info for the first line from the bottom
8243 }
8244
8245 if (src_clipmask)
8246 {
8247 // determine target wrap boundary and draw scanline in two passes if the source is clipped
8248 dst_wrapmask = dst_height - 1;
8249 passes = 2;
8250 }
8251 else
8252 {
8253 // otherwise disable target wraparound and draw scanline in a single pass
8254 dst_wrapmask = ~0;
8255 passes = 1;
8256 }
8257 }
8258 }
8259
8260 linedata_offs *= 4; // each line info packet has four words(eight bytes)
8261 linedata_offs &= 0x7ff; // and it should wrap at the four-kilobyte boundary
8262 linedata_offs += line_start * linedata_adv; // pre-advance line info offset for the clipped region
8263
8264 // load physical palette base
8265 pal_base = Machine->remapped_colortable + (colorbase << 4) % Machine->drv->total_colors;
8266
8267 // walk the target bitmap within the visible area vertically or horizontally, one line at a time
8268 for (line_pos=line_start; line_pos<=line_end; linedata_offs+=linedata_adv, line_pos++)
8269 {
8270 linedata_offs &= 0x7ff; // line info data wraps at the four-kilobyte boundary
8271
8272 color = line_ram[linedata_offs]; // get scanline color code
8273 if (color == 0xffff) continue; // reject scanline if color code equals minus one
8274
8275 offset = line_ram[linedata_offs+1]; // get first pixel offset in ROM
8276 if (!(color & 0xff) && !offset) continue; // reject scanline if both color and pixel offset are zero
8277
8278 // calculate physical palette location
8279 // there can be thirty-two color codes and each code represents sixteen pens
8280 pal_ptr = pal_base + ((color & 0x1f)<<4);
8281
8282 // calculate physical pixel location
8283 // each offset unit represents two hundred and fifty six pixels and should wrap at ROM boundary for safty
8284 pix_ptr = pix_base + (offset<<8) % rommask;
8285
8286 // get scanline zoom factor
8287 // For example, 0x20 doubles the length, 0x40 maintains a one-to-one length,
8288 // and 0x80 halves the length. The zoom center is at the beginning of the
8289 // scanline therefore it is not necessary to adjust render start position
8290 zoom = line_ram[linedata_offs+2];
8291
8292 scroll = (short)line_ram[linedata_offs+3]; // get signed local scroll value for the current scanline
8293
8294 // scavenged from old code; improves Xexex' first level sky
8295 if (flags & K053250_WRAP500 && scroll >= 0x500) scroll -= 0x800;
8296
8297 scroll += scroll_corr; // apply final scroll correction
8298 scroll &= dst_wrapmask; // wraparound scroll value if necessary
8299
8300 // draw scanlines wrapped at virtual bitmap boundary in two passes
8301 // this should not impose too much overhead due to clipping performed by the render code
8302 i = passes;
8303 do
8304 {
8305 /*
8306 Parameter descriptions:
8307
8308 bitmap : pointer to a MAME bitmap as the render target
8309 pal_ptr : pointer to the palette's physical location relative to the scanline
8310 pix_ptr : pointer to the physical start location of source pixels in ROM
8311 cliprect : pointer to a rectangle structue which describes the visible area of the target bitmap
8312 line_pos : scanline render position relative to the target bitmap
8313 should be a Y offset to the target bitmap in normal orientaion,
8314 or an X offset to the target bitmap if X,Y are swapped
8315 scroll : source scroll value of the scanline
8316 zoom : source zoom factor of the scanline
8317 src_clipmask : source offset clip mask; source pixels with offsets beyond the scope of this mask will not be drawn
8318 src_wrapmask : source offset wrap mask; wraps source offset around, no effect when src_clipmask is set
8319 orientation : flags indicating whether scanlines should be drawn horizontally, vertically, forward or backward
8320 priority : value to be written to the priority bitmap, no effect when equals zero
8321 */
8322 K053250_pdraw_scanline32(bitmap, pal_ptr, pix_ptr, cliprect,
8323 line_pos, scroll, zoom, src_clipmask, src_wrapmask, orientation, priority);
8324
8325 // shift scanline position one virtual screen upward to render the wrapped end if necessary
8326 scroll -= dst_height;
8327 }
8328 while (--i);
8329 }
8330 }
8331
8332 #endif
8333
8334
8335
8336 /***************************************************************************/
8337 /* */
8338 /* 053252 */
8339 /* */
8340 /***************************************************************************/
8341
8342 // K053252 CRT and interrupt control unit
8343 static data16_t K053252_regs[16];
8344
READ16_HANDLER(K053252_word_r)8345 READ16_HANDLER( K053252_word_r )
8346 {
8347 return(K053252_regs[offset]);
8348 }
8349
WRITE16_HANDLER(K053252_word_w)8350 WRITE16_HANDLER( K053252_word_w )
8351 {
8352 COMBINE_DATA(K053252_regs + offset);
8353 }
8354
WRITE32_HANDLER(K053252_long_w)8355 WRITE32_HANDLER( K053252_long_w )
8356 {
8357 offset <<= 1;
8358 K053252_word_w(offset, data>>16, mem_mask>>16);
8359 K053252_word_w(offset+1, data, mem_mask);
8360 }
8361
8362
8363
8364 // debug handlers
READ16_HANDLER(K054157_word_r)8365 READ16_HANDLER( K054157_word_r ) { return(K054157_regs[offset]); } // VACSET (legacy)
READ16_HANDLER(K056832_word_r)8366 READ16_HANDLER( K056832_word_r ) { return(K056832_regs[offset]); } // VACSET
READ16_HANDLER(K056832_b_word_r)8367 READ16_HANDLER( K056832_b_word_r ) { return(K056832_regsb[offset]); } // VSCCS (board dependent)
READ16_HANDLER(K053246_reg_word_r)8368 READ16_HANDLER( K053246_reg_word_r ) { return(K053246_regs[offset*2]<<8|K053246_regs[offset*2+1]); } // OBJSET1
READ16_HANDLER(K053247_reg_word_r)8369 READ16_HANDLER( K053247_reg_word_r ) { return(K053247_regs[offset]); } // OBJSET2
READ16_HANDLER(K054338_word_r)8370 READ16_HANDLER( K054338_word_r ) { return(k54338_regs[offset]); } // CLTC
READ16_HANDLER(K053251_lsb_r)8371 READ16_HANDLER( K053251_lsb_r ) { return(K053251_ram[offset]); } // PCU1
READ16_HANDLER(K053251_msb_r)8372 READ16_HANDLER( K053251_msb_r ) { return(K053251_ram[offset]<<8); } // PCU1
READ16_HANDLER(K055555_word_r)8373 READ16_HANDLER( K055555_word_r ) { return(k55555_regs[offset]<<8); } // PCU2
8374
READ32_HANDLER(K056832_long_r)8375 READ32_HANDLER( K056832_long_r )
8376 {
8377 offset <<= 1;
8378 return (K056832_word_r(offset+1, 0xffff) | K056832_word_r(offset, 0xffff)<<16);
8379 }
8380
READ32_HANDLER(K053247_reg_long_r)8381 READ32_HANDLER( K053247_reg_long_r )
8382 {
8383 offset <<= 1;
8384 return (K053247_reg_word_r(offset+1, 0xffff) | K053247_reg_word_r(offset, 0xffff)<<16);
8385 }
8386
READ32_HANDLER(K055555_long_r)8387 READ32_HANDLER( K055555_long_r )
8388 {
8389 offset <<= 1;
8390 return (K055555_word_r(offset+1, 0xffff) | K055555_word_r(offset, 0xffff)<<16);
8391 }
8392
READ16_HANDLER(K053244_reg_word_r)8393 READ16_HANDLER( K053244_reg_word_r ) { return(K053244_regs[offset*2]<<8|K053244_regs[offset*2+1]); }
8394