📄 smashtv.c
字号:
/*************************************************************************
Driver for Williams/Midway games using the TMS34010 processor
**************************************************************************/
#include "driver.h"
#include "osd_cpu.h"
#include "TMS34010/tms34010.h"
#include "M6809/M6809.h"
#include "6821pia.h"
#include "vidhrdw/generic.h"
#if LSB_FIRST
#define BYTE_XOR_LE(a) (a)
#define BIG_DWORD_LE(x) (x)
#else
#define BYTE_XOR_LE(a) ( (char*) ((unsigned int) (a) ^ 1) )
#define BIG_DWORD_LE(x) (((UINT32)(x) >> 16) + ((x) << 16))
#endif
#define CODE_ROM cpu_bankbase[1]
#define GFX_ROM cpu_bankbase[8]
#define SCRATCH_RAM cpu_bankbase[2]
void narc_sound_w (int offset,int data);
void mk_sound_w (int offset,int data);
void smashtv_sound_w (int offset,int data);
void trog_sound_w (int offset,int data);
void wms_vram_w(int offset, int data);
void wms_objpalram_w(int offset, int data);
int wms_vram_r(int offset);
int wms_objpalram_r(int offset);
extern unsigned short *wms_videoram;
unsigned char *wms_cmos_ram;
int wms_bank2_size;
extern int wms_videoram_size;
int wms_code_rom_size;
int wms_gfx_rom_size;
extern unsigned int wms_rom_loaded;
static unsigned int wms_cmos_page = 0;
int wms_objpalram_select = 0;
unsigned int wms_autoerase_enable = 0;
unsigned int wms_autoerase_start = 1000;
static unsigned int wms_dma_rows=0;
static int wms_dma_write_rows=0;
static unsigned int wms_dma_cols=0;
static unsigned int wms_dma_bank=0;
static unsigned int wms_dma_subbank=0;
static unsigned int wms_dma_x=0;
static unsigned int wms_dma_y=0;
unsigned int wms_dma_pal=0;
unsigned int wms_dma_pal_word=0;
static unsigned int wms_dma_dst=0;
static unsigned int wms_dma_stat=0;
static unsigned int wms_dma_fgcol=0;
static short wms_dma_woffset=0;
static unsigned int wms_dma_odd_nibble=0; /* are we not on a byte boundary? */
static unsigned int wms_dma_14=0;
static unsigned int wms_dma_16=0;
static unsigned int wms_dma_18=0;
static unsigned int wms_dma_1a=0;
static unsigned int wms_dma_1c=0;
static unsigned int wms_dma_1e=0;
static unsigned int smashtv_cmos_w_enable=1;
static unsigned int wms_protect_s=0xffffffff; /* never gets here */
static unsigned int wms_protect_d=0xffffffff;
static int narc_input_r (int offset)
{
int ans = 0xffff;
switch (offset)
{
case 0:
ans = (input_port_1_r (offset) << 8) + (input_port_0_r (offset));
break;
case 2:
ans = (input_port_3_r (offset) << 8) + (input_port_2_r (offset));
break;
case 4:
ans = (input_port_5_r (offset) << 8) + (soundlatch3_r (0));
break;
default:
break;
}
return ans;
}
int wms_input_r (int offset)
{
int ans = 0xffff;
switch (offset)
{
case 0:
ans = (input_port_1_r (offset) << 8) + (input_port_0_r (offset));
break;
case 2:
ans = (input_port_3_r (offset) << 8) + (input_port_2_r (offset));
break;
case 4:
ans = (input_port_5_r (offset) << 8) + (input_port_4_r (offset));
break;
case 6:
ans = (input_port_7_r (offset) << 8) + (input_port_6_r (offset));
break;
case 8:
ans = (input_port_9_r (offset) << 8) + (input_port_8_r (offset));
break;
default:
break;
}
return ans;
}
static int term2_input_lo_r (int offset)
{
int ans = 0xffff;
switch (offset)
{
default:
break;
}
return ans;
}
static void dma_callback(int param)
{
wms_dma_stat = 0; /* tell the cpu we're done */
cpu_cause_interrupt(0,TMS34010_INT1);
}
int wms_dma_r(int offset)
{
if (wms_dma_stat&0x8000)
{
switch (cpu_getpc())
{
case 0xfff7aa20: /* narc */
case 0xffe1c970: /* trog */
case 0xffe1c9a0: /* trog3 */
case 0xffe1d4a0: /* trogp */
case 0xffe07690: /* smashtv */
case 0xffe00450: /* hiimpact */
case 0xffe14930: /* strkforc */
case 0xffe02c20: /* strkforc */
case 0xffc79890: /* mk */
case 0xffc7a5a0: /* mk */
case 0xffc063b0: /* term2 */
case 0xffc00720: /* term2 */
case 0xffc07a60: /* totcarn/totcarnp */
case 0xff805200: /* mk2 */
case 0xff8044e0: /* mk2 */
case 0xff82e200: /* nbajam */
cpu_spinuntil_int();
wms_dma_stat=0;
break;
default:
break;
}
}
return wms_dma_stat;
}
/*****************************************************************************************
* *
* They may not be optimal for other compilers. If you change anything, make *
* sure you test it on a Pentium II. Even a trivial change can make a huge *
* difference! *
* *
*****************************************************************************************/
#define DMA_DRAW_NONZERO_BYTES_INC(data) \
if (write_cols >= 0) \
{ \
pal = wms_dma_pal; \
line_skip = 511 - write_cols; \
wrva = &(wms_videoram[wms_dma_dst]); \
for (i=wms_dma_write_rows;i;i--) \
{ \
j=write_cols; \
do \
{ \
if ((write_data = *BYTE_XOR_LE(rda))) \
{ \
*wrva = pal | (data); \
} \
rda++; \
wrva++; \
} \
while (j--); \
rda+=dma_skip; \
wrva+=line_skip; \
} \
}
#define DMA_DRAW_NONZERO_BYTES_DEC(data) \
if (write_cols >= 0) \
{ \
pal = wms_dma_pal; \
line_skip = 511 - write_cols; \
wrva = &(wms_videoram[wms_dma_dst]); \
for (i=wms_dma_write_rows;i;i--) \
{ \
j=write_cols; \
do \
{ \
if ((write_data = *BYTE_XOR_LE(rda))) \
{ \
*wrva = pal | (data); \
} \
rda--; \
wrva++; \
} \
while (j--); \
rda+=dma_skip; \
wrva+=line_skip; \
} \
}
#define DMA_DRAW_ALL_BYTES(data) \
if (write_cols >= 0) \
{ \
pal = wms_dma_pal; \
line_skip = 511 - write_cols; \
wrva = &(wms_videoram[wms_dma_dst]); \
for (i=wms_dma_write_rows;i;i--) \
{ \
j=write_cols; \
do \
{ \
*(wrva++) = pal | (data); \
} \
while (j--); \
rda+=dma_skip; \
wrva+=line_skip; \
} \
}
void wms_dma_w(int offset, int data)
{
unsigned int i, j, pal, write_data, line_skip, dma_skip;
int write_cols;
unsigned char *rda;
unsigned short *wrva;
switch (offset)
{
case 0:
write_cols = (wms_dma_cols+wms_dma_x<512?wms_dma_cols:512-wms_dma_x)-1; /* Note the -1 */
wms_dma_write_rows = (wms_dma_rows+wms_dma_y<512?wms_dma_rows:512-wms_dma_y);
wms_dma_dst = ((wms_dma_y<<9) + (wms_dma_x)); /* byte addr */
rda = &(GFX_ROM[wms_dma_bank+wms_dma_subbank]);
wms_dma_stat = data;
/*
* DMA registers
* ------------------
*
* Register | Bit | Use
* ----------+-FEDCBA9876543210-+------------
* 0 | x--------------- | trigger write (or clear if zero)
* | ---184-1-------- | unknown
* | ----------x----- | flip y
* | -----------x---- | flip x
* | ------------x--- | blit nonzero pixels as color
* | -------------x-- | blit zero pixels as color
* | --------------x- | blit nonzero pixels
* | ---------------x | blit zero pixels
* 1 | xxxxxxxxxxxxxxxx | width offset
* 2 | xxxxxxxxxxxxxxxx | source address low word
* 3 | xxxxxxxxxxxxxxxx | source address high word
* 4 | xxxxxxxxxxxxxxxx | detination x
* 5 | xxxxxxxxxxxxxxxx | destination y
* 6 | xxxxxxxxxxxxxxxx | image columns
* 7 | xxxxxxxxxxxxxxxx | image rows
* 8 | xxxxxxxxxxxxxxxx | palette
* 9 | xxxxxxxxxxxxxxxx | color
*/
switch(data&0x803f)
{
case 0x0000: /* clear registers */
dma_skip=0;
wms_dma_cols=0;
wms_dma_rows=0;
wms_dma_pal=0;
wms_dma_fgcol=0;
break;
case 0x8000: /* draw nothing */
break;
case 0x8002: /* draw only nonzero pixels */
dma_skip = ((wms_dma_cols + wms_dma_woffset+3)&(~3)) - wms_dma_cols;
DMA_DRAW_NONZERO_BYTES_INC(write_data);
break;
case 0x8003: /* draw all pixels */
dma_skip = ((wms_dma_cols + wms_dma_woffset+3)&(~3)) - wms_dma_cols;
DMA_DRAW_ALL_BYTES(*BYTE_XOR_LE(rda++));
break;
case 0x8006: /* draw nonzero pixels, zero as color */
dma_skip = ((wms_dma_cols + wms_dma_woffset+3)&(~3)) - wms_dma_cols;
DMA_DRAW_ALL_BYTES((*BYTE_XOR_LE(rda++)?*BYTE_XOR_LE(rda-1):wms_dma_fgcol));
break;
case 0x800a: /* ????? */
case 0x8008: /* draw nonzero pixels as color */
dma_skip = ((wms_dma_cols + wms_dma_woffset+3)&(~3)) - wms_dma_cols;
DMA_DRAW_NONZERO_BYTES_INC(wms_dma_fgcol);
break;
case 0x8009: /* draw nonzero pixels as color, zero as zero */
dma_skip = ((wms_dma_cols + wms_dma_woffset+3)&(~3)) - wms_dma_cols;
DMA_DRAW_ALL_BYTES((*BYTE_XOR_LE(rda++)?wms_dma_fgcol:0));
break;
case 0x800e: /* ????? */
case 0x800c: /* draw all pixels as color (fill) */
DMA_DRAW_ALL_BYTES(wms_dma_fgcol);
break;
case 0x8010: /* draw nothing */
break;
case 0x8012: /* draw nonzero pixels x-flipped */
dma_skip = ((wms_dma_woffset + 3 - wms_dma_cols)&(~3)) + wms_dma_cols;
DMA_DRAW_NONZERO_BYTES_DEC(write_data);
break;
case 0x8013: /* draw all pixels x-flipped */
dma_skip = ((wms_dma_woffset + 3 - wms_dma_cols)&(~3)) + wms_dma_cols;
DMA_DRAW_ALL_BYTES(*BYTE_XOR_LE(rda--));
break;
case 0x801a: /* ????? */
case 0x8018: /* draw nonzero pixels as color x-flipped */
dma_skip = ((wms_dma_woffset + 3 - wms_dma_cols)&(~3)) + wms_dma_cols;
DMA_DRAW_NONZERO_BYTES_DEC(wms_dma_fgcol);
break;
case 0x8022: /* draw nonzero pixels y-flipped */
dma_skip = ((wms_dma_cols + wms_dma_woffset+3)&(~3)) - wms_dma_cols;
DMA_DRAW_NONZERO_BYTES_INC(write_data);
break;
case 0x8032: /* draw nonzero pixels x-flipped and y-flipped */
dma_skip = ((wms_dma_woffset + 3 - wms_dma_cols)&(~3)) + wms_dma_cols;
DMA_DRAW_NONZERO_BYTES_DEC(write_data);
break;
default:
break;
}
/*
* One pixel every 41 ns (1e-9 sec)
*/
timer_set (TIME_IN_NSEC(41*wms_dma_cols*wms_dma_rows), data, dma_callback);
break;
case 2:
wms_dma_woffset = data;
break;
case 4:
wms_dma_subbank = data>>3;
break;
case 6:
wms_dma_bank = ((data&0xfe00)?(data-0x200)*0x2000:data*0x2000);
break;
case 8:
wms_dma_x = data&0x1ff;
break;
case 0x0a:
wms_dma_y = data&0x1ff;
break;
case 0x0c:
wms_dma_cols = data;
dma_skip = data;
break;
case 0x0e:
wms_dma_rows = data;
break;
case 0x10: /* set palette */
wms_dma_pal = (data&0xff) << 8;
wms_dma_pal_word = data;
break;
case 0x12: /* set color for 1-bit */
wms_dma_fgcol = data&0xff;
break;
default:
break;
}
}
void wms_dma2_w(int offset, int data)
{
/*
* This is a MESS! -- lots to do
* one pixel every 41 ns (1e-9 sec)
* 50,000,000 cycles per second
* --> approximately 2 cycles per pixel
*/
unsigned int i, pal, write_data, line_skip, dma_skip;
int j, write_cols;
unsigned char *rda;
unsigned short *wrva;
switch (offset)
{
case 0:
break;
case 2:
write_cols = (wms_dma_cols+wms_dma_x<512?wms_dma_cols:512-wms_dma_x)-1; /* Note the -1 */
wms_dma_write_rows = (wms_dma_rows+wms_dma_y<512?wms_dma_rows:512-wms_dma_y);
wms_dma_dst = ((wms_dma_y<<9) + (wms_dma_x)); /* byte addr */
rda = &(GFX_ROM[wms_dma_bank+wms_dma_subbank]);
wms_dma_stat = data;
/*
* DMA registers
* ------------------
*
* Register | Bit | Use
* ----------+-FEDCBA9876543210-+------------
* 0 | x--------------- | trigger write (or clear if zero)
* | ---184-1-------- | unknown
* | ----------x----- | flip y
* | -----------x---- | flip x
* | ------------x--- | blit nonzero pixels as color
* | -------------x-- | blit zero pixels as color
* | --------------x- | blit nonzero pixels
* | ---------------x | blit zero pixels
* 1 | xxxxxxxxxxxxxxxx | width offset
* 2 | xxxxxxxxxxxxxxxx | source address low word
* 3 | xxxxxxxxxxxxxxxx | source address high word
* 4 | xxxxxxxxxxxxxxxx | detination x
* 5 | xxxxxxxxxxxxxxxx | destination y
* 6 | xxxxxxxxxxxxxxxx | image columns
* 7 | xxxxxxxxxxxxxxxx | image rows
* 8 | xxxxxxxxxxxxxxxx | palette
* 9 | xxxxxxxxxxxxxxxx | color
*/
switch(data&0xe03f)
{
case 0x0000: /* clear registers */
dma_skip=0;
wms_dma_cols=0;
wms_dma_rows=0;
wms_dma_fgcol=0;
break;
case 0x8000: /* draw nothing */
break;
case 0x8002: /* draw only nonzero pixels */
dma_skip = ((wms_dma_cols + wms_dma_woffset+3)&(~3)) - wms_dma_cols;
DMA_DRAW_NONZERO_BYTES_INC(write_data);
break;
case 0xc002: /* draw only nonzero pixels ??? */
dma_skip = ((wms_dma_cols + wms_dma_woffset+1)&(~1)) - wms_dma_cols;
for (i=0;i<(wms_dma_write_rows<<9);i+=512)
{
wrva = &(wms_videoram[wms_dma_dst+i]);
for (j=write_cols;j>=0;j--)
{
if (wms_dma_odd_nibble&0x01)
{
write_data = (((*BYTE_XOR_LE(rda++))>>4)&0x0f);
if (write_data)
{
*wrva = wms_dma_pal | write_data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -