another missing from konicdev split (nw)

This commit is contained in:
Scott Stone 2013-07-11 17:54:40 +00:00
parent 97e61103cb
commit 817df6f79e
2 changed files with 356 additions and 0 deletions

1
.gitattributes vendored
View File

@ -5525,6 +5525,7 @@ src/mame/video/jalblend.c svneol=native#text/plain
src/mame/video/jalblend.h svneol=native#text/plain
src/mame/video/jedi.c svneol=native#text/plain
src/mame/video/jpmimpct.c svneol=native#text/plain
src/mame/video/k007121.c svneol=native#text/plain
src/mame/video/k007121.h svneol=native#text/plain
src/mame/video/k007342.c svneol=native#text/plain
src/mame/video/k007342.h svneol=native#text/plain

355
src/mame/video/k007121.c Normal file
View File

@ -0,0 +1,355 @@
/*
Konami 007121
------
This is an interesting beast. It is an evolution of the 005885, with more
features. Many games use two of these in pair.
It manages sprites and two 32x32 tilemaps. The tilemaps can be joined to form
a single 64x32 one, or one of them can be moved to the side of screen, giving
a high score display suitable for vertical games.
The chip also generates clock and interrupt signals suitable for a 6809.
It uses 0x2000 bytes of RAM for the tilemaps and sprites, and an additional
0x100 bytes, maybe for scroll RAM and line buffers. The maximum addressable
ROM is 0x80000 bytes (addressed 16 bits at a time). Tile and sprite data both
come from the same ROM space.
Two 256x4 lookup PROMs are also used to increase the color combinations.
All tilemap / sprite priority handling is done internally and the chip exports
7 bits of color code, composed of 2 bits of palette bank, 1 bit indicating tile
or sprite, and 4 bits of ROM data remapped through the PROM.
inputs:
- address lines (A0-A13)
- data lines (DB0-DB7)
- misc interface stuff
- data from the gfx ROMs (RDL0-RDL7, RDU0-RDU7)
- data from the tile lookup PROMs (VCD0-VCD3)
- data from the sprite lookup PROMs (OCD0-OCD3)
outputs:
- address lines for tilemap RAM (AX0-AX12)
- data lines for tilemap RAM (VO0-VO7)
- address lines for the small RAM (FA0-FA7)
- data lines for the small RAM (FD0-FD7)
- address lines for the gfx ROMs (R0-R17)
- address lines for the tile lookup PROMs (VCF0-VCF3, VCB0-VCB3)
- address lines for the sprite lookup PROMs (OCB0-OCB3, OCF0-OCF3)
- NNMI, NIRQ, NFIR, NE, NQ for the main CPU
- misc interface stuff
- color code to be output on screen (COA0-COA6)
control registers
000: scroll x (low 8 bits)
001: -------x scroll x (high bit)
------x- enable rowscroll? (combatsc)
----x--- this probably selects an alternate screen layout used in combat
school where tilemap #2 is overlayed on front and doesn't scroll.
The 32 lines of the front layer can be individually turned on or
off using the second 32 bytes of scroll RAM.
002: scroll y
003: -------x bit 13 of the tile code
------x- unknown (contra)
-----x-- might be sprite / tilemap priority (0 = sprites have priority)
(combat school, contra, haunted castle(0/1), labyrunr)
----x--- selects sprite buffer (and makes a copy to a private buffer?)
---x---- screen layout selector:
when this is set, 5 columns are added on the left of the screen
(that means 5 rows at the top for vertical games), and the
rightmost 2 columns are chopped away.
Tilemap #2 is used to display the 5 additional columns on the
left. The rest of tilemap #2 is not used and can be used as work
RAM by the program.
The visible area becomes 280x224.
Note that labyrunr changes this at runtime, setting it during
gameplay and resetting it on the title screen and crosshatch.
--x----- might be sprite / tilemap priority (0 = sprites have priority)
(combat school, contra, haunted castle(0/1), labyrunr)
-x------ Chops away the leftmost and rightmost columns, switching the
visible area from 256 to 240 pixels. This is used by combatsc on
the scrolling stages, and by labyrunr on the title screen.
At first I thought that this enabled an extra bank of 0x40
sprites, needed by combatsc, but labyrunr proves that this is not
the case
x------- unknown (contra)
004: ----xxxx bits 9-12 of the tile code. Only the bits enabled by the following
mask are actually used, and replace the ones selected by register
005.
xxxx---- mask enabling the above bits
005: selects where in the attribute byte to pick bits 9-12 of the tile code,
output to pins R12-R15. The bit of the attribute byte to use is the
specified bit (0-3) + 3, that is one of bits 3-6. Bit 7 is hardcoded as
bit 8 of the code. Bits 0-2 are used for the color, however note that
some games use bit 3 as well (see below).
------xx attribute bit to use for tile code bit 9
----xx-- attribute bit to use for tile code bit 10
--xx---- attribute bit to use for tile code bit 11
xx------ attribute bit to use for tile code bit 12
006: ----xxxx select additional effect for bits 3-6 of the tile attribute (the
same ones indexed by register 005). Note that an attribute bit
can therefore be used at the same time to be BOTH a tile code bit
and an additional effect.
-------x bit 3 of attribute is bit 3 of color (combatsc, fastlane, flkatck)
------x- bit 4 of attribute is tile flip X (assumption - no game uses this)
-----x-- bit 5 of attribute is tile flip Y (flkatck)
----x--- bit 6 of attribute is tile priority over sprites (combatsc, hcastle,
labyrunr)
Note that hcastle sets this bit for layer 0, and bit 6 of the
attribute is also used as bit 12 of the tile code, however that
bit is ALWAYS set throughout the game.
combatsc uses the bit in the "graduation" scene during attract mode,
to place soldiers behind the stand.
Use in labyrunr has not been investigated yet.
--xx---- palette bank (both tiles and sprites, see contra)
007: -------x nmi enable
------x- irq enable
-----x-- firq enable
----x--- flip screen
---x---- unknown (contra, labyrunr)
*/
#include "emu.h"
#include "k007121.h"
#include "konami_helper.h"
#define VERBOSE 0
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
const device_type K007121 = &device_creator<k007121_device>;
k007121_device::k007121_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, K007121, "Konami 007121", tag, owner, clock, "k007121", __FILE__),
m_flipscreen(0)
{
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void k007121_device::device_config_complete()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void k007121_device::device_start()
{
save_item(NAME(m_ctrlram));
save_item(NAME(m_flipscreen));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void k007121_device::device_reset()
{
int i;
m_flipscreen = 0;
for (i = 0; i < 8; i++)
m_ctrlram[i] = 0;
}
/*****************************************************************************
DEVICE HANDLERS
*****************************************************************************/
READ8_MEMBER( k007121_device::ctrlram_r )
{
assert(offset < 8);
return m_ctrlram[offset];
}
WRITE8_MEMBER( k007121_device::ctrl_w )
{
assert(offset < 8);
switch (offset)
{
case 6:
/* palette bank change */
if ((m_ctrlram[offset] & 0x30) != (data & 0x30))
space.machine().tilemap().mark_all_dirty();
break;
case 7:
m_flipscreen = data & 0x08;
break;
}
m_ctrlram[offset] = data;
}
/*
* Sprite Format
* ------------------
*
* There are 0x40 sprites, each one using 5 bytes. However the number of
* sprites can be increased to 0x80 with a control register (Combat School
* sets it on and off during the game).
*
* Byte | Bit(s) | Use
* -----+-76543210-+----------------
* 0 | xxxxxxxx | sprite code
* 1 | xxxx---- | color
* 1 | ----xx-- | sprite code low 2 bits for 16x8/8x8 sprites
* 1 | ------xx | sprite code bank bits 1/0
* 2 | xxxxxxxx | y position
* 3 | xxxxxxxx | x position (low 8 bits)
* 4 | xx------ | sprite code bank bits 3/2
* 4 | --x----- | flip y
* 4 | ---x---- | flip x
* 4 | ----xxx- | sprite size 000=16x16 001=16x8 010=8x16 011=8x8 100=32x32
* 4 | -------x | x position (high bit)
*
* Flack Attack uses a different, "wider" layout with 32 bytes per sprite,
* mapped as follows, and the priority order is reversed. Maybe it is a
* compatibility mode with an older custom IC. It is not known how this
* alternate layout is selected.
*
* 0 -> e
* 1 -> f
* 2 -> 6
* 3 -> 4
* 4 -> 8
*
*/
void k007121_device::sprites_draw( bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, colortable_t *ctable,
const UINT8 *source, int base_color, int global_x_offset, int bank_base, UINT32 pri_mask )
{
// gfx_element *gfx = gfxs[chip];
bitmap_ind8 &priority_bitmap = gfx->machine().priority_bitmap;
int flipscreen = m_flipscreen;
int i, num, inc, offs[5];
int is_flakatck = (ctable == NULL);
if (is_flakatck)
{
num = 0x40;
inc = -0x20;
source += 0x3f * 0x20;
offs[0] = 0x0e;
offs[1] = 0x0f;
offs[2] = 0x06;
offs[3] = 0x04;
offs[4] = 0x08;
}
else /* all others */
{
/* TODO: sprite limit is supposed to be per-line! (check MT #00185) */
num = 0x40;
//num = (k007121->ctrlram[0x03] & 0x40) ? 0x80 : 0x40; /* WRONG!!! (needed by combatsc) */
inc = 5;
offs[0] = 0x00;
offs[1] = 0x01;
offs[2] = 0x02;
offs[3] = 0x03;
offs[4] = 0x04;
/* when using priority buffer, draw front to back */
if (pri_mask != -1)
{
source += (num - 1)*inc;
inc = -inc;
}
}
for (i = 0; i < num; i++)
{
int number = source[offs[0]]; /* sprite number */
int sprite_bank = source[offs[1]] & 0x0f; /* sprite bank */
int sx = source[offs[3]]; /* vertical position */
int sy = source[offs[2]]; /* horizontal position */
int attr = source[offs[4]]; /* attributes */
int xflip = source[offs[4]] & 0x10; /* flip x */
int yflip = source[offs[4]] & 0x20; /* flip y */
int color = base_color + ((source[offs[1]] & 0xf0) >> 4);
int width, height;
int transparent_mask;
static const int x_offset[4] = {0x0,0x1,0x4,0x5};
static const int y_offset[4] = {0x0,0x2,0x8,0xa};
int x,y, ex, ey, flipx, flipy, destx, desty;
if (attr & 0x01) sx -= 256;
if (sy >= 240) sy -= 256;
number += ((sprite_bank & 0x3) << 8) + ((attr & 0xc0) << 4);
number = number << 2;
number += (sprite_bank >> 2) & 3;
/* Flak Attack doesn't use a lookup PROM, it maps the color code directly */
/* to a palette entry */
if (is_flakatck)
transparent_mask = 1 << 0;
else
transparent_mask = colortable_get_transpen_mask(ctable, gfx, color, 0);
if (!is_flakatck || source[0x00]) /* Flak Attack needs this */
{
number += bank_base;
switch (attr & 0xe)
{
case 0x06: width = height = 1; break;
case 0x04: width = 1; height = 2; number &= (~2); break;
case 0x02: width = 2; height = 1; number &= (~1); break;
case 0x00: width = height = 2; number &= (~3); break;
case 0x08: width = height = 4; number &= (~3); break;
default: width = 1; height = 1;
// logerror("Unknown sprite size %02x\n", attr & 0xe);
// popmessage("Unknown sprite size %02x\n", attr & 0xe);
}
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
ex = xflip ? (width - 1 - x) : x;
ey = yflip ? (height - 1 - y) : y;
if (flipscreen)
{
flipx = !xflip;
flipy = !yflip;
destx = 248 - (sx + x * 8);
desty = 248 - (sy + y * 8);
}
else
{
flipx = xflip;
flipy = yflip;
destx = global_x_offset + sx + x * 8;
desty = sy + y * 8;
}
if (pri_mask != -1)
pdrawgfx_transmask(bitmap,cliprect,gfx,
number + x_offset[ex] + y_offset[ey],
color,
flipx,flipy,
destx,desty,
priority_bitmap,pri_mask,
transparent_mask);
else
drawgfx_transmask(bitmap,cliprect,gfx,
number + x_offset[ex] + y_offset[ey],
color,
flipx,flipy,
destx,desty,
transparent_mask);
}
}
}
source += inc;
}
}