📄 gladiatr.c
字号:
/*
Taito Gladiator (1986)
Known ROM SETS: Golden Castle, Ohgon no Siro
Credits:
- Victor Trucco: original emulation and MAME driver
- Steve Ellenoff: YM2203 Sound, ADPCM Sound, dip switch fixes, high score save,
input port patches, panning fix, sprite banking,
Golden Castle Rom Set Support
- Phil Stroffolino: palette, sprites, misc video driver fixes
- Nicola Salmoria: Japaneese Rom Set Support(Ohgon no Siro)
- Tatsuyuki Satoh: YM2203 sound improvements, NEC 8741 emulation
special thanks to:
- Camilty for precious hardware information and screenshots
- Jason Richmond for hardware information and misc. notes
- Joe Rounceville for schematics
- and everyone else who'se offered support along the way!
Issues:
- YM2203 mixing problems (loss of bass notes)
- YM2203 some sound effects just don't sound correct
- Audio Filter Switch not hooked up (might solve YM2203 mixing issue)
- Ports 60,61,80,81 not fully understood yet...
- CPU speed may not be accurate
- some sprites linger on later stages (perhaps a sprite enable bit?)
- Flipscreen not implemented
- Scrolling issues in Test mode!
- Sample @ 5500 Hz being used because Mame core doesn't yet support multiple sample rates.
- The four 8741 ROMs are available but not used.
Preliminary Gladiator Memory Map
Main CPU (Z80)
$0000-$3FFF QB0-5
$4000-$5FFF QB0-4
$6000-$7FFF QB0-1 Paged
$8000-$BFFF QC0-3 Paged
if port 02 = 00 QB0-1 offset (0000-1fff) at location 6000-7fff
QC0-3 offset (0000-3fff) at location 8000-bfff
if port 02 = 01 QB0-1 offset (2000-3fff) at location 6000-7fff
QC0-3 offset (4000-7fff) at location 8000-bfff
$C000-$C3FF sprite RAM
$C400-$C7FF sprite attributes
$C800-$CBFF more sprite attributes
$CC00-$D7FF video registers
(scrolling, 2 screens wide)
$D800-DFFF background layer VRAM (tiles)
$E000-E7FF background layer VRAM (attributes)
$E800-EFFF foreground text layer VRAM
$F000-$F3FF Battery Backed RAM
$F400-$F7FF Work RAM
Audio CPU (Z80)
$0000-$3FFF QB0-17
$8000-$83FF Work RAM 2.CPU
Preliminary Descriptions of I/O Ports.
Main z80
8 pins of LS259:
00 - OBJACS ? (I can't read the name in schematics)
01 - OBJCGBK (Sprite banking)
02 - PR.BK (ROM banking)
03 - NMIFG (connects to NMI of main Z80, but there's no code in 0066)
04 - SRST (probably some type of reset)
05 - CBK0 (unknown)
06 - LOBJ (connected near graphic ROMs)
07 - REVERS
9E - Send data to NEC 8741-0 (comunicate with 2nd z80)
(dip switch 1 is read in these ports too)
9F - Send commands to NEC 8741-0
C0-DF 8251 (Debug port ?)
2nd z80
00 - YM2203 Control Reg.
01 - YM2203 Data Read / Write Reg.
Port B of the YM2203 is connected to dip switch 3
20 - Send data to NEC 8741-1 (comunicate with Main z80)
(dip switch 2 is read in these ports too)
21 - Send commands to NEC 8741-1 (comunicate with Main z80)
40 - Clear Interrupt latch
60 - Send data to NEC 8741-2 (Read Joystick and Coin Slot (both players)
61 - Send commands to NEC 8741-2
80 - Send data to NEC 8741-3 (Read buttons (Fire 1, 2 and 3 (both players), service button) )
81 - Send commands to NEC 8741-3
A0-BF - Audio mixer control ?
E0 - Comunication port to 6809
*/
#include "driver.h"
#include "vidhrdw/generic.h"
#include "z80/z80.h"
/*Video functions*/
extern unsigned char *gladiator_text;
extern void gladiatr_video_registers_w( int offset, int data );
extern int gladiatr_video_registers_r( int offset );
extern void gladiatr_paletteram_rg_w( int offset, int data );
extern void gladiatr_paletteram_b_w( int offset, int data );
extern int gladiatr_vh_start(void);
extern void gladiatr_vh_stop(void);
extern void gladiatr_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
extern void gladiatr_spritebank_w( int offset, int data );
/*Sound and I/O Functions*/
void glad_adpcm_w( int channel, int data );
void glad_cpu_sound_command_w(int offset,int data);
/*Rom bankswitching*/
static int banka;
static int port9f;
void gladiatr_bankswitch_w(int offset,int data);
int gladiatr_bankswitch_r(int offset);
/* NEC 8741 program mode */
#define GLADIATOR_8741_MASTER 0
#define GLADIATOR_8741_SLAVE 1
#define GLADIATOR_8741_PORT 2
typedef struct gladiator_8741_status{
unsigned char rdata;
unsigned char status;
unsigned char mode;
unsigned char txd[8];
unsigned char rxd[8];
unsigned char parallelselect;
unsigned char txpoint;
unsigned char connect;
unsigned char pending_4a;
int (*portHandler)(unsigned char num);
}I8741;
static I8741 gladiator_8741[4];
/*Rom bankswitching*/
void gladiatr_bankswitch_w(int offset,int data){
static int bank1[2] = { 0x10000, 0x12000 };
static int bank2[2] = { 0x14000, 0x18000 };
unsigned char *RAM = Machine->memory_region[Machine->drv->cpu[0].memory_region];
banka = data;
cpu_setbank(1,&RAM[bank1[(data & 0x03)]]);
cpu_setbank(2,&RAM[bank2[(data & 0x03)]]);
}
int gladiatr_bankswitch_r(int offset){
return banka;
}
static int gladiator_dsw1_r(unsigned char num)
{
int orig = readinputport(0); /* DSW1 */
/*Reverse all bits for Input Port 0*/
/*ie..Bit order is: 0,1,2,3,4,5,6,7*/
return ((orig&0x01)<<7) | ((orig&0x02)<<5)
| ((orig&0x04)<<3) | ((orig&0x08)<<1)
| ((orig&0x10)>>1) | ((orig&0x20)>>3)
| ((orig&0x40)>>5) | ((orig&0x80)>>7);;
}
static int gladiator_dsw2_r(unsigned char num)
{
int orig = readinputport(1); /* DSW2 */
/*Bits 2-7 are reversed for Input Port 1*/
/*ie..Bit order is: 2,3,4,5,6,7,1,0*/
return (orig&0x01) | (orig&0x02)
| ((orig&0x04)<<5) | ((orig&0x08)<<3)
| ((orig&0x10)<<1) | ((orig&0x20)>>1)
| ((orig&0x40)>>3) | ((orig&0x80)>>5);
}
static int gladiator_controll_r(unsigned char num)
{
int coins = 0;
if( readinputport(4) & 0xc0 ) coins = 0x80;
switch(num)
{
case 0x01: /* start button , coins */
return readinputport(3) | coins;
case 0x02: /* Player 1 Controller , coins */
return readinputport(5) | coins;
case 0x04: /* Player 2 Controller , coins */
return readinputport(6) | coins;
}
/* unknown */
return 0;
}
static int gladiator_button3_r(unsigned char num)
{
switch(num)
{
case 0x01: /* button 3 */
return readinputport(7);
}
/* unknown */
return 0;
}
void gladiator_machine_init(void)
{
int i;
memset( gladiator_8741,0,sizeof(gladiator_8741));
/* connect I8741 MASTER and SLAVE */
gladiator_8741[0].connect = 1;
gladiator_8741[1].connect = 0;
for(i=0;i<4;i++)
{
gladiator_8741[i].status = 0x00;
}
gladiator_8741[0].portHandler = gladiator_dsw1_r; /* DSW1 */
gladiator_8741[1].portHandler = gladiator_dsw2_r; /* DSW2 */
/* button controller */
gladiator_8741[2].portHandler = gladiator_button3_r; /* button3 */
/* joystick controller */
gladiator_8741[3].portHandler = gladiator_controll_r;
}
#if 1
/* !!!!! patch to IRQ timming for 2nd CPU !!!!! */
void gladiatr_irq_patch_w(int offset,int data)
{
cpu_cause_interrupt(1,Z80_INT_REQ);
}
#endif
/* YM2203 port A handler (input) */
static int gladiator_dsw3_r(int offset)
{
return input_port_2_r(offset)^0xff;
}
/* YM2203 port B handler (output) */
static void gladiator_int_controll_w(int offer , int data)
{
/* bit 7 : SSRST = sound reset ? */
/* bit 6-1 : N.C. */
/* bit 0 : ?? */
}
/* YM2203 IRQ */
static void gladiator_ym_irq(void)
{
/* NMI IRQ is not used by gladiator sound program */
cpu_cause_interrupt(1,Z80_NMI_INT);
}
/* gladiator I8741 emulation */
/* exchange data with serial port MASTER and SLAVE chip */
static void I8741_exchange_serial_data(int num)
{
I8741 *mst = &gladiator_8741[num];
I8741 *sst = &gladiator_8741[mst->connect];
int rp,wp;
/* master -> slave transfer */
rp = 0;
sst->rxd[rp++] = mst->portHandler ? mst->portHandler(0) : 0;
for( wp = 0 ; wp < 6 ; wp++)
sst->rxd[rp++] = mst->txd[wp];
/* slave -> master transfer */
rp = 0;
mst->rxd[rp++] = sst->portHandler ? sst->portHandler(0) : 0;
for( wp = 0 ; wp < 6 ; wp++)
mst->rxd[rp++] = sst->txd[wp];
}
/* read status port */
int I8741_status_r(int num)
{
I8741 *st = &gladiator_8741[num];
return st->status;
}
/* read data port */
int I8741_data_r(int num)
{
I8741 *st = &gladiator_8741[num];
int ret = st->rdata;
st->status &= 0xfe;
switch( st->mode )
{
case GLADIATOR_8741_PORT: /* parallel data */
st->rdata = st->portHandler ? st->portHandler(st->parallelselect) : 0;
st->status |= 0x01;
break;
}
return ret;
}
/* Write data port */
void I8741_data_w(int num, int data)
{
I8741 *st = &gladiator_8741[num];
switch( st->mode )
{
case GLADIATOR_8741_MASTER:
case GLADIATOR_8741_SLAVE:
/* buffering transmit data */
if( st->txpoint < 8 )
{
st->txd[st->txpoint++] = data;
}
break;
case GLADIATOR_8741_PORT:
st->parallelselect = data;
break;
}
}
/* Write command port */
void I8741_command_w(int num, int data)
{
I8741 *st = &gladiator_8741[num];
I8741 *sst;
switch( data )
{
case 0x00: /* read parallel port */
st->rdata = st->portHandler ? st->portHandler(0) : 0;
st->status |= 0x01;
break;
case 0x01: /* read receive buffer 0 */
case 0x02: /* read receive buffer 1 */
case 0x03: /* read receive buffer 2 */
case 0x04: /* read receive buffer 3 */
case 0x05: /* read receive buffer 4 */
case 0x06: /* read receive buffer 5 */
case 0x07: /* read receive buffer 6 */
st->rdata = st->rxd[data-1];
st->status |= 0x01;
break;
case 0x08: /* fix up transnit data */
if( st->mode == GLADIATOR_8741_SLAVE )
{
I8741_exchange_serial_data(num);
sst = &gladiator_8741[st->connect];
/* release MASTER command 4a holding */
if( sst->pending_4a )
{
sst->pending_4a = 0;
sst->rdata = 0x00; /* return code */
sst->status |= 0x01;
}
}
st->txpoint = 0;
break;
case 0x0a: /* 8741-0 : set serial comminucation mode 'MASTER' */
st->mode = GLADIATOR_8741_MASTER;
break;
case 0x0b: /* 8741-1 : set serial comminucation mode 'SLAVE' */
st->mode = GLADIATOR_8741_SLAVE;
break;
case 0x1f: /* 8741-2,3 : ?? set parallelport mode ?? */
case 0x3f: /* 8741-2,3 : ?? set parallelport mode ?? */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -