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