attckufo: Imported MOS6560 device emulation from MESS and removed the existent custom audio/video emulation [Fabio Priuli]
This commit is contained in:
parent
9d7196b0fe
commit
f26c5bf115
4
.gitattributes
vendored
4
.gitattributes
vendored
@ -884,6 +884,8 @@ src/emu/sound/k054539.c svneol=native#text/plain
|
||||
src/emu/sound/k054539.h svneol=native#text/plain
|
||||
src/emu/sound/k056800.c svneol=native#text/plain
|
||||
src/emu/sound/k056800.h svneol=native#text/plain
|
||||
src/emu/sound/mos6560.c svneol=native#text/plain
|
||||
src/emu/sound/mos6560.h svneol=native#text/plain
|
||||
src/emu/sound/msm5205.c svneol=native#text/plain
|
||||
src/emu/sound/msm5205.h svneol=native#text/plain
|
||||
src/emu/sound/msm5232.c svneol=native#text/plain
|
||||
@ -2383,7 +2385,6 @@ src/mame/includes/atarigx2.h svneol=native#text/plain
|
||||
src/mame/includes/atarisy1.h svneol=native#text/plain
|
||||
src/mame/includes/atarisy2.h svneol=native#text/plain
|
||||
src/mame/includes/atetris.h svneol=native#text/plain
|
||||
src/mame/includes/attckufo.h svneol=native#text/plain
|
||||
src/mame/includes/avalnche.h svneol=native#text/plain
|
||||
src/mame/includes/aztarac.h svneol=native#text/plain
|
||||
src/mame/includes/badlands.h svneol=native#text/plain
|
||||
@ -3226,7 +3227,6 @@ src/mame/video/atarirle.h svneol=native#text/plain
|
||||
src/mame/video/atarisy1.c svneol=native#text/plain
|
||||
src/mame/video/atarisy2.c svneol=native#text/plain
|
||||
src/mame/video/atetris.c svneol=native#text/plain
|
||||
src/mame/video/attckufo.c svneol=native#text/plain
|
||||
src/mame/video/avgdvg.c svneol=native#text/plain
|
||||
src/mame/video/avgdvg.h svneol=native#text/plain
|
||||
src/mame/video/awpvid.c svneol=native#text/plain
|
||||
|
910
src/emu/sound/mos6560.c
Normal file
910
src/emu/sound/mos6560.c
Normal file
@ -0,0 +1,910 @@
|
||||
/***************************************************************************
|
||||
|
||||
MOS 6560 / 6561 Video Interface Chip
|
||||
|
||||
|
||||
Original code by PeT (mess@utanet.at), 1999
|
||||
|
||||
|
||||
2010 FP: converted to a device and merged the video & sound components
|
||||
|
||||
TODO:
|
||||
- plenty of cleanups!
|
||||
- investigate attckufo chip features (no invert mode, no multicolor, 16 col chars)
|
||||
- investigate why some vic20 carts crash emulation
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "streams.h"
|
||||
#include "sound/mos6560.h"
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
typedef struct _mos6560_state mos6560_state;
|
||||
struct _mos6560_state
|
||||
{
|
||||
mos6560_type type;
|
||||
|
||||
running_device *screen;
|
||||
|
||||
UINT8 reg[16];
|
||||
|
||||
bitmap_t *bitmap;
|
||||
|
||||
int rasterline, lastline;
|
||||
double lightpenreadtime;
|
||||
|
||||
int charheight, matrix8x16, inverted;
|
||||
int chars_x, chars_y;
|
||||
int xsize, ysize, xpos, ypos;
|
||||
int chargenaddr, videoaddr;
|
||||
|
||||
/* values in videoformat */
|
||||
UINT16 backgroundcolor, framecolor, helpercolor;
|
||||
|
||||
/* arrays for bit to color conversion without condition checking */
|
||||
UINT16 mono[2], monoinverted[2], multi[4], multiinverted[4];
|
||||
|
||||
/* video chip settings */
|
||||
int total_xsize, total_ysize, total_lines, total_vretracerate;
|
||||
|
||||
/* DMA */
|
||||
mos6560_dma_read dma_read;
|
||||
mos6560_dma_read_color dma_read_color;
|
||||
|
||||
/* lightpen */
|
||||
mos6560_lightpen_button_callback lightpen_button_cb;
|
||||
mos6560_lightpen_x_callback lightpen_x_cb;
|
||||
mos6560_lightpen_y_callback lightpen_y_cb;
|
||||
|
||||
/* paddles */
|
||||
mos6560_paddle_callback paddle_cb[2];
|
||||
|
||||
/* sound part */
|
||||
int tone1pos, tone2pos, tone3pos,
|
||||
tonesize, tone1samples, tone2samples, tone3samples,
|
||||
noisesize, /* number of samples */
|
||||
noisepos, /* pos of tone */
|
||||
noisesamples; /* count of samples to give out per tone */
|
||||
|
||||
sound_stream *channel;
|
||||
INT16 *tone;
|
||||
INT8 *noise;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
INLINE FUNCTIONS
|
||||
*****************************************************************************/
|
||||
|
||||
INLINE mos6560_state *get_safe_token( running_device *device )
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->token != NULL);
|
||||
assert(device->type == MOS6560);
|
||||
|
||||
return (mos6560_state *)device->token;
|
||||
}
|
||||
|
||||
INLINE const mos6560_interface *get_interface( running_device *device )
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert((device->type == MOS6560));
|
||||
return (const mos6560_interface *) device->baseconfig().static_config;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
PARAMETERS
|
||||
*****************************************************************************/
|
||||
|
||||
#define VERBOSE_LEVEL 0
|
||||
#define DBG_LOG(N,M,A) \
|
||||
do { \
|
||||
if(VERBOSE_LEVEL >= N) \
|
||||
{ \
|
||||
if( M ) \
|
||||
logerror("%11.6f: %-24s", attotime_to_double(timer_get_time(device->machine)), (char*) M ); \
|
||||
logerror A; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* 2008-05 FP: lightpen code needs to read input port from vc20.c */
|
||||
|
||||
#define LIGHTPEN_BUTTON (mos6560->lightpen_button_cb(device->machine))
|
||||
#define LIGHTPEN_X_VALUE (mos6560->lightpen_x_cb(device->machine))
|
||||
#define LIGHTPEN_Y_VALUE (mos6560->lightpen_y_cb(device->machine))
|
||||
|
||||
/* lightpen delivers values from internal counters
|
||||
* they do not start with the visual area or frame area */
|
||||
#define MOS6560_X_BEGIN 38
|
||||
#define MOS6560_Y_BEGIN -6 /* first 6 lines after retrace not for lightpen! */
|
||||
#define MOS6561_X_BEGIN 38
|
||||
#define MOS6561_Y_BEGIN -6
|
||||
#define MOS656X_X_BEGIN ((mos6560->type == MOS6561) ? MOS6561_X_BEGIN : MOS6560_X_BEGIN)
|
||||
#define MOS656X_Y_BEGIN ((mos6560->type == MOS6561) ? MOS6561_Y_BEGIN : MOS6560_Y_BEGIN)
|
||||
|
||||
#define MOS656X_MAME_XPOS ((mos6560->type == MOS6561) ? MOS6561_MAME_XPOS : MOS6560_MAME_XPOS)
|
||||
#define MOS656X_MAME_YPOS ((mos6560->type == MOS6561) ? MOS6561_MAME_YPOS : MOS6560_MAME_YPOS)
|
||||
|
||||
/* lightpen behaviour in pal or mono multicolor not tested */
|
||||
#define MOS656X_X_VALUE ((LIGHTPEN_X_VALUE + MOS656X_X_BEGIN + MOS656X_MAME_XPOS)/2)
|
||||
#define MOS656X_Y_VALUE ((LIGHTPEN_Y_VALUE + MOS656X_Y_BEGIN + MOS656X_MAME_YPOS)/2)
|
||||
|
||||
#define MOS656X_VRETRACERATE ((mos6560->type == MOS6561) ? MOS6561_VRETRACERATE : MOS6560_VRETRACERATE)
|
||||
|
||||
/* ntsc 1 - 8 */
|
||||
/* pal 5 - 19 */
|
||||
#define XPOS (((int)mos6560->reg[0] & 0x7f) * 4)
|
||||
#define YPOS ((int)mos6560->reg[1] * 2)
|
||||
|
||||
/* ntsc values >= 31 behave like 31 */
|
||||
/* pal value >= 32 behave like 32 */
|
||||
#define CHARS_X ((int)mos6560->reg[2] & 0x7f)
|
||||
#define CHARS_Y (((int)mos6560->reg[3] & 0x7e) >> 1)
|
||||
|
||||
/* colorram and backgroundcolor are changed */
|
||||
#define INVERTED (!(mos6560->reg[0x0f] & 8))
|
||||
|
||||
#define CHARGENADDR (((int)mos6560->reg[5] & 0x0f) << 10)
|
||||
#define VIDEOADDR ((((int)mos6560->reg[5] & 0xf0) << (10 - 4)) | (((int)mos6560->reg[2] & 0x80) << (9-7)))
|
||||
#define VIDEORAMSIZE (YSIZE * XSIZE)
|
||||
#define CHARGENSIZE (256 * HEIGHTPIXEL)
|
||||
|
||||
#define HELPERCOLOR (mos6560->reg[0x0e] >> 4)
|
||||
#define BACKGROUNDCOLOR (mos6560->reg[0x0f] >> 4)
|
||||
#define FRAMECOLOR (mos6560->reg[0x0f] & 0x07)
|
||||
|
||||
/*****************************************************************************
|
||||
IMPLEMENTATION
|
||||
*****************************************************************************/
|
||||
|
||||
static void mos6560_soundport_w( running_device *device, int offset, int data );
|
||||
|
||||
/*-------------------------------------------------
|
||||
mos6560_draw_character
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void mos6560_draw_character( running_device *device, int ybegin, int yend, int ch, int yoff, int xoff, UINT16 *color )
|
||||
{
|
||||
mos6560_state *mos6560 = get_safe_token(device);
|
||||
int y, code;
|
||||
|
||||
for (y = ybegin; y <= yend; y++)
|
||||
{
|
||||
code = mos6560->dma_read(device->machine, (mos6560->chargenaddr + ch * mos6560->charheight + y) & 0x3fff);
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 0) = color[code >> 7];
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 1) = color[(code >> 6) & 1];
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 2) = color[(code >> 5) & 1];
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 3) = color[(code >> 4) & 1];
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 4) = color[(code >> 3) & 1];
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 5) = color[(code >> 2) & 1];
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 6) = color[(code >> 1) & 1];
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 7) = color[code & 1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mos6560_draw_character_multi
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void mos6560_draw_character_multi( running_device *device, int ybegin, int yend, int ch, int yoff, int xoff, UINT16 *color )
|
||||
{
|
||||
mos6560_state *mos6560 = get_safe_token(device);
|
||||
int y, code;
|
||||
|
||||
for (y = ybegin; y <= yend; y++)
|
||||
{
|
||||
code = mos6560->dma_read(device->machine, (mos6560->chargenaddr + ch * mos6560->charheight + y) & 0x3fff);
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 0) =
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 1) = color[code >> 6];
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 2) =
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 3) = color[(code >> 4) & 3];
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 4) =
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 5) = color[(code >> 2) & 3];
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 6) =
|
||||
*BITMAP_ADDR16(mos6560->bitmap, y + yoff, xoff + 7) = color[code & 3];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mos6560_drawlines - draw a certain numer of lines
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void mos6560_drawlines( running_device *device, int first, int last )
|
||||
{
|
||||
mos6560_state *mos6560 = get_safe_token(device);
|
||||
int line, vline;
|
||||
int offs, yoff, xoff, ybegin, yend, i, j;
|
||||
int attr, ch;
|
||||
|
||||
mos6560->lastline = last;
|
||||
if (first >= last)
|
||||
return;
|
||||
|
||||
for (line = first; (line < mos6560->ypos) && (line < last); line++)
|
||||
{
|
||||
for (j = 0; j < mos6560->total_xsize; j++)
|
||||
*BITMAP_ADDR16(mos6560->bitmap, line, j) = mos6560->framecolor;
|
||||
}
|
||||
|
||||
for (vline = line - mos6560->ypos; (line < last) && (line < mos6560->ypos + mos6560->ysize);)
|
||||
{
|
||||
if (mos6560->matrix8x16)
|
||||
{
|
||||
offs = (vline >> 4) * mos6560->chars_x;
|
||||
yoff = (vline & ~0xf) + mos6560->ypos;
|
||||
ybegin = vline & 0xf;
|
||||
yend = (vline + 0xf < last - mos6560->ypos) ? 0xf : ((last - line) & 0xf) + ybegin;
|
||||
}
|
||||
else
|
||||
{
|
||||
offs = (vline >> 3) * mos6560->chars_x;
|
||||
yoff = (vline & ~7) + mos6560->ypos;
|
||||
ybegin = vline & 7;
|
||||
yend = (vline + 7 < last - mos6560->ypos) ? 7 : ((last - line) & 7) + ybegin;
|
||||
}
|
||||
|
||||
if (mos6560->xpos > 0)
|
||||
{
|
||||
for (i = ybegin; i <= yend; i++)
|
||||
for (j = 0; j < mos6560->xpos; j++)
|
||||
*BITMAP_ADDR16(mos6560->bitmap, yoff + i, j) = mos6560->framecolor;
|
||||
}
|
||||
|
||||
for (xoff = mos6560->xpos; (xoff < mos6560->xpos + mos6560->xsize) && (xoff < mos6560->total_xsize); xoff += 8, offs++)
|
||||
{
|
||||
ch = mos6560->dma_read(device->machine, (mos6560->videoaddr + offs) & 0x3fff);
|
||||
attr = (mos6560->dma_read_color(device->machine, (mos6560->videoaddr + offs) & 0x3fff)) & 0xf;
|
||||
|
||||
if (mos6560->type == MOS6560_ATTACKUFO)
|
||||
{
|
||||
/* the mos6560 variant used in attckufo only has only one draw mode */
|
||||
mos6560->mono[1] = attr;
|
||||
mos6560_draw_character(device, ybegin, yend, ch, yoff, xoff, mos6560->mono);
|
||||
}
|
||||
else if (mos6560->inverted)
|
||||
{
|
||||
if (attr & 8)
|
||||
{
|
||||
mos6560->multiinverted[0] = attr & 7;
|
||||
mos6560_draw_character_multi(device, ybegin, yend, ch, yoff, xoff, mos6560->multiinverted);
|
||||
}
|
||||
else
|
||||
{
|
||||
mos6560->monoinverted[0] = attr;
|
||||
mos6560_draw_character(device, ybegin, yend, ch, yoff, xoff, mos6560->monoinverted);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (attr & 8)
|
||||
{
|
||||
mos6560->multi[2] = attr & 7;
|
||||
mos6560_draw_character_multi(device, ybegin, yend, ch, yoff, xoff, mos6560->multi);
|
||||
}
|
||||
else
|
||||
{
|
||||
mos6560->mono[1] = attr;
|
||||
mos6560_draw_character(device, ybegin, yend, ch, yoff, xoff, mos6560->mono);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (xoff < mos6560->total_xsize)
|
||||
{
|
||||
for (i = ybegin; i <= yend; i++)
|
||||
for (j = xoff; j < mos6560->total_xsize; j++)
|
||||
*BITMAP_ADDR16(mos6560->bitmap, yoff + i, j) = mos6560->framecolor;
|
||||
}
|
||||
|
||||
if (mos6560->matrix8x16)
|
||||
{
|
||||
vline = (vline + 16) & ~0xf;
|
||||
line = vline + mos6560->ypos;
|
||||
}
|
||||
else
|
||||
{
|
||||
vline = (vline + 8) & ~7;
|
||||
line = vline + mos6560->ypos;
|
||||
}
|
||||
}
|
||||
|
||||
for (; line < last; line++)
|
||||
for (j = 0; j < mos6560->total_xsize; j++)
|
||||
*BITMAP_ADDR16(mos6560->bitmap, line, j) = mos6560->framecolor;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mos6560_port_w - write to regs
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_DEVICE_HANDLER( mos6560_port_w )
|
||||
{
|
||||
mos6560_state *mos6560 = get_safe_token(device);
|
||||
|
||||
DBG_LOG(1, "mos6560_port_w", ("%.4x:%.2x\n", offset, data));
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0xa:
|
||||
case 0xb:
|
||||
case 0xc:
|
||||
case 0xd:
|
||||
case 0xe:
|
||||
mos6560_soundport_w(device, offset, data);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mos6560->reg[offset] != data)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 5:
|
||||
case 0xe:
|
||||
case 0xf:
|
||||
mos6560_drawlines(device, mos6560->lastline, mos6560->rasterline);
|
||||
break;
|
||||
}
|
||||
mos6560->reg[offset] = data;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
if ((mos6560->type != MOS6560_ATTACKUFO))
|
||||
mos6560->xpos = XPOS;
|
||||
break;
|
||||
case 1:
|
||||
if ((mos6560->type != MOS6560_ATTACKUFO))
|
||||
mos6560->ypos = YPOS;
|
||||
break;
|
||||
case 2:
|
||||
/* ntsc values >= 31 behave like 31 */
|
||||
/* pal value >= 32 behave like 32 */
|
||||
mos6560->chars_x = CHARS_X;
|
||||
mos6560->videoaddr = VIDEOADDR;
|
||||
mos6560->xsize = CHARS_X * 8;
|
||||
break;
|
||||
case 3:
|
||||
if ((mos6560->type != MOS6560_ATTACKUFO))
|
||||
{
|
||||
mos6560->matrix8x16 = data & 0x01;
|
||||
mos6560->charheight = mos6560->matrix8x16 ? 16 : 8;
|
||||
}
|
||||
mos6560->chars_y = CHARS_Y;
|
||||
mos6560->ysize = CHARS_Y * mos6560->charheight;
|
||||
break;
|
||||
case 5:
|
||||
mos6560->chargenaddr = CHARGENADDR;
|
||||
mos6560->videoaddr = VIDEOADDR;
|
||||
break;
|
||||
case 0xe:
|
||||
mos6560->multi[3] = mos6560->multiinverted[3] = mos6560->helpercolor = HELPERCOLOR;
|
||||
break;
|
||||
case 0xf:
|
||||
if ((mos6560->type != MOS6560_ATTACKUFO))
|
||||
mos6560->inverted = INVERTED;
|
||||
mos6560->multi[1] = mos6560->multiinverted[1] = mos6560->framecolor = FRAMECOLOR;
|
||||
mos6560->mono[0] = mos6560->monoinverted[1] = mos6560->multi[0] = mos6560->multiinverted[2] = mos6560->backgroundcolor = BACKGROUNDCOLOR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mos6560_port_r - read from regs
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_DEVICE_HANDLER( mos6560_port_r )
|
||||
{
|
||||
mos6560_state *mos6560 = get_safe_token(device);
|
||||
int val;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 3:
|
||||
val = ((mos6560->rasterline & 1) << 7) | (mos6560->reg[offset] & 0x7f);
|
||||
break;
|
||||
case 4: /*rasterline */
|
||||
mos6560_drawlines(device, mos6560->lastline, mos6560->rasterline);
|
||||
val = (mos6560->rasterline / 2) & 0xff;
|
||||
break;
|
||||
case 6: /*lightpen horizontal */
|
||||
case 7: /*lightpen vertical */
|
||||
if (LIGHTPEN_BUTTON && ((attotime_to_double(timer_get_time(device->machine)) - mos6560->lightpenreadtime) * MOS656X_VRETRACERATE >= 1))
|
||||
{
|
||||
/* only 1 update each frame */
|
||||
/* and diode must recognize light */
|
||||
if (1)
|
||||
{
|
||||
mos6560->reg[6] = MOS656X_X_VALUE;
|
||||
mos6560->reg[7] = MOS656X_Y_VALUE;
|
||||
}
|
||||
mos6560->lightpenreadtime = attotime_to_double(timer_get_time(device->machine));
|
||||
}
|
||||
val = mos6560->reg[offset];
|
||||
break;
|
||||
case 8: /* poti 1 */
|
||||
case 9: /* poti 2 */
|
||||
val = mos6560->paddle_cb[offset - 8](device->machine);
|
||||
break;
|
||||
default:
|
||||
val = mos6560->reg[offset];
|
||||
break;
|
||||
}
|
||||
DBG_LOG(3, "mos6560_port_r", ("%.4x:%.2x\n", offset, val));
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mos6560_raster_interrupt_gen
|
||||
-------------------------------------------------*/
|
||||
|
||||
void mos6560_raster_interrupt_gen( running_device *device )
|
||||
{
|
||||
mos6560_state *mos6560 = get_safe_token(device);
|
||||
|
||||
mos6560->rasterline++;
|
||||
if (mos6560->rasterline >= mos6560->total_lines)
|
||||
{
|
||||
mos6560->rasterline = 0;
|
||||
mos6560_drawlines(device, mos6560->lastline, mos6560->total_lines);
|
||||
mos6560->lastline = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mos6560_video_update - copy the VIC bitmap to
|
||||
main screen bitmap
|
||||
-------------------------------------------------*/
|
||||
|
||||
UINT32 mos6560_video_update( running_device *device, bitmap_t *bitmap, const rectangle *cliprect )
|
||||
{
|
||||
mos6560_state *mos6560 = get_safe_token(device);
|
||||
|
||||
copybitmap(bitmap, mos6560->bitmap, 0, 0, 0, 0, cliprect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
SOUND IMPLEMENTATION
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* assumed model:
|
||||
* each write to a ton/noise generated starts it new
|
||||
* each generator behaves like an timer
|
||||
* when it reaches 0, the next samplevalue is given out
|
||||
*/
|
||||
|
||||
/*
|
||||
* noise channel
|
||||
* based on a document by diku0748@diku.dk (Asger Alstrup Nielsen)
|
||||
*
|
||||
* 23 bit shift register
|
||||
* initial value (0x7ffff8)
|
||||
* after shift bit 0 is set to bit 22 xor bit 17
|
||||
* dac sample bit22 bit20 bit16 bit13 bit11 bit7 bit4 bit2(lsb)
|
||||
*
|
||||
* emulation:
|
||||
* allocate buffer for 5 sec sampledata (fastest played frequency)
|
||||
* and fill this buffer in init with the required sample
|
||||
* fast turning off channel, immediate change of frequency
|
||||
*/
|
||||
|
||||
#define NOISE_BUFFER_SIZE_SEC 5
|
||||
|
||||
#define TONE1_ON (mos6560->reg[0x0a] & 0x80)
|
||||
#define TONE2_ON (mos6560->reg[0x0b] & 0x80)
|
||||
#define TONE3_ON (mos6560->reg[0x0c] & 0x80)
|
||||
#define NOISE_ON (mos6560->reg[0x0d] & 0x80)
|
||||
#define VOLUME (mos6560->reg[0x0e] & 0x0f)
|
||||
|
||||
#define MOS656X_CLOCK ((mos6560->type == MOS6561) ? MOS6561_CLOCK : MOS6560_CLOCK)
|
||||
|
||||
#define TONE_FREQUENCY_MIN (MOS656X_CLOCK/256/128)
|
||||
|
||||
#define TONE1_VALUE (8 * (128 - ((mos6560->reg[0x0a] + 1) & 0x7f)))
|
||||
#define TONE1_FREQUENCY (MOS656X_CLOCK/32/TONE1_VALUE)
|
||||
|
||||
#define TONE2_VALUE (4 * (128 - ((mos6560->reg[0x0b] + 1) & 0x7f)))
|
||||
#define TONE2_FREQUENCY (MOS656X_CLOCK/32/TONE2_VALUE)
|
||||
|
||||
#define TONE3_VALUE (2 * (128 - ((mos6560->reg[0x0c] + 1) & 0x7f)))
|
||||
#define TONE3_FREQUENCY (MOS656X_CLOCK/32/TONE3_VALUE)
|
||||
|
||||
#define NOISE_VALUE (32 * (128 - ((mos6560->reg[0x0d] + 1) & 0x7f)))
|
||||
#define NOISE_FREQUENCY (MOS656X_CLOCK/NOISE_VALUE)
|
||||
|
||||
#define NOISE_FREQUENCY_MAX (MOS656X_CLOCK/32/1)
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mos6560_soundport_w - write to regs
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void mos6560_soundport_w( running_device *device, int offset, int data )
|
||||
{
|
||||
mos6560_state *mos6560 = get_safe_token(device);
|
||||
int old = mos6560->reg[offset];
|
||||
stream_update(mos6560->channel);
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x0a:
|
||||
mos6560->reg[offset] = data;
|
||||
if (!(old & 0x80) && TONE1_ON)
|
||||
{
|
||||
mos6560->tone1pos = 0;
|
||||
mos6560->tone1samples = device->machine->sample_rate / TONE1_FREQUENCY;
|
||||
if (!mos6560->tone1samples == 0)
|
||||
mos6560->tone1samples = 1;
|
||||
}
|
||||
DBG_LOG(1, "mos6560", ("tone1 %.2x %d\n", data, TONE1_FREQUENCY));
|
||||
break;
|
||||
case 0x0b:
|
||||
mos6560->reg[offset] = data;
|
||||
if (!(old & 0x80) && TONE2_ON)
|
||||
{
|
||||
mos6560->tone2pos = 0;
|
||||
mos6560->tone2samples = device->machine->sample_rate / TONE2_FREQUENCY;
|
||||
if (mos6560->tone2samples == 0)
|
||||
mos6560->tone2samples = 1;
|
||||
}
|
||||
DBG_LOG(1, "mos6560", ("tone2 %.2x %d\n", data, TONE2_FREQUENCY));
|
||||
break;
|
||||
case 0x0c:
|
||||
mos6560->reg[offset] = data;
|
||||
if (!(old & 0x80) && TONE3_ON)
|
||||
{
|
||||
mos6560->tone3pos = 0;
|
||||
mos6560->tone3samples = device->machine->sample_rate / TONE3_FREQUENCY;
|
||||
if (mos6560->tone3samples == 0)
|
||||
mos6560->tone3samples = 1;
|
||||
}
|
||||
DBG_LOG(1, "mos6560", ("tone3 %.2x %d\n", data, TONE3_FREQUENCY));
|
||||
break;
|
||||
case 0x0d:
|
||||
mos6560->reg[offset] = data;
|
||||
if (NOISE_ON)
|
||||
{
|
||||
mos6560->noisesamples = (int) ((double) NOISE_FREQUENCY_MAX * device->machine->sample_rate
|
||||
* NOISE_BUFFER_SIZE_SEC / NOISE_FREQUENCY);
|
||||
DBG_LOG (1, "mos6560", ("noise %.2x %d sample:%d\n",
|
||||
data, NOISE_FREQUENCY, mos6560->noisesamples));
|
||||
if ((double) mos6560->noisepos / mos6560->noisesamples >= 1.0)
|
||||
{
|
||||
mos6560->noisepos = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mos6560->noisepos = 0;
|
||||
}
|
||||
break;
|
||||
case 0x0e:
|
||||
mos6560->reg[offset] = (old & ~0x0f) | (data & 0x0f);
|
||||
DBG_LOG (3, "mos6560", ("volume %d\n", data & 0x0f));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mos6560_update - update audio stream
|
||||
-------------------------------------------------*/
|
||||
|
||||
static STREAM_UPDATE( mos6560_update )
|
||||
{
|
||||
mos6560_state *mos6560 = get_safe_token(device);
|
||||
int i, v;
|
||||
stream_sample_t *buffer = outputs[0];
|
||||
|
||||
for (i = 0; i < samples; i++)
|
||||
{
|
||||
v = 0;
|
||||
if (TONE1_ON /*||(mos6560->tone1pos != 0) */ )
|
||||
{
|
||||
v += mos6560->tone[mos6560->tone1pos * mos6560->tonesize / mos6560->tone1samples];
|
||||
mos6560->tone1pos++;
|
||||
#if 0
|
||||
mos6560->tone1pos %= mos6560->tone1samples;
|
||||
#else
|
||||
if (mos6560->tone1pos >= mos6560->tone1samples)
|
||||
{
|
||||
mos6560->tone1pos = 0;
|
||||
mos6560->tone1samples = device->machine->sample_rate / TONE1_FREQUENCY;
|
||||
if (mos6560->tone1samples == 0)
|
||||
mos6560->tone1samples = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (TONE2_ON /*||(mos6560->tone2pos != 0) */ )
|
||||
{
|
||||
v += mos6560->tone[mos6560->tone2pos * mos6560->tonesize / mos6560->tone2samples];
|
||||
mos6560->tone2pos++;
|
||||
#if 0
|
||||
mos6560->tone2pos %= mos6560->tone2samples;
|
||||
#else
|
||||
if (mos6560->tone2pos >= mos6560->tone2samples)
|
||||
{
|
||||
mos6560->tone2pos = 0;
|
||||
mos6560->tone2samples = device->machine->sample_rate / TONE2_FREQUENCY;
|
||||
if (mos6560->tone2samples == 0)
|
||||
mos6560->tone2samples = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (TONE3_ON /*||(mos6560->tone3pos != 0) */ )
|
||||
{
|
||||
v += mos6560->tone[mos6560->tone3pos * mos6560->tonesize / mos6560->tone3samples];
|
||||
mos6560->tone3pos++;
|
||||
#if 0
|
||||
mos6560->tone3pos %= mos6560->tone3samples;
|
||||
#else
|
||||
if (mos6560->tone3pos >= mos6560->tone3samples)
|
||||
{
|
||||
mos6560->tone3pos = 0;
|
||||
mos6560->tone3samples = device->machine->sample_rate / TONE3_FREQUENCY;
|
||||
if (mos6560->tone3samples == 0)
|
||||
mos6560->tone3samples = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (NOISE_ON)
|
||||
{
|
||||
v += mos6560->noise[(int) ((double) mos6560->noisepos * mos6560->noisesize / mos6560->noisesamples)];
|
||||
mos6560->noisepos++;
|
||||
if ((double) mos6560->noisepos / mos6560->noisesamples >= 1.0)
|
||||
{
|
||||
mos6560->noisepos = 0;
|
||||
}
|
||||
}
|
||||
v = (v * VOLUME) << 2;
|
||||
if (v > 32767)
|
||||
buffer[i] = 32767;
|
||||
else if (v < -32767)
|
||||
buffer[i] = -32767;
|
||||
else
|
||||
buffer[i] = v;
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
DEVICE INTERFACE
|
||||
*****************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
mos6560_sound_start - start audio emulation
|
||||
(to be called at device start)
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void mos6560_sound_start( running_device *device )
|
||||
{
|
||||
mos6560_state *mos6560 = get_safe_token(device);
|
||||
int i;
|
||||
|
||||
mos6560->channel = stream_create(device, 0, 1, device->machine->sample_rate, 0, mos6560_update);
|
||||
|
||||
/* buffer for fastest played sample for 5 second so we have enough data for min 5 second */
|
||||
mos6560->noisesize = NOISE_FREQUENCY_MAX * NOISE_BUFFER_SIZE_SEC;
|
||||
mos6560->noise = auto_alloc_array(device->machine, INT8, mos6560->noisesize);
|
||||
{
|
||||
int noiseshift = 0x7ffff8;
|
||||
char data;
|
||||
|
||||
for (i = 0; i < mos6560->noisesize; i++)
|
||||
{
|
||||
data = 0;
|
||||
if (noiseshift & 0x400000)
|
||||
data |= 0x80;
|
||||
if (noiseshift & 0x100000)
|
||||
data |= 0x40;
|
||||
if (noiseshift & 0x010000)
|
||||
data |= 0x20;
|
||||
if (noiseshift & 0x002000)
|
||||
data |= 0x10;
|
||||
if (noiseshift & 0x000800)
|
||||
data |= 0x08;
|
||||
if (noiseshift & 0x000080)
|
||||
data |= 0x04;
|
||||
if (noiseshift & 0x000010)
|
||||
data |= 0x02;
|
||||
if (noiseshift & 0x000004)
|
||||
data |= 0x01;
|
||||
mos6560->noise[i] = data;
|
||||
if (((noiseshift & 0x400000) == 0) != ((noiseshift & 0x002000) == 0))
|
||||
noiseshift = (noiseshift << 1) | 1;
|
||||
else
|
||||
noiseshift <<= 1;
|
||||
}
|
||||
}
|
||||
mos6560->tonesize = device->machine->sample_rate / TONE_FREQUENCY_MIN;
|
||||
|
||||
if (mos6560->tonesize > 0)
|
||||
{
|
||||
mos6560->tone = auto_alloc_array(device->machine, INT16, mos6560->tonesize);
|
||||
|
||||
for (i = 0; i < mos6560->tonesize; i++)
|
||||
{
|
||||
mos6560->tone[i] = (INT16)(sin (2 * M_PI * i / mos6560->tonesize) * 127 + 0.5);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mos6560->tone = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
DEVICE_START( mos6560 )
|
||||
-------------------------------------------------*/
|
||||
|
||||
static DEVICE_START( mos6560 )
|
||||
{
|
||||
mos6560_state *mos6560 = get_safe_token(device);
|
||||
const mos6560_interface *intf = (mos6560_interface *)device->baseconfig().static_config;
|
||||
int width, height;
|
||||
|
||||
mos6560->screen = devtag_get_device(device->machine, intf->screen);
|
||||
width = video_screen_get_width(mos6560->screen);
|
||||
height = video_screen_get_height(mos6560->screen);
|
||||
|
||||
mos6560->type = intf->type;
|
||||
|
||||
mos6560->bitmap = auto_bitmap_alloc(device->machine, width, height, BITMAP_FORMAT_INDEXED16);
|
||||
|
||||
mos6560->dma_read = intf->dma_read;
|
||||
mos6560->dma_read_color = intf->dma_read_color;
|
||||
|
||||
mos6560->lightpen_button_cb = intf->button_cb;
|
||||
mos6560->lightpen_x_cb = intf->x_cb;
|
||||
mos6560->lightpen_y_cb = intf->y_cb;
|
||||
|
||||
mos6560->paddle_cb[0] = intf->paddle0_cb;
|
||||
mos6560->paddle_cb[1] = intf->paddle1_cb;
|
||||
|
||||
switch (mos6560->type)
|
||||
{
|
||||
case MOS6560:
|
||||
mos6560->total_xsize = MOS6560_XSIZE;
|
||||
mos6560->total_ysize = MOS6560_YSIZE;
|
||||
mos6560->total_lines = MOS6560_LINES;
|
||||
mos6560->total_vretracerate = MOS6560_VRETRACERATE;
|
||||
break;
|
||||
case MOS6560_ATTACKUFO:
|
||||
mos6560->total_xsize = 23 * 8;
|
||||
mos6560->total_ysize = 22 * 8;
|
||||
mos6560->total_lines = MOS6560_LINES;
|
||||
mos6560->total_vretracerate = MOS6560_VRETRACERATE;
|
||||
break;
|
||||
case MOS6561:
|
||||
mos6560->total_xsize = MOS6561_XSIZE;
|
||||
mos6560->total_ysize = MOS6561_YSIZE;
|
||||
mos6560->total_lines = MOS6561_LINES;
|
||||
mos6560->total_vretracerate = MOS6561_VRETRACERATE;
|
||||
break;
|
||||
}
|
||||
|
||||
mos6560_sound_start(device);
|
||||
|
||||
state_save_register_device_item(device, 0, mos6560->lightpenreadtime);
|
||||
state_save_register_device_item(device, 0, mos6560->rasterline);
|
||||
state_save_register_device_item(device, 0, mos6560->lastline);
|
||||
|
||||
state_save_register_device_item(device, 0, mos6560->charheight);
|
||||
state_save_register_device_item(device, 0, mos6560->matrix8x16);
|
||||
state_save_register_device_item(device, 0, mos6560->inverted);
|
||||
state_save_register_device_item(device, 0, mos6560->chars_x);
|
||||
state_save_register_device_item(device, 0, mos6560->chars_y);
|
||||
state_save_register_device_item(device, 0, mos6560->xsize);
|
||||
state_save_register_device_item(device, 0, mos6560->ysize);
|
||||
state_save_register_device_item(device, 0, mos6560->xpos);
|
||||
state_save_register_device_item(device, 0, mos6560->ypos);
|
||||
state_save_register_device_item(device, 0, mos6560->chargenaddr);
|
||||
state_save_register_device_item(device, 0, mos6560->videoaddr);
|
||||
|
||||
state_save_register_device_item(device, 0, mos6560->backgroundcolor);
|
||||
state_save_register_device_item(device, 0, mos6560->framecolor);
|
||||
state_save_register_device_item(device, 0, mos6560->helpercolor);
|
||||
|
||||
state_save_register_device_item_array(device, 0, mos6560->reg);
|
||||
|
||||
state_save_register_device_item_array(device, 0, mos6560->mono);
|
||||
state_save_register_device_item_array(device, 0, mos6560->monoinverted);
|
||||
state_save_register_device_item_array(device, 0, mos6560->multi);
|
||||
state_save_register_device_item_array(device, 0, mos6560->multiinverted);
|
||||
|
||||
state_save_register_device_item_bitmap(device, 0, mos6560->bitmap);
|
||||
|
||||
state_save_register_device_item(device, 0, mos6560->tone1pos);
|
||||
state_save_register_device_item(device, 0, mos6560->tone2pos);
|
||||
state_save_register_device_item(device, 0, mos6560->tone3pos);
|
||||
state_save_register_device_item(device, 0, mos6560->tone1samples);
|
||||
state_save_register_device_item(device, 0, mos6560->tone2samples);
|
||||
state_save_register_device_item(device, 0, mos6560->tone3samples);
|
||||
state_save_register_device_item(device, 0, mos6560->noisepos);
|
||||
state_save_register_device_item(device, 0, mos6560->noisesamples);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
DEVICE_RESET( mos6560 )
|
||||
-------------------------------------------------*/
|
||||
|
||||
static DEVICE_RESET( mos6560 )
|
||||
{
|
||||
mos6560_state *mos6560 = get_safe_token(device);
|
||||
|
||||
mos6560->lightpenreadtime = 0.0;
|
||||
mos6560->rasterline = 0;
|
||||
mos6560->lastline = 0;
|
||||
|
||||
memset(mos6560->reg, 0, 16);
|
||||
|
||||
mos6560->charheight = 8;
|
||||
mos6560->matrix8x16 = 0;
|
||||
mos6560->inverted = 0;
|
||||
mos6560->chars_x = 0;
|
||||
mos6560->chars_y = 0;
|
||||
mos6560->xsize = 0;
|
||||
mos6560->ysize = 0;
|
||||
mos6560->xpos = 0;
|
||||
mos6560->ypos = 0;
|
||||
mos6560->chargenaddr = 0;
|
||||
mos6560->videoaddr = 0;
|
||||
|
||||
mos6560->backgroundcolor = 0;
|
||||
mos6560->framecolor = 0;
|
||||
mos6560->helpercolor = 0;
|
||||
|
||||
mos6560->mono[0] = 0;
|
||||
mos6560->mono[1] = 0;
|
||||
mos6560->monoinverted[0] = 0;
|
||||
mos6560->monoinverted[1] = 0;
|
||||
mos6560->multi[0] = 0;
|
||||
mos6560->multi[1] = 0;
|
||||
mos6560->multi[2] = 0;
|
||||
mos6560->multi[3] = 0;
|
||||
mos6560->multiinverted[0] = 0;
|
||||
mos6560->multiinverted[1] = 0;
|
||||
mos6560->multiinverted[2] = 0;
|
||||
mos6560->multiinverted[3] = 0;
|
||||
|
||||
mos6560->tone1pos = 0;
|
||||
mos6560->tone2pos = 0;
|
||||
mos6560->tone3pos = 0;
|
||||
mos6560->tone1samples = 1;
|
||||
mos6560->tone2samples = 1;
|
||||
mos6560->tone3samples = 1;
|
||||
mos6560->noisepos = 0;
|
||||
mos6560->noisesamples = 1;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
Device definition
|
||||
-------------------------------------------------*/
|
||||
|
||||
static const char DEVTEMPLATE_SOURCE[] = __FILE__;
|
||||
|
||||
#define DEVTEMPLATE_ID(p,s) p##mos6560##s
|
||||
#define DEVTEMPLATE_FEATURES DT_HAS_START | DT_HAS_RESET
|
||||
#define DEVTEMPLATE_NAME "MOS 6560 / 6561 VIC"
|
||||
#define DEVTEMPLATE_FAMILY "MOS Video Interface Chip"
|
||||
#include "devtempl.h"
|
116
src/emu/sound/mos6560.h
Normal file
116
src/emu/sound/mos6560.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* audio/vic6560.h
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __MOS6560_H__
|
||||
#define __MOS6560_H__
|
||||
|
||||
#include "devcb.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
typedef UINT8 (*mos6560_lightpen_x_callback)(running_machine *machine);
|
||||
typedef UINT8 (*mos6560_lightpen_y_callback)(running_machine *machine);
|
||||
typedef UINT8 (*mos6560_lightpen_button_callback)(running_machine *machine);
|
||||
typedef UINT8 (*mos6560_paddle_callback)(running_machine *machine);
|
||||
|
||||
typedef int (*mos6560_dma_read)(running_machine *machine, int);
|
||||
typedef int (*mos6560_dma_read_color)(running_machine *machine, int);
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MOS6560_ATTACKUFO, // this is a 6560VIC derivative, missing some of the features
|
||||
MOS6560, // this is the NTSC version
|
||||
MOS6561 // this is the PAL version
|
||||
} mos6560_type;
|
||||
|
||||
typedef struct _mos6560_interface mos6560_interface;
|
||||
struct _mos6560_interface
|
||||
{
|
||||
const char *screen;
|
||||
|
||||
mos6560_type type;
|
||||
|
||||
mos6560_lightpen_x_callback x_cb;
|
||||
mos6560_lightpen_y_callback y_cb;
|
||||
mos6560_lightpen_button_callback button_cb;
|
||||
|
||||
mos6560_paddle_callback paddle0_cb, paddle1_cb;
|
||||
|
||||
mos6560_dma_read dma_read;
|
||||
mos6560_dma_read_color dma_read_color;
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
#define MOS6560_VRETRACERATE 60
|
||||
#define MOS6561_VRETRACERATE 50
|
||||
#define MOS656X_HRETRACERATE 15625
|
||||
|
||||
#define MOS6560_MAME_XPOS 4 /* xleft not displayed */
|
||||
#define MOS6560_MAME_YPOS 10 /* y up not displayed */
|
||||
#define MOS6561_MAME_XPOS 20
|
||||
#define MOS6561_MAME_YPOS 10
|
||||
#define MOS6560_MAME_XSIZE 200
|
||||
#define MOS6560_MAME_YSIZE 248
|
||||
#define MOS6561_MAME_XSIZE 224
|
||||
#define MOS6561_MAME_YSIZE 296
|
||||
/* real values */
|
||||
|
||||
#define MOS6560_LINES 261
|
||||
#define MOS6561_LINES 312
|
||||
|
||||
#define MOS6560_XSIZE (4+201) /* 4 left not visible */
|
||||
#define MOS6560_YSIZE (10+251) /* 10 not visible */
|
||||
/* cycles 65 */
|
||||
|
||||
#define MOS6561_XSIZE (20+229) /* 20 left not visible */
|
||||
#define MOS6561_YSIZE (10+302) /* 10 not visible */
|
||||
/* cycles 71 */
|
||||
|
||||
|
||||
/* the following values depend on the VIC clock,
|
||||
* but to achieve TV-frequency the clock must have a fix frequency */
|
||||
#define MOS6560_CLOCK (14318181/14)
|
||||
#define MOS6561_CLOCK (4433618/4)
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
INFO PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
DEVICE_GET_INFO( mos6560 );
|
||||
|
||||
/***************************************************************************
|
||||
DEVICE CONFIGURATION MACROS
|
||||
***************************************************************************/
|
||||
|
||||
#define MOS656X DEVICE_GET_INFO_NAME( mos6560 )
|
||||
#define SOUND_MOS656X MOS656X
|
||||
|
||||
#define MDRV_MOS656X_ADD(_tag, _interface) \
|
||||
MDRV_DEVICE_ADD(_tag, SOUND, 0) \
|
||||
MDRV_DEVICE_CONFIG_DATAPTR(sound_config, type, SOUND_MOS656X) \
|
||||
MDRV_DEVICE_CONFIG(_interface)
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
I/O PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
WRITE8_DEVICE_HANDLER( mos6560_port_w );
|
||||
READ8_DEVICE_HANDLER( mos6560_port_r );
|
||||
|
||||
void mos6560_raster_interrupt_gen( running_device *device );
|
||||
UINT32 mos6560_video_update( running_device *device, bitmap_t *bitmap, const rectangle *cliprect );
|
||||
|
||||
|
||||
#endif /* __MOS6560_H__ */
|
@ -270,6 +270,17 @@ SOUNDOBJS += $(SOUNDOBJ)/k056800.o
|
||||
endif
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------
|
||||
# MOS 6560VIC
|
||||
#-------------------------------------------------
|
||||
|
||||
ifneq ($(filter MOS656X,$(SOUNDS)),)
|
||||
SOUNDOBJS += $(SOUNDOBJ)/mos6560.o
|
||||
endif
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------
|
||||
# Namco custom sound chips
|
||||
#-------------------------------------------------
|
||||
|
@ -43,12 +43,36 @@ LOIPOIO-B
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "includes/attckufo.h"
|
||||
#include "sound/mos6560.h"
|
||||
|
||||
|
||||
static UINT8 *mainram;
|
||||
static UINT8 *tileram;
|
||||
|
||||
static const rgb_t attckufo_palette[] =
|
||||
{
|
||||
/* ripped from vice, a very excellent emulator */
|
||||
MAKE_RGB(0x00, 0x00, 0x00),
|
||||
MAKE_RGB(0xff, 0xff, 0xff),
|
||||
MAKE_RGB(0xf0, 0x00, 0x00),
|
||||
MAKE_RGB(0x00, 0xf0, 0xf0),
|
||||
|
||||
MAKE_RGB(0x60, 0x00, 0x60),
|
||||
MAKE_RGB(0x00, 0xa0, 0x00),
|
||||
MAKE_RGB(0x00, 0x00, 0xf0),
|
||||
MAKE_RGB(0xd0, 0xd0, 0x00),
|
||||
|
||||
MAKE_RGB(0xc0, 0xa0, 0x00),
|
||||
MAKE_RGB(0xff, 0xa0, 0x00),
|
||||
MAKE_RGB(0xf0, 0x80, 0x80),
|
||||
MAKE_RGB(0x00, 0xff, 0xff),
|
||||
|
||||
MAKE_RGB(0xff, 0x00, 0xff),
|
||||
MAKE_RGB(0x00, 0xff, 0x00),
|
||||
MAKE_RGB(0x00, 0xa0, 0xff),
|
||||
MAKE_RGB(0xff, 0xff, 0x00)
|
||||
};
|
||||
|
||||
static PALETTE_INIT( attckufo )
|
||||
{
|
||||
palette_set_colors(machine, 0, attckufo_palette, ARRAY_LENGTH(attckufo_palette));
|
||||
@ -80,7 +104,7 @@ static WRITE8_HANDLER(attckufo_io_w)
|
||||
static ADDRESS_MAP_START( cpu_map, ADDRESS_SPACE_PROGRAM, 8 )
|
||||
ADDRESS_MAP_GLOBAL_MASK(0x3fff)
|
||||
AM_RANGE(0x0000, 0x0fff) AM_RAM AM_BASE(&mainram)
|
||||
AM_RANGE(0x1000, 0x100f) AM_READWRITE(attckufo_port_r, attckufo_port_w)
|
||||
AM_RANGE(0x1000, 0x100f) AM_DEVREADWRITE("mos6560", mos6560_port_r, mos6560_port_w)
|
||||
AM_RANGE(0x1400, 0x1403) AM_READWRITE(attckufo_io_r, attckufo_io_w)
|
||||
AM_RANGE(0x1c00, 0x1fff) AM_RAM AM_BASE(&tileram)
|
||||
AM_RANGE(0x2000, 0x3fff) AM_ROM
|
||||
@ -114,28 +138,61 @@ static INPUT_PORTS_START( attckufo )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
INTERRUPT_GEN( attckufo_raster_interrupt )
|
||||
{
|
||||
running_device *mos6560 = devtag_get_device(device->machine, "mos6560");
|
||||
mos6560_raster_interrupt_gen(mos6560);
|
||||
}
|
||||
|
||||
VIDEO_UPDATE( attckufo )
|
||||
{
|
||||
running_device *mos6560 = devtag_get_device(screen->machine, "mos6560");
|
||||
mos6560_video_update(mos6560, bitmap, cliprect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int attckufo_dma_read( running_machine *machine, int offset )
|
||||
{
|
||||
const address_space *program = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM);
|
||||
return memory_read_byte(program, offset);
|
||||
}
|
||||
|
||||
static int attckufo_dma_read_color( running_machine *machine, int offset )
|
||||
{
|
||||
const address_space *program = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM);
|
||||
return memory_read_byte(program, offset + 0x400);
|
||||
}
|
||||
|
||||
static const mos6560_interface attckufo_6560_intf =
|
||||
{
|
||||
"screen", /* screen */
|
||||
MOS6560_ATTACKUFO,
|
||||
NULL, NULL, NULL, /* lightgun cb */
|
||||
NULL, NULL, /* paddle cb */
|
||||
attckufo_dma_read, attckufo_dma_read_color /* DMA */
|
||||
};
|
||||
|
||||
static MACHINE_DRIVER_START( attckufo )
|
||||
MDRV_CPU_ADD("maincpu", M6502, 14318181/14)
|
||||
MDRV_CPU_PROGRAM_MAP(cpu_map)
|
||||
MDRV_CPU_PERIODIC_INT(attckufo_raster_interrupt, 15625)
|
||||
|
||||
/* video hardware */
|
||||
MDRV_CPU_PERIODIC_INT(attckufo_raster_interrupt, MOS656X_HRETRACERATE)
|
||||
|
||||
/* video hardware */
|
||||
MDRV_SCREEN_ADD("screen", RASTER)
|
||||
MDRV_SCREEN_REFRESH_RATE(60)
|
||||
MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
|
||||
MDRV_SCREEN_REFRESH_RATE(MOS6560_VRETRACERATE)
|
||||
MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
||||
MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
|
||||
MDRV_SCREEN_SIZE(256, 256)
|
||||
MDRV_SCREEN_VISIBLE_AREA(0, 23*8-1, 0, 22*8-1)
|
||||
MDRV_SCREEN_SIZE((MOS6560_XSIZE + 7) & ~7, MOS6560_YSIZE)
|
||||
MDRV_SCREEN_VISIBLE_AREA(0, 23*8 - 1, 0, 22*8 - 1)
|
||||
|
||||
MDRV_PALETTE_LENGTH(ARRAY_LENGTH(attckufo_palette))
|
||||
MDRV_PALETTE_INIT( attckufo )
|
||||
MDRV_PALETTE_INIT(attckufo)
|
||||
|
||||
MDRV_VIDEO_UPDATE( attckufo )
|
||||
MDRV_VIDEO_UPDATE(attckufo)
|
||||
|
||||
/* sound hardware */
|
||||
MDRV_SPEAKER_STANDARD_MONO("mono")
|
||||
MDRV_SOUND_ADD("attckufo", ATTCKUFO, 0)
|
||||
MDRV_MOS656X_ADD("mos6560", attckufo_6560_intf)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
@ -154,4 +211,4 @@ ROM_START( attckufo )
|
||||
ROM_COPY( "maincpu", 0x02000, 0x00000, 0x400)
|
||||
ROM_END
|
||||
|
||||
GAME( 1980, attckufo, 0, attckufo, attckufo, 0, ROT270, "Ryoto Electric Co.", "Attack Ufo", 0)
|
||||
GAME( 1980, attckufo, 0, attckufo, attckufo, 0, ROT270, "Ryoto Electric Co.", "Attack Ufo", 0 )
|
||||
|
@ -1,20 +0,0 @@
|
||||
/*----------- defined in audio/attckufo.c -----------*/
|
||||
|
||||
void attckufo_soundport_w (int offset, int data);
|
||||
|
||||
DEVICE_GET_INFO( attckufo_sound );
|
||||
#define SOUND_ATTCKUFO DEVICE_GET_INFO_NAME(attckufo_sound)
|
||||
|
||||
|
||||
/*----------- defined in video/attckufo.c -----------*/
|
||||
|
||||
extern const rgb_t attckufo_palette[16];
|
||||
extern UINT8 attckufo_regs[16];
|
||||
|
||||
VIDEO_UPDATE( attckufo );
|
||||
|
||||
WRITE8_HANDLER ( attckufo_port_w );
|
||||
READ8_HANDLER ( attckufo_port_r );
|
||||
|
||||
INTERRUPT_GEN( attckufo_raster_interrupt );
|
||||
|
@ -221,6 +221,7 @@ SOUNDS += DIGITALKER
|
||||
SOUNDS += CDP1863
|
||||
SOUNDS += CDP1864
|
||||
SOUNDS += ZSG2
|
||||
SOUNDS += MOS656X
|
||||
|
||||
#-------------------------------------------------
|
||||
# this is the list of driver libraries that
|
||||
@ -1485,7 +1486,7 @@ $(MAMEOBJ)/misc.a: \
|
||||
$(DRIVERS)/amspdwy.o $(VIDEO)/amspdwy.o \
|
||||
$(DRIVERS)/artmagic.o $(VIDEO)/artmagic.o \
|
||||
$(DRIVERS)/astrocorp.o \
|
||||
$(DRIVERS)/attckufo.o $(AUDIO)/attckufo.o $(VIDEO)/attckufo.o \
|
||||
$(DRIVERS)/attckufo.o \
|
||||
$(DRIVERS)/aztarac.o $(AUDIO)/aztarac.o $(VIDEO)/aztarac.o \
|
||||
$(DRIVERS)/beaminv.o \
|
||||
$(DRIVERS)/big10.o \
|
||||
|
@ -1,171 +0,0 @@
|
||||
/***************************************************************************
|
||||
|
||||
Attack ufo video emulation
|
||||
based on MOS 6560 emulator by
|
||||
PeT mess@utanet.at
|
||||
|
||||
Differences between 6560 and Attack Ufo chip:
|
||||
- no invert mode
|
||||
- no multicolor
|
||||
- 16 col chars
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/attckufo.h"
|
||||
|
||||
#define MAX_LINES 261
|
||||
|
||||
const rgb_t attckufo_palette[] =
|
||||
{
|
||||
/* ripped from vice, a very excellent emulator */
|
||||
MAKE_RGB(0x00, 0x00, 0x00),
|
||||
MAKE_RGB(0xff, 0xff, 0xff),
|
||||
MAKE_RGB(0xf0, 0x00, 0x00),
|
||||
MAKE_RGB(0x00, 0xf0, 0xf0),
|
||||
|
||||
MAKE_RGB(0x60, 0x00, 0x60),
|
||||
MAKE_RGB(0x00, 0xa0, 0x00),
|
||||
MAKE_RGB(0x00, 0x00, 0xf0),
|
||||
MAKE_RGB(0xd0, 0xd0, 0x00),
|
||||
|
||||
MAKE_RGB(0xc0, 0xa0, 0x00),
|
||||
MAKE_RGB(0xff, 0xa0, 0x00),
|
||||
MAKE_RGB(0xf0, 0x80, 0x80),
|
||||
MAKE_RGB(0x00, 0xff, 0xff),
|
||||
|
||||
MAKE_RGB(0xff, 0x00, 0xff),
|
||||
MAKE_RGB(0x00, 0xff, 0x00),
|
||||
MAKE_RGB(0x00, 0xa0, 0xff),
|
||||
MAKE_RGB(0xff, 0xff, 0x00)
|
||||
};
|
||||
|
||||
|
||||
|
||||
UINT8 attckufo_regs[16];
|
||||
|
||||
#define CHARS_X ((int)attckufo_regs[2]&0x7f)
|
||||
#define CHARS_Y (((int)attckufo_regs[3]&0x7e)>>1)
|
||||
|
||||
|
||||
#define XSIZE (CHARS_X*8)
|
||||
#define YSIZE (CHARS_Y*8)
|
||||
|
||||
#define CHARGENADDR (((int)attckufo_regs[5]&0xf)<<10)
|
||||
#define VIDEOADDR ( ( ((int)attckufo_regs[5]&0xf0)<<(10-4))\
|
||||
| ( ((int)attckufo_regs[2]&0x80)<<(9-7)) )
|
||||
|
||||
static int rasterline = 0;
|
||||
|
||||
static int chars_x, chars_y;
|
||||
static int xsize, ysize ;
|
||||
static int chargenaddr, videoaddr;
|
||||
|
||||
WRITE8_HANDLER ( attckufo_port_w )
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0xa:
|
||||
case 0xb:
|
||||
case 0xc:
|
||||
case 0xd:
|
||||
case 0xe:
|
||||
attckufo_soundport_w (offset, data);
|
||||
break;
|
||||
}
|
||||
if (attckufo_regs[offset] != data)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 5:
|
||||
case 0xe:
|
||||
case 0xf:
|
||||
video_screen_update_partial(space->machine->primary_screen, rasterline);
|
||||
break;
|
||||
}
|
||||
attckufo_regs[offset] = data;
|
||||
switch (offset)
|
||||
{
|
||||
case 2:
|
||||
/* ntsc values >= 31 behave like 31 */
|
||||
chars_x = CHARS_X;
|
||||
videoaddr = VIDEOADDR;
|
||||
xsize = XSIZE;
|
||||
break;
|
||||
case 3:
|
||||
chars_y = CHARS_Y;
|
||||
ysize = YSIZE;
|
||||
break;
|
||||
case 5:
|
||||
chargenaddr = CHARGENADDR;
|
||||
videoaddr = VIDEOADDR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
READ8_HANDLER ( attckufo_port_r )
|
||||
{
|
||||
int val;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 3:
|
||||
val = ((rasterline & 1) << 7) | (attckufo_regs[offset] & 0x7f);
|
||||
break;
|
||||
case 4: /*rasterline */
|
||||
val = (rasterline / 2) & 0xff;
|
||||
break;
|
||||
default:
|
||||
val = attckufo_regs[offset];
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
INTERRUPT_GEN( attckufo_raster_interrupt )
|
||||
{
|
||||
rasterline++;
|
||||
if (rasterline >= MAX_LINES)
|
||||
rasterline = 0;
|
||||
}
|
||||
|
||||
VIDEO_UPDATE( attckufo )
|
||||
{
|
||||
const address_space *space = cputag_get_address_space(screen->machine, "maincpu", ADDRESS_SPACE_PROGRAM);
|
||||
int x, y, yy;
|
||||
|
||||
for (y = cliprect->min_y & ~7; y <= cliprect->max_y; y += 8)
|
||||
{
|
||||
UINT16 *destrow = BITMAP_ADDR16(bitmap, y, 0);
|
||||
int offs = videoaddr + (y / 8) * chars_x;
|
||||
int ymin = MAX(y, cliprect->min_y) & 7;
|
||||
int ymax = MIN(y + 7, cliprect->max_y) & 7;
|
||||
|
||||
for (x = cliprect->min_x & ~7; x <= cliprect->max_x; x += 8)
|
||||
{
|
||||
UINT8 ch = memory_read_byte(space, offs + x/8);
|
||||
UINT8 attr = memory_read_byte(space, offs + x/8 + 0x400) & 0xf;
|
||||
UINT16 *dest = destrow;
|
||||
|
||||
for (yy = ymin; yy <= ymax; yy++)
|
||||
{
|
||||
UINT8 code = memory_read_byte(space, chargenaddr + ch * 8 + yy);
|
||||
dest[x + 0] = (code & 0x80) ? attr : 0;
|
||||
dest[x + 1] = (code & 0x40) ? attr : 0;
|
||||
dest[x + 2] = (code & 0x20) ? attr : 0;
|
||||
dest[x + 3] = (code & 0x10) ? attr : 0;
|
||||
dest[x + 4] = (code & 0x08) ? attr : 0;
|
||||
dest[x + 5] = (code & 0x04) ? attr : 0;
|
||||
dest[x + 6] = (code & 0x02) ? attr : 0;
|
||||
dest[x + 7] = (code & 0x01) ? attr : 0;
|
||||
dest += bitmap->rowpixels;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user