/*
Sega system24 hardware
System 24 68000x2 315-5292 315-5293 315-5294 315-5242 ym2151 dac 315-5195(x3) 315-5296(IO)
System24:
The odd one out. Medium resolution. Entirely ram-based, no
graphics roms. 4-layer tilemap hardware in two pairs, selection
on a 8-pixels basis. Tile-based sprites(!) organised as a linked
list. The tilemap chip has been reused for model1 and model2,
probably because they had it handy and it handles medium res.
*/
#include "emu.h"
#include "segaic24.h"
const device_type S24TILE = &device_creator<segas24_tile>;
const device_type S24SPRITE = &device_creator<segas24_sprite>;
const device_type S24MIXER = &device_creator<segas24_mixer>;
segas24_tile::segas24_tile(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, S24TILE, "S24TILE", tag, owner, clock)
{
}
void segas24_tile::static_set_tile_mask(device_t &device, UINT16 _tile_mask)
{
segas24_tile &dev = downcast<segas24_tile &>(device);
dev.tile_mask = _tile_mask;
}
#define XOR(a) WORD_XOR_BE(a)
const gfx_layout segas24_tile::char_layout = {
8, 8,
SYS24_TILES,
4,
{ 0, 1, 2, 3 },
{ XOR(0)*4, XOR(1)*4, XOR(2)*4, XOR(3)*4, XOR(4)*4, XOR(5)*4, XOR(6)*4, XOR(7)*4 },
{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
8*32
};
void segas24_tile::tile_info(int offset, tile_data *tileinfo, tilemap_memory_index tile_index)
{
UINT16 val = tile_ram[tile_index|offset];
tileinfo->category = (val & 0x8000) != 0;
tileinfo_set(machine(), tileinfo, char_gfx_index, val & tile_mask, (val >> 7) & 0xff, 0);
}
TILE_GET_INFO_DEVICE( segas24_tile::tile_info_0s )
{
downcast<segas24_tile *>(device)->tile_info(0x0000, tileinfo, tile_index);
}
TILE_GET_INFO_DEVICE( segas24_tile::tile_info_0w )
{
downcast<segas24_tile *>(device)->tile_info(0x1000, tileinfo, tile_index);
}
TILE_GET_INFO_DEVICE( segas24_tile::tile_info_1s )
{
downcast<segas24_tile *>(device)->tile_info(0x2000, tileinfo, tile_index);
}
TILE_GET_INFO_DEVICE( segas24_tile::tile_info_1w )
{
downcast<segas24_tile *>(device)->tile_info(0x3000, tileinfo, tile_index);
}
void segas24_tile::device_start()
{
for(char_gfx_index = 0; char_gfx_index < MAX_GFX_ELEMENTS; char_gfx_index++)
if (machine().gfx[char_gfx_index] == 0)
break;
assert(char_gfx_index != MAX_GFX_ELEMENTS);
char_ram = auto_alloc_array(machine(), UINT16, 0x80000/2);
tile_ram = auto_alloc_array(machine(), UINT16, 0x10000/2);
tile_layer[0] = tilemap_create_device(this, tile_info_0s, tilemap_scan_rows, 8, 8, 64, 64);
tile_layer[1] = tilemap_create_device(this, tile_info_0w, tilemap_scan_rows, 8, 8, 64, 64);
tile_layer[2] = tilemap_create_device(this, tile_info_1s, tilemap_scan_rows, 8, 8, 64, 64);
tile_layer[3] = tilemap_create_device(this, tile_info_1w, tilemap_scan_rows, 8, 8, 64, 64);
tilemap_set_transparent_pen(tile_layer[0], 0);
tilemap_set_transparent_pen(tile_layer[1], 0);
tilemap_set_transparent_pen(tile_layer[2], 0);
tilemap_set_transparent_pen(tile_layer[3], 0);
memset(char_ram, 0, 0x80000);
memset(tile_ram, 0, 0x10000);
machine().gfx[char_gfx_index] = gfx_element_alloc(machine(), &char_layout, (UINT8 *)char_ram, machine().total_colors() / 16, 0);
save_pointer(NAME(tile_ram), 0x10000/2);
save_pointer(NAME(char_ram), 0x80000/2);
}
void segas24_tile::draw_rect(bitmap_t *bm, bitmap_t *tm, bitmap_t *dm, const UINT16 *mask,
UINT16 tpri, UINT8 lpri, int win, int sx, int sy, int xx1, int yy1, int xx2, int yy2)
{
int y;
const UINT16 *source = ((UINT16 *)bm->base) + sx + sy*bm->rowpixels;
const UINT8 *trans = ((UINT8 *) tm->base) + sx + sy*tm->rowpixels;
UINT8 *prib = (UINT8 *)machine().priority_bitmap->base;
UINT16 *dest = (UINT16 *)dm->base;
tpri |= TILEMAP_PIXEL_LAYER0;
dest += yy1*dm->rowpixels + xx1;
prib += yy1*machine().priority_bitmap->rowpixels + xx1;
mask += yy1*4;
yy2 -= yy1;
while(xx1 >= 128) {
xx1 -= 128;
xx2 -= 128;
mask++;
}
for(y=0; y<yy2; y++) {
const UINT16 *src = source;
const UINT8 *srct = trans;
UINT16 *dst = dest;
UINT8 *pr = prib;
const UINT16 *mask1 = mask;
int llx = xx2;
int cur_x = xx1;
while(llx > 0) {
UINT16 m = *mask1++;
if(win)
m = ~m;
if(!cur_x && llx>=128) {
// Fast paths for the 128-pixels without side clipping case
if(!m) {
// 1- 128 pixels from this layer
int x;
for(x=0; x<128; x++) {
if(*srct++ == tpri) {
*dst = *src;
*pr |= lpri;
}
src++;
dst++;
pr++;
}
} else if(m == 0xffff) {
// 2- 128 pixels from the other layer
src += 128;
srct += 128;
dst += 128;
pr += 128;
} else {
// 3- 128 pixels from both layers
int x;
for(x=0; x<128; x+=8) {
if(!(m & 0x8000)) {
int xx;
for(xx=0; xx<8; xx++)
if(srct[xx] == tpri) {
dst[xx] = src[xx];
pr[xx] |= lpri;
}
}
src += 8;
srct += 8;
dst += 8;
pr += 8;
m <<= 1;
}
}
} else {
// Clipped path
int llx1 = llx >= 128 ? 128 : llx;
if(!m) {
// 1- 128 pixels from this layer
int x;
for(x = cur_x; x<llx1; x++) {
if(*srct++ == tpri) {
*dst = *src;
*pr |= lpri;
}
src++;
dst++;
pr++;
}
} else if(m == 0xffff) {
// 2- 128 pixels from the other layer
src += 128 - cur_x;
srct += 128 - cur_x;
dst += 128 - cur_x;
pr += 128 - cur_x;
} else {
// 3- 128 pixels from both layers
int x;
for(x=cur_x; x<llx1; x++) {
if(*srct++ == tpri && !(m & (0x8000 >> (x >> 3)))) {
*dst = *src;
*pr |= lpri;
}
src++;
dst++;
pr++;
}
}
}
llx -= 128;
cur_x = 0;
}
source += bm->rowpixels;
trans += tm->rowpixels;
dest += dm->rowpixels;
prib += machine().priority_bitmap->rowpixels;
mask += 4;
}
}
// The rgb version is used by model 1 & 2 which do not need to care
// about sprite priority hence the lack of support for the
// priority_bitmap
void segas24_tile::draw_rect_rgb(bitmap_t *bm, bitmap_t *tm, bitmap_t *dm, const UINT16 *mask,
UINT16 tpri, UINT8 lpri, int win, int sx, int sy, int xx1, int yy1, int xx2, int yy2)
{
int y;
const UINT16 *source = ((UINT16 *)bm->base) + sx + sy*bm->rowpixels;
const UINT8 *trans = ((UINT8 *) tm->base) + sx + sy*tm->rowpixels;
UINT16 *dest = (UINT16 *)dm->base;
const pen_t *pens = machine().pens;
tpri |= TILEMAP_PIXEL_LAYER0;
dest += yy1*dm->rowpixels + xx1;
mask += yy1*4;
yy2 -= yy1;
while(xx1 >= 128) {
xx1 -= 128;
xx2 -= 128;
mask++;
}
for(y=0; y<yy2; y++) {
const UINT16 *src = source;
const UINT8 *srct = trans;
UINT16 *dst = dest;
const UINT16 *mask1 = mask;
int llx = xx2;
int cur_x = xx1;
while(llx > 0) {
UINT16 m = *mask1++;
if(win)
m = ~m;
if(!cur_x && llx>=128) {
// Fast paths for the 128-pixels without side clipping case
if(!m) {
// 1- 128 pixels from this layer
int x;
for(x=0; x<128; x++) {
if(*srct++ == tpri)
*dst = pens[*src];
src++;
dst++;
}
} else if(m == 0xffff) {
// 2- 128 pixels from the other layer
src += 128;
srct += 128;
dst += 128;
} else {
// 3- 128 pixels from both layers
int x;
for(x=0; x<128; x+=8) {
if(!(m & 0x8000)) {
int xx;
for(xx=0; xx<8; xx++)
if(srct[xx] == tpri)
dst[xx] = pens[src[xx]];
}
src += 8;
srct += 8;
dst += 8;
m <<= 1;
}
}
} else {
// Clipped path
int llx1 = llx >= 128 ? 128 : llx;
if(!m) {
// 1- 128 pixels from this layer
int x;
for(x = cur_x; x<llx1; x++) {
if(*srct++ == tpri)
*dst = pens[*src];
src++;
dst++;
}
} else if(m == 0xffff) {
// 2- 128 pixels from the other layer
src += 128 - cur_x;
srct += 128 - cur_x;
dst += 128 - cur_x;
} else {
// 3- 128 pixels from both layers
int x;
for(x=cur_x; x<llx1; x++) {
if(*srct++ == tpri && !(m & (0x8000 >> (x >> 3))))
*dst = pens[*src];
src++;
dst++;
}
}
}
llx -= 128;
cur_x = 0;
}
source += bm->rowpixels;
trans += tm->rowpixels;
dest += dm->rowpixels;
mask += 4;
}
}
void segas24_tile::draw(bitmap_t *bitmap, const rectangle *cliprect, int layer, int lpri, int flags)
{
UINT16 hscr = tile_ram[0x5000+(layer >> 1)];
UINT16 vscr = tile_ram[0x5004+(layer >> 1)];
UINT16 ctrl = tile_ram[0x5004+((layer >> 1) & 2)];
UINT16 *mask = tile_ram + (layer & 4 ? 0x6800 : 0x6000);
UINT16 tpri = layer & 1;
lpri = 1 << lpri;
layer >>= 1;
// Layer disable
if(vscr & 0x8000)
return;
if(ctrl & 0x6000) {
// Special window/scroll modes
if(layer & 1)
return;
tilemap_set_scrolly(tile_layer[layer], 0, vscr & 0x1ff);
tilemap_set_scrolly(tile_layer[layer|1], 0, vscr & 0x1ff);
if(hscr & 0x8000) {
UINT16 *hscrtb = tile_ram + 0x4000 + 0x200*layer;
switch((ctrl & 0x6000) >> 13) {
case 1: {
int y;
UINT16 v = (-vscr) & 0x1ff;
if(!((-vscr) & 0x200))
layer ^= 1;
for(y=cliprect->min_y; y<=cliprect->max_y; y++) {
UINT16 h;
rectangle c = *cliprect;
int l1 = layer;
if(y >= v)
l1 ^= 1;
c.min_y = c.max_y = y;
hscr = hscrtb[y];
h = hscr & 0x1ff;
tilemap_set_scrollx(tile_layer[l1], 0, -h);
tilemap_draw(bitmap, &c, tile_layer[l1], tpri, lpri);
}
break;
}
case 2: case 3: {
int y;
for(y=cliprect->min_y; y<=cliprect->max_y; y++) {
UINT16 h;
rectangle c1 = *cliprect;
rectangle c2 = *cliprect;
int l1 = layer;
hscr = hscrtb[y];
h = hscr & 0x1ff;
tilemap_set_scrollx(tile_layer[layer], 0, -h);
tilemap_set_scrollx(tile_layer[layer|1], 0, -h);
if(c1.max_x >= h)
c1.max_x = h-1;
if(c2.min_x < h)
c2.min_x = h;
if(!(hscr & 0x200))
l1 ^= 1;
c1.min_y = c1.max_y = c2.min_y = c2.max_y = y;
tilemap_draw(bitmap, &c1, tile_layer[l1], tpri, lpri);
tilemap_draw(bitmap, &c2, tile_layer[l1^1], tpri, lpri);
}
break;
}
}
} else {
tilemap_set_scrollx(tile_layer[layer], 0, -(hscr & 0x1ff));
tilemap_set_scrollx(tile_layer[layer|1], 0, -(hscr & 0x1ff));
switch((ctrl & 0x6000) >> 13) {
case 1: {
rectangle c1 = *cliprect;
rectangle c2 = *cliprect;
UINT16 v;
v = (-vscr) & 0x1ff;
if(c1.max_y >= v)
c1.max_y = v-1;
if(c2.min_y < v)
c2.min_y = v;
if(!((-vscr) & 0x200))
layer ^= 1;
tilemap_draw(bitmap, &c1, tile_layer[layer], tpri, lpri);
tilemap_draw(bitmap, &c2, tile_layer[layer^1], tpri, lpri);
break;
}
case 2: case 3: {
rectangle c1 = *cliprect;
rectangle c2 = *cliprect;
UINT16 h;
h = (+hscr) & 0x1ff;
if(c1.max_x >= h)
c1.max_x = h-1;
if(c2.min_x < h)
c2.min_x = h;
if(!((+hscr) & 0x200))
layer ^= 1;
tilemap_draw(bitmap, &c1, tile_layer[layer], tpri, lpri);
tilemap_draw(bitmap, &c2, tile_layer[layer^1], tpri, lpri);
break;
}
}
}
} else {
bitmap_t *bm, *tm;
void (segas24_tile::*draw)(bitmap_t *, bitmap_t *, bitmap_t *, const UINT16 *,
UINT16, UINT8, int, int, int, int, int, int, int);
int win = layer & 1;
if(bitmap->format != BITMAP_FORMAT_INDEXED16)
draw = &segas24_tile::draw_rect_rgb;
else
draw = &segas24_tile::draw_rect;
bm = tilemap_get_pixmap(tile_layer[layer]);
tm = tilemap_get_flagsmap(tile_layer[layer]);
if(hscr & 0x8000) {
int y;
UINT16 *hscrtb = tile_ram + 0x4000 + 0x200*layer;
vscr &= 0x1ff;
for(y=0; y<384; y++) {
hscr = (-hscrtb[y]) & 0x1ff;
if(hscr + 496 <= 512) {
// Horizontal split unnecessary
(this->*draw)(bm, tm, bitmap, mask, tpri, lpri, win, hscr, vscr, 0, y, 496, y+1);
} else {
// Horizontal split necessary
(this->*draw)(bm, tm, bitmap, mask, tpri, lpri, win, hscr, vscr, 0, y, 512-hscr, y+1);
(this->*draw)(bm, tm, bitmap, mask, tpri, lpri, win, 0, vscr, 512-hscr, y, 496, y+1);
}
vscr = (vscr + 1) & 0x1ff;
}
} else {
hscr = (-hscr) & 0x1ff;
vscr = (+vscr) & 0x1ff;
if(hscr + 496 <= 512) {
// Horizontal split unnecessary
if(vscr + 384 <= 512) {
// Vertical split unnecessary
(this->*draw)(bm, tm, bitmap, mask, tpri, lpri, win, hscr, vscr, 0, 0, 496, 384);
} else {
// Vertical split necessary
(this->*draw)(bm, tm, bitmap, mask, tpri, lpri, win, hscr, vscr, 0, 0, 496, 512-vscr);
(this->*draw)(bm, tm, bitmap, mask, tpri, lpri, win, hscr, 0, 0, 512-vscr, 496, 384);
}
} else {
// Horizontal split necessary
if(vscr + 384 <= 512) {
// Vertical split unnecessary
(this->*draw)(bm, tm, bitmap, mask, tpri, lpri, win, hscr, vscr, 0, 0, 512-hscr, 384);
(this->*draw)(bm, tm, bitmap, mask, tpri, lpri, win, 0, vscr, 512-hscr, 0, 496, 384);
} else {
// Vertical split necessary
(this->*draw)(bm, tm, bitmap, mask, tpri, lpri, win, hscr, vscr, 0, 0, 512-hscr, 512-vscr);
(this->*draw)(bm, tm, bitmap, mask, tpri, lpri, win, 0, vscr, 512-hscr, 0, 496, 512-vscr);
(this->*draw)(bm, tm, bitmap, mask, tpri, lpri, win, hscr, 0, 0, 512-vscr, 512-hscr, 384);
(this->*draw)(bm, tm, bitmap, mask, tpri, lpri, win, 0, 0, 512-hscr, 512-vscr, 496, 384);
}
}
}
}
}
READ16_MEMBER(segas24_tile::tile_r)
{
return tile_ram[offset];
}
READ16_MEMBER(segas24_tile::char_r)
{
return char_ram[offset];
}
WRITE16_MEMBER(segas24_tile::tile_w)
{
COMBINE_DATA(tile_ram + offset);
if(offset < 0x4000)
tilemap_mark_tile_dirty(tile_layer[offset >> 12], offset & 0xfff);
}
WRITE16_MEMBER(segas24_tile::char_w)
{
UINT16 old = char_ram[offset];
COMBINE_DATA(char_ram + offset);
if(old != char_ram[offset])
gfx_element_mark_dirty(machine().gfx[char_gfx_index], offset / 16);
}
READ32_MEMBER(segas24_tile::tile32_r)
{
return tile_r(space, offset*2, mem_mask&0xffff) | tile_r(space, (offset*2)+1, mem_mask>>16)<<16;
}
READ32_MEMBER(segas24_tile::char32_r)
{
return char_r(space, offset*2, mem_mask&0xffff) | char_r(space, (offset*2)+1, mem_mask>>16)<<16;
}
WRITE32_MEMBER(segas24_tile::tile32_w)
{
tile_w(space, offset*2, data&0xffff, mem_mask&0xffff);
tile_w(space, (offset*2)+1, data>>16, mem_mask>>16);
}
WRITE32_MEMBER(segas24_tile::char32_w)
{
char_w(space, offset*2, data&0xffff, mem_mask&0xffff);
char_w(space, (offset*2)+1, data>>16, mem_mask>>16);
}
segas24_sprite::segas24_sprite(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, S24SPRITE, "S24SPRITE", tag, owner, clock)
{
}
void segas24_sprite::device_start()
{
sprite_ram = auto_alloc_array(machine(), UINT16, 0x40000/2);
save_pointer(NAME(sprite_ram), 0x40000/2);
}
/* System24 sprites
Normal sprite:
0 00Z--nnn nnnnnnnn zoom mode (1 = separate x and y), next sprite
1 xxxxxxxx yyyyyyyy zoom x, zoom y (zoom y is used for both when mode = 0)
2 --TTTTTT TTTTTTTT sprite number
3 PPPPCCCC CCCCCCCC priority, indirect palette base
4 FSSSYYYY YYYYYYYY flipy, y size, top
5 FSSSXXXX XXXXXXXX flipx, x size, left
Clip?
0 01---nnn nnnnnnnn next sprite
1 hVH----- -------- hide/vflip/hflip
2 -------y yyyyyyyy Clip top
2 -------x xxxxxxxx Clip left
2 -------y yyyyyyyy Clip bottom
2 -------x xxxxxxxx Clip right
Skipped entry
0 10---nnn nnnnnnnn next sprite
End of sprite list
0 11------ --------
*/
void segas24_sprite::draw(bitmap_t *bitmap, const rectangle *cliprect, const int *spri)
{
UINT16 curspr = 0;
int countspr = 0;
int seen;
UINT8 pmt[4];
int i;
UINT16 *sprd[0x2000], *clip[0x2000];
UINT16 *cclip = 0;
for(i=0; i<4; i++)
pmt[i] = 0xff << (1+spri[3-i]);
for(seen = 0; seen < 0x2000; seen++) {
UINT16 *source;
UINT16 type;
source = sprite_ram + (curspr << 3);
if(curspr == 0 && source[0] == 0)
break;
curspr = source[0];
type = curspr & 0xc000;
curspr &= 0x03ff;
if(type == 0xc000)
break;
if(type == 0x8000)
continue;
if(type == 0x4000) {
cclip = source;
continue;
}
sprd[countspr] = source;
clip[countspr] = cclip;
countspr++;
if(!curspr)
break;
}
for(countspr--; countspr >= 0; countspr--) {
UINT16 *source, *pix;
int x, y, sx, sy;
int px, py;
UINT16 colors[16];
int flipx, flipy;
int zoomx, zoomy;
UINT8 pm[16];
// int dump;
int xmod, ymod;
int min_x, min_y, max_x, max_y;
UINT32 addoffset;
UINT32 newoffset;
UINT32 offset;
source = sprd[countspr];
cclip = clip[countspr];
if(cclip) {
min_y = (cclip[2] & 511);
min_x = (cclip[3] & 511) - 8;
max_y = (cclip[4] & 511);
max_x = (cclip[5] & 511) - 8;
} else {
min_x = 0;
max_x = 495;
min_y = 0;
max_y = 383;
}
if(min_x < cliprect->min_x)
min_x = cliprect->min_x;
if(min_y < cliprect->min_y)
min_y = cliprect->min_y;
if(max_x > cliprect->max_x)
max_x = cliprect->max_x;
if(max_y > cliprect->max_y)
max_y = cliprect->max_y;
if(!(source[0] & 0x2000))
zoomx = zoomy = source[1] & 0xff;
else {
zoomx = source[1] >> 8;
zoomy = source[1] & 0xff;
}
if(!zoomx)
zoomx = 0x3f;
if(!zoomy)
zoomy = 0x3f;
zoomx++;
zoomy++;
x = source[5] & 0xfff;
flipx = source[5] & 0x8000;
if(x & 0x800)
x -= 0x1000;
sx = 1 << ((source[5] & 0x7000) >> 12);
x -= 8;
y = source[4] & 0xfff;
if(y & 0x800)
y -= 0x1000;
flipy = source[4] & 0x8000;
sy = 1 << ((source[4] & 0x7000) >> 12);
pix = &sprite_ram[(source[3] & 0x3fff)* 0x8];
for(px=0; px<8; px++) {
int c;
c = pix[px] >> 8;
pm[px*2] = pmt[c>>6];
if(c>1)
c |= 0x1000;
colors[px*2] = c;
c = pix[px] & 0xff;
pm[px*2+1] = pmt[c>>6];
if(c>1)
c |= 0x1000;
colors[px*2+1] = c;
}
offset = (source[2] & 0x7fff) * 0x10;
xmod = 0x20;
ymod = 0x20;
for(py=0; py<sy; py++) {
int xmod1 = xmod;
int xpos1 = x;
int ypos1 = y, ymod1 = ymod;
for(px=0; px<sx; px++) {
int xmod2 = xmod1, xpos2 = xpos1;
int zy;
addoffset = 0x10*(flipx ? sx-px-1 : px) + 0x10*sx*(flipy ? sy-py-1 : py) + (flipy ? 7*2 : 0);
newoffset = offset + addoffset;
ymod1 = ymod;
ypos1 = y;
for(zy=0; zy<8; zy++) {
ymod1 += zoomy;
while(ymod1 >= 0x40) {
if(ypos1 >= min_y && ypos1 <= max_y) {
int zx;
xmod2 = xmod1;
xpos2 = xpos1;
for(zx=0; zx<8; zx++) {
xmod2 += zoomx;
while(xmod2 >= 0x40) {
if(xpos2 >= min_x && xpos2 <= max_x) {
int zx1 = flipx ? 7-zx : zx;
UINT32 neweroffset = (newoffset+(zx1>>2))&0x1ffff; // crackdown sometimes attempts to use data past the end of spriteram
int c = (sprite_ram[neweroffset] >> (((~zx1) & 3) << 2)) & 0xf;
UINT8 *pri = BITMAP_ADDR8(machine().priority_bitmap, ypos1, xpos2);
if(!(*pri & pm[c])) {
c = colors[c];
if(c) {
UINT16 *dst = BITMAP_ADDR16(bitmap, ypos1, xpos2);
if(c==1)
*dst = (*dst) | 0x2000;
else
*dst = c;
*pri = 0xff;
}
}
}
xmod2 -= 0x40;
xpos2++;
}
}
}
ymod1 -= 0x40;
ypos1++;
}
if(flipy)
newoffset -= 2;
else
newoffset += 2;
}
xpos1 = xpos2;
xmod1 = xmod2;
}
y = ypos1;
ymod = ymod1;
}
}
}
WRITE16_MEMBER(segas24_sprite::write)
{
COMBINE_DATA(sprite_ram + offset);
}
READ16_MEMBER(segas24_sprite::read)
{
return sprite_ram[offset];
}
segas24_mixer::segas24_mixer(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, S24MIXER, "S24MIXER", tag, owner, clock)
{
}
void segas24_mixer::device_start()
{
memset(mixer_reg, 0, sizeof(mixer_reg));
save_item(NAME(mixer_reg));
}
WRITE16_MEMBER(segas24_mixer::write)
{
COMBINE_DATA(mixer_reg + offset);
}
READ16_MEMBER(segas24_mixer::read)
{
return mixer_reg[offset];
}
UINT16 segas24_mixer::get_reg(int reg)
{
return mixer_reg[reg];
}