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