mirror of
https://github.com/holub/mame
synced 2025-05-30 09:33:05 +03:00
New games added or promoted from NOT_WORKING
-------------------------------------------- The Last Starfighter (prototype) [Phil Bennett, Ken Van Mersbergen] Air Race (prototype) [Phil Bennett, Ken Van Mersbergen]
This commit is contained in:
parent
f53f8c3660
commit
cf66ab4463
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1424,6 +1424,7 @@ src/mame/drivers/atarigt.c svneol=native#text/plain
|
||||
src/mame/drivers/atarigx2.c svneol=native#text/plain
|
||||
src/mame/drivers/atarisy1.c svneol=native#text/plain
|
||||
src/mame/drivers/atarisy2.c svneol=native#text/plain
|
||||
src/mame/drivers/atarisy4.c svneol=native#text/plain
|
||||
src/mame/drivers/ataxx.c svneol=native#text/plain
|
||||
src/mame/drivers/atetris.c svneol=native#text/plain
|
||||
src/mame/drivers/attckufo.c svneol=native#text/plain
|
||||
|
992
src/mame/drivers/atarisy4.c
Normal file
992
src/mame/drivers/atarisy4.c
Normal file
@ -0,0 +1,992 @@
|
||||
/***************************************************************************
|
||||
|
||||
Atari System IV hardware
|
||||
|
||||
preliminary driver by Phil Bennett
|
||||
|
||||
Games supported:
|
||||
* The Last Starfighter (prototype)
|
||||
* Air Race (prototype)
|
||||
|
||||
To do:
|
||||
* Finish video implementation
|
||||
* Find missing HUD/text data for both games
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "cpu/tms32010/tms32010.h"
|
||||
#include "video/poly.h"
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* State
|
||||
*
|
||||
*************************************/
|
||||
|
||||
struct _gpu_
|
||||
{
|
||||
/* Memory-mapped registers */
|
||||
UINT16 gr[8]; /* Command parameters */
|
||||
|
||||
UINT16 bcrw; /* Screen buffer W control */
|
||||
UINT16 bcrx; /* Screen buffer X control */
|
||||
UINT16 bcry; /* Screen buffer Y control */
|
||||
UINT16 bcrz; /* Screen buffer Z control */
|
||||
UINT16 psrw;
|
||||
UINT16 psrx;
|
||||
UINT16 psry;
|
||||
UINT16 psrz;
|
||||
|
||||
UINT16 dpr;
|
||||
UINT16 ctr;
|
||||
UINT16 lfr;
|
||||
UINT16 ifr;
|
||||
UINT16 ecr; /* Execute command register */
|
||||
UINT16 far;
|
||||
UINT16 mcr; /* Interrupt control */
|
||||
UINT16 qlr;
|
||||
UINT16 qar;
|
||||
|
||||
UINT16 dhr; /* Scanline counter */
|
||||
UINT16 dlr;
|
||||
|
||||
/* Others */
|
||||
UINT16 idr;
|
||||
UINT16 icd;
|
||||
|
||||
UINT8 transpose;
|
||||
UINT8 vblank_wait;
|
||||
|
||||
/* Polygon points */
|
||||
struct
|
||||
{
|
||||
INT16 x;
|
||||
INT16 y;
|
||||
} points[16];
|
||||
|
||||
UINT16 pt_idx;
|
||||
bool poly_open;
|
||||
|
||||
UINT16 clip_min_x;
|
||||
UINT16 clip_max_x;
|
||||
UINT16 clip_min_y;
|
||||
UINT16 clip_max_y;
|
||||
} gpu;
|
||||
|
||||
static UINT8 r_color_table[256];
|
||||
static UINT8 g_color_table[256];
|
||||
static UINT8 b_color_table[256];
|
||||
|
||||
static UINT16 dsp_bank[2];
|
||||
static UINT8 csr[2];
|
||||
|
||||
static UINT16 *m68k_ram;
|
||||
static UINT16 *shared_ram[2];
|
||||
static UINT16 *screen_ram;
|
||||
|
||||
static poly_manager *poly;
|
||||
typedef struct _poly_extra_data poly_extra_data;
|
||||
struct _poly_extra_data
|
||||
{
|
||||
UINT16 color;
|
||||
};
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Forward declarations
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static READ16_HANDLER( analog_r );
|
||||
static MACHINE_RESET( atarisy4 );
|
||||
static MACHINE_RESET( airrace );
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Video hardware
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static VIDEO_START( atarisy4 )
|
||||
{
|
||||
poly = poly_alloc(machine, 1024, sizeof(poly_extra_data), POLYFLAG_NO_WORK_QUEUE);
|
||||
}
|
||||
|
||||
static VIDEO_RESET( atarisy4 )
|
||||
{
|
||||
gpu.vblank_wait = 0;
|
||||
}
|
||||
|
||||
static VIDEO_UPDATE( atarisy4 )
|
||||
{
|
||||
int y;
|
||||
UINT32 offset = 0;
|
||||
|
||||
if (gpu.bcrw & 0x80)
|
||||
{
|
||||
offset = 0;
|
||||
}
|
||||
else if (gpu.bcrx & 0x80)
|
||||
{
|
||||
offset = 0x10 << 5;
|
||||
}
|
||||
|
||||
//UINT32 offset = gpu.dpr << 5;
|
||||
|
||||
for (y = cliprect->min_y; y <= cliprect->max_y; ++y)
|
||||
{
|
||||
UINT16 *src = &screen_ram[(offset + (4096 * y)) / 2];
|
||||
UINT32 *dest = BITMAP_ADDR32(bitmap, y, cliprect->min_x);
|
||||
int x;
|
||||
|
||||
for (x = cliprect->min_x; x < cliprect->max_x; x += 2)
|
||||
{
|
||||
UINT16 data = *src++;
|
||||
|
||||
*dest++ = screen->machine->pens[data & 0xff];
|
||||
*dest++ = screen->machine->pens[data >> 8];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline UINT32 xy_to_screen_addr(UINT32 x, UINT32 y)
|
||||
{
|
||||
// UINT32 offset = ((gpu.mcr >> 4) & 3) << 9;
|
||||
UINT32 offset = 0;
|
||||
|
||||
if (~gpu.bcrw & 0x80)
|
||||
{
|
||||
offset = 0;
|
||||
}
|
||||
else if (~gpu.bcrx & 0x80)
|
||||
{
|
||||
offset = 0x10 << 5;
|
||||
}
|
||||
|
||||
return (y * 4096) + offset + x;
|
||||
}
|
||||
|
||||
static void image_mem_to_screen(bool clip)
|
||||
{
|
||||
UINT16 y = gpu.gr[1] - 0x200;
|
||||
UINT16 h = gpu.gr[3];
|
||||
|
||||
if (h & 0x8000)
|
||||
h = -h;
|
||||
|
||||
/* Not 100% sure of this */
|
||||
while (h--)
|
||||
{
|
||||
UINT16 w = gpu.gr[2];
|
||||
UINT16 x = gpu.gr[0] - 0x400;
|
||||
|
||||
if (w & 0x8000)
|
||||
w = -w;
|
||||
|
||||
if (y >= 0 && y <= 511)
|
||||
{
|
||||
while (w--)
|
||||
{
|
||||
if (x >= 0 && x <= 511)
|
||||
{
|
||||
UINT16 pix = screen_ram[xy_to_screen_addr(x,y) >> 1];
|
||||
|
||||
if (x & 1)
|
||||
pix = (pix & (0x00ff)) | gpu.idr << 8;
|
||||
else
|
||||
pix = (pix & (0xff00)) | gpu.idr;
|
||||
|
||||
screen_ram[xy_to_screen_addr(x,y) >> 1] = pix;
|
||||
}
|
||||
++x;
|
||||
}
|
||||
}
|
||||
++y;
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_scanline(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid)
|
||||
{
|
||||
const poly_extra_data *extra = (const poly_extra_data *)extradata;
|
||||
UINT16 color = extra->color;
|
||||
int x;
|
||||
|
||||
for (x = extent->startx; x < extent->stopx; ++x)
|
||||
{
|
||||
UINT32 addr = xy_to_screen_addr(x, scanline);
|
||||
UINT16 pix = screen_ram[addr >> 1];
|
||||
|
||||
if (x & 1)
|
||||
pix = (pix & (0x00ff)) | color << 8;
|
||||
else
|
||||
pix = (pix & (0xff00)) | color;
|
||||
|
||||
screen_ram[addr >> 1] = pix;
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_polygon(UINT16 color)
|
||||
{
|
||||
int i;
|
||||
rectangle clip;
|
||||
poly_vertex v1, v2, v3;
|
||||
poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(poly);
|
||||
|
||||
clip.min_x = 0;
|
||||
clip.min_y = 0;
|
||||
clip.max_x = 511;
|
||||
clip.max_y = 511;
|
||||
|
||||
extra->color = color;
|
||||
|
||||
v1.x = gpu.points[0].x;
|
||||
v1.y = gpu.points[0].y;
|
||||
|
||||
v2.x = gpu.points[1].x;
|
||||
v2.y = gpu.points[1].y;
|
||||
|
||||
/* Draw a triangle fan */
|
||||
for (i = 2; i <= gpu.pt_idx; ++i)
|
||||
{
|
||||
v3.x = gpu.points[i].x;
|
||||
v3.y = gpu.points[i].y;
|
||||
|
||||
poly_render_triangle(poly, 0, &clip, draw_scanline, 1, &v1, &v2, &v3);
|
||||
v2 = v3;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
GPU commands
|
||||
|
||||
REXP 0x00 Reset expansion
|
||||
SEXP 0x01 Set expansion
|
||||
ROFF 0x02 Reset offset on update
|
||||
SOFF 0x03 Set offset
|
||||
RTPS 0x04 Reset transposition
|
||||
STPS 0x05 Set transposition
|
||||
SIMD 0x06 Load IDR register
|
||||
SICD 0x07 Load partial transfer compare value
|
||||
RCW 0x08 Reset clipping window
|
||||
SCW 0x09 Set clipping window
|
||||
WVB 0x0B Wait for VBlank
|
||||
FXOT 0x10 Fill x offset table
|
||||
FYOT 0x11 Fill y offset table
|
||||
FERT 0x14 Fill expansion table
|
||||
FCT 0x15 Fill color table
|
||||
SMCT 0x16 Screen memory to color table
|
||||
ITSN 0x20 Image memory to screen memory transfer
|
||||
ITSC 0x21 Image memory to screen memory transfer with clip
|
||||
PPA 0x24 Plot point absolute
|
||||
PFOA 0x28 Polygon open absolute
|
||||
PFOR 0x29 Polygon open relative
|
||||
PFVA 0x2A Polygon vector absolute
|
||||
PFVR 0x2B Polygon vector relative
|
||||
PFC 0x2C Polygon close
|
||||
*/
|
||||
void execute_gpu_command(running_machine *machine)
|
||||
{
|
||||
switch (gpu.ecr)
|
||||
{
|
||||
case 0x04:
|
||||
{
|
||||
gpu.transpose = 0;
|
||||
break;
|
||||
}
|
||||
case 0x05:
|
||||
{
|
||||
gpu.transpose = 1;
|
||||
break;
|
||||
}
|
||||
case 0x06:
|
||||
{
|
||||
gpu.idr = gpu.gr[0];
|
||||
break;
|
||||
}
|
||||
case 0x07:
|
||||
{
|
||||
gpu.icd = gpu.gr[0];
|
||||
break;
|
||||
}
|
||||
case 0x09:
|
||||
{
|
||||
gpu.clip_max_x = gpu.gr[0];
|
||||
gpu.clip_min_x = gpu.gr[1];
|
||||
gpu.clip_max_y = gpu.gr[2];
|
||||
gpu.clip_min_y = gpu.gr[3];
|
||||
break;
|
||||
}
|
||||
case 0x0b:
|
||||
{
|
||||
// Wait for VBLANK and swap buffers?
|
||||
gpu.vblank_wait = 1;
|
||||
break;
|
||||
}
|
||||
case 0x16:
|
||||
{
|
||||
/*
|
||||
Copy screen RAM to color RAM
|
||||
GR0 : Color start X
|
||||
GR1 : Color start Y
|
||||
GR2 : Color table offset
|
||||
GR3 : Size
|
||||
GR4 : Channels to set (R: 0x10, G: 0x20, B: 0x40)
|
||||
*/
|
||||
int i;
|
||||
int offset = xy_to_screen_addr(gpu.gr[0] - 0x400, gpu.gr[1] - 0x200);
|
||||
int table_offs = gpu.gr[2];
|
||||
|
||||
for (i = 0; i < gpu.gr[3]; ++i)
|
||||
{
|
||||
UINT16 val = screen_ram[offset >> 1];
|
||||
val >>= (~offset & 1) << 3;
|
||||
|
||||
if (gpu.gr[4] & 0x10)
|
||||
r_color_table[table_offs] = val;
|
||||
if (gpu.gr[4] & 0x20)
|
||||
g_color_table[table_offs] = val;
|
||||
if (gpu.gr[4] & 0x40)
|
||||
b_color_table[table_offs] = val;
|
||||
|
||||
/* Update */
|
||||
palette_set_color(machine, table_offs, MAKE_RGB(r_color_table[table_offs], g_color_table[table_offs], b_color_table[table_offs]));
|
||||
|
||||
++table_offs;
|
||||
++offset;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x20:
|
||||
{
|
||||
image_mem_to_screen(false);
|
||||
break;
|
||||
}
|
||||
case 0x21:
|
||||
{
|
||||
image_mem_to_screen(true);
|
||||
break;
|
||||
}
|
||||
case 0x28:
|
||||
{
|
||||
gpu.points[0].x = gpu.gr[0] - 0x400;
|
||||
gpu.points[0].y = gpu.gr[1] - 0x200;
|
||||
gpu.pt_idx = 0;
|
||||
break;
|
||||
}
|
||||
case 0x29:
|
||||
{
|
||||
gpu.points[0].x = gpu.points[gpu.pt_idx].x + gpu.gr[0];
|
||||
gpu.points[0].y = gpu.points[gpu.pt_idx].y + gpu.gr[1];
|
||||
gpu.pt_idx = 0;
|
||||
break;
|
||||
}
|
||||
case 0x2a:
|
||||
{
|
||||
++gpu.pt_idx;
|
||||
gpu.points[gpu.pt_idx].x = gpu.gr[0] - 0x400;
|
||||
gpu.points[gpu.pt_idx].y = gpu.gr[1] - 0x200;
|
||||
break;
|
||||
}
|
||||
case 0x2b:
|
||||
{
|
||||
UINT16 x = gpu.points[gpu.pt_idx].x + gpu.gr[0];
|
||||
UINT16 y = gpu.points[gpu.pt_idx].y + gpu.gr[1];
|
||||
++gpu.pt_idx;
|
||||
gpu.points[gpu.pt_idx].x = x;
|
||||
gpu.points[gpu.pt_idx].y = y;
|
||||
break;
|
||||
}
|
||||
case 0x2c:
|
||||
{
|
||||
draw_polygon(gpu.gr[2]);
|
||||
poly_wait(poly, "Normal");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
logerror("GPU COMMAND: %x\n", gpu.ecr);
|
||||
}
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( gpu_w )
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00: gpu.gr[0] = data; break;
|
||||
case 0x01: gpu.gr[1] = data; break;
|
||||
case 0x02: gpu.gr[2] = data; break;
|
||||
case 0x03: gpu.gr[3] = data; break;
|
||||
case 0x04: gpu.gr[4] = data; break;
|
||||
case 0x05: gpu.gr[5] = data; break;
|
||||
case 0x06: gpu.gr[6] = data; break;
|
||||
case 0x07: gpu.gr[7] = data; break;
|
||||
|
||||
case 0x08: gpu.bcrw = data; break;
|
||||
case 0x09: gpu.bcrx = data; break;
|
||||
case 0x0a: gpu.bcry = data; break;
|
||||
case 0x0b: gpu.bcrz = data; break;
|
||||
case 0x0c: gpu.psrw = data; break;
|
||||
case 0x0d: gpu.psrx = data; break;
|
||||
case 0x0e: gpu.psry = data; break;
|
||||
case 0x0f: gpu.psrz = data; break;
|
||||
|
||||
case 0x14: gpu.dpr = data; break;
|
||||
case 0x15: gpu.ctr = data; break;
|
||||
case 0x16: gpu.ifr = data; break;
|
||||
case 0x17:
|
||||
{
|
||||
gpu.ecr = data;
|
||||
execute_gpu_command(space->machine);
|
||||
break;
|
||||
}
|
||||
case 0x1a: gpu.far = data; break;
|
||||
case 0x20:
|
||||
{
|
||||
gpu.mcr = data;
|
||||
|
||||
if (~data & 0x08)
|
||||
cputag_set_input_line(space->machine, "maincpu", 6, CLEAR_LINE);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x21: gpu.qlr = data; break;
|
||||
case 0x22: gpu.qar = data; break;
|
||||
}
|
||||
}
|
||||
|
||||
static READ16_HANDLER( gpu_r )
|
||||
{
|
||||
UINT16 res = 0;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x08: res = gpu.bcrw; break;
|
||||
case 0x09: res = gpu.bcrx; break;
|
||||
case 0x0a: res = gpu.bcry; break;
|
||||
case 0x0b: res = gpu.bcrz; break;
|
||||
|
||||
case 0x20: res = gpu.mcr; break;
|
||||
|
||||
case 0x400: res = 5; break; // TODO!
|
||||
case 0x420: res = 5; break;
|
||||
|
||||
default: logerror("GPU_R[%x]\n", offset);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static INTERRUPT_GEN( vblank_int )
|
||||
{
|
||||
if (gpu.mcr & 0x08)
|
||||
cputag_set_input_line(device->machine, "maincpu", 6, ASSERT_LINE);
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* 68000<->TMS comms
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static READ16_HANDLER( m68k_shared_0_r )
|
||||
{
|
||||
if (!BIT(csr[0], 3))
|
||||
return (shared_ram[0][offset]);
|
||||
else
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( m68k_shared_0_w )
|
||||
{
|
||||
if (!BIT(csr[0], 3))
|
||||
COMBINE_DATA(&shared_ram[0][offset]);
|
||||
}
|
||||
|
||||
static READ16_HANDLER( m68k_shared_1_r )
|
||||
{
|
||||
if (!BIT(csr[1], 3))
|
||||
return (shared_ram[1][offset]);
|
||||
else
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( m68k_shared_1_w )
|
||||
{
|
||||
if (!BIT(csr[1], 3))
|
||||
COMBINE_DATA(&shared_ram[1][offset]);
|
||||
}
|
||||
|
||||
static READ16_HANDLER( dsp0_status_r )
|
||||
{
|
||||
return csr[0];
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( dsp0_control_w )
|
||||
{
|
||||
cputag_set_input_line(space->machine, "dsp0", INPUT_LINE_RESET, data & 0x01 ? CLEAR_LINE : ASSERT_LINE);
|
||||
cputag_set_input_line(space->machine, "dsp0", 0, data & 0x02 ? ASSERT_LINE : CLEAR_LINE);
|
||||
|
||||
csr[0] = data;
|
||||
}
|
||||
|
||||
static READ16_HANDLER( dsp0_bio_r )
|
||||
{
|
||||
return BIT(csr[0], 2);
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( dsp0_bank_w )
|
||||
{
|
||||
if (data & 0x4000)
|
||||
{
|
||||
/* Set TIDONE bit */
|
||||
csr[0] |= 0x10;
|
||||
|
||||
if (BIT(csr[0], 5) == 1)
|
||||
fatalerror("68000 interrupt enable was set!");
|
||||
}
|
||||
|
||||
data &= 0x3800;
|
||||
memory_set_bankptr(space->machine, "dsp0_bank1", &shared_ram[0][data]);
|
||||
dsp_bank[0] = data;
|
||||
}
|
||||
|
||||
static READ16_HANDLER( dsp1_status_r )
|
||||
{
|
||||
return csr[1];
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( dsp1_control_w )
|
||||
{
|
||||
cputag_set_input_line(space->machine, "dsp1", INPUT_LINE_RESET, data & 0x01 ? CLEAR_LINE : ASSERT_LINE);
|
||||
cputag_set_input_line(space->machine, "dsp1", 0, data & 0x02 ? ASSERT_LINE : CLEAR_LINE);
|
||||
|
||||
csr[1] = data;
|
||||
}
|
||||
|
||||
static READ16_HANDLER( dsp1_bio_r )
|
||||
{
|
||||
return BIT(csr[1], 2);
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( dsp1_bank_w )
|
||||
{
|
||||
if (data & 0x4000)
|
||||
{
|
||||
/* Set TIDONE bit */
|
||||
csr[1] |= 0x10;
|
||||
|
||||
if (BIT(csr[1], 5) == 1)
|
||||
fatalerror("68000 interrupt enable was set!");
|
||||
}
|
||||
|
||||
data &= 0x3800;
|
||||
memory_set_bankptr(space->machine, "dsp1_bank1", &shared_ram[1][data]);
|
||||
dsp_bank[1] = data;
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Main CPU memory map
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 16 )
|
||||
AM_RANGE(0x000000, 0x00ffff) AM_RAM AM_BASE(&m68k_ram)
|
||||
AM_RANGE(0x010000, 0x01ffff) AM_RAM
|
||||
AM_RANGE(0x580000, 0x580001) AM_READ_PORT("JOYSTICK")
|
||||
AM_RANGE(0x588000, 0x588001) AM_READ(analog_r)
|
||||
AM_RANGE(0x598000, 0x598001) AM_NOP /* Sound board */
|
||||
AM_RANGE(0x7c0000, 0x7c4fff) AM_READWRITE(m68k_shared_1_r, m68k_shared_1_w)
|
||||
AM_RANGE(0x7c6000, 0x7c6001) AM_READWRITE(dsp1_status_r, dsp1_control_w)
|
||||
AM_RANGE(0x7f0000, 0x7f4fff) AM_READWRITE(m68k_shared_0_r, m68k_shared_0_w)
|
||||
AM_RANGE(0x7f6000, 0x7f6001) AM_READWRITE(dsp0_status_r, dsp0_control_w)
|
||||
AM_RANGE(0xa00400, 0xbfffff) AM_RAM AM_BASE(&screen_ram)
|
||||
AM_RANGE(0xff8000, 0xff8fff) AM_READWRITE(gpu_r, gpu_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Mathbox DSP memory map
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static ADDRESS_MAP_START( dsp0_map, ADDRESS_SPACE_PROGRAM, 16 )
|
||||
ADDRESS_MAP_GLOBAL_MASK(0xfff)
|
||||
AM_RANGE(0x0000, 0x07ff) AM_RAMBANK("dsp0_bank0")
|
||||
AM_RANGE(0x0800, 0x0fff) AM_RAMBANK("dsp0_bank1")
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( dsp0_io_map, ADDRESS_SPACE_IO, 16 )
|
||||
AM_RANGE(0x00, 0x01) AM_WRITE(dsp0_bank_w)
|
||||
AM_RANGE(TMS32010_BIO, TMS32010_BIO) AM_READ(dsp0_bio_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Mathbox DSP memory map
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static ADDRESS_MAP_START( dsp1_map, ADDRESS_SPACE_PROGRAM, 16 )
|
||||
ADDRESS_MAP_GLOBAL_MASK(0xfff)
|
||||
AM_RANGE(0x0000, 0x07ff) AM_RAMBANK("dsp1_bank0")
|
||||
AM_RANGE(0x0800, 0x0fff) AM_RAMBANK("dsp1_bank1")
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( dsp1_io_map, ADDRESS_SPACE_IO, 16 )
|
||||
AM_RANGE(0x00, 0x01) AM_WRITE(dsp1_bank_w)
|
||||
AM_RANGE(TMS32010_BIO, TMS32010_BIO) AM_READ(dsp1_bio_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Input ports
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static READ16_HANDLER( analog_r )
|
||||
{
|
||||
return (input_port_read(space->machine, "STICKX") << 8) | input_port_read(space->machine, "STICKY");
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( atarisy4 )
|
||||
PORT_START("JOYSTICK")
|
||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICKRIGHT_LEFT )
|
||||
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICKRIGHT_RIGHT )
|
||||
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICKRIGHT_DOWN )
|
||||
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICKRIGHT_UP )
|
||||
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_LEFT )
|
||||
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_RIGHT )
|
||||
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_DOWN )
|
||||
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_UP )
|
||||
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON1 )
|
||||
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON2 )
|
||||
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON3 )
|
||||
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON4 )
|
||||
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON5 )
|
||||
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_BUTTON6 )
|
||||
|
||||
PORT_START("STICKY")
|
||||
PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(5)
|
||||
|
||||
PORT_START("STICKX")
|
||||
PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(5)
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Machine driver
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static MACHINE_DRIVER_START( atarisy4 )
|
||||
MDRV_CPU_ADD("maincpu", M68000, 8000000)
|
||||
MDRV_CPU_PROGRAM_MAP(main_map)
|
||||
MDRV_CPU_VBLANK_INT("screen", vblank_int)
|
||||
|
||||
MDRV_CPU_ADD("dsp0", TMS32010, 16000000)
|
||||
MDRV_CPU_PROGRAM_MAP(dsp0_map)
|
||||
MDRV_CPU_IO_MAP(dsp0_io_map)
|
||||
|
||||
MDRV_VIDEO_RESET(atarisy4)
|
||||
MDRV_MACHINE_RESET(atarisy4)
|
||||
|
||||
MDRV_SCREEN_ADD("screen", RASTER)
|
||||
MDRV_SCREEN_RAW_PARAMS(32000000/2, 660, 0, 512, 404, 0, 384)
|
||||
MDRV_VIDEO_ATTRIBUTES(VIDEO_UPDATE_AFTER_VBLANK)
|
||||
MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
|
||||
MDRV_PALETTE_LENGTH(256)
|
||||
|
||||
MDRV_VIDEO_START(atarisy4)
|
||||
MDRV_VIDEO_UPDATE(atarisy4)
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
static MACHINE_DRIVER_START( airrace )
|
||||
MDRV_IMPORT_FROM(atarisy4)
|
||||
|
||||
MDRV_CPU_ADD("dsp1", TMS32010, 16000000)
|
||||
MDRV_CPU_PROGRAM_MAP(dsp1_map)
|
||||
MDRV_CPU_IO_MAP(dsp1_io_map)
|
||||
|
||||
MDRV_MACHINE_RESET(airrace)
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* ROM definition(s)
|
||||
*
|
||||
*************************************/
|
||||
|
||||
ROM_START( laststar )
|
||||
ROM_REGION( 0x20000, "code", 0 )
|
||||
ROM_LOAD( "demo.hex", 0x00000, 0x1c2c4, CRC(7f9e344e) SHA1(ff1462f4f3fa01c47b74d365c240b1c3fdd36755) )
|
||||
|
||||
ROM_REGION( 0x20000, "data", 0 )
|
||||
ROM_LOAD( "data1.hex", 0x00000, 0x077cb, CRC(0e75efc0) SHA1(badfcadd92625637bb3223bee986a29428c8d35a) )
|
||||
|
||||
ROM_REGION( 0x20000, "dsp", 0 )
|
||||
ROM_LOAD( "mathbs.lda", 0x00000, 0x01e00, CRC(4378739a) SHA1(7c360da99a1366a3315f4846244ed3b2514ef7ec) )
|
||||
|
||||
ROM_REGION( 0x20000, "gfx", 0 )
|
||||
ROM_LOAD( "2d_data", 0x00000, 0x077cb, NO_DUMP )
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( airrace )
|
||||
ROM_REGION( 0x30000, "code", 0 )
|
||||
ROM_LOAD( "demo.hex", 0x00000, 0x25d23, CRC(937fa025) SHA1(c393a05645ad5df9268f03fffad294477e6f090b) )
|
||||
|
||||
ROM_REGION( 0x20000, "dsp", 0 )
|
||||
ROM_LOAD( "mathbs.lda", 0x00000, 0x01e00, CRC(d215acd4) SHA1(853e792b343dc6bcb5b11d455af478a79edfd740) )
|
||||
|
||||
ROM_REGION( 0x20000, "gfx", 0 )
|
||||
ROM_LOAD( "2d_data", 0x00000, 0x077cb, NO_DUMP )
|
||||
ROM_END
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Driver initialization
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static inline UINT8 hex_to_ascii(UINT8 in)
|
||||
{
|
||||
if (in < 0x3a)
|
||||
return in - 0x30;
|
||||
else if (in < 0x47)
|
||||
return in - 0x37;
|
||||
else
|
||||
return in;
|
||||
}
|
||||
|
||||
void load_ldafile(const address_space *space, const UINT8 *file)
|
||||
{
|
||||
#define READ_CHAR() file[i++]
|
||||
int i = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
UINT8 c;
|
||||
UINT8 sum = 1;
|
||||
UINT16 len;
|
||||
UINT16 addr;
|
||||
|
||||
if (READ_CHAR() != 0x01)
|
||||
fatalerror("Bad .LDA file");
|
||||
|
||||
if (READ_CHAR() != 0x00)
|
||||
fatalerror("Bad .LDA file");
|
||||
|
||||
len = READ_CHAR();
|
||||
sum += len;
|
||||
|
||||
c = READ_CHAR();
|
||||
len |= c << 8;
|
||||
sum += c;
|
||||
|
||||
/* End of file */
|
||||
if (len == 6)
|
||||
break;
|
||||
|
||||
addr = READ_CHAR();
|
||||
sum += addr;
|
||||
|
||||
c = READ_CHAR();
|
||||
addr |= c << 8;
|
||||
sum += c;
|
||||
|
||||
len -= 6;
|
||||
|
||||
addr <<= 1;
|
||||
do
|
||||
{
|
||||
UINT8 data = READ_CHAR();
|
||||
sum += data;
|
||||
memory_write_byte(space, addr++, data);
|
||||
} while (--len);
|
||||
|
||||
sum += READ_CHAR();
|
||||
|
||||
if (sum != 0)
|
||||
fatalerror(".LDA checksum failure");
|
||||
}
|
||||
}
|
||||
|
||||
/* Load memory space with data from a Tektronix-Extended HEX file */
|
||||
void load_hexfile(const address_space *space, const UINT8 *file)
|
||||
{
|
||||
#define READ_HEX_CHAR() hex_to_ascii(file[i++])
|
||||
|
||||
UINT32 i = 0;
|
||||
UINT32 line = 1;
|
||||
bool end = false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
UINT8 len;
|
||||
UINT8 record;
|
||||
UINT8 checksum;
|
||||
UINT8 sum = 0;
|
||||
UINT8 addr_len;
|
||||
UINT32 addr = 0;
|
||||
|
||||
/* Ignore blank lines */
|
||||
while (file[i] == '\n') i++;
|
||||
|
||||
/* First character of each line should be a '%' */
|
||||
if (file[i++] != '%')
|
||||
fatalerror("Error on line %d - invalid line start character", line);
|
||||
|
||||
/* Get the line length */
|
||||
len = READ_HEX_CHAR() << 4;
|
||||
len |= READ_HEX_CHAR();
|
||||
|
||||
sum += len & 0xf;
|
||||
sum += len >> 4;
|
||||
|
||||
/* Get the record type */
|
||||
record = READ_HEX_CHAR();
|
||||
sum += record;
|
||||
|
||||
/* Record type */
|
||||
if (record == 8)
|
||||
{
|
||||
end = true;
|
||||
}
|
||||
else if (record == 3)
|
||||
{
|
||||
/* Ignore this type */
|
||||
i += len - 2;
|
||||
goto next_line;
|
||||
}
|
||||
else if (record != 6)
|
||||
{
|
||||
fatalerror("Error on line %d - Invalid record type %d\n", line, record);
|
||||
}
|
||||
|
||||
/* Get the checksum for this line */
|
||||
checksum = READ_HEX_CHAR() << 4;
|
||||
checksum |= READ_HEX_CHAR();
|
||||
|
||||
/* Get the number of address digits */
|
||||
addr_len = READ_HEX_CHAR();
|
||||
sum += addr_len;
|
||||
|
||||
len = len - 6 - addr_len;
|
||||
|
||||
/* Form the address */
|
||||
while (addr_len)
|
||||
{
|
||||
UINT8 digit;
|
||||
|
||||
addr <<= 4;
|
||||
digit = READ_HEX_CHAR();
|
||||
sum += digit;
|
||||
addr |= digit;
|
||||
--addr_len;
|
||||
}
|
||||
|
||||
/* Now read the data */
|
||||
while (len)
|
||||
{
|
||||
UINT8 data;
|
||||
|
||||
data = READ_HEX_CHAR() << 4;
|
||||
data |= READ_HEX_CHAR();
|
||||
sum += data >> 4;
|
||||
sum += data & 0xf;
|
||||
|
||||
if (record == 6)
|
||||
memory_write_byte(space, addr++, data);
|
||||
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
/* Eat the carriage return */
|
||||
++i;
|
||||
|
||||
if (sum != checksum)
|
||||
fatalerror("Checksum mismatch on line %d (Found 0x%.2x but expected 0x%.2x)\n", line, sum, checksum);
|
||||
|
||||
next_line:
|
||||
++line;
|
||||
|
||||
if (end == true)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static DRIVER_INIT( laststar )
|
||||
{
|
||||
const address_space *main = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM);
|
||||
|
||||
/* Allocate 16kB of shared RAM */
|
||||
shared_ram[0] = auto_alloc_array_clear(machine, UINT16, 0x2000);
|
||||
|
||||
/* Populate the 68000 address space with data from the HEX files */
|
||||
load_hexfile(main, memory_region(machine, "code"));
|
||||
load_hexfile(main, memory_region(machine, "data"));
|
||||
|
||||
/* Set up the DSP */
|
||||
memory_set_bankptr(machine, "dsp0_bank0", shared_ram[0]);
|
||||
memory_set_bankptr(machine, "dsp0_bank1", &shared_ram[0][0x800]);
|
||||
load_ldafile(cputag_get_address_space(machine, "dsp0", ADDRESS_SPACE_PROGRAM), memory_region(machine, "dsp"));
|
||||
}
|
||||
|
||||
static DRIVER_INIT( airrace )
|
||||
{
|
||||
/* Allocate two sets of 32kB shared RAM */
|
||||
shared_ram[0] = auto_alloc_array_clear(machine, UINT16, 0x4000);
|
||||
shared_ram[1] = auto_alloc_array_clear(machine, UINT16, 0x4000);
|
||||
|
||||
/* Populate RAM with data from the HEX files */
|
||||
load_hexfile(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), memory_region(machine, "code"));
|
||||
|
||||
/* Set up the first DSP */
|
||||
memory_set_bankptr(machine, "dsp0_bank0", shared_ram[0]);
|
||||
memory_set_bankptr(machine, "dsp0_bank1", &shared_ram[0][0x800]);
|
||||
load_ldafile(cputag_get_address_space(machine, "dsp0", ADDRESS_SPACE_PROGRAM), memory_region(machine, "dsp"));
|
||||
|
||||
/* Set up the second DSP */
|
||||
memory_set_bankptr(machine, "dsp1_bank0", shared_ram[1]);
|
||||
memory_set_bankptr(machine, "dsp1_bank1", &shared_ram[1][0x800]);
|
||||
load_ldafile(cputag_get_address_space(machine, "dsp1", ADDRESS_SPACE_PROGRAM), memory_region(machine, "dsp"));
|
||||
}
|
||||
|
||||
static MACHINE_RESET( atarisy4 )
|
||||
{
|
||||
cputag_set_input_line(machine, "dsp0", INPUT_LINE_RESET, ASSERT_LINE);
|
||||
}
|
||||
|
||||
static MACHINE_RESET( airrace )
|
||||
{
|
||||
cputag_set_input_line(machine, "dsp0", INPUT_LINE_RESET, ASSERT_LINE);
|
||||
cputag_set_input_line(machine, "dsp1", INPUT_LINE_RESET, ASSERT_LINE);
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Game driver(s)
|
||||
*
|
||||
*************************************/
|
||||
|
||||
GAME( 1984, laststar, 0, atarisy4, atarisy4, laststar, ROT0, "Atari Games", "The Last Starfighter (prototype)", GAME_IMPERFECT_GRAPHICS | GAME_NO_SOUND_HW )
|
||||
GAME( 1985, airrace, 0, airrace, atarisy4, airrace, ROT0, "Atari Games", "Air Race (prototype)", GAME_IMPERFECT_GRAPHICS | GAME_NO_SOUND_HW )
|
@ -385,6 +385,7 @@ $(MAMEOBJ)/atari.a: \
|
||||
$(DRIVERS)/atarigt.o $(VIDEO)/atarigt.o \
|
||||
$(DRIVERS)/atarisy1.o $(VIDEO)/atarisy1.o \
|
||||
$(DRIVERS)/atarisy2.o $(VIDEO)/atarisy2.o \
|
||||
$(DRIVERS)/atarisy4.o \
|
||||
$(DRIVERS)/atetris.o $(VIDEO)/atetris.o \
|
||||
$(DRIVERS)/avalnche.o $(AUDIO)/avalnche.o \
|
||||
$(DRIVERS)/badlands.o $(VIDEO)/badlands.o \
|
||||
|
@ -6109,6 +6109,9 @@ BOMULEUL CHAJARA SEGA ST-V 1997/04/11
|
||||
|
||||
/* Atari polygon games */
|
||||
DRIVER( irobot ) /* 136029 (c) 1983 */
|
||||
/* Atari System IV */
|
||||
DRIVER( laststar ) /* (proto) (c) 1984 */
|
||||
DRIVER( airrace ) /* (proto) (c) 1985 */
|
||||
/* Hard Drivin' */
|
||||
DRIVER( harddriv ) /* 136052 (c) 1988 */
|
||||
DRIVER( harddrivb ) /* 136052 (c) 1988 */
|
||||
|
Loading…
Reference in New Issue
Block a user