1 #define VERBOSE 0
2 
3 /***************************************************************************
4 
5 TODO:
6 - implement shadows properly
7 - in Aliens shadows should be disabled (tubes at the beginning of the game
8   have a vertical line which is supposed to be white)
9 - understand global Y position for the 053247
10 - understand how the 051316 positioning works (probably just an external timing thing)
11 
12 
13 
14                       Emulated
15                          |
16                   board #|year    CPU      tiles        sprites  priority palette    other
17                     -----|---- ------- ------------- ------------- ------ ------ ----------------
18 Hyper Crash         GX401 1985
19 Twinbee             GX412*1985   68000           GX400
20 Yie Ar Kung Fu      GX407*1985    6809
21 Gradius / Nemesis   GX456*1985   68000           GX400
22 Shao-lins Road      GX477*1985    6809
23 Jail Break          GX507*1986 KONAMI-1          005849
24 Finalizer           GX523*1985 KONAMI-1          005885
25 Konami's Ping Pong  GX555*1985     Z80
26 Iron Horse          GX560*1986    6809           005885
27 Konami GT           GX561*1985   68000           GX400
28 Green Beret         GX577*1985     Z80           005849
29 Galactic Warriors   GX578*1985   68000           GX400
30 Salamander          GX587*1986   68000           GX400
31 WEC Le Mans 24      GX602*1986 2x68000
32 BAW / Black Panther GX604 1987   68000           GX400                    007593
33 Combat School /     GX611*1987    6309           007121(x2)               007327
34   Boot Camp
35 Rock 'n Rage /      GX620*1986    6309 007342        007420               007327
36   Koi no Hotrock
37 Mr Kabuki/Mr Goemon GX621*1986     Z80           005849
38 Jackal              GX631*1986    6809?          005885(x2)
39 Contra / Gryzor     GX633*1987    6809?          007121(x2)               007593
40 Flak Attack         GX669*1987    6309           007121                   007327 007452
41 Devil World / Dark  GX687*1987 2x68000           TWIN16
42   Adventure / Majuu no Oukoku
43 Double Dribble      GX690*1986  3x6809           005885(x2)               007327 007452
44 Kitten Kaboodle /   GX712+1988                   GX400                    007593 051550
45   Nyan Nyan Panic
46 Chequered Flag      GX717*1988  052001               051960 051937(x2)           051316(x2) (zoom/rotation) 051733 (protection)
47 Fast Lane           GX752*1987    6309           007121                          051733 (protection) 007801
48 Hot Chase           GX763*1988 2x68000                                           051316(x3) (zoom/rotation) 007634 007635 007558 007557
49 Rack 'Em Up /       GX765*1987    6309 007342        007420               007327 007324
50   The Hustler
51 Haunted Castle      GX768*1988  052001           007121(x2)               007327
52 Ajax / Typhoon      GX770*1987   6309+ 052109 051962 051960 051937  PROM  007327 051316 (zoom/rotation)
53                                 052001
54 Labyrinth Runner    GX771*1987    6309           007121                   007593 051733 (protection) 051550
55 Super Contra        GX775*1988  052001 052109 051962 051960 051937  PROM  007327
56 Battlantis          GX777*1987    6309 007342        007420               007327 007324
57 Vulcan Venture /    GX785*1988 2x68000           TWIN16
58   Gradius 2
59 City Bomber         GX787+1987   68000           GX400                    007593 051550
60 Over Drive          GX789 1990
61 Hyper Crash         GX790 1987
62 Blades of Steel     GX797*1987    6309 007342        007420               007327 051733 (protection)
63 The Main Event      GX799*1988    6309 052109 051962 051960 051937  PROM
64 Missing in Action   GX808*1989   68000 052109 051962 051960 051937  PROM
65 Missing in Action J GX808*1989 2x68000           TWIN16
66 Crime Fighters      GX821*1989  052526 052109 051962 051960 051937  PROM
67 Special Project Y   GX857*1989    6309 052109 051962 051960 051937  PROM         052591 (protection)
68 '88 Games           GX861*1988  052001 052109 051962 051960 051937  PROM         051316 (zoom/rotation)
69 Final Round /       GX870*1988 1x68000           TWIN16?
70   Hard Puncher
71 Thunder Cross       GX873*1988  052001 052109 051962 051960 051937  PROM  007327 052591 (protection)
72 Aliens              GX875*1990  052526 052109 051962 051960 051937  PROM
73 Gang Busters        GX878*1988  052526 052109 051962 051960 051937  PROM
74 Devastators         GX890*1988    6309 052109 051962 051960 051937  PROM         007324 051733 (protection)
75 Bottom of the Ninth GX891*1989    6809 052109 051962 051960 051937  PROM         051316 (zoom/rotation)
76 Cue Brick           GX903*1989 2x68000           TWIN16
77 Punk Shot           GX907*1990   68000 052109 051962 051960 051937 053251
78 Ultraman            GX910*1991   68000 ------ ------ 051960 051937  PROM         051316(x3) (zoom/rotation) 051550
79 Surprise Attack     GX911*1990  053248 052109 051962 053245 053244 053251
80 Lightning Fighters /GX939*1990   68000 052109 051962 053245 053244 053251
81   Trigon
82 Gradius 3           GX945*1989 2x68000 052109 051962 051960 051937  PROM
83 Parodius            GX955*1990  053248 052109 051962 053245 053244 053251
84 TMNT                GX963*1989   68000 052109 051962 051960 051937  PROM
85 Block Hole          GX973*1989  052526 052109 051962 051960 051937  PROM
86 Escape Kids         GX975 1991  053248 052109 051962 053247 053246 053251        053252 - same board as Vendetta
87 Rollergames         GX999*1991  053248 ------ ------ 053245 053244               051316 (zoom/rotation) 053252
88 Bells & Whistles /  GX060*1991   68000 052109 051962 053245 053244 053251        054000 (collision)
89   Detana!! Twin Bee
90 Golfing Greats      GX061*1991   68000 052109 051962 053245 053244 053251        053936 (3D)
91 TMNT 2              GX063*1991   68000 052109 051962 053245 053244 053251        053990
92 Sunset Riders       GX064*1991   68000 052109 051962 053245 053244 053251        054358
93 X-Men               GX065*1992   68000 052109 051962 053247 053246 053251
94 XEXEX               GX067*1991   68000 054157 054156 053247 053246 053251        054338 054539
95 Asterix             GX068+1992   68000 054157 054156 053245 053244 053251        054358
96 G.I. Joe            GX069+1992   68000 054157 054156 053247 053246 053251        054539
97 The Simpsons        GX072*1991  053248 052109 051962 053247 053246 053251
98 Thunder Cross 2     GX073*1991   68000 052109 051962 051960 051937 053251        054000 (collision)
99 Vendetta /          GX081*1991  053248 052109 051962 053247 053246 053251        054000 (collision)
100   Crime Fighters 2
101 Premier Soccer      GX101 1993   68000 052109 051962 053245 053244 053251        053936 (3D)
102 Hexion              GX122+1992     Z80                                           052591 (protection) 053252
103 Entapous /          GX123+1993   68000 054157 054156 055673 053246               053252 054000 055555
104   Gaiapolis
105 Mystic Warrior      GX128 1993
106 Cowboys of Moo Mesa GX151 1993   68000 054157 054156 053247 053246               053252 054338 053990
107 Violent Storm       GX168+1993   68000 054157 054156 055673 053246               054338 054539(x2) 055550 055555
108 Bucky 'O Hare       GX173+1992   68000 054157 054156 053247 053246 053251        054338 054539
109 Potrio              GX174 1992
110 Lethal Enforcers    GX191 1992    6309 054157(x2) 054156 053245 053244(x2)       054000 054539 054906
111 Metamorphic Force   GX224 1993
112 Martial Champion    GX234+1993   68000 054157 054156 055673 053246               053252 054338 054539 055555 053990 054986 054573
113 Run and Gun         GX247+1993   68000               055673 053246               053253(x2)
114 Polygonet CommandersGX305 1993   68020                                           056230?063936?054539?054986?
115 
116 
117 Notes:
118 - Old games use 051961 instead of 052109, it is an earlier version functionally
119   equivalent (maybe 052109 had bugs fixed). The list always shows 052109 because
120   the two are exchangeable and 052109's are found also on original boards whose
121   schematics show a 051961.
122 
123 
124 
125 Status of the ROM tests in the emulated games:
126 
127 Ajax / Typhoon      pass
128 Super Contra        pass
129 The Main Event      pass
130 Missing in Action   pass
131 Crime Fighters      pass
132 Special Project Y   pass
133 Konami 88           pass
134 Thunder Cross       pass
135 Aliens              pass
136 Gang Busters        pass
137 Devastators         pass
138 Bottom of the Ninth pass
139 Punk Shot           pass
140 Surprise Attack     fails D05-6 (052109) because it uses mirror addresses to
141                     select banks, and supporting those addresses breaks the
142                     normal game ;-(
143 Lightning Fighters  pass
144 Gradius 3           pass
145 Parodius            pass
146 TMNT                pass
147 Block Hole          pass
148 Rollergames         pass
149 Bells & Whistles    pass
150 Golfing Greats      fails B05..B10 (053936)
151 TMNT 2              pass
152 Sunset Riders       pass
153 X-Men               fails 1F (054544)
154 The Simpsons        pass
155 Thunder Cross 2     pass
156 Vendetta            pass
157 Xexex               pass
158 
159 
160 THE FOLLOWING INFORMATION IS PRELIMINARY AND INACCURATE. DON'T RELY ON IT.
161 
162 
163 007121
164 ------
165 This is an interesting beast. Many games use two of these in pair.
166 It manages sprites and two 32x32 tilemaps. The tilemaps can be joined to form
167 a single 64x32 one, or one of them can be moved to the side of screen, giving
168 a high score display suitable for vertical games.
169 The chip also generates clock and interrupt signals suitable for a 6809.
170 It uses 0x2000 bytes of RAM for the tilemaps and sprites, and an additional
171 0x100 bytes, maybe for scroll RAM and line buffers. The maximum addressable
172 ROM is 0x80000 bytes (addressed 16 bits at a time).
173 Two 256x4 lookup PROMs are also used to increase the color combinations.
174 All tilemap / sprite priority handling is done internally and the chip exports
175 7 bits of color code, composed of 2 bits of palette bank, 1 bit indicating tile
176 or sprite, and 4 bits of ROM data remapped through the PROM.
177 
178 inputs:
179 - address lines (A0-A13)
180 - data lines (DB0-DB7)
181 - misc interface stuff
182 - data from the gfx ROMs (RDL0-RDL7, RDU0-RDU7)
183 - data from the tile lookup PROMs (VCD0-VCD3)
184 - data from the sprite lookup PROMs (OCD0-OCD3)
185 
186 outputs:
187 - address lines for tilemap RAM (AX0-AX12)
188 - data lines for tilemap RAM (VO0-VO7)
189 - address lines for the small RAM (FA0-FA7)
190 - data lines for the small RAM (FD0-FD7)
191 - address lines for the gfx ROMs (R0-R17)
192 - address lines for the tile lookup PROMs (VCF0-VCF3, VCB0-VCB3)
193 - address lines for the sprite lookup PROMs (OCB0-OCB3, OCF0-OCF3)
194 - NNMI, NIRQ, NFIR, NE, NQ for the main CPU
195 - misc interface stuff
196 - color code to be output on screen (COA0-COA6)
197 
198 
199 control registers
200 000:          scroll x (low 8 bits)
201 001: -------x scroll x (high bit)
202      ------x- enable rowscroll? (combasc)
203      ----x--- this probably selects an alternate screen layout used in combat
204               school where tilemap #2 is overlayed on front and doesn't scroll.
205               The 32 lines of the front layer can be individually turned on or
206               off using the second 32 bytes of scroll RAM.
207 002:          scroll y
208 003: -------x bit 13 of the tile code
209      ------x- unknown (contra)
210      -----x-- might be sprite / tilemap priority (0 = sprites have priority)
211               (combat school, contra, haunted castle(0/1), labyrunr)
212      ----x--- selects sprite buffer (and makes a copy to a private buffer?)
213      ---x---- screen layout selector:
214               when this is set, 5 columns are added on the left of the screen
215               (that means 5 rows at the top for vertical games), and the
216               rightmost 2 columns are chopped away.
217               Tilemap #2 is used to display the 5 additional columns on the
218               left. The rest of tilemap #2 is not used and can be used as work
219               RAM by the program.
220               The visible area becomes 280x224.
221               Note that labyrunr changes this at runtime, setting it during
222               gameplay and resetting it on the title screen and crosshatch.
223      --x----- might be sprite / tilemap priority (0 = sprites have priority)
224               (combat school, contra, haunted castle(0/1), labyrunr)
225      -x------ Chops away the leftmost and rightmost columns, switching the
226               visible area from 256 to 240 pixels. This is used by combasc on
227               the scrolling stages, and by labyrunr on the title screen.
228               At first I thought that this enabled an extra bank of 0x40
229               sprites, needed by combasc, but labyrunr proves that this is not
230               the case
231      x------- unknown (contra)
232 004: ----xxxx bits 9-12 of the tile code. Only the bits enabled by the following
233               mask are actually used, and replace the ones selected by register
234 			  005.
235      xxxx---- mask enabling the above bits
236 005: selects where in the attribute byte to pick bits 9-12 of the tile code,
237      output to pins R12-R15. The bit of the attribute byte to use is the
238      specified bit (0-3) + 3, that is one of bits 3-6. Bit 7 is hardcoded as
239      bit 8 of the code. Bits 0-2 are used for the color, however note that
240      some games (combat school, flak attack, maybe fast lane) use bit 3 as well,
241      and indeed there are 4 lines going to the color lookup PROM, so there has
242      to be a way to select this.
243      ------xx attribute bit to use for tile code bit  9
244      ----xx-- attribute bit to use for tile code bit 10
245      --xx---- attribute bit to use for tile code bit 11
246      xx------ attribute bit to use for tile code bit 12
247 006: ----xxxx select additional effect for bits 3-6 of the tile attribute (the
248               same ones indexed by register 005). Note that an attribute bit
249               can therefore be used at the same time to be BOTH a tile code bit
250               and an additional effect.
251      -------x bit 3 of attribute is bit 3 of color (combasc, fastlane, flkatck)
252 	 ------x- bit 4 of attribute is tile flip X (assumption - no game uses this)
253      -----x-- bit 5 of attribute is tile flip Y (flkatck)
254      ----x--- bit 6 of attribute is tile priority over sprites (combasc, hcastle,
255               labyrunr)
256               Note that hcastle sets this bit for layer 0, and bit 6 of the
257               attribute is also used as bit 12 of the tile code, however that
258               bit is ALWAYS set thoughout the game.
259               combasc uses the bit inthe "graduation" scene during attract mode,
260               to place soldiers behind the stand.
261               Use in labyrunr has not been investigated yet.
262      --xx---- palette bank (both tiles and sprites, see contra)
263 007: -------x nmi enable
264      ------x- irq enable
265      -----x-- firq enable (probably)
266      ----x--- flip screen
267      ---x---- unknown (contra, labyrunr)
268 
269 
270 
271 007342
272 ------
273 The 007342 manages 2 64x32 scrolling tilemaps with 8x8 characters, and
274 optionally generates timing clocks and interrupt signals. It uses 0x2000
275 bytes of RAM, plus 0x0200 bytes for scrolling, and a variable amount of ROM.
276 It cannot read the ROMs.
277 
278 control registers
279 000: ------x- INT control
280      ---x---- flip screen (TODO: doesn't work with thehustl)
281 001: Used for banking in Rock'n'Rage
282 002: -------x MSB of x scroll 1
283      ------x- MSB of x scroll 2
284      ---xxx-- layer 1 row/column scroll control
285               000 = disabled
286 			  010 = unknown (bladestl shootout between periods)
287               011 = 32 columns (Blades of Steel)
288               101 = 256 rows (Battlantis, Rock 'n Rage)
289      x------- enable sprite wraparound from bottom to top (see Blades of Steel
290               high score table)
291 003: x scroll 1
292 004: y scroll 1
293 005: x scroll 2
294 006: y scroll 2
295 007: not used
296 
297 
298 007420
299 ------
300 Sprite generator. 8 bytes per sprite with zoom. It uses 0x200 bytes of RAM,
301 and a variable amount of ROM. Nothing is known about its external interface.
302 
303 
304 
305 052109/051962
306 -------------
307 These work in pair.
308 The 052109 manages 3 64x32 scrolling tilemaps with 8x8 characters, and
309 optionally generates timing clocks and interrupt signals. It uses 0x4000
310 bytes of RAM, and a variable amount of ROM. It cannot read the ROMs:
311 instead, it exports 21 bits (16 from the tilemap RAM + 3 for the character
312 raster line + 2 additional ones for ROM banking) and these are externally
313 used to generate the address of the required data on the ROM; the output of
314 the ROMs is sent to the 051962, along with a color code. In theory you could
315 have any combination of bits in the tilemap RAM, as long as they add to 16.
316 In practice, all the games supported so far standardize on the same format
317 which uses 3 bits for the color code and 13 bits for the character code.
318 The 051962 multiplexes the data of the three layers and converts it into
319 palette indexes and transparency bits which will be mixed later in the video
320 chain.
321 Priority is handled externally: these chips only generate the tilemaps, they
322 don't mix them.
323 Both chips are interfaced with the main CPU. When the RMRD pin is asserted,
324 the CPU can read the gfx ROM data. This is done by telling the 052109 which
325 dword to read (this is a combination of some banking registers, and the CPU
326 address lines), and then reading it from the 051962.
327 
328 052109 inputs:
329 - address lines (AB0-AB15, AB13-AB15 seem to have a different function)
330 - data lines (DB0-DB7)
331 - misc interface stuff
332 
333 052109 outputs:
334 - address lines for the private RAM (RA0-RA12)
335 - data lines for the private RAM (VD0-VD15)
336 - NMI, IRQ, FIRQ for the main CPU
337 - misc interface stuff
338 - ROM bank selector (CAB1-CAB2)
339 - character "code" (VC0-VC10)
340 - character "color" (COL0-COL7); used foc color but also bank switching and tile
341   flipping. Exact meaning depends on externl connections. All evidence indicates
342   that COL2 and COL3 select the tile bank, and are replaced with the low 2 bits
343   from the bank register. The top 2 bits of the register go to CAB1-CAB2.
344   However, this DOES NOT WORK with Gradius III. "color" seems to pass through
345   unaltered.
346 - layer A horizontal scroll (ZA1H-ZA4H)
347 - layer B horizontal scroll (ZB1H-ZB4H)
348 - ????? (BEN)
349 
350 051962 inputs:
351 - gfx data from the ROMs (VC0-VC31)
352 - color code (COL0-COL7); only COL4-COL7 seem to really be used for color; COL0
353   is tile flip X.
354 - layer A horizontal scroll (ZA1H-ZA4H)
355 - layer B horizontal scroll (ZB1H-ZB4H)
356 - let main CPU read the gfx ROMs (RMRD)
357 - address lines to be used with RMRD (AB0-AB1)
358 - data lines to be used with RMRD (DB0-DB7)
359 - ????? (BEN)
360 - misc interface stuff
361 
362 051962 outputs:
363 - FIX layer palette index (DFI0-DFI7)
364 - FIX layer transparency (NFIC)
365 - A layer palette index (DSA0-DSAD); DSAA-DSAD seem to be unused
366 - A layer transparency (NSAC)
367 - B layer palette index (DSB0-DSBD); DSBA-DSBD seem to be unused
368 - B layer transparency (NSBC)
369 - misc interface stuff
370 
371 
372 052109 memory layout:
373 0000-07ff: layer FIX tilemap (attributes)
374 0800-0fff: layer A tilemap (attributes)
375 1000-1fff: layer B tilemap (attributes)
376 180c-1833: A y scroll
377 1a00-1bff: A x scroll
378 1c00     : ?
379 1c80     : row/column scroll control
380            ------xx layer A row scroll
381                     00 = disabled
382                     01 = disabled? (gradius3, vendetta)
383                     10 = 32 lines
384                     11 = 256 lines
385            -----x-- layer A column scroll
386                     0 = disabled
387                     1 = 64 (actually 40) columns
388            ---xx--- layer B row scroll
389            --x----- layer B column scroll
390            surpratk sets this register to 70 during the second boss. There is
391            nothing obviously wrong so it's not clear what should happen.
392 1d00     : bits 0 & 1 might enable NMI and FIRQ, not sure
393          : bit 2 = IRQ enable
394 1d80     : ROM bank selector bits 0-3 = bank 0 bits 4-7 = bank 1
395 1e00     : ROM subbank selector for ROM testing
396 1e80     : bit 0 = flip screen (applies to tilemaps only, not sprites)
397          : bit 1 = set by crimfght, mainevt, surpratk, xmen, mia, punkshot, thndrx2, spy
398          :         it seems to enable tile flip X, however flip X is handled by the
399          :         051962 and it is not hardwired to a specific tile attribute.
400          :         Note that xmen, punkshot and thndrx2 set the bit but the current
401          :         drivers don't use flip X and seem to work fine.
402          : bit 2 = enables tile flip Y when bit 1 of the tile attribute is set
403 1f00     : ROM bank selector bits 0-3 = bank 2 bits 4-7 = bank 3
404 2000-27ff: layer FIX tilemap (code)
405 2800-2fff: layer A tilemap (code)
406 3000-37ff: layer B tilemap (code)
407 3800-3807: nothing here, so the chip can share address space with a 051937
408 380c-3833: B y scroll
409 3a00-3bff: B x scroll
410 3c00-3fff: nothing here, so the chip can share address space with a 051960
411 3d80     : mirror of 1d80, but ONLY during ROM test (surpratk)
412 3e00     : mirror of 1e00, but ONLY during ROM test (surpratk)
413 3f00     : mirror of 1f00, but ONLY during ROM test (surpratk)
414 EXTRA ADDRESSING SPACE USED BY X-MEN:
415 4000-47ff: layer FIX tilemap (code high bits)
416 4800-4fff: layer A tilemap (code high bits)
417 5000-57ff: layer B tilemap (code high bits)
418 
419 The main CPU doesn't have direct acces to the RAM used by the 052109, it has
420 to through the chip.
421 
422 
423 
424 051960/051937
425 -------------
426 Sprite generators. Designed to work in pair. The 051960 manages the sprite
427 list and produces and address that is fed to the gfx ROMs. The data from the
428 ROMs is sent to the 051937, along with color code and other stuff from the
429 051960. The 051937 outputs up to 12 bits of palette index, plus "shadow" and
430 transparency information.
431 Both chips are interfaced to the main CPU, through 8-bit data buses and 11
432 bits of address space. The 051937 sits in the range 000-007, while the 051960
433 in the range 400-7ff (all RAM). The main CPU can read the gfx ROM data though
434 the 051937 data bus, while the 051960 provides the address lines.
435 The 051960 is designed to directly address 1MB of ROM space, since it produces
436 18 address lines that go to two 16-bit wide ROMs (the 051937 has a 32-bit data
437 bus to the ROMs). However, the addressing space can be increased by using one
438 or more of the "color attribute" bits of the sprites as bank selectors.
439 Moreover a few games store the gfx data in the ROMs in a format different from
440 the one expected by the 051960, and use external logic to reorder the address
441 lines.
442 The 051960 can also genenrate IRQ, FIRQ and NMI signals.
443 
444 memory map:
445 000-007 is for the 051937, but also seen by the 051960
446 400-7ff is 051960 only
447 000     R  bit 0 = unknown, looks like a status flag or something
448                    aliens waits for it to be 0 before starting to copy sprite data
449 				   thndrx2 needs it to pulse for the startup checks to succeed
450 000     W  bit 0 = irq enable/acknowledge?
451            bit 3 = flip screen (applies to sprites only, not tilemaps)
452            bit 4 = unknown, used by Devastators, TMNT, Aliens, Chequered Flag, maybe others
453                    aliens sets it just after checking bit 0, and before copying
454                    the sprite data
455            bit 5 = enable gfx ROM reading
456 001     W  Devastators sets bit 1, function unknown, could it be a global shadow enable?
457            None of the other games I tested seem to set this register to other than 0.
458 002-003 W  selects the portion of the gfx ROMs to be read.
459 004     W  Aliens uses this to select the ROM bank to be read, but Punk Shot
460            and TMNT don't, they use another bit of the registers above. Many
461            other games write to this register before testing.
462            It is possible that bits 2-7 of 003 go to OC0-OC5, and bits 0-1 of
463            004 go to OC6-OC7.
464 004-007 R  reads data from the gfx ROMs (32 bits in total). The address of the
465            data is determined by the register above and by the last address
466            accessed on the 051960; plus bank switch bits for larger ROMs.
467            It seems that the data can also be read directly from the 051960
468            address space: 88 Games does this. First it reads 004 and discards
469            the result, then it reads from the 051960 the data at the address
470            it wants. The normal order is the opposite, read from the 051960 at
471            the address you want, discard the result, and fetch the data from
472            004-007.
473 400-7ff RW sprite RAM, 8 bytes per sprite
474 
475 
476 
477 053245/053244
478 -------------
479 Sprite generators. The 053245 has a 16-bit data bus to the main CPU.
480 
481 053244 memory map (but the 053245 sees and processes them too):
482 000-001 W  global X offset
483 002-003 W  global Y offset
484 004     W  unknown
485 005     W  bit 0 = flip screen X
486            bit 1 = flip screen Y
487            bit 2 = unknown, used by Parodius
488            bit 4 = enable gfx ROM reading
489            bit 5 = unknown, used by Rollergames
490 006     W  unknown
491 007     W  unknown
492 008-009 W  low 16 bits of the ROM address to read
493 00a-00b W  high 3 bits of the ROM address to read
494 00c-00f R  reads data from the gfx ROMs (32 bits in total). The address of the
495            data is determined by the registers above; plus bank switch bits for
496            larger ROMs.
497 
498 
499 
500 053247/053246
501 -------------
502 Sprite generators. Nothing is known about their external interface.
503 The sprite RAM format is very similar to the 053245.
504 
505 053246 memory map (but the 053247 sees and processes them too):
506 000-001 W  global X offset
507 002-003 W  global Y offset. TODO: it is not clear how this works, we use a hack
508 004     W  low 8 bits of the ROM address to read
509 005     W  bit 0 = flip screen X
510            bit 1 = flip screen Y
511            bit 2 = unknown
512            bit 4 = interrupt enable
513            bit 5 = unknown
514 006-007 W  high 16 bits of the ROM address to read
515 
516 ???-??? R  reads data from the gfx ROMs (16 bits in total). The address of the
517            data is determined by the registers above
518 
519 
520 
521 051316
522 ------
523 Manages a 32x32 tilemap (16x16 tiles, 512x512 pixels) which can be zoomed,
524 distorted and rotated.
525 It uses two internal 24 bit counters which are incremented while scanning the
526 picture. The coordinates of the pixel in the tilemap that has to be drawn to
527 the current beam position are the counters / (2^11).
528 The chip doesn't directly generate the color information for the pixel, it
529 just generates a 24 bit address (whose top 16 bits are the contents of the
530 tilemap RAM), and a "visible" signal. It's up to external circuitry to convert
531 the address into a pixel color. Most games seem to use 4bpp graphics, but Ajax
532 uses 7bpp.
533 If the value in the internal counters is out of the visible range (0..511), it
534 is truncated and the corresponding address is still generated, but the "visible"
535 signal is not asserted. The external circuitry might ignore that signal and
536 still generate the pixel, therefore making the tilemap a continuous playfield
537 that wraps around instead of a large sprite.
538 
539 
540 control registers
541 000-001 X counter starting value / 256
542 002-003 amount to add to the X counter after each horizontal pixel
543 004-005 amount to add to the X counter after each line (0 = no rotation)
544 006-007 Y counter starting value / 256
545 008-009 amount to add to the Y counter after each horizontal pixel (0 = no rotation)
546 00a-00b amount to add to the Y counter after each line
547 00c-00d ROM bank to read, used during ROM testing
548 00e     bit 0 = enable ROM reading (active low). This only makes the chip output the
549                 requested address: the ROM is actually read externally, not through
550                 the chip's data bus.
551         bit 1 = unknown
552         bit 2 = unknown
553 00f     unused
554 
555 
556 
557 053251
558 ------
559 Priority encoder.
560 
561 The chip has inputs for 5 layers (CI0-CI4); only 4 are used (CI1-CI4)
562 CI0-CI2 are 9(=5+4) bits inputs, CI3-CI4 8(=4+4) bits
563 
564 The input connctions change from game to game. E.g. in Simpsons,
565 CI0 = grounded (background color)
566 CI1 = sprites
567 CI2 = FIX
568 CI3 = A
569 CI4 = B
570 
571 in lgtnfght:
572 CI0 = grounded
573 CI1 = sprites
574 CI2 = FIX
575 CI3 = B
576 CI4 = A
577 
578 there are three 6 bit priority inputs, PR0-PR2
579 
580 simpsons:
581 PR0 = 111111
582 PR1 = xxxxx0 x bits coming from the sprite attributes
583 PR2 = 111111
584 
585 lgtnfght:
586 PR0 = 111111
587 PR1 = 1xx000 x bits coming from the sprite attributes
588 PR2 = 111111
589 
590 also two shadow inputs, SDI0 and SDI1 (from the sprite attributes)
591 
592 the chip outputs the 11 bit palette index, CO0-CO10, and two shadow bits.
593 
594 16 internal registers; registers are 6 bits wide (input is D0-D5)
595 For the most part, their meaning is unknown
596 All registers are write only.
597 There must be a way to enable/disable the three external PR inputs.
598 Some games initialize the priorities of the sprite & background layers,
599 others don't. It isn't clear whether the data written to those registers is
600 actually used, since the priority is taken from the external ports.
601 
602  0  priority of CI0 (higher = lower priority)
603     punkshot: unused?
604     lgtnfght: unused?
605     simpsons: 3f = 111111
606     xmen:     05 = 000101  default value
607     xmen:     09 = 001001  used to swap CI0 and CI2
608  1  priority of CI1 (higher = lower priority)
609     punkshot: 28 = 101000
610     lgtnfght: unused?
611     simpsons: unused?
612     xmen:     02 = 000010
613  2  priority of CI2 (higher = lower priority)
614     punkshot: 24 = 100100
615     lgtnfght: 24 = 100100
616     simpsons: 04 = 000100
617     xmen:     09 = 001001  default value
618     xmen:     05 = 000101  used to swap CI0 and CI2
619  3  priority of CI3 (higher = lower priority)
620     punkshot: 34 = 110100
621     lgtnfght: 34 = 110100
622     simpsons: 28 = 101000
623     xmen:     00 = 000000
624  4  priority of CI4 (higher = lower priority)
625     punkshot: 2c = 101100  default value
626     punkshot: 3c = 111100  used to swap CI3 and CI4
627     punkshot: 26 = 100110  used to swap CI1 and CI4
628     lgtnfght: 2c = 101100
629     simpsons: 18 = 011000
630     xmen:     fe = 111110
631  5  unknown
632     punkshot: unused?
633     lgtnfght: 2a = 101010
634     simpsons: unused?
635     xmen: unused?
636  6  unknown
637     punkshot: 26 = 100110
638     lgtnfght: 30 = 110000
639     simpsons: 17 = 010111
640     xmen:     03 = 000011 (written after initial tests)
641  7  unknown
642     punkshot: unused?
643     lgtnfght: unused?
644     simpsons: 27 = 100111
645     xmen:     07 = 000111 (written after initial tests)
646  8  unknown
647     punkshot: unused?
648     lgtnfght: unused?
649     simpsons: 37 = 110111
650     xmen:     ff = 111111 (written after initial tests)
651  9  ----xx CI0 palette index base (CO9-CO10)
652     --xx-- CI1 palette index base (CO9-CO10)
653     xx---- CI2 palette index base (CO9-CO10)
654 10  ---xxx CI3 palette index base (CO8-CO10)
655     xxx--- CI4 palette index base (CO8-CO10)
656 11  unknown
657     punkshot: 00 = 000000
658     lgtnfght: 00 = 000000
659     simpsons: 00 = 000000
660     xmen:     00 = 000000 (written after initial tests)
661 12  unknown
662     punkshot: 04 = 000100
663     lgtnfght: 04 = 000100
664     simpsons: 05 = 000101
665     xmen:     05 = 000101
666 13  unused
667 14  unused
668 15  unused
669 
670 
671 054000
672 ------
673 Sort of a protection device, used for collision detection.
674 It is passed a few parameters, and returns a boolean telling if collision
675 happened. It has no access to gfx data, it only does arithmetical operations
676 on the parameters.
677 
678 Memory map:
679 00      unused
680 01-03 W A center X
681 04    W unknown, needed by thndrx2 to pass the startup check, we use a hack
682 05      unused
683 06    W A semiaxis X
684 07    W A semiaxis Y
685 08      unused
686 09-0b W A center Y
687 0c    W unknown, needed by thndrx2 to pass the startup check, we use a hack
688 0d      unused
689 0e    W B semiaxis X
690 0f    W B semiaxis Y
691 10      unused
692 11-13 W B center Y
693 14      unused
694 15-17 W B center X
695 18    R 0 = collision, 1 = no collision
696 
697 
698 051733
699 ------
700 Sort of a protection device, used for collision detection, and for
701 arithmetical operations.
702 It is passed a few parameters, and returns the result.
703 
704 Memory map(preliminary):
705 ------------------------
706 00-01 W operand 1
707 02-03 W operand 2
708 
709 00-01 R operand 1/operand 2
710 02-03 R operand 1%operand 2?
711 
712 06-07 W Radius
713 08-09 W Y pos of obj1
714 0a-0b W X pos of obj1
715 0c-0d W Y pos of obj2
716 0e-0f W X pos of obj2
717 13	  W unknown
718 
719 07	  R collision (0x80 = no, 0x00 = yes)
720 
721 Other addresses are unknown or unused.
722 
723 Fast Lane:
724 ----------
725 $9def:
726 This routine is called only after a collision.
727 (R) 0x0006:	unknown. Only bits 0-3 are used.
728 
729 Blades of Steel:
730 ----------------
731 $ac2f:
732 (R) 0x2f86: unknown. Only uses bit 0.
733 
734 $a5de:
735 writes to 0x2f84-0x2f85, waits a little, and then reads from 0x2f84.
736 
737 $7af3:
738 (R) 0x2f86: unknown. Only uses bit 0.
739 
740 
741 Devastators:
742 ------------
743 $6ce8:
744 reads from 0x0006, and only uses bit 1.
745 
746 ***************************************************************************/
747 
748 #include "driver.h"
749 #include "vidhrdw/konamiic.h"
750 
751 
752 /*
753 	This recursive function doesn't use additional memory
754 	(it could be easily converted into an iterative one).
755 	It's called shuffle because it mimics the shuffling of a deck of cards.
756 */
shuffle(UINT16 * buf,int len)757 static void shuffle(UINT16 *buf,int len)
758 {
759 	int i;
760 	UINT16 t;
761 
762 	if (len == 2) return;
763 
764 	if (len % 4) exit(1);   /* must not happen */
765 
766 	len /= 2;
767 
768 	for (i = 0;i < len/2;i++)
769 	{
770 		t = buf[len/2 + i];
771 		buf[len/2 + i] = buf[len + i];
772 		buf[len + i] = t;
773 	}
774 
775 	shuffle(buf,len);
776 	shuffle(buf + len,len);
777 }
778 
779 
780 /* helper function to join two 16-bit ROMs and form a 32-bit data stream */
konami_rom_deinterleave_2(int mem_region)781 void konami_rom_deinterleave_2(int mem_region)
782 {
783 	shuffle((UINT16 *)memory_region(mem_region),memory_region_length(mem_region)/2);
784 }
785 
786 /* helper function to join four 16-bit ROMs and form a 64-bit data stream */
konami_rom_deinterleave_4(int mem_region)787 void konami_rom_deinterleave_4(int mem_region)
788 {
789 	konami_rom_deinterleave_2(mem_region);
790 	konami_rom_deinterleave_2(mem_region);
791 }
792 
793 
794 
795 
796 
797 
798 
799 
800 /*#define MAX_K007121 2*/
801 
802 /*static*/ unsigned char K007121_ctrlram[MAX_K007121][8];
803 static int K007121_flipscreen[MAX_K007121];
804 
805 
K007121_ctrl_w(int chip,int offset,int data)806 void K007121_ctrl_w(int chip,int offset,int data)
807 {
808 	switch (offset)
809 	{
810 		case 6:
811 /* palette bank change */
812 if ((K007121_ctrlram[chip][offset] & 0x30) != (data & 0x30))
813 	tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
814 			break;
815 		case 7:
816 			K007121_flipscreen[chip] = data & 0x08;
817 			break;
818 	}
819 
820 	K007121_ctrlram[chip][offset] = data;
821 }
822 
WRITE_HANDLER(K007121_ctrl_0_w)823 WRITE_HANDLER( K007121_ctrl_0_w )
824 {
825 	K007121_ctrl_w(0,offset,data);
826 }
827 
WRITE_HANDLER(K007121_ctrl_1_w)828 WRITE_HANDLER( K007121_ctrl_1_w )
829 {
830 	K007121_ctrl_w(1,offset,data);
831 }
832 
833 
834 /*
835  * Sprite Format
836  * ------------------
837  *
838  * There are 0x40 sprites, each one using 5 bytes. However the number of
839  * sprites can be increased to 0x80 with a control register (Combat School
840  * sets it on and off during the game).
841  *
842  * Byte | Bit(s)   | Use
843  * -----+-76543210-+----------------
844  *   0  | xxxxxxxx | sprite code
845  *   1  | xxxx---- | color
846  *   1  | ----xx-- | sprite code low 2 bits for 16x8/8x8 sprites
847  *   1  | ------xx | sprite code bank bits 1/0
848  *   2  | xxxxxxxx | y position
849  *   3  | xxxxxxxx | x position (low 8 bits)
850  *   4  | xx------ | sprite code bank bits 3/2
851  *   4  | --x----- | flip y
852  *   4  | ---x---- | flip x
853  *   4  | ----xxx- | sprite size 000=16x16 001=16x8 010=8x16 011=8x8 100=32x32
854  *   4  | -------x | x position (high bit)
855  *
856  * Flack Attack uses a different, "wider" layout with 32 bytes per sprites,
857  * mapped as follows, and the priority order is reversed. Maybe it is a
858  * compatibility mode with an older custom IC. It is not known how this
859  * alternate layout is selected.
860  *
861  * 0 -> e
862  * 1 -> f
863  * 2 -> 6
864  * 3 -> 4
865  * 4 -> 8
866  *
867  */
868 
K007121_sprites_draw(int chip,struct osd_bitmap * bitmap,const unsigned char * source,int base_color,int global_x_offset,int bank_base,UINT32 pri_mask)869 void K007121_sprites_draw(int chip,struct osd_bitmap *bitmap,
870 		const unsigned char *source,int base_color,int global_x_offset,int bank_base,
871 		UINT32 pri_mask)
872 {
873 	const struct GfxElement *gfx = Machine->gfx[chip];
874 	int flipscreen = K007121_flipscreen[chip];
875 	int i,num,inc,offs[5],trans;
876 	int is_flakatck = K007121_ctrlram[chip][0x06] & 0x04;	/* WRONG!!!! */
877 
878 #if 0
879 usrintf_showmessage("%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
880 	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],
881 	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]);
882 #endif
883 #if 0
884 if (keyboard_pressed(KEYCODE_D))
885 {
886 	FILE *fp;
887 	fp=fopen(chip?"SPRITE1.DMP":"SPRITE0.DMP", "w+b");
888 	if (fp)
889 	{
890 		fwrite(source, 0x800, 1, fp);
891 		usrintf_showmessage("saved");
892 		fclose(fp);
893 	}
894 }
895 #endif
896 
897 	if (is_flakatck)
898 	{
899 		num = 0x40;
900 		inc = -0x20;
901 		source += 0x3f*0x20;
902 		offs[0] = 0x0e;
903 		offs[1] = 0x0f;
904 		offs[2] = 0x06;
905 		offs[3] = 0x04;
906 		offs[4] = 0x08;
907 		/* Flak Attack doesn't use a lookup PROM, it maps the color code directly */
908 		/* to a palette entry */
909 		trans = TRANSPARENCY_PEN;
910 	}
911 	else	/* all others */
912 	{
913 		num = (K007121_ctrlram[chip][0x03] & 0x40) ? 0x80 : 0x40;	/* WRONG!!! (needed by combasc)  */
914 		inc = 5;
915 		offs[0] = 0x00;
916 		offs[1] = 0x01;
917 		offs[2] = 0x02;
918 		offs[3] = 0x03;
919 		offs[4] = 0x04;
920 		trans = TRANSPARENCY_COLOR;
921 		/* when using priority buffer, draw front to back */
922 		if (pri_mask != -1)
923 		{
924 			source += (num-1)*inc;
925 			inc = -inc;
926 		}
927 	}
928 
929 	for (i = 0;i < num;i++)
930 	{
931 		int number = source[offs[0]];				/* sprite number */
932 		int sprite_bank = source[offs[1]] & 0x0f;	/* sprite bank */
933 		int sx = source[offs[3]];					/* vertical position */
934 		int sy = source[offs[2]];					/* horizontal position */
935 		int attr = source[offs[4]];				/* attributes */
936 		int xflip = source[offs[4]] & 0x10;		/* flip x */
937 		int yflip = source[offs[4]] & 0x20;		/* flip y */
938 		int color = base_color + ((source[offs[1]] & 0xf0) >> 4);
939 		int width,height;
940 		static int x_offset[4] = {0x0,0x1,0x4,0x5};
941 		static int y_offset[4] = {0x0,0x2,0x8,0xa};
942 		int x,y, ex, ey;
943 
944 		if (attr & 0x01) sx -= 256;
945 		if (sy >= 240) sy -= 256;
946 
947 		number += ((sprite_bank & 0x3) << 8) + ((attr & 0xc0) << 4);
948 		number = number << 2;
949 		number += (sprite_bank >> 2) & 3;
950 
951 		if (!is_flakatck || source[0x00])	/* Flak Attack needs this */
952 		{
953 			number += bank_base;
954 
955 			switch( attr&0xe )
956 			{
957 				case 0x06: width = height = 1; break;
958 				case 0x04: width = 1; height = 2; number &= (~2); break;
959 				case 0x02: width = 2; height = 1; number &= (~1); break;
960 				case 0x00: width = height = 2; number &= (~3); break;
961 				case 0x08: width = height = 4; number &= (~3); break;
962 				default: width = 1; height = 1;
963 //					logerror("Unknown sprite size %02x\n",attr&0xe);
964 //					usrintf_showmessage("Unknown sprite size %02x\n",attr&0xe);
965 			}
966 
967 			for (y = 0;y < height;y++)
968 			{
969 				for (x = 0;x < width;x++)
970 				{
971 					ex = xflip ? (width-1-x) : x;
972 					ey = yflip ? (height-1-y) : y;
973 
974 					if (flipscreen)
975 					{
976 						if (pri_mask != -1)
977 							pdrawgfx(bitmap,gfx,
978 								number + x_offset[ex] + y_offset[ey],
979 								color,
980 								!xflip,!yflip,
981 								248-(sx+x*8),248-(sy+y*8),
982 								&Machine->visible_area,trans,0,
983 								pri_mask);
984 						else
985 							drawgfx(bitmap,gfx,
986 								number + x_offset[ex] + y_offset[ey],
987 								color,
988 								!xflip,!yflip,
989 								248-(sx+x*8),248-(sy+y*8),
990 								&Machine->visible_area,trans,0);
991 					}
992 					else
993 					{
994 						if (pri_mask != -1)
995 							pdrawgfx(bitmap,gfx,
996 								number + x_offset[ex] + y_offset[ey],
997 								color,
998 								xflip,yflip,
999 								global_x_offset+sx+x*8,sy+y*8,
1000 								&Machine->visible_area,trans,0,
1001 								pri_mask);
1002 						else
1003 							drawgfx(bitmap,gfx,
1004 								number + x_offset[ex] + y_offset[ey],
1005 								color,
1006 								xflip,yflip,
1007 								global_x_offset+sx+x*8,sy+y*8,
1008 								&Machine->visible_area,trans,0);
1009 					}
1010 				}
1011 			}
1012 		}
1013 
1014 		source += inc;
1015 	}
1016 }
1017 
K007121_mark_sprites_colors(int chip,const unsigned char * source,int base_color,int bank_base)1018 void K007121_mark_sprites_colors(int chip,
1019 		const unsigned char *source,int base_color,int bank_base)
1020 {
1021 	int i,num,inc,offs[5];
1022 	int is_flakatck = K007121_ctrlram[chip][0x06] & 0x04;	/* WRONG!!!! */
1023 
1024 	unsigned short palette_map[512];
1025 
1026 	if (is_flakatck)
1027 	{
1028 		num = 0x40;
1029 		inc = -0x20;
1030 		source += 0x3f*0x20;
1031 		offs[0] = 0x0e;
1032 		offs[1] = 0x0f;
1033 		offs[2] = 0x06;
1034 		offs[3] = 0x04;
1035 		offs[4] = 0x08;
1036 	}
1037 	else	/* all others */
1038 	{
1039 		num = (K007121_ctrlram[chip][0x03] & 0x40) ? 0x80 : 0x40;
1040 		inc = 5;
1041 		offs[0] = 0x00;
1042 		offs[1] = 0x01;
1043 		offs[2] = 0x02;
1044 		offs[3] = 0x03;
1045 		offs[4] = 0x04;
1046 	}
1047 
1048 	memset (palette_map, 0, sizeof (palette_map));
1049 
1050 	/* sprites */
1051 	for (i = 0;i < num;i++)
1052 	{
1053 		int color;
1054 
1055 		color = base_color + ((source[offs[1]] & 0xf0) >> 4);
1056 		palette_map[color] |= 0xffff;
1057 
1058 		source += inc;
1059 	}
1060 
1061 	/* now build the final table */
1062 	for (i = 0; i < 512; i++)
1063 	{
1064 		int usage = palette_map[i], j;
1065 		if (usage)
1066 		{
1067 			for (j = 0; j < 16; j++)
1068 				if (usage & (1 << j))
1069 					palette_used_colors[i * 16 + j] |= PALETTE_COLOR_VISIBLE;
1070 		}
1071 	}
1072 }
1073 
1074 
1075 
1076 
1077 
1078 
1079 
1080 static unsigned char *K007342_ram,*K007342_scroll_ram;
1081 static int K007342_gfxnum;
1082 static int K007342_int_enabled;
1083 static int K007342_flipscreen;
1084 static int K007342_scrollx[2];
1085 static int K007342_scrolly[2];
1086 static unsigned char *K007342_videoram_0,*K007342_colorram_0;
1087 static unsigned char *K007342_videoram_1,*K007342_colorram_1;
1088 static int K007342_regs[8];
1089 static void (*K007342_callback)(int tilemap, int bank, int *code, int *color);
1090 static struct tilemap *K007342_tilemap[2];
1091 
1092 /***************************************************************************
1093 
1094   Callbacks for the TileMap code
1095 
1096 ***************************************************************************/
1097 
1098 /*
1099   data format:
1100   video RAM     xxxxxxxx    tile number (bits 0-7)
1101   color RAM     x-------    tiles with priority over the sprites
1102   color RAM     -x------    depends on external conections
1103   color RAM     --x-----    flip Y
1104   color RAM     ---x----    flip X
1105   color RAM     ----xxxx    depends on external connections (usually color and banking)
1106 */
1107 
1108 static unsigned char *colorram,*videoram1,*videoram2;
1109 static int layer;
1110 
tilemap_0_preupdate(void)1111 static void tilemap_0_preupdate(void)
1112 {
1113 	colorram = K007342_colorram_0;
1114 	videoram1 = K007342_videoram_0;
1115 	layer = 0;
1116 }
1117 
tilemap_1_preupdate(void)1118 static void tilemap_1_preupdate(void)
1119 {
1120 	colorram = K007342_colorram_1;
1121 	videoram1 = K007342_videoram_1;
1122 	layer = 1;
1123 }
1124 
K007342_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)1125 static UINT32 K007342_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)
1126 {
1127 	/* logical (col,row) -> memory offset */
1128 	return (col & 0x1f) + ((row & 0x1f) << 5) + ((col & 0x20) << 5);
1129 }
1130 
K007342_get_tile_info(int tile_index)1131 static void K007342_get_tile_info(int tile_index)
1132 {
1133 	int color, code;
1134 
1135 	color = colorram[tile_index];
1136 	code = videoram1[tile_index];
1137 
1138 	tile_info.flags = TILE_FLIPYX((color & 0x30) >> 4);
1139 	tile_info.priority = (color & 0x80) >> 7;
1140 
1141 	(*K007342_callback)(layer, K007342_regs[1], &code, &color);
1142 
1143 	SET_TILE_INFO(K007342_gfxnum,code,color);
1144 }
1145 
K007342_vh_start(int gfx_index,void (* callback)(int tilemap,int bank,int * code,int * color))1146 int K007342_vh_start(int gfx_index, void (*callback)(int tilemap, int bank, int *code, int *color))
1147 {
1148 	K007342_gfxnum = gfx_index;
1149 	K007342_callback = callback;
1150 
1151 	K007342_tilemap[0] = tilemap_create(K007342_get_tile_info,K007342_scan,TILEMAP_TRANSPARENT,8,8,64,32);
1152 	K007342_tilemap[1] = tilemap_create(K007342_get_tile_info,K007342_scan,TILEMAP_TRANSPARENT,8,8,64,32);
1153 
1154 	K007342_ram = (unsigned char*)malloc(0x2000);
1155 	K007342_scroll_ram = (unsigned char*)malloc(0x0200);
1156 
1157 	if (!K007342_ram || !K007342_scroll_ram || !K007342_tilemap[0] || !K007342_tilemap[1])
1158 	{
1159 		K007342_vh_stop();
1160 		return 1;
1161 	}
1162 
1163 	memset(K007342_ram,0,0x2000);
1164 
1165 	K007342_colorram_0 = &K007342_ram[0x0000];
1166 	K007342_colorram_1 = &K007342_ram[0x1000];
1167 	K007342_videoram_0 = &K007342_ram[0x0800];
1168 	K007342_videoram_1 = &K007342_ram[0x1800];
1169 
1170 	K007342_tilemap[0]->transparent_pen = 0;
1171 	K007342_tilemap[1]->transparent_pen = 0;
1172 
1173 	return 0;
1174 }
1175 
K007342_vh_stop(void)1176 void K007342_vh_stop(void)
1177 {
1178 	free(K007342_ram);
1179 	K007342_ram = 0;
1180 	free(K007342_scroll_ram);
1181 	K007342_scroll_ram = 0;
1182 }
1183 
READ_HANDLER(K007342_r)1184 READ_HANDLER( K007342_r )
1185 {
1186 	return K007342_ram[offset];
1187 }
1188 
WRITE_HANDLER(K007342_w)1189 WRITE_HANDLER( K007342_w )
1190 {
1191 	if (offset < 0x1000)
1192 	{		/* layer 0 */
1193 		if (K007342_ram[offset] != data)
1194 		{
1195 			K007342_ram[offset] = data;
1196 			tilemap_mark_tile_dirty(K007342_tilemap[0],offset & 0x7ff);
1197 		}
1198 	}
1199 	else
1200 	{						/* layer 1 */
1201 		if (K007342_ram[offset] != data)
1202 		{
1203 			K007342_ram[offset] = data;
1204 			tilemap_mark_tile_dirty(K007342_tilemap[1],offset & 0x7ff);
1205 		}
1206 	}
1207 }
1208 
READ_HANDLER(K007342_scroll_r)1209 READ_HANDLER( K007342_scroll_r )
1210 {
1211 	return K007342_scroll_ram[offset];
1212 }
1213 
WRITE_HANDLER(K007342_scroll_w)1214 WRITE_HANDLER( K007342_scroll_w )
1215 {
1216 	K007342_scroll_ram[offset] = data;
1217 }
1218 
WRITE_HANDLER(K007342_vreg_w)1219 WRITE_HANDLER( K007342_vreg_w )
1220 {
1221 	switch(offset)
1222 	{
1223 		case 0x00:
1224 			/* bit 1: INT control */
1225 			K007342_int_enabled = data & 0x02;
1226 			K007342_flipscreen = data & 0x10;
1227 			tilemap_set_flip(K007342_tilemap[0],K007342_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
1228 			tilemap_set_flip(K007342_tilemap[1],K007342_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
1229 			break;
1230 		case 0x01:  /* used for banking in Rock'n'Rage */
1231 			if (data != K007342_regs[1])
1232 				tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
1233 		case 0x02:
1234 			K007342_scrollx[0] = (K007342_scrollx[0] & 0xff) | ((data & 0x01) << 8);
1235 			K007342_scrollx[1] = (K007342_scrollx[1] & 0xff) | ((data & 0x02) << 7);
1236 			break;
1237 		case 0x03:  /* scroll x (register 0) */
1238 			K007342_scrollx[0] = (K007342_scrollx[0] & 0x100) | data;
1239 			break;
1240 		case 0x04:  /* scroll y (register 0) */
1241 			K007342_scrolly[0] = data;
1242 			break;
1243 		case 0x05:  /* scroll x (register 1) */
1244 			K007342_scrollx[1] = (K007342_scrollx[1] & 0x100) | data;
1245 			break;
1246 		case 0x06:  /* scroll y (register 1) */
1247 			K007342_scrolly[1] = data;
1248 		case 0x07:  /* unused */
1249 			break;
1250 	}
1251 	K007342_regs[offset] = data;
1252 }
1253 
K007342_tilemap_update(void)1254 void K007342_tilemap_update(void)
1255 {
1256 	int offs;
1257 
1258 
1259 	/* update scroll */
1260 	switch (K007342_regs[2] & 0x1c)
1261 	{
1262 		case 0x00:
1263 		case 0x08:	/* unknown, blades of steel shootout between periods */
1264 			tilemap_set_scroll_rows(K007342_tilemap[0],1);
1265 			tilemap_set_scroll_cols(K007342_tilemap[0],1);
1266 			tilemap_set_scrollx(K007342_tilemap[0],0,K007342_scrollx[0]);
1267 			tilemap_set_scrolly(K007342_tilemap[0],0,K007342_scrolly[0]);
1268 			break;
1269 
1270 		case 0x0c:	/* 32 columns */
1271 			tilemap_set_scroll_rows(K007342_tilemap[0],1);
1272 			tilemap_set_scroll_cols(K007342_tilemap[0],512);
1273 			tilemap_set_scrollx(K007342_tilemap[0],0,K007342_scrollx[0]);
1274 			for (offs = 0;offs < 256;offs++)
1275 				tilemap_set_scrolly(K007342_tilemap[0],(offs + K007342_scrollx[0]) & 0x1ff,
1276 						K007342_scroll_ram[2*(offs/8)] + 256 * K007342_scroll_ram[2*(offs/8)+1]);
1277 			break;
1278 
1279 		case 0x14:	/* 256 rows */
1280 			tilemap_set_scroll_rows(K007342_tilemap[0],256);
1281 			tilemap_set_scroll_cols(K007342_tilemap[0],1);
1282 			tilemap_set_scrolly(K007342_tilemap[0],0,K007342_scrolly[0]);
1283 			for (offs = 0;offs < 256;offs++)
1284 				tilemap_set_scrollx(K007342_tilemap[0],(offs + K007342_scrolly[0]) & 0xff,
1285 						K007342_scroll_ram[2*offs] + 256 * K007342_scroll_ram[2*offs+1]);
1286 			break;
1287 
1288 		default:
1289 usrintf_showmessage("unknown scroll ctrl %02x",K007342_regs[2] & 0x1c);
1290 			break;
1291 	}
1292 
1293 	tilemap_set_scrollx(K007342_tilemap[1],0,K007342_scrollx[1]);
1294 	tilemap_set_scrolly(K007342_tilemap[1],0,K007342_scrolly[1]);
1295 
1296 	/* update all layers */
1297 	tilemap_0_preupdate(); tilemap_update(K007342_tilemap[0]);
1298 	tilemap_1_preupdate(); tilemap_update(K007342_tilemap[1]);
1299 
1300 #if 0
1301 	{
1302 		static int current_layer = 0;
1303 
1304 		if (keyboard_pressed_memory(KEYCODE_Z)) current_layer = !current_layer;
1305 		tilemap_set_enable(K007342_tilemap[current_layer], 1);
1306 		tilemap_set_enable(K007342_tilemap[!current_layer], 0);
1307 
1308 		usrintf_showmessage("regs:%02x %02x %02x %02x-%02x %02x %02x %02x:%02x",
1309 			K007342_regs[0], K007342_regs[1], K007342_regs[2], K007342_regs[3],
1310 			K007342_regs[4], K007342_regs[5], K007342_regs[6], K007342_regs[7],
1311 			current_layer);
1312 	}
1313 #endif
1314 }
1315 
K007342_tilemap_set_enable(int tilemap,int enable)1316 void K007342_tilemap_set_enable(int tilemap, int enable)
1317 {
1318 	tilemap_set_enable(K007342_tilemap[tilemap], enable);
1319 }
1320 
K007342_tilemap_draw(struct osd_bitmap * bitmap,int num,int flags)1321 void K007342_tilemap_draw(struct osd_bitmap *bitmap,int num,int flags)
1322 {
1323 	tilemap_draw(bitmap,K007342_tilemap[num],flags);
1324 }
1325 
K007342_is_INT_enabled(void)1326 int K007342_is_INT_enabled(void)
1327 {
1328 	return K007342_int_enabled;
1329 }
1330 
1331 
1332 
1333 static struct GfxElement *K007420_gfx;
1334 static void (*K007420_callback)(int *code,int *color);
1335 static unsigned char *K007420_ram;
1336 
K007420_vh_start(int gfxnum,void (* callback)(int * code,int * color))1337 int K007420_vh_start(int gfxnum, void (*callback)(int *code,int *color))
1338 {
1339 	K007420_gfx = Machine->gfx[gfxnum];
1340 	K007420_callback = callback;
1341 	K007420_ram = (unsigned char*)malloc(0x200);
1342 	if (!K007420_ram) return 1;
1343 
1344 	memset(K007420_ram,0,0x200);
1345 
1346 	return 0;
1347 }
1348 
K007420_vh_stop(void)1349 void K007420_vh_stop(void)
1350 {
1351 	free(K007420_ram);
1352 	K007420_ram = 0;
1353 }
1354 
READ_HANDLER(K007420_r)1355 READ_HANDLER( K007420_r )
1356 {
1357 	return K007420_ram[offset];
1358 }
1359 
WRITE_HANDLER(K007420_w)1360 WRITE_HANDLER( K007420_w )
1361 {
1362 	K007420_ram[offset] = data;
1363 }
1364 
1365 /*
1366  * Sprite Format
1367  * ------------------
1368  *
1369  * Byte | Bit(s)   | Use
1370  * -----+-76543210-+----------------
1371  *   0  | xxxxxxxx | y position
1372  *   1  | xxxxxxxx | sprite code (low 8 bits)
1373  *   2  | xxxxxxxx | depends on external conections. Usually banking
1374  *   3  | xxxxxxxx | x position (low 8 bits)
1375  *   4  | x------- | x position (high bit)
1376  *   4  | -xxx---- | sprite size 000=16x16 001=8x16 010=16x8 011=8x8 100=32x32
1377  *   4  | ----x--- | flip y
1378  *   4  | -----x-- | flip x
1379  *   4  | ------xx | zoom (bits 8 & 9)
1380  *   5  | xxxxxxxx | zoom (low 8 bits)  0x080 = normal, < 0x80 enlarge, > 0x80 reduce
1381  *   6  | xxxxxxxx | unused
1382  *   7  | xxxxxxxx | unused
1383  */
1384 
K007420_sprites_draw(struct osd_bitmap * bitmap)1385 void K007420_sprites_draw(struct osd_bitmap *bitmap)
1386 {
1387 #define K007420_SPRITERAM_SIZE 0x200
1388 	int offs;
1389 
1390 	for (offs = K007420_SPRITERAM_SIZE - 8; offs >= 0; offs -= 8)
1391 	{
1392 		int ox,oy,code,color,flipx,flipy,zoom,w,h,x,y;
1393 		static int xoffset[4] = { 0, 1, 4, 5 };
1394 		static int yoffset[4] = { 0, 2, 8, 10 };
1395 
1396 		code = K007420_ram[offs+1];
1397 		color = K007420_ram[offs+2];
1398 		ox = K007420_ram[offs+3] - ((K007420_ram[offs+4] & 0x80) << 1);
1399 		oy = 256 - K007420_ram[offs+0];
1400 		flipx = K007420_ram[offs+4] & 0x04;
1401 		flipy = K007420_ram[offs+4] & 0x08;
1402 
1403 		(*K007420_callback)(&code,&color);
1404 
1405 		/* kludge for rock'n'rage */
1406 		if ((K007420_ram[offs+4] == 0x40) && (K007420_ram[offs+1] == 0xff) &&
1407 			(K007420_ram[offs+2] == 0x00) && (K007420_ram[offs+5] == 0xf0)) continue;
1408 
1409 		/* 0x080 = normal scale, 0x040 = double size, 0x100 half size */
1410 		zoom = K007420_ram[offs+5] | ((K007420_ram[offs+4] & 0x03) << 8);
1411 		if (!zoom) continue;
1412 		zoom = 0x10000 * 128 / zoom;
1413 
1414 		switch (K007420_ram[offs+4] & 0x70)
1415 		{
1416 			case 0x30: w = h = 1; break;
1417 			case 0x20: w = 2; h = 1; code &= (~1); break;
1418 			case 0x10: w = 1; h = 2; code &= (~2); break;
1419 			case 0x00: w = h = 2; code &= (~3); break;
1420 			case 0x40: w = h = 4; code &= (~3); break;
1421 			default: w = 1; h = 1;
1422 //logerror("Unknown sprite size %02x\n",(K007420_ram[offs+4] & 0x70)>>4);
1423 		}
1424 
1425 		if (K007342_flipscreen)
1426 		{
1427 			ox = 256 - ox - ((zoom * w + (1<<12)) >> 13);
1428 			oy = 256 - oy - ((zoom * h + (1<<12)) >> 13);
1429 			flipx = !flipx;
1430 			flipy = !flipy;
1431 		}
1432 
1433 		if (zoom == 0x10000)
1434 		{
1435 			int sx,sy;
1436 
1437 			for (y = 0;y < h;y++)
1438 			{
1439 				sy = oy + 8 * y;
1440 
1441 				for (x = 0;x < w;x++)
1442 				{
1443 					int c = code;
1444 
1445 					sx = ox + 8 * x;
1446 					if (flipx) c += xoffset[(w-1-x)];
1447 					else c += xoffset[x];
1448 					if (flipy) c += yoffset[(h-1-y)];
1449 					else c += yoffset[y];
1450 
1451 					drawgfx(bitmap,K007420_gfx,
1452 						c,
1453 						color,
1454 						flipx,flipy,
1455 						sx,sy,
1456 						&Machine->visible_area,TRANSPARENCY_PEN,0);
1457 
1458 					if (K007342_regs[2] & 0x80)
1459 						drawgfx(bitmap,K007420_gfx,
1460 							c,
1461 							color,
1462 							flipx,flipy,
1463 							sx,sy-256,
1464 							&Machine->visible_area,TRANSPARENCY_PEN,0);
1465 				}
1466 			}
1467 		}
1468 		else
1469 		{
1470 			int sx,sy,zw,zh;
1471 			for (y = 0;y < h;y++)
1472 			{
1473 				sy = oy + ((zoom * y + (1<<12)) >> 13);
1474 				zh = (oy + ((zoom * (y+1) + (1<<12)) >> 13)) - sy;
1475 
1476 				for (x = 0;x < w;x++)
1477 				{
1478 					int c = code;
1479 
1480 					sx = ox + ((zoom * x + (1<<12)) >> 13);
1481 					zw = (ox + ((zoom * (x+1) + (1<<12)) >> 13)) - sx;
1482 					if (flipx) c += xoffset[(w-1-x)];
1483 					else c += xoffset[x];
1484 					if (flipy) c += yoffset[(h-1-y)];
1485 					else c += yoffset[y];
1486 
1487 					drawgfxzoom(bitmap,K007420_gfx,
1488 						c,
1489 						color,
1490 						flipx,flipy,
1491 						sx,sy,
1492 						&Machine->visible_area,TRANSPARENCY_PEN,0,
1493 						(zw << 16) / 8,(zh << 16) / 8);
1494 
1495 					if (K007342_regs[2] & 0x80)
1496 						drawgfxzoom(bitmap,K007420_gfx,
1497 							c,
1498 							color,
1499 							flipx,flipy,
1500 							sx,sy-256,
1501 							&Machine->visible_area,TRANSPARENCY_PEN,0,
1502 							(zw << 16) / 8,(zh << 16) / 8);
1503 				}
1504 			}
1505 		}
1506 	}
1507 #if 0
1508 	{
1509 		static int current_sprite = 0;
1510 
1511 		if (keyboard_pressed_memory(KEYCODE_Z)) current_sprite = (current_sprite+1) & ((K007420_SPRITERAM_SIZE/8)-1);
1512 		if (keyboard_pressed_memory(KEYCODE_X)) current_sprite = (current_sprite-1) & ((K007420_SPRITERAM_SIZE/8)-1);
1513 
1514 		usrintf_showmessage("%02x:%02x %02x %02x %02x %02x %02x %02x %02x", current_sprite,
1515 			K007420_ram[(current_sprite*8)+0], K007420_ram[(current_sprite*8)+1],
1516 			K007420_ram[(current_sprite*8)+2], K007420_ram[(current_sprite*8)+3],
1517 			K007420_ram[(current_sprite*8)+4], K007420_ram[(current_sprite*8)+5],
1518 			K007420_ram[(current_sprite*8)+6], K007420_ram[(current_sprite*8)+7]);
1519 	}
1520 #endif
1521 }
1522 
1523 
1524 
1525 
1526 static int K052109_memory_region;
1527 static int K052109_gfxnum;
1528 static void (*K052109_callback)(int tilemap,int bank,int *code,int *color);
1529 static unsigned char *K052109_ram;
1530 static unsigned char *K052109_videoram_F,*K052109_videoram2_F,*K052109_colorram_F;
1531 static unsigned char *K052109_videoram_A,*K052109_videoram2_A,*K052109_colorram_A;
1532 static unsigned char *K052109_videoram_B,*K052109_videoram2_B,*K052109_colorram_B;
1533 static unsigned char K052109_charrombank[4];
1534 static int has_extra_video_ram;
1535 static int K052109_RMRD_line;
1536 static int K052109_tileflip_enable;
1537 static int K052109_irq_enabled;
1538 static unsigned char K052109_romsubbank,K052109_scrollctrl;
1539 static struct tilemap *K052109_tilemap[3];
1540 
1541 
1542 
1543 /***************************************************************************
1544 
1545   Callbacks for the TileMap code
1546 
1547 ***************************************************************************/
1548 
1549 /*
1550   data format:
1551   video RAM    xxxxxxxx  tile number (low 8 bits)
1552   color RAM    xxxx----  depends on external connections (usually color and banking)
1553   color RAM    ----xx--  bank select (0-3): these bits are replaced with the 2
1554                          bottom bits of the bank register before being placed on
1555                          the output pins. The other two bits of the bank register are
1556                          placed on the CAB1 and CAB2 output pins.
1557   color RAM    ------xx  depends on external connections (usually banking, flip)
1558 */
1559 
tilemap0_preupdate(void)1560 static void tilemap0_preupdate(void)
1561 {
1562 	colorram = K052109_colorram_F;
1563 	videoram1 = K052109_videoram_F;
1564 	videoram2 = K052109_videoram2_F;
1565 	layer = 0;
1566 }
1567 
tilemap1_preupdate(void)1568 static void tilemap1_preupdate(void)
1569 {
1570 	colorram = K052109_colorram_A;
1571 	videoram1 = K052109_videoram_A;
1572 	videoram2 = K052109_videoram2_A;
1573 	layer = 1;
1574 }
1575 
tilemap2_preupdate(void)1576 static void tilemap2_preupdate(void)
1577 {
1578 	colorram = K052109_colorram_B;
1579 	videoram1 = K052109_videoram_B;
1580 	videoram2 = K052109_videoram2_B;
1581 	layer = 2;
1582 }
1583 
K052109_get_tile_info(int tile_index)1584 static void K052109_get_tile_info(int tile_index)
1585 {
1586 	int flipy = 0;
1587 	int code = videoram1[tile_index] + 256 * videoram2[tile_index];
1588 	int color = colorram[tile_index];
1589 	int bank = K052109_charrombank[(color & 0x0c) >> 2];
1590 if (has_extra_video_ram) bank = (color & 0x0c) >> 2;	/* kludge for X-Men */
1591 	color = (color & 0xf3) | ((bank & 0x03) << 2);
1592 	bank >>= 2;
1593 
1594 	flipy = color & 0x02;
1595 
1596 	tile_info.flags = 0;
1597 
1598 	(*K052109_callback)(layer,bank,&code,&color);
1599 
1600 	SET_TILE_INFO(K052109_gfxnum,code,color);
1601 
1602 	/* if the callback set flip X but it is not enabled, turn it off */
1603 	if (!(K052109_tileflip_enable & 1)) tile_info.flags &= ~TILE_FLIPX;
1604 
1605 	/* if flip Y is enabled and the attribute but is set, turn it on */
1606 	if (flipy && (K052109_tileflip_enable & 2)) tile_info.flags |= TILE_FLIPY;
1607 }
1608 
1609 
1610 
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))1611 int K052109_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,
1612 		void (*callback)(int tilemap,int bank,int *code,int *color))
1613 {
1614 	int gfx_index;
1615 	static struct GfxLayout charlayout =
1616 	{
1617 		8,8,
1618 		0,				/* filled in later */
1619 		4,
1620 		{ 0, 0, 0, 0 },	/* filled in later */
1621 		{ 0, 1, 2, 3, 4, 5, 6, 7 },
1622 		{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
1623 		32*8
1624 	};
1625 
1626 
1627 	/* find first empty slot to decode gfx */
1628 	for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
1629 		if (Machine->gfx[gfx_index] == 0)
1630 			break;
1631 	if (gfx_index == MAX_GFX_ELEMENTS)
1632 		return 1;
1633 
1634 	/* tweak the structure for the number of tiles we have */
1635 	charlayout.total = memory_region_length(gfx_memory_region) / 32;
1636 	charlayout.planeoffset[0] = plane3 * 8;
1637 	charlayout.planeoffset[1] = plane2 * 8;
1638 	charlayout.planeoffset[2] = plane1 * 8;
1639 	charlayout.planeoffset[3] = plane0 * 8;
1640 
1641 	/* decode the graphics */
1642 	Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&charlayout);
1643 	if (!Machine->gfx[gfx_index])
1644 		return 1;
1645 
1646 	/* set the color information */
1647 	Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
1648 	Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
1649 
1650 	K052109_memory_region = gfx_memory_region;
1651 	K052109_gfxnum = gfx_index;
1652 	K052109_callback = callback;
1653 	K052109_RMRD_line = CLEAR_LINE;
1654 
1655 	has_extra_video_ram = 0;
1656 
1657 	K052109_tilemap[0] = tilemap_create(K052109_get_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,64,32);
1658 	K052109_tilemap[1] = tilemap_create(K052109_get_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,64,32);
1659 	K052109_tilemap[2] = tilemap_create(K052109_get_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,8,8,64,32);
1660 
1661 	K052109_ram = (unsigned char*)malloc(0x6000);
1662 
1663 	if (!K052109_ram || !K052109_tilemap[0] || !K052109_tilemap[1] || !K052109_tilemap[2])
1664 	{
1665 		K052109_vh_stop();
1666 		return 1;
1667 	}
1668 
1669 	memset(K052109_ram,0,0x6000);
1670 
1671 	K052109_colorram_F = &K052109_ram[0x0000];
1672 	K052109_colorram_A = &K052109_ram[0x0800];
1673 	K052109_colorram_B = &K052109_ram[0x1000];
1674 	K052109_videoram_F = &K052109_ram[0x2000];
1675 	K052109_videoram_A = &K052109_ram[0x2800];
1676 	K052109_videoram_B = &K052109_ram[0x3000];
1677 	K052109_videoram2_F = &K052109_ram[0x4000];
1678 	K052109_videoram2_A = &K052109_ram[0x4800];
1679 	K052109_videoram2_B = &K052109_ram[0x5000];
1680 
1681 	K052109_tilemap[0]->transparent_pen = 0;
1682 	K052109_tilemap[1]->transparent_pen = 0;
1683 	K052109_tilemap[2]->transparent_pen = 0;
1684 
1685 	return 0;
1686 }
1687 
K052109_vh_stop(void)1688 void K052109_vh_stop(void)
1689 {
1690 	free(K052109_ram);
1691 	K052109_ram = 0;
1692 }
1693 
1694 
1695 
READ_HANDLER(K052109_r)1696 READ_HANDLER( K052109_r )
1697 {
1698 	if (K052109_RMRD_line == CLEAR_LINE)
1699 	{
1700 //		if ((offset & 0x1fff) >= 0x1800)
1701 //		{
1702 //			if (offset >= 0x180c && offset < 0x1834)
1703 //			{	/* A y scroll */	}
1704 //			else if (offset >= 0x1a00 && offset < 0x1c00)
1705 //			{	/* A x scroll */	}
1706 //			else if (offset == 0x1d00)
1707 //			{	/* read for bitwise operations before writing */	}
1708 //			else if (offset >= 0x380c && offset < 0x3834)
1709 //			{	/* B y scroll */	}
1710 //			else if (offset >= 0x3a00 && offset < 0x3c00)
1711 //			{	/* B x scroll */	}
1712 //			else
1713 //logerror("%04x: read from unknown 052109 address %04x\n",cpu_get_pc(),offset);
1714 //		}
1715 
1716 		return K052109_ram[offset];
1717 	}
1718 	else	/* Punk Shot and TMNT read from 0000-1fff, Aliens from 2000-3fff */
1719 	{
1720 		int code = (offset & 0x1fff) >> 5;
1721 		int color = K052109_romsubbank;
1722 		int bank = K052109_charrombank[(color & 0x0c) >> 2] >> 2;   /* discard low bits (TMNT) */
1723 		int addr;
1724 
1725 if (has_extra_video_ram) code |= color << 8;	/* kludge for X-Men */
1726 else
1727 		(*K052109_callback)(0,bank,&code,&color);
1728 
1729 		addr = (code << 5) + (offset & 0x1f);
1730 		addr &= memory_region_length(K052109_memory_region)-1;
1731 
1732 #if 0
1733 	usrintf_showmessage("%04x: off%04x sub%02x (bnk%x) adr%06x",cpu_get_pc(),offset,K052109_romsubbank,bank,addr);
1734 #endif
1735 
1736 		return memory_region(K052109_memory_region)[addr];
1737 	}
1738 }
1739 
WRITE_HANDLER(K052109_w)1740 WRITE_HANDLER( K052109_w )
1741 {
1742 	if ((offset & 0x1fff) < 0x1800) /* tilemap RAM */
1743 	{
1744 		if (K052109_ram[offset] != data)
1745 		{
1746 			if (offset >= 0x4000) has_extra_video_ram = 1;  /* kludge for X-Men */
1747 			K052109_ram[offset] = data;
1748 			tilemap_mark_tile_dirty(K052109_tilemap[(offset & 0x1800) >> 11],offset & 0x7ff);
1749 		}
1750 	}
1751 	else	/* control registers */
1752 	{
1753 		K052109_ram[offset] = data;
1754 
1755 		if (offset >= 0x180c && offset < 0x1834)
1756 		{	/* A y scroll */	}
1757 		else if (offset >= 0x1a00 && offset < 0x1c00)
1758 		{	/* A x scroll */	}
1759 		else if (offset == 0x1c80)
1760 		{
1761 if (K052109_scrollctrl != data)
1762 {
1763 #if 0
1764 usrintf_showmessage("scrollcontrol = %02x",data);
1765 #endif
1766 //logerror("%04x: rowscrollcontrol = %02x\n",cpu_get_pc(),data);
1767 			K052109_scrollctrl = data;
1768 }
1769 		}
1770 		else if (offset == 0x1d00)
1771 		{
1772 #if VERBOSE
1773 logerror("%04x: 052109 register 1d00 = %02x\n",cpu_get_pc(),data);
1774 #endif
1775 			/* bit 2 = irq enable */
1776 			/* the custom chip can also generate NMI and FIRQ, for use with a 6809 */
1777 			K052109_irq_enabled = data & 0x04;
1778 		}
1779 		else if (offset == 0x1d80)
1780 		{
1781 			int dirty = 0;
1782 
1783 			if (K052109_charrombank[0] != (data & 0x0f)) dirty |= 1;
1784 			if (K052109_charrombank[1] != ((data >> 4) & 0x0f)) dirty |= 2;
1785 			if (dirty)
1786 			{
1787 				int i;
1788 
1789 				K052109_charrombank[0] = data & 0x0f;
1790 				K052109_charrombank[1] = (data >> 4) & 0x0f;
1791 
1792 				for (i = 0;i < 0x1800;i++)
1793 				{
1794 					int bank = (K052109_ram[i]&0x0c) >> 2;
1795 					if ((bank == 0 && (dirty & 1)) || (bank == 1 && dirty & 2))
1796 					{
1797 						tilemap_mark_tile_dirty(K052109_tilemap[(i & 0x1800) >> 11],i & 0x7ff);
1798 					}
1799 				}
1800 			}
1801 		}
1802 		else if (offset == 0x1e00)
1803 		{
1804 //logerror("%04x: 052109 register 1e00 = %02x\n",cpu_get_pc(),data);
1805 			K052109_romsubbank = data;
1806 		}
1807 		else if (offset == 0x1e80)
1808 		{
1809 //if ((data & 0xfe)) logerror("%04x: 052109 register 1e80 = %02x\n",cpu_get_pc(),data);
1810 			tilemap_set_flip(K052109_tilemap[0],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
1811 			tilemap_set_flip(K052109_tilemap[1],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
1812 			tilemap_set_flip(K052109_tilemap[2],(data & 1) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
1813 			if (K052109_tileflip_enable != ((data & 0x06) >> 1))
1814 			{
1815 				K052109_tileflip_enable = ((data & 0x06) >> 1);
1816 
1817 				tilemap_mark_all_tiles_dirty(K052109_tilemap[0]);
1818 				tilemap_mark_all_tiles_dirty(K052109_tilemap[1]);
1819 				tilemap_mark_all_tiles_dirty(K052109_tilemap[2]);
1820 			}
1821 		}
1822 		else if (offset == 0x1f00)
1823 		{
1824 			int dirty = 0;
1825 
1826 			if (K052109_charrombank[2] != (data & 0x0f)) dirty |= 1;
1827 			if (K052109_charrombank[3] != ((data >> 4) & 0x0f)) dirty |= 2;
1828 			if (dirty)
1829 			{
1830 				int i;
1831 
1832 				K052109_charrombank[2] = data & 0x0f;
1833 				K052109_charrombank[3] = (data >> 4) & 0x0f;
1834 
1835 				for (i = 0;i < 0x1800;i++)
1836 				{
1837 					int bank = (K052109_ram[i] & 0x0c) >> 2;
1838 					if ((bank == 2 && (dirty & 1)) || (bank == 3 && dirty & 2))
1839 						tilemap_mark_tile_dirty(K052109_tilemap[(i & 0x1800) >> 11],i & 0x7ff);
1840 				}
1841 			}
1842 		}
1843 		else if (offset >= 0x380c && offset < 0x3834)
1844 		{	/* B y scroll */	}
1845 		else if (offset >= 0x3a00 && offset < 0x3c00)
1846 		{	/* B x scroll */	}
1847 //		else
1848 //logerror("%04x: write %02x to unknown 052109 address %04x\n",cpu_get_pc(),data,offset);
1849 	}
1850 }
1851 
K052109_set_RMRD_line(int state)1852 void K052109_set_RMRD_line(int state)
1853 {
1854 	K052109_RMRD_line = state;
1855 }
1856 
1857 
K052109_tilemap_update(void)1858 void K052109_tilemap_update(void)
1859 {
1860 #if 0
1861 {
1862 usrintf_showmessage("%x %x %x %x",
1863 	K052109_charrombank[0],
1864 	K052109_charrombank[1],
1865 	K052109_charrombank[2],
1866 	K052109_charrombank[3]);
1867 }
1868 #endif
1869 	if ((K052109_scrollctrl & 0x03) == 0x02)
1870 	{
1871 		int xscroll,yscroll,offs;
1872 		unsigned char *scrollram = &K052109_ram[0x1a00];
1873 
1874 
1875 		tilemap_set_scroll_rows(K052109_tilemap[1],256);
1876 		tilemap_set_scroll_cols(K052109_tilemap[1],1);
1877 		yscroll = K052109_ram[0x180c];
1878 		tilemap_set_scrolly(K052109_tilemap[1],0,yscroll);
1879 		for (offs = 0;offs < 256;offs++)
1880 		{
1881 			xscroll = scrollram[2*(offs&0xfff8)+0] + 256 * scrollram[2*(offs&0xfff8)+1];
1882 			xscroll -= 6;
1883 			tilemap_set_scrollx(K052109_tilemap[1],(offs+yscroll)&0xff,xscroll);
1884 		}
1885 	}
1886 	else if ((K052109_scrollctrl & 0x03) == 0x03)
1887 	{
1888 		int xscroll,yscroll,offs;
1889 		unsigned char *scrollram = &K052109_ram[0x1a00];
1890 
1891 
1892 		tilemap_set_scroll_rows(K052109_tilemap[1],256);
1893 		tilemap_set_scroll_cols(K052109_tilemap[1],1);
1894 		yscroll = K052109_ram[0x180c];
1895 		tilemap_set_scrolly(K052109_tilemap[1],0,yscroll);
1896 		for (offs = 0;offs < 256;offs++)
1897 		{
1898 			xscroll = scrollram[2*offs+0] + 256 * scrollram[2*offs+1];
1899 			xscroll -= 6;
1900 			tilemap_set_scrollx(K052109_tilemap[1],(offs+yscroll)&0xff,xscroll);
1901 		}
1902 	}
1903 	else if ((K052109_scrollctrl & 0x04) == 0x04)
1904 	{
1905 		int xscroll,yscroll,offs;
1906 		unsigned char *scrollram = &K052109_ram[0x1800];
1907 
1908 
1909 		tilemap_set_scroll_rows(K052109_tilemap[1],1);
1910 		tilemap_set_scroll_cols(K052109_tilemap[1],512);
1911 		xscroll = K052109_ram[0x1a00] + 256 * K052109_ram[0x1a01];
1912 		xscroll -= 6;
1913 		tilemap_set_scrollx(K052109_tilemap[1],0,xscroll);
1914 		for (offs = 0;offs < 512;offs++)
1915 		{
1916 			yscroll = scrollram[offs/8];
1917 			tilemap_set_scrolly(K052109_tilemap[1],(offs+xscroll)&0x1ff,yscroll);
1918 		}
1919 	}
1920 	else
1921 	{
1922 		int xscroll,yscroll;
1923 		unsigned char *scrollram = &K052109_ram[0x1a00];
1924 
1925 
1926 		tilemap_set_scroll_rows(K052109_tilemap[1],1);
1927 		tilemap_set_scroll_cols(K052109_tilemap[1],1);
1928 		xscroll = scrollram[0] + 256 * scrollram[1];
1929 		xscroll -= 6;
1930 		yscroll = K052109_ram[0x180c];
1931 		tilemap_set_scrollx(K052109_tilemap[1],0,xscroll);
1932 		tilemap_set_scrolly(K052109_tilemap[1],0,yscroll);
1933 	}
1934 
1935 	if ((K052109_scrollctrl & 0x18) == 0x10)
1936 	{
1937 		int xscroll,yscroll,offs;
1938 		unsigned char *scrollram = &K052109_ram[0x3a00];
1939 
1940 
1941 		tilemap_set_scroll_rows(K052109_tilemap[2],256);
1942 		tilemap_set_scroll_cols(K052109_tilemap[2],1);
1943 		yscroll = K052109_ram[0x380c];
1944 		tilemap_set_scrolly(K052109_tilemap[2],0,yscroll);
1945 		for (offs = 0;offs < 256;offs++)
1946 		{
1947 			xscroll = scrollram[2*(offs&0xfff8)+0] + 256 * scrollram[2*(offs&0xfff8)+1];
1948 			xscroll -= 6;
1949 			tilemap_set_scrollx(K052109_tilemap[2],(offs+yscroll)&0xff,xscroll);
1950 		}
1951 	}
1952 	else if ((K052109_scrollctrl & 0x18) == 0x18)
1953 	{
1954 		int xscroll,yscroll,offs;
1955 		unsigned char *scrollram = &K052109_ram[0x3a00];
1956 
1957 
1958 		tilemap_set_scroll_rows(K052109_tilemap[2],256);
1959 		tilemap_set_scroll_cols(K052109_tilemap[2],1);
1960 		yscroll = K052109_ram[0x380c];
1961 		tilemap_set_scrolly(K052109_tilemap[2],0,yscroll);
1962 		for (offs = 0;offs < 256;offs++)
1963 		{
1964 			xscroll = scrollram[2*offs+0] + 256 * scrollram[2*offs+1];
1965 			xscroll -= 6;
1966 			tilemap_set_scrollx(K052109_tilemap[2],(offs+yscroll)&0xff,xscroll);
1967 		}
1968 	}
1969 	else if ((K052109_scrollctrl & 0x20) == 0x20)
1970 	{
1971 		int xscroll,yscroll,offs;
1972 		unsigned char *scrollram = &K052109_ram[0x3800];
1973 
1974 
1975 		tilemap_set_scroll_rows(K052109_tilemap[2],1);
1976 		tilemap_set_scroll_cols(K052109_tilemap[2],512);
1977 		xscroll = K052109_ram[0x3a00] + 256 * K052109_ram[0x3a01];
1978 		xscroll -= 6;
1979 		tilemap_set_scrollx(K052109_tilemap[2],0,xscroll);
1980 		for (offs = 0;offs < 512;offs++)
1981 		{
1982 			yscroll = scrollram[offs/8];
1983 			tilemap_set_scrolly(K052109_tilemap[2],(offs+xscroll)&0x1ff,yscroll);
1984 		}
1985 	}
1986 	else
1987 	{
1988 		int xscroll,yscroll;
1989 		unsigned char *scrollram = &K052109_ram[0x3a00];
1990 
1991 
1992 		tilemap_set_scroll_rows(K052109_tilemap[2],1);
1993 		tilemap_set_scroll_cols(K052109_tilemap[2],1);
1994 		xscroll = scrollram[0] + 256 * scrollram[1];
1995 		xscroll -= 6;
1996 		yscroll = K052109_ram[0x380c];
1997 		tilemap_set_scrollx(K052109_tilemap[2],0,xscroll);
1998 		tilemap_set_scrolly(K052109_tilemap[2],0,yscroll);
1999 	}
2000 
2001 	tilemap0_preupdate(); tilemap_update(K052109_tilemap[0]);
2002 	tilemap1_preupdate(); tilemap_update(K052109_tilemap[1]);
2003 	tilemap2_preupdate(); tilemap_update(K052109_tilemap[2]);
2004 }
2005 
K052109_tilemap_draw(struct osd_bitmap * bitmap,int num,int flags)2006 void K052109_tilemap_draw(struct osd_bitmap *bitmap,int num,int flags)
2007 {
2008 	tilemap_draw(bitmap,K052109_tilemap[num],flags);
2009 }
2010 
K052109_is_IRQ_enabled(void)2011 int K052109_is_IRQ_enabled(void)
2012 {
2013 	return K052109_irq_enabled;
2014 }
2015 
2016 
2017 
2018 
2019 
2020 
2021 
2022 static int K051960_memory_region;
2023 static struct GfxElement *K051960_gfx;
2024 static void (*K051960_callback)(int *code,int *color,int *priority,int *shadow);
2025 static int K051960_romoffset;
2026 static int K051960_spriteflip,K051960_readroms,K051960_force_shadows;
2027 static unsigned char K051960_spriterombank[3];
2028 static unsigned char *K051960_ram;
2029 static int K051960_irq_enabled, K051960_nmi_enabled;
2030 
2031 
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))2032 int K051960_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,
2033 		void (*callback)(int *code,int *color,int *priority,int *shadow))
2034 {
2035 	int gfx_index;
2036 	static struct GfxLayout spritelayout =
2037 	{
2038 		16,16,
2039 		0,				/* filled in later */
2040 		4,
2041 		{ 0, 0, 0, 0 },	/* filled in later */
2042 		{ 0, 1, 2, 3, 4, 5, 6, 7,
2043 				8*32+0, 8*32+1, 8*32+2, 8*32+3, 8*32+4, 8*32+5, 8*32+6, 8*32+7 },
2044 		{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32,
2045 				16*32, 17*32, 18*32, 19*32, 20*32, 21*32, 22*32, 23*32 },
2046 		128*8
2047 	};
2048 
2049 
2050 	/* find first empty slot to decode gfx */
2051 	for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
2052 		if (Machine->gfx[gfx_index] == 0)
2053 			break;
2054 	if (gfx_index == MAX_GFX_ELEMENTS)
2055 		return 1;
2056 
2057 	/* tweak the structure for the number of tiles we have */
2058 	spritelayout.total = memory_region_length(gfx_memory_region) / 128;
2059 	spritelayout.planeoffset[0] = plane0 * 8;
2060 	spritelayout.planeoffset[1] = plane1 * 8;
2061 	spritelayout.planeoffset[2] = plane2 * 8;
2062 	spritelayout.planeoffset[3] = plane3 * 8;
2063 
2064 	/* decode the graphics */
2065 	Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&spritelayout);
2066 	if (!Machine->gfx[gfx_index])
2067 		return 1;
2068 
2069 	/* set the color information */
2070 	Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
2071 	Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
2072 
2073 	K051960_memory_region = gfx_memory_region;
2074 	K051960_gfx = Machine->gfx[gfx_index];
2075 	K051960_callback = callback;
2076 	K051960_ram = (unsigned char*)malloc(0x400);
2077 	if (!K051960_ram) return 1;
2078 	memset(K051960_ram,0,0x400);
2079 	K051960_force_shadows = 0;
2080 
2081 	return 0;
2082 }
2083 
K051960_vh_stop(void)2084 void K051960_vh_stop(void)
2085 {
2086 	free(K051960_ram);
2087 	K051960_ram = 0;
2088 }
2089 
2090 
K051960_fetchromdata(int byte)2091 static int K051960_fetchromdata(int byte)
2092 {
2093 	int code,color,pri,shadow,off1,addr;
2094 
2095 
2096 	addr = K051960_romoffset + (K051960_spriterombank[0] << 8) +
2097 			((K051960_spriterombank[1] & 0x03) << 16);
2098 	code = (addr & 0x3ffe0) >> 5;
2099 	off1 = addr & 0x1f;
2100 	color = ((K051960_spriterombank[1] & 0xfc) >> 2) + ((K051960_spriterombank[2] & 0x03) << 6);
2101 	pri = 0;
2102 	shadow = color & 0x80;
2103 	(*K051960_callback)(&code,&color,&pri,&shadow);
2104 
2105 	addr = (code << 7) | (off1 << 2) | byte;
2106 	addr &= memory_region_length(K051960_memory_region)-1;
2107 
2108 #if 0
2109 	usrintf_showmessage("%04x: addr %06x",cpu_get_pc(),addr);
2110 #endif
2111 
2112 	return memory_region(K051960_memory_region)[addr];
2113 }
2114 
READ_HANDLER(K051960_r)2115 READ_HANDLER( K051960_r )
2116 {
2117 	if (K051960_readroms)
2118 	{
2119 		/* the 051960 remembers the last address read and uses it when reading the sprite ROMs */
2120 		K051960_romoffset = (offset & 0x3fc) >> 2;
2121 		return K051960_fetchromdata(offset & 3);	/* only 88 Games reads the ROMs from here */
2122 	}
2123 	else
2124 		return K051960_ram[offset];
2125 }
2126 
WRITE_HANDLER(K051960_w)2127 WRITE_HANDLER( K051960_w )
2128 {
2129 	K051960_ram[offset] = data;
2130 }
2131 
READ_HANDLER(K051960_word_r)2132 READ_HANDLER( K051960_word_r )
2133 {
2134 	return K051960_r(offset + 1) | (K051960_r(offset) << 8);
2135 }
2136 
WRITE_HANDLER(K051960_word_w)2137 WRITE_HANDLER( K051960_word_w )
2138 {
2139 	if ((data & 0xff000000) == 0)
2140 		K051960_w(offset,(data >> 8) & 0xff);
2141 	if ((data & 0x00ff0000) == 0)
2142 		K051960_w(offset + 1,data & 0xff);
2143 }
2144 
READ_HANDLER(K051937_r)2145 READ_HANDLER( K051937_r )
2146 {
2147 	if (K051960_readroms && offset >= 4 && offset < 8)
2148 	{
2149 		return K051960_fetchromdata(offset & 3);
2150 	}
2151 	else
2152 	{
2153 		if (offset == 0)
2154 		{
2155 			static int counter;
2156 
2157 			/* some games need bit 0 to pulse */
2158 			return (counter++) & 1;
2159 		}
2160 //logerror("%04x: read unknown 051937 address %x\n",cpu_get_pc(),offset);
2161 		return 0;
2162 	}
2163 }
2164 
WRITE_HANDLER(K051937_w)2165 WRITE_HANDLER( K051937_w )
2166 {
2167 	if (offset == 0)
2168 	{
2169 		/* bit 0 is IRQ enable */
2170 		K051960_irq_enabled = (data & 0x01);
2171 
2172 		/* bit 1: probably FIRQ enable */
2173 
2174 		/* bit 2 is NMI enable */
2175 		K051960_nmi_enabled = (data & 0x04);
2176 
2177 		/* bit 3 = flip screen */
2178 		K051960_spriteflip = data & 0x08;
2179 
2180 		/* bit 4 used by Devastators and TMNT, unknown */
2181 
2182 		/* bit 5 = enable gfx ROM reading */
2183 		K051960_readroms = data & 0x20;
2184 #if VERBOSE
2185 logerror("%04x: write %02x to 051937 address %x\n",cpu_get_pc(),data,offset);
2186 #endif
2187 	}
2188 	else if (offset == 1)
2189 	{
2190 #if 0
2191 	usrintf_showmessage("%04x: write %02x to 051937 address %x",cpu_get_pc(),data,offset);
2192 #endif
2193 //logerror("%04x: write %02x to unknown 051937 address %x\n",cpu_get_pc(),data,offset);
2194 		K051960_force_shadows = data & 0x02;
2195 	}
2196 	else if (offset >= 2 && offset < 5)
2197 	{
2198 		K051960_spriterombank[offset - 2] = data;
2199 	}
2200 	else
2201 	{
2202 #if 0
2203 	usrintf_showmessage("%04x: write %02x to 051937 address %x",cpu_get_pc(),data,offset);
2204 #endif
2205 //logerror("%04x: write %02x to unknown 051937 address %x\n",cpu_get_pc(),data,offset);
2206 	}
2207 }
2208 
READ_HANDLER(K051937_word_r)2209 READ_HANDLER( K051937_word_r )
2210 {
2211 	return K051937_r(offset + 1) | (K051937_r(offset) << 8);
2212 }
2213 
WRITE_HANDLER(K051937_word_w)2214 WRITE_HANDLER( K051937_word_w )
2215 {
2216 	if ((data & 0xff000000) == 0)
2217 		K051937_w(offset,(data >> 8) & 0xff);
2218 	if ((data & 0x00ff0000) == 0)
2219 		K051937_w(offset + 1,data & 0xff);
2220 }
2221 
2222 
2223 /*
2224  * Sprite Format
2225  * ------------------
2226  *
2227  * Byte | Bit(s)   | Use
2228  * -----+-76543210-+----------------
2229  *   0  | x------- | active (show this sprite)
2230  *   0  | -xxxxxxx | priority order
2231  *   1  | xxx----- | sprite size (see below)
2232  *   1  | ---xxxxx | sprite code (high 5 bits)
2233  *   2  | xxxxxxxx | sprite code (low 8 bits)
2234  *   3  | xxxxxxxx | "color", but depends on external connections (see below)
2235  *   4  | xxxxxx-- | zoom y (0 = normal, >0 = shrink)
2236  *   4  | ------x- | flip y
2237  *   4  | -------x | y position (high bit)
2238  *   5  | xxxxxxxx | y position (low 8 bits)
2239  *   6  | xxxxxx-- | zoom x (0 = normal, >0 = shrink)
2240  *   6  | ------x- | flip x
2241  *   6  | -------x | x position (high bit)
2242  *   7  | xxxxxxxx | x position (low 8 bits)
2243  *
2244  * Example of "color" field for Punk Shot:
2245  *   3  | x------- | shadow
2246  *   3  | -xx----- | priority
2247  *   3  | ---x---- | use second gfx ROM bank
2248  *   3  | ----xxxx | color code
2249  *
2250  * shadow enables transparent shadows. Note that it applies to pen 0x0f ONLY.
2251  * The rest of the sprite remains normal.
2252  * Note that Aliens also uses the shadow bit to select the second sprite bank.
2253  */
2254 
K051960_sprites_draw(struct osd_bitmap * bitmap,int min_priority,int max_priority)2255 void K051960_sprites_draw(struct osd_bitmap *bitmap,int min_priority,int max_priority)
2256 {
2257 #define NUM_SPRITES 128
2258 	int offs,pri_code;
2259 	int sortedlist[NUM_SPRITES];
2260 
2261 	for (offs = 0;offs < NUM_SPRITES;offs++)
2262 		sortedlist[offs] = -1;
2263 
2264 	/* prebuild a sorted table */
2265 	for (offs = 0;offs < 0x400;offs += 8)
2266 	{
2267 		if (K051960_ram[offs] & 0x80)
2268 		{
2269 			if (max_priority == -1)	/* draw front to back when using priority buffer */
2270 				sortedlist[(K051960_ram[offs] & 0x7f) ^ 0x7f] = offs;
2271 			else
2272 				sortedlist[K051960_ram[offs] & 0x7f] = offs;
2273 		}
2274 	}
2275 
2276 	for (pri_code = 0;pri_code < NUM_SPRITES;pri_code++)
2277 	{
2278 		int ox,oy,code,color,pri,shadow,size,w,h,x,y,flipx,flipy,zoomx,zoomy;
2279 		/* sprites can be grouped up to 8x8. The draw order is
2280 			 0  1  4  5 16 17 20 21
2281 			 2  3  6  7 18 19 22 23
2282 			 8  9 12 13 24 25 28 29
2283 			10 11 14 15 26 27 30 31
2284 			32 33 36 37 48 49 52 53
2285 			34 35 38 39 50 51 54 55
2286 			40 41 44 45 56 57 60 61
2287 			42 43 46 47 58 59 62 63
2288 		*/
2289 		static int xoffset[8] = { 0, 1, 4, 5, 16, 17, 20, 21 };
2290 		static int yoffset[8] = { 0, 2, 8, 10, 32, 34, 40, 42 };
2291 		static int width[8] =  { 1, 2, 1, 2, 4, 2, 4, 8 };
2292 		static int height[8] = { 1, 1, 2, 2, 2, 4, 4, 8 };
2293 
2294 
2295 		offs = sortedlist[pri_code];
2296 		if (offs == -1) continue;
2297 
2298 		code = K051960_ram[offs+2] + ((K051960_ram[offs+1] & 0x1f) << 8);
2299 		color = K051960_ram[offs+3] & 0xff;
2300 		pri = 0;
2301 		shadow = color & 0x80;
2302 		(*K051960_callback)(&code,&color,&pri,&shadow);
2303 
2304 		if (max_priority != -1)
2305 			if (pri < min_priority || pri > max_priority) continue;
2306 
2307 		size = (K051960_ram[offs+1] & 0xe0) >> 5;
2308 		w = width[size];
2309 		h = height[size];
2310 
2311 		if (w >= 2) code &= ~0x01;
2312 		if (h >= 2) code &= ~0x02;
2313 		if (w >= 4) code &= ~0x04;
2314 		if (h >= 4) code &= ~0x08;
2315 		if (w >= 8) code &= ~0x10;
2316 		if (h >= 8) code &= ~0x20;
2317 
2318 		ox = (256 * K051960_ram[offs+6] + K051960_ram[offs+7]) & 0x01ff;
2319 		oy = 256 - ((256 * K051960_ram[offs+4] + K051960_ram[offs+5]) & 0x01ff);
2320 		flipx = K051960_ram[offs+6] & 0x02;
2321 		flipy = K051960_ram[offs+4] & 0x02;
2322 		zoomx = (K051960_ram[offs+6] & 0xfc) >> 2;
2323 		zoomy = (K051960_ram[offs+4] & 0xfc) >> 2;
2324 		zoomx = 0x10000 / 128 * (128 - zoomx);
2325 		zoomy = 0x10000 / 128 * (128 - zoomy);
2326 
2327 		if (K051960_spriteflip)
2328 		{
2329 			ox = 512 - (zoomx * w >> 12) - ox;
2330 			oy = 256 - (zoomy * h >> 12) - oy;
2331 			flipx = !flipx;
2332 			flipy = !flipy;
2333 		}
2334 
2335 		if (zoomx == 0x10000 && zoomy == 0x10000)
2336 		{
2337 			int sx,sy;
2338 
2339 			for (y = 0;y < h;y++)
2340 			{
2341 				sy = oy + 16 * y;
2342 
2343 				for (x = 0;x < w;x++)
2344 				{
2345 					int c = code;
2346 
2347 					sx = ox + 16 * x;
2348 					if (flipx) c += xoffset[(w-1-x)];
2349 					else c += xoffset[x];
2350 					if (flipy) c += yoffset[(h-1-y)];
2351 					else c += yoffset[y];
2352 
2353 					/* hack to simulate shadow */
2354 					if (K051960_force_shadows || shadow)
2355 					{
2356 						int o = K051960_gfx->colortable[16*color+15];
2357 						K051960_gfx->colortable[16*color+15] = palette_transparent_pen;
2358 						if (max_priority == -1)
2359 							pdrawgfx(bitmap,K051960_gfx,
2360 									c,
2361 									color,
2362 									flipx,flipy,
2363 									sx & 0x1ff,sy,
2364 									&Machine->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,pri);
2365 						else
2366 							drawgfx(bitmap,K051960_gfx,
2367 									c,
2368 									color,
2369 									flipx,flipy,
2370 									sx & 0x1ff,sy,
2371 									&Machine->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001);
2372 						K051960_gfx->colortable[16*color+15] = o;
2373 					}
2374 					else
2375 					{
2376 						if (max_priority == -1)
2377 							pdrawgfx(bitmap,K051960_gfx,
2378 									c,
2379 									color,
2380 									flipx,flipy,
2381 									sx & 0x1ff,sy,
2382 									&Machine->visible_area,TRANSPARENCY_PEN,0,pri);
2383 						else
2384 							drawgfx(bitmap,K051960_gfx,
2385 									c,
2386 									color,
2387 									flipx,flipy,
2388 									sx & 0x1ff,sy,
2389 									&Machine->visible_area,TRANSPARENCY_PEN,0);
2390 					}
2391 				}
2392 			}
2393 		}
2394 		else
2395 		{
2396 			int sx,sy,zw,zh;
2397 
2398 			for (y = 0;y < h;y++)
2399 			{
2400 				sy = oy + ((zoomy * y + (1<<11)) >> 12);
2401 				zh = (oy + ((zoomy * (y+1) + (1<<11)) >> 12)) - sy;
2402 
2403 				for (x = 0;x < w;x++)
2404 				{
2405 					int c = code;
2406 
2407 					sx = ox + ((zoomx * x + (1<<11)) >> 12);
2408 					zw = (ox + ((zoomx * (x+1) + (1<<11)) >> 12)) - sx;
2409 					if (flipx) c += xoffset[(w-1-x)];
2410 					else c += xoffset[x];
2411 					if (flipy) c += yoffset[(h-1-y)];
2412 					else c += yoffset[y];
2413 
2414 					/* hack to simulate shadow */
2415 					if (K051960_force_shadows || shadow)
2416 					{
2417 						int o = K051960_gfx->colortable[16*color+15];
2418 						K051960_gfx->colortable[16*color+15] = palette_transparent_pen;
2419 						if (max_priority == -1)
2420 							pdrawgfxzoom(bitmap,K051960_gfx,
2421 									c,
2422 									color,
2423 									flipx,flipy,
2424 									sx & 0x1ff,sy,
2425 									&Machine->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,
2426 									(zw << 16) / 16,(zh << 16) / 16,pri);
2427 						else
2428 							drawgfxzoom(bitmap,K051960_gfx,
2429 									c,
2430 									color,
2431 									flipx,flipy,
2432 									sx & 0x1ff,sy,
2433 									&Machine->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,
2434 									(zw << 16) / 16,(zh << 16) / 16);
2435 						K051960_gfx->colortable[16*color+15] = o;
2436 					}
2437 					else
2438 					{
2439 						if (max_priority == -1)
2440 							pdrawgfxzoom(bitmap,K051960_gfx,
2441 									c,
2442 									color,
2443 									flipx,flipy,
2444 									sx & 0x1ff,sy,
2445 									&Machine->visible_area,TRANSPARENCY_PEN,0,
2446 									(zw << 16) / 16,(zh << 16) / 16,pri);
2447 						else
2448 							drawgfxzoom(bitmap,K051960_gfx,
2449 									c,
2450 									color,
2451 									flipx,flipy,
2452 									sx & 0x1ff,sy,
2453 									&Machine->visible_area,TRANSPARENCY_PEN,0,
2454 									(zw << 16) / 16,(zh << 16) / 16);
2455 					}
2456 				}
2457 			}
2458 		}
2459 	}
2460 #if 0
2461 if (keyboard_pressed(KEYCODE_D))
2462 {
2463 	FILE *fp;
2464 	fp=fopen("SPRITE.DMP", "w+b");
2465 	if (fp)
2466 	{
2467 		fwrite(K051960_ram, 0x400, 1, fp);
2468 		usrintf_showmessage("saved");
2469 		fclose(fp);
2470 	}
2471 }
2472 #endif
2473 #undef NUM_SPRITES
2474 }
2475 
K051960_mark_sprites_colors(void)2476 void K051960_mark_sprites_colors(void)
2477 {
2478 	int offs,i;
2479 
2480 	unsigned short palette_map[512];
2481 
2482 	memset (palette_map, 0, sizeof (palette_map));
2483 
2484 	/* sprites */
2485 	for (offs = 0x400-8;offs >= 0;offs -= 8)
2486 	{
2487 		if (K051960_ram[offs] & 0x80)
2488 		{
2489 			int code,color,pri,shadow;
2490 
2491 			code = K051960_ram[offs+2] + ((K051960_ram[offs+1] & 0x1f) << 8);
2492 			color = (K051960_ram[offs+3] & 0xff);
2493 			pri = 0;
2494 			shadow = color & 0x80;
2495 			(*K051960_callback)(&code,&color,&pri,&shadow);
2496 			palette_map[color] |= 0xffff;
2497 		}
2498 	}
2499 
2500 	/* now build the final table */
2501 	for (i = 0; i < 512; i++)
2502 	{
2503 		int usage = palette_map[i], j;
2504 		if (usage)
2505 		{
2506 			for (j = 1; j < 16; j++)
2507 				if (usage & (1 << j))
2508 					palette_used_colors[i * 16 + j] |= PALETTE_COLOR_VISIBLE;
2509 		}
2510 	}
2511 }
2512 
K051960_is_IRQ_enabled(void)2513 int K051960_is_IRQ_enabled(void)
2514 {
2515 	return K051960_irq_enabled;
2516 }
2517 
K051960_is_NMI_enabled(void)2518 int K051960_is_NMI_enabled(void)
2519 {
2520 	return K051960_nmi_enabled;
2521 }
2522 
2523 
2524 
2525 
READ_HANDLER(K052109_051960_r)2526 READ_HANDLER( K052109_051960_r )
2527 {
2528 	if (K052109_RMRD_line == CLEAR_LINE)
2529 	{
2530 		if (offset >= 0x3800 && offset < 0x3808)
2531 			return K051937_r(offset - 0x3800);
2532 		else if (offset < 0x3c00)
2533 			return K052109_r(offset);
2534 		else
2535 			return K051960_r(offset - 0x3c00);
2536 	}
2537 	else return K052109_r(offset);
2538 }
2539 
WRITE_HANDLER(K052109_051960_w)2540 WRITE_HANDLER( K052109_051960_w )
2541 {
2542 	if (offset >= 0x3800 && offset < 0x3808)
2543 		K051937_w(offset - 0x3800,data);
2544 	else if (offset < 0x3c00)
2545 		K052109_w(offset,data);
2546 	else
2547 		K051960_w(offset - 0x3c00,data);
2548 }
2549 
2550 
2551 
2552 
2553 
2554 static int K053245_memory_region=2;
2555 static struct GfxElement *K053245_gfx;
2556 static void (*K053245_callback)(int *code,int *color,int *priority);
2557 static int K053244_romoffset,K053244_rombank;
2558 static int K053244_readroms;
2559 static int K053245_flipscreenX,K053245_flipscreenY;
2560 static int K053245_spriteoffsX,K053245_spriteoffsY;
2561 static unsigned char *K053245_ram;
2562 
K053245_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,void (* callback)(int * code,int * color,int * priority))2563 int K053245_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,
2564 		void (*callback)(int *code,int *color,int *priority))
2565 {
2566 	int gfx_index;
2567 	static struct GfxLayout spritelayout =
2568 	{
2569 		16,16,
2570 		0,				/* filled in later */
2571 		4,
2572 		{ 0, 0, 0, 0 },	/* filled in later */
2573 		{ 0, 1, 2, 3, 4, 5, 6, 7,
2574 				8*32+0, 8*32+1, 8*32+2, 8*32+3, 8*32+4, 8*32+5, 8*32+6, 8*32+7 },
2575 		{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32,
2576 				16*32, 17*32, 18*32, 19*32, 20*32, 21*32, 22*32, 23*32 },
2577 		128*8
2578 	};
2579 
2580 
2581 	/* find first empty slot to decode gfx */
2582 	for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
2583 		if (Machine->gfx[gfx_index] == 0)
2584 			break;
2585 	if (gfx_index == MAX_GFX_ELEMENTS)
2586 		return 1;
2587 
2588 	/* tweak the structure for the number of tiles we have */
2589 	spritelayout.total = memory_region_length(gfx_memory_region) / 128;
2590 	spritelayout.planeoffset[0] = plane3 * 8;
2591 	spritelayout.planeoffset[1] = plane2 * 8;
2592 	spritelayout.planeoffset[2] = plane1 * 8;
2593 	spritelayout.planeoffset[3] = plane0 * 8;
2594 
2595 	/* decode the graphics */
2596 	Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&spritelayout);
2597 	if (!Machine->gfx[gfx_index])
2598 		return 1;
2599 
2600 	/* set the color information */
2601 	Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
2602 	Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
2603 
2604 	K053245_memory_region = gfx_memory_region;
2605 	K053245_gfx = Machine->gfx[gfx_index];
2606 	K053245_callback = callback;
2607 	K053244_rombank = 0;
2608 	K053245_ram = (unsigned char*)malloc(0x800);
2609 	if (!K053245_ram) return 1;
2610 
2611 	memset(K053245_ram,0,0x800);
2612 
2613 	return 0;
2614 }
2615 
K053245_vh_stop(void)2616 void K053245_vh_stop(void)
2617 {
2618 	free(K053245_ram);
2619 	K053245_ram = 0;
2620 }
2621 
READ_HANDLER(K053245_word_r)2622 READ_HANDLER( K053245_word_r )
2623 {
2624 	return READ_WORD(&K053245_ram[offset]);
2625 }
2626 
WRITE_HANDLER(K053245_word_w)2627 WRITE_HANDLER( K053245_word_w )
2628 {
2629 	COMBINE_WORD_MEM(&K053245_ram[offset],data);
2630 }
2631 
READ_HANDLER(K053245_r)2632 READ_HANDLER( K053245_r )
2633 {
2634 	int shift = ((offset & 1) ^ 1) << 3;
2635 	return (READ_WORD(&K053245_ram[offset & ~1]) >> shift) & 0xff;
2636 }
2637 
WRITE_HANDLER(K053245_w)2638 WRITE_HANDLER( K053245_w )
2639 {
2640 	int shift = ((offset & 1) ^ 1) << 3;
2641 	offset &= ~1;
2642 	COMBINE_WORD_MEM(&K053245_ram[offset],(0xff000000 >> shift) | ((data & 0xff) << shift));
2643 }
2644 
READ_HANDLER(K053244_r)2645 READ_HANDLER( K053244_r )
2646 {
2647 	if (K053244_readroms && offset >= 0x0c && offset < 0x10)
2648 	{
2649 		int addr;
2650 
2651 
2652 		addr = 0x200000 * K053244_rombank + 4 * (K053244_romoffset & 0x7ffff) + ((offset & 3) ^ 1);
2653 		addr &= memory_region_length(K053245_memory_region)-1;
2654 
2655 #if 0
2656 	usrintf_showmessage("%04x: offset %02x addr %06x",cpu_get_pc(),offset&3,addr);
2657 #endif
2658 
2659 		return memory_region(K053245_memory_region)[addr];
2660 	}
2661 	else
2662 	{
2663 //logerror("%04x: read from unknown 053244 address %x\n",cpu_get_pc(),offset);
2664 		return 0;
2665 	}
2666 }
2667 
WRITE_HANDLER(K053244_w)2668 WRITE_HANDLER( K053244_w )
2669 {
2670 	if (offset == 0x00)
2671 		K053245_spriteoffsX = (K053245_spriteoffsX & 0x00ff) | (data << 8);
2672 	else if (offset == 0x01)
2673 		K053245_spriteoffsX = (K053245_spriteoffsX & 0xff00) | data;
2674 	else if (offset == 0x02)
2675 		K053245_spriteoffsY = (K053245_spriteoffsY & 0x00ff) | (data << 8);
2676 	else if (offset == 0x03)
2677 		K053245_spriteoffsY = (K053245_spriteoffsY & 0xff00) | data;
2678 	else if (offset == 0x05)
2679 	{
2680 		/* bit 0/1 = flip screen */
2681 		K053245_flipscreenX = data & 0x01;
2682 		K053245_flipscreenY = data & 0x02;
2683 
2684 		/* bit 2 = unknown, Parodius uses it */
2685 
2686 		/* bit 4 = enable gfx ROM reading */
2687 		K053244_readroms = data & 0x10;
2688 
2689 		/* bit 5 = unknown, Rollergames uses it */
2690 #if VERBOSE
2691 logerror("%04x: write %02x to 053244 address 5\n",cpu_get_pc(),data);
2692 #endif
2693 	}
2694 	else if (offset >= 0x08 && offset < 0x0c)
2695 	{
2696 		offset = 8*((offset & 0x03) ^ 0x01);
2697 		K053244_romoffset = (K053244_romoffset & ~(0xff << offset)) | (data << offset);
2698 		return;
2699 	}
2700 //	else
2701 //logerror("%04x: write %02x to unknown 053244 address %x\n",cpu_get_pc(),data,offset);
2702 }
2703 
K053244_bankselect(int bank)2704 void K053244_bankselect(int bank)   /* used by TMNT2 for ROM testing */
2705 {
2706 	K053244_rombank = bank;
2707 }
2708 
2709 /*
2710  * Sprite Format
2711  * ------------------
2712  *
2713  * Word | Bit(s)           | Use
2714  * -----+-fedcba9876543210-+----------------
2715  *   0  | x--------------- | active (show this sprite)
2716  *   0  | -x-------------- | maintain aspect ratio (when set, zoom y acts on both axis)
2717  *   0  | --x------------- | flip y
2718  *   0  | ---x------------ | flip x
2719  *   0  | ----xxxx-------- | sprite size (see below)
2720  *   0  | ---------xxxxxxx | priority order
2721  *   1  | --xxxxxxxxxxxxxx | sprite code. We use an additional bit in TMNT2, but this is
2722  *                           probably not accurate (protection related so we can't verify)
2723  *   2  | ------xxxxxxxxxx | y position
2724  *   3  | ------xxxxxxxxxx | x position
2725  *   4  | xxxxxxxxxxxxxxxx | zoom y (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
2726  *   5  | xxxxxxxxxxxxxxxx | zoom x (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
2727  *   6  | ------x--------- | mirror y (top half is drawn as mirror image of the bottom)
2728  *   6  | -------x-------- | mirror x (right half is drawn as mirror image of the left)
2729  *   6  | --------x------- | shadow
2730  *   6  | ---------xxxxxxx | "color", but depends on external connections
2731  *   7  | ---------------- |
2732  *
2733  * shadow enables transparent shadows. Note that it applies to pen 0x0f ONLY.
2734  * The rest of the sprite remains normal.
2735  */
2736 
K053245_sprites_draw(struct osd_bitmap * bitmap)2737 void K053245_sprites_draw(struct osd_bitmap *bitmap)
2738 {
2739 #define NUM_SPRITES 128
2740 	int offs,pri_code;
2741 	int sortedlist[NUM_SPRITES];
2742 
2743 	for (offs = 0;offs < NUM_SPRITES;offs++)
2744 		sortedlist[offs] = -1;
2745 
2746 	/* prebuild a sorted table */
2747 	for (offs = 0;offs < 0x800;offs += 16)
2748 	{
2749 		if (READ_WORD(&K053245_ram[offs]) & 0x8000)
2750 		{
2751 			sortedlist[READ_WORD(&K053245_ram[offs]) & 0x007f] = offs;
2752 		}
2753 	}
2754 
2755 	for (pri_code = NUM_SPRITES-1;pri_code >= 0;pri_code--)
2756 	{
2757 		int ox,oy,color,code,size,w,h,x,y,flipx,flipy,mirrorx,mirrory,zoomx,zoomy,pri;
2758 
2759 
2760 		offs = sortedlist[pri_code];
2761 		if (offs == -1) continue;
2762 
2763 		/* the following changes the sprite draw order from
2764 			 0  1  4  5 16 17 20 21
2765 			 2  3  6  7 18 19 22 23
2766 			 8  9 12 13 24 25 28 29
2767 			10 11 14 15 26 27 30 31
2768 			32 33 36 37 48 49 52 53
2769 			34 35 38 39 50 51 54 55
2770 			40 41 44 45 56 57 60 61
2771 			42 43 46 47 58 59 62 63
2772 
2773 			to
2774 
2775 			 0  1  2  3  4  5  6  7
2776 			 8  9 10 11 12 13 14 15
2777 			16 17 18 19 20 21 22 23
2778 			24 25 26 27 28 29 30 31
2779 			32 33 34 35 36 37 38 39
2780 			40 41 42 43 44 45 46 47
2781 			48 49 50 51 52 53 54 55
2782 			56 57 58 59 60 61 62 63
2783 		*/
2784 
2785 		/* NOTE: from the schematics, it looks like the top 2 bits should be ignored */
2786 		/* (there are not output pins for them), and probably taken from the "color" */
2787 		/* field to do bank switching. However this applies only to TMNT2, with its */
2788 		/* protection mcu creating the sprite table, so we don't know where to fetch */
2789 		/* the bits from. */
2790 		code = READ_WORD(&K053245_ram[offs+0x02]);
2791 		code = ((code & 0xffe1) + ((code & 0x0010) >> 2) + ((code & 0x0008) << 1)
2792 				 + ((code & 0x0004) >> 1) + ((code & 0x0002) << 2));
2793 		color = READ_WORD(&K053245_ram[offs+0x0c]) & 0x00ff;
2794 		pri = 0;
2795 
2796 		(*K053245_callback)(&code,&color,&pri);
2797 
2798 		size = (READ_WORD(&K053245_ram[offs]) & 0x0f00) >> 8;
2799 
2800 		w = 1 << (size & 0x03);
2801 		h = 1 << ((size >> 2) & 0x03);
2802 
2803 		/* zoom control:
2804 		   0x40 = normal scale
2805 		  <0x40 enlarge (0x20 = double size)
2806 		  >0x40 reduce (0x80 = half size)
2807 		*/
2808 		zoomy = READ_WORD(&K053245_ram[offs+0x08]);
2809 		if (zoomy > 0x2000) continue;
2810 		if (zoomy) zoomy = (0x400000+zoomy/2) / zoomy;
2811 		else zoomy = 2 * 0x400000;
2812 		if ((READ_WORD(&K053245_ram[offs]) & 0x4000) == 0)
2813 		{
2814 			zoomx = READ_WORD(&K053245_ram[offs+0x0a]);
2815 			if (zoomx > 0x2000) continue;
2816 			if (zoomx) zoomx = (0x400000+zoomx/2) / zoomx;
2817 //			else zoomx = 2 * 0x400000;
2818 else zoomx = zoomy; /* workaround for TMNT2 */
2819 		}
2820 		else zoomx = zoomy;
2821 
2822 		ox = READ_WORD(&K053245_ram[offs+0x06]) + K053245_spriteoffsX;
2823 		oy = READ_WORD(&K053245_ram[offs+0x04]);
2824 
2825 		flipx = READ_WORD(&K053245_ram[offs]) & 0x1000;
2826 		flipy = READ_WORD(&K053245_ram[offs]) & 0x2000;
2827 		mirrorx = READ_WORD(&K053245_ram[offs+0x0c]) & 0x0100;
2828 		mirrory = READ_WORD(&K053245_ram[offs+0x0c]) & 0x0200;
2829 
2830 		if (K053245_flipscreenX)
2831 		{
2832 			ox = 512 - ox;
2833 			if (!mirrorx) flipx = !flipx;
2834 		}
2835 		if (K053245_flipscreenY)
2836 		{
2837 			oy = -oy;
2838 			if (!mirrory) flipy = !flipy;
2839 		}
2840 
2841 		ox = (ox + 0x5d) & 0x3ff;
2842 		if (ox >= 768) ox -= 1024;
2843 		oy = (-(oy + K053245_spriteoffsY + 0x07)) & 0x3ff;
2844 		if (oy >= 640) oy -= 1024;
2845 
2846 		/* the coordinates given are for the *center* of the sprite */
2847 		ox -= (zoomx * w) >> 13;
2848 		oy -= (zoomy * h) >> 13;
2849 
2850 		for (y = 0;y < h;y++)
2851 		{
2852 			int sx,sy,zw,zh;
2853 
2854 			sy = oy + ((zoomy * y + (1<<11)) >> 12);
2855 			zh = (oy + ((zoomy * (y+1) + (1<<11)) >> 12)) - sy;
2856 
2857 			for (x = 0;x < w;x++)
2858 			{
2859 				int c,fx,fy;
2860 
2861 				sx = ox + ((zoomx * x + (1<<11)) >> 12);
2862 				zw = (ox + ((zoomx * (x+1) + (1<<11)) >> 12)) - sx;
2863 				c = code;
2864 				if (mirrorx)
2865 				{
2866 					if ((flipx == 0) ^ (2*x < w))
2867 					{
2868 						/* mirror left/right */
2869 						c += (w-x-1);
2870 						fx = 1;
2871 					}
2872 					else
2873 					{
2874 						c += x;
2875 						fx = 0;
2876 					}
2877 				}
2878 				else
2879 				{
2880 					if (flipx) c += w-1-x;
2881 					else c += x;
2882 					fx = flipx;
2883 				}
2884 				if (mirrory)
2885 				{
2886 					if ((flipy == 0) ^ (2*y >= h))
2887 					{
2888 						/* mirror top/bottom */
2889 						c += 8*(h-y-1);
2890 						fy = 1;
2891 					}
2892 					else
2893 					{
2894 						c += 8*y;
2895 						fy = 0;
2896 					}
2897 				}
2898 				else
2899 				{
2900 					if (flipy) c += 8*(h-1-y);
2901 					else c += 8*y;
2902 					fy = flipy;
2903 				}
2904 
2905 				/* the sprite can start at any point in the 8x8 grid, but it must stay */
2906 				/* in a 64 entries window, wrapping around at the edges. The animation */
2907 				/* at the end of the saloon level in SUnset Riders breaks otherwise. */
2908 				c = (c & 0x3f) | (code & ~0x3f);
2909 
2910 				if (zoomx == 0x10000 && zoomy == 0x10000)
2911 				{
2912 					/* hack to simulate shadow */
2913 					if (READ_WORD(&K053245_ram[offs+0x0c]) & 0x0080)
2914 					{
2915 						int o = K053245_gfx->colortable[16*color+15];
2916 						K053245_gfx->colortable[16*color+15] = palette_transparent_pen;
2917 						pdrawgfx(bitmap,K053245_gfx,
2918 								c,
2919 								color,
2920 								fx,fy,
2921 								sx,sy,
2922 								&Machine->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,pri);
2923 						K053245_gfx->colortable[16*color+15] = o;
2924 					}
2925 					else
2926 					{
2927 						pdrawgfx(bitmap,K053245_gfx,
2928 								c,
2929 								color,
2930 								fx,fy,
2931 								sx,sy,
2932 								&Machine->visible_area,TRANSPARENCY_PEN,0,pri);
2933 					}
2934 				}
2935 				else
2936 				{
2937 					/* hack to simulate shadow */
2938 					if (READ_WORD(&K053245_ram[offs+0x0c]) & 0x0080)
2939 					{
2940 						int o = K053245_gfx->colortable[16*color+15];
2941 						K053245_gfx->colortable[16*color+15] = palette_transparent_pen;
2942 						pdrawgfxzoom(bitmap,K053245_gfx,
2943 								c,
2944 								color,
2945 								fx,fy,
2946 								sx,sy,
2947 								&Machine->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,
2948 								(zw << 16) / 16,(zh << 16) / 16,pri);
2949 						K053245_gfx->colortable[16*color+15] = o;
2950 					}
2951 					else
2952 					{
2953 						pdrawgfxzoom(bitmap,K053245_gfx,
2954 								c,
2955 								color,
2956 								fx,fy,
2957 								sx,sy,
2958 								&Machine->visible_area,TRANSPARENCY_PEN,0,
2959 								(zw << 16) / 16,(zh << 16) / 16,pri);
2960 					}
2961 				}
2962 			}
2963 		}
2964 	}
2965 #if 0
2966 if (keyboard_pressed(KEYCODE_D))
2967 {
2968 	FILE *fp;
2969 	fp=fopen("SPRITE.DMP", "w+b");
2970 	if (fp)
2971 	{
2972 		fwrite(K053245_ram, 0x800, 1, fp);
2973 		usrintf_showmessage("saved");
2974 		fclose(fp);
2975 	}
2976 }
2977 #endif
2978 #undef NUM_SPRITES
2979 }
2980 
K053245_mark_sprites_colors(void)2981 void K053245_mark_sprites_colors(void)
2982 {
2983 	int offs,i;
2984 
2985 	unsigned short palette_map[512];
2986 
2987 	memset (palette_map, 0, sizeof (palette_map));
2988 
2989 	/* sprites */
2990 	for (offs = 0x800-16;offs >= 0;offs -= 16)
2991 	{
2992 		if (READ_WORD(&K053245_ram[offs]) & 0x8000)
2993 		{
2994 			int code,color,pri;
2995 
2996 			code = READ_WORD(&K053245_ram[offs+0x02]);
2997 			code = ((code & 0xffe1) + ((code & 0x0010) >> 2) + ((code & 0x0008) << 1)
2998 					 + ((code & 0x0004) >> 1) + ((code & 0x0002) << 2));
2999 			color = READ_WORD(&K053245_ram[offs+0x0c]) & 0x00ff;
3000 			pri = 0;
3001 			(*K053245_callback)(&code,&color,&pri);
3002 			palette_map[color] |= 0xffff;
3003 		}
3004 	}
3005 
3006 	/* now build the final table */
3007 	for (i = 0; i < 512; i++)
3008 	{
3009 		int usage = palette_map[i], j;
3010 		if (usage)
3011 		{
3012 			for (j = 1; j < 16; j++)
3013 				if (usage & (1 << j))
3014 					palette_used_colors[i * 16 + j] |= PALETTE_COLOR_VISIBLE;
3015 		}
3016 	}
3017 }
3018 
3019 
3020 
3021 
3022 static int K053247_memory_region;
3023 static struct GfxElement *K053247_gfx;
3024 static void (*K053247_callback)(int *code,int *color,int *priority);
3025 static int K053246_OBJCHA_line;
3026 static int K053246_romoffset;
3027 static int K053247_flipscreenX,K053247_flipscreenY;
3028 static int K053247_spriteoffsX,K053247_spriteoffsY;
3029 static unsigned char *K053247_ram;
3030 static int K053247_irq_enabled;
3031 
3032 
K053247_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,void (* callback)(int * code,int * color,int * priority))3033 int K053247_vh_start(int gfx_memory_region,int plane0,int plane1,int plane2,int plane3,
3034 		void (*callback)(int *code,int *color,int *priority))
3035 {
3036 	int gfx_index;
3037 	static struct GfxLayout spritelayout =
3038 	{
3039 		16,16,
3040 		0,				/* filled in later */
3041 		4,
3042 		{ 0, 0, 0, 0 },	/* filled in later */
3043 		{ 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4,
3044 				10*4, 11*4, 8*4, 9*4, 14*4, 15*4, 12*4, 13*4 },
3045 		{ 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64,
3046 				8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 },
3047 		128*8
3048 	};
3049 
3050 
3051 	/* find first empty slot to decode gfx */
3052 	for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
3053 		if (Machine->gfx[gfx_index] == 0)
3054 			break;
3055 	if (gfx_index == MAX_GFX_ELEMENTS)
3056 		return 1;
3057 
3058 	/* tweak the structure for the number of tiles we have */
3059 	spritelayout.total = memory_region_length(gfx_memory_region) / 128;
3060 	spritelayout.planeoffset[0] = plane0;
3061 	spritelayout.planeoffset[1] = plane1;
3062 	spritelayout.planeoffset[2] = plane2;
3063 	spritelayout.planeoffset[3] = plane3;
3064 
3065 	/* decode the graphics */
3066 	Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&spritelayout);
3067 	if (!Machine->gfx[gfx_index])
3068 		return 1;
3069 
3070 	/* set the color information */
3071 	Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
3072 	Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / 16;
3073 
3074 	K053247_memory_region = gfx_memory_region;
3075 	K053247_gfx = Machine->gfx[gfx_index];
3076 	K053247_callback = callback;
3077 	K053246_OBJCHA_line = CLEAR_LINE;
3078 	K053247_ram = (unsigned char*)malloc(0x1000);
3079 	if (!K053247_ram) return 1;
3080 
3081 	memset(K053247_ram,0,0x1000);
3082 
3083 	return 0;
3084 }
3085 
K053247_vh_stop(void)3086 void K053247_vh_stop(void)
3087 {
3088 	free(K053247_ram);
3089 	K053247_ram = 0;
3090 }
3091 
READ_HANDLER(K053247_word_r)3092 READ_HANDLER( K053247_word_r )
3093 {
3094 	return READ_WORD(&K053247_ram[offset]);
3095 }
3096 
WRITE_HANDLER(K053247_word_w)3097 WRITE_HANDLER( K053247_word_w )
3098 {
3099 	COMBINE_WORD_MEM(&K053247_ram[offset],data);
3100 }
3101 
READ_HANDLER(K053247_r)3102 READ_HANDLER( K053247_r )
3103 {
3104 	int shift = ((offset & 1) ^ 1) << 3;
3105 	return (READ_WORD(&K053247_ram[offset & ~1]) >> shift) & 0xff;
3106 }
3107 
WRITE_HANDLER(K053247_w)3108 WRITE_HANDLER( K053247_w )
3109 {
3110 	int shift = ((offset & 1) ^ 1) << 3;
3111 	offset &= ~1;
3112 	COMBINE_WORD_MEM(&K053247_ram[offset],(0xff000000 >> shift) | ((data & 0xff) << shift));
3113 }
3114 
READ_HANDLER(K053246_r)3115 READ_HANDLER( K053246_r )
3116 {
3117 	if (K053246_OBJCHA_line == ASSERT_LINE)
3118 	{
3119 		int addr;
3120 
3121 
3122 		addr = 2 * K053246_romoffset + ((offset & 1) ^ 1);
3123 		addr &= memory_region_length(K053247_memory_region)-1;
3124 
3125 #if 0
3126 	usrintf_showmessage("%04x: offset %02x addr %06x",cpu_get_pc(),offset,addr);
3127 #endif
3128 
3129 		return memory_region(K053247_memory_region)[addr];
3130 	}
3131 	else
3132 	{
3133 //logerror("%04x: read from unknown 053244 address %x\n",cpu_get_pc(),offset);
3134 		return 0;
3135 	}
3136 }
3137 
WRITE_HANDLER(K053246_w)3138 WRITE_HANDLER( K053246_w )
3139 {
3140 	if (offset == 0x00)
3141 		K053247_spriteoffsX = (K053247_spriteoffsX & 0x00ff) | (data << 8);
3142 	else if (offset == 0x01)
3143 		K053247_spriteoffsX = (K053247_spriteoffsX & 0xff00) | data;
3144 	else if (offset == 0x02)
3145 		K053247_spriteoffsY = (K053247_spriteoffsY & 0x00ff) | (data << 8);
3146 	else if (offset == 0x03)
3147 		K053247_spriteoffsY = (K053247_spriteoffsY & 0xff00) | data;
3148 	else if (offset == 0x05)
3149 	{
3150 		/* bit 0/1 = flip screen */
3151 		K053247_flipscreenX = data & 0x01;
3152 		K053247_flipscreenY = data & 0x02;
3153 
3154 		/* bit 2 = unknown */
3155 
3156 		/* bit 4 = interrupt enable */
3157 		K053247_irq_enabled = data & 0x10;
3158 
3159 		/* bit 5 = unknown */
3160 
3161 //logerror("%04x: write %02x to 053246 address 5\n",cpu_get_pc(),data);
3162 	}
3163 	else if (offset >= 0x04 && offset < 0x08)   /* only 4,6,7 - 5 is handled above */
3164 	{
3165 		offset = 8*(((offset & 0x03) ^ 0x01) - 1);
3166 		K053246_romoffset = (K053246_romoffset & ~(0xff << offset)) | (data << offset);
3167 		return;
3168 	}
3169 //	else
3170 //logerror("%04x: write %02x to unknown 053246 address %x\n",cpu_get_pc(),data,offset);
3171 }
3172 
READ_HANDLER(K053246_word_r)3173 READ_HANDLER( K053246_word_r )
3174 {
3175 	return K053246_r(offset + 1) | (K053246_r(offset) << 8);
3176 }
3177 
WRITE_HANDLER(K053246_word_w)3178 WRITE_HANDLER( K053246_word_w )
3179 {
3180 	if ((data & 0xff000000) == 0)
3181 		K053246_w(offset,(data >> 8) & 0xff);
3182 	if ((data & 0x00ff0000) == 0)
3183 		K053246_w(offset + 1,data & 0xff);
3184 }
3185 
K053246_set_OBJCHA_line(int state)3186 void K053246_set_OBJCHA_line(int state)
3187 {
3188 	K053246_OBJCHA_line = state;
3189 }
3190 
3191 /*
3192  * Sprite Format
3193  * ------------------
3194  *
3195  * Word | Bit(s)           | Use
3196  * -----+-fedcba9876543210-+----------------
3197  *   0  | x--------------- | active (show this sprite)
3198  *   0  | -x-------------- | maintain aspect ratio (when set, zoom y acts on both axis)
3199  *   0  | --x------------- | flip y
3200  *   0  | ---x------------ | flip x
3201  *   0  | ----xxxx-------- | sprite size (see below)
3202  *   0  | ---------xxxxxxx | priority order
3203  *   1  | xxxxxxxxxxxxxxxx | sprite code
3204  *   2  | ------xxxxxxxxxx | y position
3205  *   3  | ------xxxxxxxxxx | x position
3206  *   4  | xxxxxxxxxxxxxxxx | zoom y (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
3207  *   5  | xxxxxxxxxxxxxxxx | zoom x (0x40 = normal, <0x40 = enlarge, >0x40 = reduce)
3208  *   6  | x--------------- | mirror y (top half is drawn as mirror image of the bottom)
3209  *   6  | -x-------------- | mirror x (right half is drawn as mirror image of the left)
3210  *   6  | -----x---------- | shadow
3211  *   6  | xxxxxxxxxxxxxxxx | "color", but depends on external connections
3212  *   7  | ---------------- |
3213  *
3214  * shadow enables transparent shadows. Note that it applies to pen 0x0f ONLY.
3215  * The rest of the sprite remains normal.
3216  */
3217 
K053247_sprites_draw(struct osd_bitmap * bitmap)3218 void K053247_sprites_draw(struct osd_bitmap *bitmap)
3219 {
3220 #define NUM_SPRITES 256
3221 	int offs,pri_code;
3222 	int sortedlist[NUM_SPRITES];
3223 
3224 	for (offs = 0;offs < NUM_SPRITES;offs++)
3225 		sortedlist[offs] = -1;
3226 
3227 	/* prebuild a sorted table */
3228 	for (offs = 0;offs < 0x1000;offs += 16)
3229 	{
3230 //		if (READ_WORD(&K053247_ram[offs]) & 0x8000)
3231 		sortedlist[READ_WORD(&K053247_ram[offs]) & 0x00ff] = offs;
3232 	}
3233 
3234 	for (pri_code = 0;pri_code < NUM_SPRITES;pri_code++)
3235 	{
3236 		int ox,oy,color,code,size,w,h,x,y,xa,ya,flipx,flipy,mirrorx,mirrory,zoomx,zoomy,pri;
3237 		/* sprites can be grouped up to 8x8. The draw order is
3238 			 0  1  4  5 16 17 20 21
3239 			 2  3  6  7 18 19 22 23
3240 			 8  9 12 13 24 25 28 29
3241 			10 11 14 15 26 27 30 31
3242 			32 33 36 37 48 49 52 53
3243 			34 35 38 39 50 51 54 55
3244 			40 41 44 45 56 57 60 61
3245 			42 43 46 47 58 59 62 63
3246 		*/
3247 		static int xoffset[8] = { 0, 1, 4, 5, 16, 17, 20, 21 };
3248 		static int yoffset[8] = { 0, 2, 8, 10, 32, 34, 40, 42 };
3249 		static int offsetkludge;
3250 
3251 
3252 		offs = sortedlist[pri_code];
3253 		if (offs == -1) continue;
3254 
3255 		if ((READ_WORD(&K053247_ram[offs]) & 0x8000) == 0) continue;
3256 
3257 		code = READ_WORD(&K053247_ram[offs+0x02]);
3258 		color = READ_WORD(&K053247_ram[offs+0x0c]);
3259 		pri = 0;
3260 
3261 		(*K053247_callback)(&code,&color,&pri);
3262 
3263 		size = (READ_WORD(&K053247_ram[offs]) & 0x0f00) >> 8;
3264 
3265 		w = 1 << (size & 0x03);
3266 		h = 1 << ((size >> 2) & 0x03);
3267 
3268 		/* the sprite can start at any point in the 8x8 grid. We have to */
3269 		/* adjust the offsets to draw it correctly. Simpsons does this all the time. */
3270 		xa = 0;
3271 		ya = 0;
3272 		if (code & 0x01) xa += 1;
3273 		if (code & 0x02) ya += 1;
3274 		if (code & 0x04) xa += 2;
3275 		if (code & 0x08) ya += 2;
3276 		if (code & 0x10) xa += 4;
3277 		if (code & 0x20) ya += 4;
3278 		code &= ~0x3f;
3279 
3280 
3281 		/* zoom control:
3282 		   0x40 = normal scale
3283 		  <0x40 enlarge (0x20 = double size)
3284 		  >0x40 reduce (0x80 = half size)
3285 		*/
3286 		zoomy = READ_WORD(&K053247_ram[offs+0x08]);
3287 		if (zoomy > 0x2000) continue;
3288 		if (zoomy) zoomy = (0x400000+zoomy/2) / zoomy;
3289 		else zoomy = 2 * 0x400000;
3290 		if ((READ_WORD(&K053247_ram[offs]) & 0x4000) == 0)
3291 		{
3292 			zoomx = READ_WORD(&K053247_ram[offs+0x0a]);
3293 			if (zoomx > 0x2000) continue;
3294 			if (zoomx) zoomx = (0x400000+zoomx/2) / zoomx;
3295 			else zoomx = 2 * 0x400000;
3296 		}
3297 		else zoomx = zoomy;
3298 
3299 		ox = READ_WORD(&K053247_ram[offs+0x06]);
3300 		oy = READ_WORD(&K053247_ram[offs+0x04]);
3301 
3302 /* TODO: it is not known how the global Y offset works */
3303 switch (K053247_spriteoffsY)
3304 {
3305 	case 0x0261:	/* simpsons */
3306 	case 0x0262:	/* simpsons (dreamland) */
3307 	case 0x0263:	/* simpsons (dreamland) */
3308 	case 0x0264:	/* simpsons (dreamland) */
3309 	case 0x0265:	/* simpsons (dreamland) */
3310 	case 0x006d:	/* simpsons flip (dreamland) */
3311 	case 0x006e:	/* simpsons flip (dreamland) */
3312 	case 0x006f:	/* simpsons flip (dreamland) */
3313 	case 0x0070:	/* simpsons flip (dreamland) */
3314 	case 0x0071:	/* simpsons flip */
3315 		offsetkludge = 0x017;
3316 		break;
3317 	case 0x02f7:	/* vendetta (level 4 boss) */
3318 	case 0x02f8:	/* vendetta (level 4 boss) */
3319 	case 0x02f9:	/* vendetta (level 4 boss) */
3320 	case 0x02fa:	/* vendetta */
3321 	case 0x02fb:	/* vendetta (fat guy jumping) */
3322 	case 0x02fc:	/* vendetta (fat guy jumping) */
3323 	case 0x02fd:	/* vendetta (fat guy jumping) */
3324 	case 0x02fe:	/* vendetta (fat guy jumping) */
3325 	case 0x02ff:	/* vendetta (fat guy jumping) */
3326 	case 0x03f7:	/* vendetta flip (level 4 boss) */
3327 	case 0x03f8:	/* vendetta flip (level 4 boss) */
3328 	case 0x03f9:	/* vendetta flip (level 4 boss) */
3329 	case 0x03fa:	/* vendetta flip */
3330 	case 0x03fb:	/* vendetta flip (fat guy jumping) */
3331 	case 0x03fc:	/* vendetta flip (fat guy jumping) */
3332 	case 0x03fd:	/* vendetta flip (fat guy jumping) */
3333 	case 0x03fe:	/* vendetta flip (fat guy jumping) */
3334 	case 0x03ff:	/* vendetta flip (fat guy jumping) */
3335 		offsetkludge = 0x006;
3336 		break;
3337 	case 0x0292:	/* xmen */
3338 	case 0x0072:	/* xmen flip */
3339 		offsetkludge = -0x002;
3340 		break;
3341 	default:
3342 		offsetkludge = 0;
3343 			usrintf_showmessage("unknown spriteoffsY %04x",K053247_spriteoffsY);
3344 		break;
3345 }
3346 
3347 		flipx = READ_WORD(&K053247_ram[offs]) & 0x1000;
3348 		flipy = READ_WORD(&K053247_ram[offs]) & 0x2000;
3349 		mirrorx = READ_WORD(&K053247_ram[offs+0x0c]) & 0x4000;
3350 		mirrory = READ_WORD(&K053247_ram[offs+0x0c]) & 0x8000;
3351 
3352 		if (K053247_flipscreenX)
3353 		{
3354 			ox = -ox;
3355 			if (!mirrorx) flipx = !flipx;
3356 		}
3357 		if (K053247_flipscreenY)
3358 		{
3359 			oy = -oy;
3360 			if (!mirrory) flipy = !flipy;
3361 		}
3362 
3363 		ox = (ox + 0x35 - K053247_spriteoffsX) & 0x3ff;
3364 		if (ox >= 768) ox -= 1024;
3365 		oy = (-(oy + K053247_spriteoffsY + offsetkludge)) & 0x3ff;
3366 		if (oy >= 640) oy -= 1024;
3367 
3368 		/* the coordinates given are for the *center* of the sprite */
3369 		ox -= (zoomx * w) >> 13;
3370 		oy -= (zoomy * h) >> 13;
3371 
3372 		for (y = 0;y < h;y++)
3373 		{
3374 			int sx,sy,zw,zh;
3375 
3376 			sy = oy + ((zoomy * y + (1<<11)) >> 12);
3377 			zh = (oy + ((zoomy * (y+1) + (1<<11)) >> 12)) - sy;
3378 
3379 			for (x = 0;x < w;x++)
3380 			{
3381 				int c,fx,fy;
3382 
3383 				sx = ox + ((zoomx * x + (1<<11)) >> 12);
3384 				zw = (ox + ((zoomx * (x+1) + (1<<11)) >> 12)) - sx;
3385 				c = code;
3386 				if (mirrorx)
3387 				{
3388 					if ((flipx == 0) ^ (2*x < w))
3389 					{
3390 						/* mirror left/right */
3391 						c += xoffset[(w-1-x+xa)&7];
3392 						fx = 1;
3393 					}
3394 					else
3395 					{
3396 						c += xoffset[(x+xa)&7];
3397 						fx = 0;
3398 					}
3399 				}
3400 				else
3401 				{
3402 					if (flipx) c += xoffset[(w-1-x+xa)&7];
3403 					else c += xoffset[(x+xa)&7];
3404 					fx = flipx;
3405 				}
3406 				if (mirrory)
3407 				{
3408 					if ((flipy == 0) ^ (2*y >= h))
3409 					{
3410 						/* mirror top/bottom */
3411 						c += yoffset[(h-1-y+ya)&7];
3412 						fy = 1;
3413 					}
3414 					else
3415 					{
3416 						c += yoffset[(y+ya)&7];
3417 						fy = 0;
3418 					}
3419 				}
3420 				else
3421 				{
3422 					if (flipy) c += yoffset[(h-1-y+ya)&7];
3423 					else c += yoffset[(y+ya)&7];
3424 					fy = flipy;
3425 				}
3426 
3427 				if (zoomx == 0x10000 && zoomy == 0x10000)
3428 				{
3429 					/* hack to simulate shadow */
3430 					if (READ_WORD(&K053247_ram[offs+0x0c]) & 0x0400)
3431 					{
3432 						int o = K053247_gfx->colortable[16*color+15];
3433 						K053247_gfx->colortable[16*color+15] = palette_transparent_pen;
3434 						pdrawgfx(bitmap,K053247_gfx,
3435 								c,
3436 								color,
3437 								fx,fy,
3438 								sx,sy,
3439 								&Machine->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,pri);
3440 						K053247_gfx->colortable[16*color+15] = o;
3441 					}
3442 					else
3443 					{
3444 						pdrawgfx(bitmap,K053247_gfx,
3445 								c,
3446 								color,
3447 								fx,fy,
3448 								sx,sy,
3449 								&Machine->visible_area,TRANSPARENCY_PEN,0,pri);
3450 					}
3451 				}
3452 				else
3453 				{
3454 					/* hack to simulate shadow */
3455 					if (READ_WORD(&K053247_ram[offs+0x0c]) & 0x0400)
3456 					{
3457 						int o = K053247_gfx->colortable[16*color+15];
3458 						K053247_gfx->colortable[16*color+15] = palette_transparent_pen;
3459 						pdrawgfxzoom(bitmap,K053247_gfx,
3460 								c,
3461 								color,
3462 								fx,fy,
3463 								sx,sy,
3464 								&Machine->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,
3465 								(zw << 16) / 16,(zh << 16) / 16,pri);
3466 						K053247_gfx->colortable[16*color+15] = o;
3467 					}
3468 					else
3469 					{
3470 						pdrawgfxzoom(bitmap,K053247_gfx,
3471 								c,
3472 								color,
3473 								fx,fy,
3474 								sx,sy,
3475 								&Machine->visible_area,TRANSPARENCY_PEN,0,
3476 								(zw << 16) / 16,(zh << 16) / 16,pri);
3477 					}
3478 				}
3479 
3480 				if (mirrory && h == 1)  /* Simpsons shadows */
3481 				{
3482 					if (zoomx == 0x10000 && zoomy == 0x10000)
3483 					{
3484 						/* hack to simulate shadow */
3485 						if (READ_WORD(&K053247_ram[offs+0x0c]) & 0x0400)
3486 						{
3487 							int o = K053247_gfx->colortable[16*color+15];
3488 							K053247_gfx->colortable[16*color+15] = palette_transparent_pen;
3489 							pdrawgfx(bitmap,K053247_gfx,
3490 									c,
3491 									color,
3492 									fx,!fy,
3493 									sx,sy,
3494 									&Machine->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,pri);
3495 							K053247_gfx->colortable[16*color+15] = o;
3496 						}
3497 						else
3498 						{
3499 							pdrawgfx(bitmap,K053247_gfx,
3500 									c,
3501 									color,
3502 									fx,!fy,
3503 									sx,sy,
3504 									&Machine->visible_area,TRANSPARENCY_PEN,0,pri);
3505 						}
3506 					}
3507 					else
3508 					{
3509 						/* hack to simulate shadow */
3510 						if (READ_WORD(&K053247_ram[offs+0x0c]) & 0x0400)
3511 						{
3512 							int o = K053247_gfx->colortable[16*color+15];
3513 							K053247_gfx->colortable[16*color+15] = palette_transparent_pen;
3514 							pdrawgfxzoom(bitmap,K053247_gfx,
3515 									c,
3516 									color,
3517 									fx,!fy,
3518 									sx,sy,
3519 									&Machine->visible_area,TRANSPARENCY_PENS,(cpu_getcurrentframe() & 1) ? 0x8001 : 0x0001,
3520 									(zw << 16) / 16,(zh << 16) / 16,pri);
3521 							K053247_gfx->colortable[16*color+15] = o;
3522 						}
3523 						else
3524 						{
3525 							pdrawgfxzoom(bitmap,K053247_gfx,
3526 									c,
3527 									color,
3528 									fx,!fy,
3529 									sx,sy,
3530 									&Machine->visible_area,TRANSPARENCY_PEN,0,
3531 									(zw << 16) / 16,(zh << 16) / 16,pri);
3532 						}
3533 					}
3534 				}
3535 			}
3536 		}
3537 	}
3538 #if 0
3539 if (keyboard_pressed(KEYCODE_D))
3540 {
3541 	FILE *fp;
3542 	fp=fopen("SPRITE.DMP", "w+b");
3543 	if (fp)
3544 	{
3545 		fwrite(K053247_ram, 0x1000, 1, fp);
3546 		usrintf_showmessage("saved");
3547 		fclose(fp);
3548 	}
3549 }
3550 #endif
3551 #undef NUM_SPRITES
3552 }
3553 
K053247_mark_sprites_colors(void)3554 void K053247_mark_sprites_colors(void)
3555 {
3556 	int offs,i;
3557 
3558 	unsigned short palette_map[512];
3559 
3560 	memset (palette_map, 0, sizeof (palette_map));
3561 
3562 	/* sprites */
3563 	for (offs = 0x1000-16;offs >= 0;offs -= 16)
3564 	{
3565 		if (READ_WORD(&K053247_ram[offs]) & 0x8000)
3566 		{
3567 			int code,color,pri;
3568 
3569 			code = READ_WORD(&K053247_ram[offs+0x02]);
3570 			color = READ_WORD(&K053247_ram[offs+0x0c]);
3571 			pri = 0;
3572 			(*K053247_callback)(&code,&color,&pri);
3573 			palette_map[color] |= 0xffff;
3574 		}
3575 	}
3576 
3577 	/* now build the final table */
3578 	for (i = 0; i < 512; i++)
3579 	{
3580 		int usage = palette_map[i], j;
3581 		if (usage)
3582 		{
3583 			for (j = 1; j < 16; j++)
3584 				if (usage & (1 << j))
3585 					palette_used_colors[i * 16 + j] |= PALETTE_COLOR_VISIBLE;
3586 		}
3587 	}
3588 }
3589 
K053247_is_IRQ_enabled(void)3590 int K053247_is_IRQ_enabled(void)
3591 {
3592 	return K053247_irq_enabled;
3593 }
3594 
3595 
3596 #define MAX_K051316 3
3597 
3598 static int K051316_memory_region[MAX_K051316];
3599 static int K051316_gfxnum[MAX_K051316];
3600 static int K051316_wraparound[MAX_K051316];
3601 static int K051316_offset[MAX_K051316][2];
3602 static int K051316_bpp[MAX_K051316];
3603 static void (*K051316_callback[MAX_K051316])(int *code,int *color);
3604 static unsigned char *K051316_ram[MAX_K051316];
3605 static unsigned char K051316_ctrlram[MAX_K051316][16];
3606 static struct tilemap *K051316_tilemap[MAX_K051316];
3607 static int K051316_chip_selected;
3608 
3609 void K051316_vh_stop(int chip);
3610 
3611 /***************************************************************************
3612 
3613   Callbacks for the TileMap code
3614 
3615 ***************************************************************************/
3616 
K051316_preupdate(int chip)3617 static void K051316_preupdate(int chip)
3618 {
3619 	K051316_chip_selected = chip;
3620 }
3621 
K051316_get_tile_info(int tile_index)3622 static void K051316_get_tile_info(int tile_index)
3623 {
3624 	int code = K051316_ram[K051316_chip_selected][tile_index];
3625 	int color = K051316_ram[K051316_chip_selected][tile_index + 0x400];
3626 
3627 	(*K051316_callback[K051316_chip_selected])(&code,&color);
3628 
3629 	SET_TILE_INFO(K051316_gfxnum[K051316_chip_selected],code,color);
3630 }
3631 
3632 
K051316_vh_start(int chip,int gfx_memory_region,int bpp,void (* callback)(int * code,int * color))3633 int K051316_vh_start(int chip, int gfx_memory_region,int bpp,
3634 		void (*callback)(int *code,int *color))
3635 {
3636 	int gfx_index;
3637 
3638 
3639 	/* find first empty slot to decode gfx */
3640 	for (gfx_index = 0; gfx_index < MAX_GFX_ELEMENTS; gfx_index++)
3641 		if (Machine->gfx[gfx_index] == 0)
3642 			break;
3643 	if (gfx_index == MAX_GFX_ELEMENTS)
3644 		return 1;
3645 
3646 	if (bpp == 4)
3647 	{
3648 		static struct GfxLayout charlayout =
3649 		{
3650 			16,16,
3651 			0,				/* filled in later */
3652 			4,
3653 			{ 0, 1, 2, 3 },
3654 			{ 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4,
3655 					8*4, 9*4, 10*4, 11*4, 12*4, 13*4, 14*4, 15*4 },
3656 			{ 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64,
3657 					8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 },
3658 			128*8
3659 		};
3660 
3661 
3662 		/* tweak the structure for the number of tiles we have */
3663 		charlayout.total = memory_region_length(gfx_memory_region) / 128;
3664 
3665 		/* decode the graphics */
3666 		Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&charlayout);
3667 	}
3668 	else if (bpp == 7)
3669 	{
3670 		static struct GfxLayout charlayout =
3671 		{
3672 			16,16,
3673 			0,				/* filled in later */
3674 			7,
3675 			{ 1, 2, 3, 4, 5, 6, 7 },
3676 			{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8,
3677 					8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 },
3678 			{ 0*128, 1*128, 2*128, 3*128, 4*128, 5*128, 6*128, 7*128,
3679 					8*128, 9*128, 10*128, 11*128, 12*128, 13*128, 14*128, 15*128 },
3680 			256*8
3681 		};
3682 
3683 
3684 		/* tweak the structure for the number of tiles we have */
3685 		charlayout.total = memory_region_length(gfx_memory_region) / 256;
3686 
3687 		/* decode the graphics */
3688 		Machine->gfx[gfx_index] = decodegfx(memory_region(gfx_memory_region),&charlayout);
3689 	}
3690 	else
3691 	{
3692 //logerror("K051316_vh_start supports only 4 or 7 bpp\n");
3693 		return 1;
3694 	}
3695 
3696 	if (!Machine->gfx[gfx_index])
3697 		return 1;
3698 
3699 	/* set the color information */
3700 	Machine->gfx[gfx_index]->colortable = Machine->remapped_colortable;
3701 	Machine->gfx[gfx_index]->total_colors = Machine->drv->color_table_len / (1 << bpp);
3702 
3703 	K051316_memory_region[chip] = gfx_memory_region;
3704 	K051316_gfxnum[chip] = gfx_index;
3705 	K051316_bpp[chip] = bpp;
3706 	K051316_callback[chip] = callback;
3707 
3708 	K051316_tilemap[chip] = tilemap_create(K051316_get_tile_info,tilemap_scan_rows,TILEMAP_OPAQUE,16,16,32,32);
3709 
3710 	K051316_ram[chip] = (unsigned char*)malloc(0x800);
3711 
3712 	if (!K051316_ram[chip] || !K051316_tilemap[chip])
3713 	{
3714 		K051316_vh_stop(chip);
3715 		return 1;
3716 	}
3717 
3718 	tilemap_set_clip(K051316_tilemap[chip],0);
3719 
3720 	K051316_wraparound[chip] = 0;	/* default = no wraparound */
3721 	K051316_offset[chip][0] = K051316_offset[chip][1] = 0;
3722 
3723 	return 0;
3724 }
3725 
K051316_vh_start_0(int gfx_memory_region,int bpp,void (* callback)(int * code,int * color))3726 int K051316_vh_start_0(int gfx_memory_region,int bpp,
3727 		void (*callback)(int *code,int *color))
3728 {
3729 	return K051316_vh_start(0,gfx_memory_region,bpp,callback);
3730 }
3731 
K051316_vh_start_1(int gfx_memory_region,int bpp,void (* callback)(int * code,int * color))3732 int K051316_vh_start_1(int gfx_memory_region,int bpp,
3733 		void (*callback)(int *code,int *color))
3734 {
3735 	return K051316_vh_start(1,gfx_memory_region,bpp,callback);
3736 }
3737 
K051316_vh_start_2(int gfx_memory_region,int bpp,void (* callback)(int * code,int * color))3738 int K051316_vh_start_2(int gfx_memory_region,int bpp,
3739 		void (*callback)(int *code,int *color))
3740 {
3741 	return K051316_vh_start(2,gfx_memory_region,bpp,callback);
3742 }
3743 
3744 
K051316_vh_stop(int chip)3745 void K051316_vh_stop(int chip)
3746 {
3747 	free(K051316_ram[chip]);
3748 	K051316_ram[chip] = 0;
3749 }
3750 
K051316_vh_stop_0(void)3751 void K051316_vh_stop_0(void)
3752 {
3753 	K051316_vh_stop(0);
3754 }
3755 
K051316_vh_stop_1(void)3756 void K051316_vh_stop_1(void)
3757 {
3758 	K051316_vh_stop(1);
3759 }
3760 
K051316_vh_stop_2(void)3761 void K051316_vh_stop_2(void)
3762 {
3763 	K051316_vh_stop(2);
3764 }
3765 
K051316_r(int chip,int offset)3766 int K051316_r(int chip, int offset)
3767 {
3768 	return K051316_ram[chip][offset];
3769 }
3770 
READ_HANDLER(K051316_0_r)3771 READ_HANDLER( K051316_0_r )
3772 {
3773 	return K051316_r(0, offset);
3774 }
3775 
READ_HANDLER(K051316_1_r)3776 READ_HANDLER( K051316_1_r )
3777 {
3778 	return K051316_r(1, offset);
3779 }
3780 
READ_HANDLER(K051316_2_r)3781 READ_HANDLER( K051316_2_r )
3782 {
3783 	return K051316_r(2, offset);
3784 }
3785 
3786 
K051316_w(int chip,int offset,int data)3787 void K051316_w(int chip,int offset,int data)
3788 {
3789 	if (K051316_ram[chip][offset] != data)
3790 	{
3791 		K051316_ram[chip][offset] = data;
3792 		tilemap_mark_tile_dirty(K051316_tilemap[chip],offset & 0x3ff);
3793 	}
3794 }
3795 
WRITE_HANDLER(K051316_0_w)3796 WRITE_HANDLER( K051316_0_w )
3797 {
3798 	K051316_w(0,offset,data);
3799 }
3800 
WRITE_HANDLER(K051316_1_w)3801 WRITE_HANDLER( K051316_1_w )
3802 {
3803 	K051316_w(1,offset,data);
3804 }
3805 
WRITE_HANDLER(K051316_2_w)3806 WRITE_HANDLER( K051316_2_w )
3807 {
3808 	K051316_w(2,offset,data);
3809 }
3810 
3811 
K051316_rom_r(int chip,int offset)3812 int K051316_rom_r(int chip, int offset)
3813 {
3814 	if ((K051316_ctrlram[chip][0x0e] & 0x01) == 0)
3815 	{
3816 		int addr;
3817 
3818 		addr = offset + (K051316_ctrlram[chip][0x0c] << 11) + (K051316_ctrlram[chip][0x0d] << 19);
3819 		if (K051316_bpp[chip] <= 4) addr /= 2;
3820 		addr &= memory_region_length(K051316_memory_region[chip])-1;
3821 
3822 #if 0
3823 	usrintf_showmessage("%04x: offset %04x addr %04x",cpu_get_pc(),offset,addr);
3824 #endif
3825 
3826 		return memory_region(K051316_memory_region[chip])[addr];
3827 	}
3828 	else
3829 	{
3830 //logerror("%04x: read 051316 ROM offset %04x but reg 0x0c bit 0 not clear\n",cpu_get_pc(),offset);
3831 		return 0;
3832 	}
3833 }
3834 
READ_HANDLER(K051316_rom_0_r)3835 READ_HANDLER( K051316_rom_0_r )
3836 {
3837 	return K051316_rom_r(0,offset);
3838 }
3839 
READ_HANDLER(K051316_rom_1_r)3840 READ_HANDLER( K051316_rom_1_r )
3841 {
3842 	return K051316_rom_r(1,offset);
3843 }
3844 
READ_HANDLER(K051316_rom_2_r)3845 READ_HANDLER( K051316_rom_2_r )
3846 {
3847 	return K051316_rom_r(2,offset);
3848 }
3849 
3850 
3851 
K051316_ctrl_w(int chip,int offset,int data)3852 void K051316_ctrl_w(int chip,int offset,int data)
3853 {
3854 	K051316_ctrlram[chip][offset] = data;
3855 //if (offset >= 0x0c) logerror("%04x: write %02x to 051316 reg %x\n",cpu_get_pc(),data,offset);
3856 }
3857 
WRITE_HANDLER(K051316_ctrl_0_w)3858 WRITE_HANDLER( K051316_ctrl_0_w )
3859 {
3860 	K051316_ctrl_w(0,offset,data);
3861 }
3862 
WRITE_HANDLER(K051316_ctrl_1_w)3863 WRITE_HANDLER( K051316_ctrl_1_w )
3864 {
3865 	K051316_ctrl_w(1,offset,data);
3866 }
3867 
WRITE_HANDLER(K051316_ctrl_2_w)3868 WRITE_HANDLER( K051316_ctrl_2_w )
3869 {
3870 	K051316_ctrl_w(2,offset,data);
3871 }
3872 
K051316_wraparound_enable(int chip,int status)3873 void K051316_wraparound_enable(int chip, int status)
3874 {
3875 	K051316_wraparound[chip] = status;
3876 }
3877 
K051316_set_offset(int chip,int xoffs,int yoffs)3878 void K051316_set_offset(int chip, int xoffs, int yoffs)
3879 {
3880 	K051316_offset[chip][0] = xoffs;
3881 	K051316_offset[chip][1] = yoffs;
3882 }
3883 
K051316_tilemap_update(int chip)3884 void K051316_tilemap_update(int chip)
3885 {
3886 	K051316_preupdate(chip);
3887 	tilemap_update(K051316_tilemap[chip]);
3888 }
3889 
K051316_tilemap_update_0(void)3890 void K051316_tilemap_update_0(void)
3891 {
3892 	K051316_tilemap_update(0);
3893 }
3894 
K051316_tilemap_update_1(void)3895 void K051316_tilemap_update_1(void)
3896 {
3897 	K051316_tilemap_update(1);
3898 }
3899 
K051316_tilemap_update_2(void)3900 void K051316_tilemap_update_2(void)
3901 {
3902 	K051316_tilemap_update(2);
3903 }
3904 
3905 
K051316_zoom_draw(int chip,struct osd_bitmap * bitmap,UINT32 priority)3906 void K051316_zoom_draw(int chip, struct osd_bitmap *bitmap,UINT32 priority)
3907 {
3908 	UINT32 startx,starty;
3909 	int incxx,incxy,incyx,incyy;
3910 	struct osd_bitmap *srcbitmap = K051316_tilemap[chip]->pixmap;
3911 
3912 	startx = 256 * ((INT16)(256 * K051316_ctrlram[chip][0x00] + K051316_ctrlram[chip][0x01]));
3913 	incxx  =        (INT16)(256 * K051316_ctrlram[chip][0x02] + K051316_ctrlram[chip][0x03]);
3914 	incyx  =        (INT16)(256 * K051316_ctrlram[chip][0x04] + K051316_ctrlram[chip][0x05]);
3915 	starty = 256 * ((INT16)(256 * K051316_ctrlram[chip][0x06] + K051316_ctrlram[chip][0x07]));
3916 	incxy  =        (INT16)(256 * K051316_ctrlram[chip][0x08] + K051316_ctrlram[chip][0x09]);
3917 	incyy  =        (INT16)(256 * K051316_ctrlram[chip][0x0a] + K051316_ctrlram[chip][0x0b]);
3918 
3919 	startx -= (16 + K051316_offset[chip][1]) * incyx;
3920 	starty -= (16 + K051316_offset[chip][1]) * incyy;
3921 
3922 	startx -= (89 + K051316_offset[chip][0]) * incxx;
3923 	starty -= (89 + K051316_offset[chip][0]) * incxy;
3924 
3925 	copyrozbitmap(bitmap,srcbitmap,startx << 5,starty << 5,
3926 			incxx << 5,incxy << 5,incyx << 5,incyy << 5,K051316_wraparound[chip],
3927 			&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen,priority);
3928 #if 0
3929 	usrintf_showmessage("%02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x",
3930 			K051316_ctrlram[chip][0x00],
3931 			K051316_ctrlram[chip][0x01],
3932 			K051316_ctrlram[chip][0x02],
3933 			K051316_ctrlram[chip][0x03],
3934 			K051316_ctrlram[chip][0x04],
3935 			K051316_ctrlram[chip][0x05],
3936 			K051316_ctrlram[chip][0x06],
3937 			K051316_ctrlram[chip][0x07],
3938 			K051316_ctrlram[chip][0x08],
3939 			K051316_ctrlram[chip][0x09],
3940 			K051316_ctrlram[chip][0x0a],
3941 			K051316_ctrlram[chip][0x0b],
3942 			K051316_ctrlram[chip][0x0c],	/* bank for ROM testing */
3943 			K051316_ctrlram[chip][0x0d],
3944 			K051316_ctrlram[chip][0x0e],	/* 0 = test ROMs */
3945 			K051316_ctrlram[chip][0x0f]);
3946 #endif
3947 }
3948 
K051316_zoom_draw_0(struct osd_bitmap * bitmap,UINT32 priority)3949 void K051316_zoom_draw_0(struct osd_bitmap *bitmap,UINT32 priority)
3950 {
3951 	K051316_zoom_draw(0,bitmap,priority);
3952 }
3953 
K051316_zoom_draw_1(struct osd_bitmap * bitmap,UINT32 priority)3954 void K051316_zoom_draw_1(struct osd_bitmap *bitmap,UINT32 priority)
3955 {
3956 	K051316_zoom_draw(1,bitmap,priority);
3957 }
3958 
K051316_zoom_draw_2(struct osd_bitmap * bitmap,UINT32 priority)3959 void K051316_zoom_draw_2(struct osd_bitmap *bitmap,UINT32 priority)
3960 {
3961 	K051316_zoom_draw(2,bitmap,priority);
3962 }
3963 
3964 
3965 
3966 
3967 static unsigned char K053251_ram[16];
3968 static int K053251_palette_index[5];
3969 
WRITE_HANDLER(K053251_w)3970 WRITE_HANDLER( K053251_w )
3971 {
3972 	data &= 0x3f;
3973 
3974 	if (K053251_ram[offset] != data)
3975 	{
3976 		K053251_ram[offset] = data;
3977 		if (offset == 9)
3978 		{
3979 			/* palette base index */
3980 			K053251_palette_index[0] = 32 * ((data >> 0) & 0x03);
3981 			K053251_palette_index[1] = 32 * ((data >> 2) & 0x03);
3982 			K053251_palette_index[2] = 32 * ((data >> 4) & 0x03);
3983 			tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
3984 		}
3985 		else if (offset == 10)
3986 		{
3987 			/* palette base index */
3988 			K053251_palette_index[3] = 16 * ((data >> 0) & 0x07);
3989 			K053251_palette_index[4] = 16 * ((data >> 3) & 0x07);
3990 			tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
3991 		}
3992 #if 0
3993 else
3994 {
3995 logerror("%04x: write %02x to K053251 register %04x\n",cpu_get_pc(),data&0xff,offset);
3996 usrintf_showmessage("pri = %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x",
3997 	K053251_ram[0],K053251_ram[1],K053251_ram[2],K053251_ram[3],
3998 	K053251_ram[4],K053251_ram[5],K053251_ram[6],K053251_ram[7],
3999 	K053251_ram[8],K053251_ram[9],K053251_ram[10],K053251_ram[11],
4000 	K053251_ram[12],K053251_ram[13],K053251_ram[14],K053251_ram[15]
4001 	);
4002 }
4003 #endif
4004 	}
4005 }
4006 
K053251_get_priority(int ci)4007 int K053251_get_priority(int ci)
4008 {
4009 	return K053251_ram[ci];
4010 }
4011 
K053251_get_palette_index(int ci)4012 int K053251_get_palette_index(int ci)
4013 {
4014 	return K053251_palette_index[ci];
4015 }
4016 
4017 
4018 
4019 static unsigned char K054000_ram[0x20];
4020 
WRITE_HANDLER(K054000_w)4021 WRITE_HANDLER( K054000_w )
4022 {
4023 #if VERBOSE
4024 logerror("%04x: write %02x to 054000 address %02x\n",cpu_get_pc(),data,offset);
4025 #endif
4026 
4027 	K054000_ram[offset] = data;
4028 }
4029 
READ_HANDLER(K054000_r)4030 READ_HANDLER( K054000_r )
4031 {
4032 	int Acx,Acy,Aax,Aay;
4033 	int Bcx,Bcy,Bax,Bay;
4034 
4035 
4036 #if VERBOSE
4037 logerror("%04x: read 054000 address %02x\n",cpu_get_pc(),offset);
4038 #endif
4039 
4040 	if (offset != 0x18) return 0;
4041 
4042 
4043 	Acx = (K054000_ram[0x01] << 16) | (K054000_ram[0x02] << 8) | K054000_ram[0x03];
4044 	Acy = (K054000_ram[0x09] << 16) | (K054000_ram[0x0a] << 8) | K054000_ram[0x0b];
4045 /* TODO: this is a hack to make thndrx2 pass the startup check. It is certainly wrong. */
4046 if (K054000_ram[0x04] == 0xff) Acx+=3;
4047 if (K054000_ram[0x0c] == 0xff) Acy+=3;
4048 	Aax = K054000_ram[0x06] + 1;
4049 	Aay = K054000_ram[0x07] + 1;
4050 
4051 	Bcx = (K054000_ram[0x15] << 16) | (K054000_ram[0x16] << 8) | K054000_ram[0x17];
4052 	Bcy = (K054000_ram[0x11] << 16) | (K054000_ram[0x12] << 8) | K054000_ram[0x13];
4053 	Bax = K054000_ram[0x0e] + 1;
4054 	Bay = K054000_ram[0x0f] + 1;
4055 
4056 	if (Acx + Aax < Bcx - Bax)
4057 		return 1;
4058 
4059 	if (Bcx + Bax < Acx - Aax)
4060 		return 1;
4061 
4062 	if (Acy + Aay < Bcy - Bay)
4063 		return 1;
4064 
4065 	if (Bcy + Bay < Acy - Aay)
4066 		return 1;
4067 
4068 	return 0;
4069 }
4070 
4071 
4072 
4073 static unsigned char K051733_ram[0x20];
4074 
WRITE_HANDLER(K051733_w)4075 WRITE_HANDLER( K051733_w )
4076 {
4077 #if VERBOSE
4078 logerror("%04x: write %02x to 051733 address %02x\n",cpu_get_pc(),data,offset);
4079 #endif
4080 
4081 	K051733_ram[offset] = data;
4082 }
4083 
READ_HANDLER(K051733_r)4084 READ_HANDLER( K051733_r )
4085 {
4086 	int op1 = (K051733_ram[0x00] << 8) | K051733_ram[0x01];
4087 	int op2 = (K051733_ram[0x02] << 8) | K051733_ram[0x03];
4088 
4089 	int rad = (K051733_ram[0x06] << 8) | K051733_ram[0x07];
4090 	int yobj1c = (K051733_ram[0x08] << 8) | K051733_ram[0x09];
4091 	int xobj1c = (K051733_ram[0x0a] << 8) | K051733_ram[0x0b];
4092 	int yobj2c = (K051733_ram[0x0c] << 8) | K051733_ram[0x0d];
4093 	int xobj2c = (K051733_ram[0x0e] << 8) | K051733_ram[0x0f];
4094 
4095 #if VERBOSE
4096 logerror("%04x: read 051733 address %02x\n",cpu_get_pc(),offset);
4097 #endif
4098 
4099 	switch(offset){
4100 		case 0x00:
4101 			if (op2) return	((op1/op2) >> 8);
4102 			else return 0xff;
4103 		case 0x01:
4104 			if (op2) return	op1/op2;
4105 			else return 0xff;
4106 
4107 		/* this is completely unverified */
4108 		case 0x02:
4109 			if (op2) return	((op1%op2) >> 8);
4110 			else return 0xff;
4111 		case 0x03:
4112 			if (op2) return	op1%op2;
4113 			else return 0xff;
4114 
4115 		case 0x07:{
4116 			if (xobj1c + rad < xobj2c - rad)
4117 				return 0x80;
4118 
4119 			if (xobj2c + rad < xobj1c - rad)
4120 				return 0x80;
4121 
4122 			if (yobj1c + rad < yobj2c - rad)
4123 				return 0x80;
4124 
4125 			if (yobj2c + rad < yobj1c - rad)
4126 				return 0x80;
4127 
4128 			return 0;
4129 		}
4130 		default:
4131 			return K051733_ram[offset];
4132 	}
4133 }
4134