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