Ported code from MESS

This commit is contained in:
Angelo Salese 2010-10-11 01:14:11 +00:00
parent 30e795e988
commit 2e43a3d36d

View File

@ -322,6 +322,8 @@ static UINT16* _32x_palette;
static UINT16* _32x_palette_lookup;
/* SegaCD! */
static cpu_device *_segacd_68k_cpu;
static emu_timer *segacd_gfx_conversion_timer;
/* SVP (virtua racing) */
static cpu_device *_svp_cpu;
@ -362,7 +364,20 @@ static timer_device* irq4_on_timer;
static bitmap_t* render_bitmap;
//emu_timer* vblankirq_off_timer;
/* Sega CD stuff */
static int sega_cd_connected = 0x00;
static UINT16 segacd_irq_mask;
static UINT8 segacd_cdd_rx[10];
static UINT8 segacd_cdd_tx[10];
static struct
{
UINT8 status;
UINT8 minute;
UINT8 seconds;
UINT8 frame;
UINT8 ext;
UINT8 ctrl;
}segacd_cdd;
#ifdef UNUSED_FUNCTION
/* taken from segaic16.c */
@ -3496,7 +3511,7 @@ static WRITE16_HANDLER( _32x_sh2_common_4006_w )
// VRES (md reset button interrupt) clear
/**********************************************************************************************/
static WRITE16_HANDLER( _32x_sh2_master_4014_w ){cpu_set_input_line(_32x_master_cpu,SH2_VRES_IRQ_LEVEL,CLEAR_LINE);}
static WRITE16_HANDLER( _32x_sh2_master_4014_w ){ cpu_set_input_line(_32x_master_cpu,SH2_VRES_IRQ_LEVEL,CLEAR_LINE);}
static WRITE16_HANDLER( _32x_sh2_slave_4014_w ) { cpu_set_input_line(_32x_slave_cpu, SH2_VRES_IRQ_LEVEL,CLEAR_LINE);}
/**********************************************************************************************/
@ -4097,6 +4112,7 @@ static WRITE16_HANDLER( segacd_comms_sub_part2_w )
static int segacd_cdc_regaddress;
static int segacd_cdc_destination_device;
static UINT8 segacd_cdc_registers[0x10];
int segacd_conversion_active = 0;
static WRITE16_HANDLER( segacd_cdc_mode_address_w )
{
@ -4258,6 +4274,20 @@ static WRITE16_HANDLER( scd_a12006_hint_register_w )
}
static TIMER_CALLBACK( segacd_gfx_conversion_timer_callback )
{
// todo irqmask
printf("segacd_gfx_conversion_timer_callback\n");
if (segacd_irq_mask & 0x02)
cputag_set_input_line(machine, "segacd_68k", 1, HOLD_LINE);
segacd_conversion_active = 0;
}
/* main CPU map set up in INIT */
void segacd_init_main_cpu( running_machine* machine )
{
@ -4290,15 +4320,25 @@ void segacd_init_main_cpu( running_machine* machine )
memory_install_read16_handler (space, 0x0000070, 0x0000073, 0, 0, scd_hint_vector_r );
segacd_gfx_conversion_timer = timer_alloc(machine, segacd_gfx_conversion_timer_callback, 0);
timer_adjust_oneshot(segacd_gfx_conversion_timer, attotime_never, 0);
}
static MACHINE_RESET( segacd )
{
int i;
cpu_set_input_line(_segacd_68k_cpu, INPUT_LINE_RESET, ASSERT_LINE);
cpu_set_input_line(_segacd_68k_cpu, INPUT_LINE_HALT, ASSERT_LINE);
segacd_hint_register = 0xffff; // -1
for(i=0;i<10;i++)
{
segacd_cdd_rx[i] = 0;
}
segacd_cdd_rx[9] = 0xf; // default checksum
}
@ -4414,6 +4454,205 @@ static WRITE16_HANDLER( segacd_sub_dataram_part2_w )
}
}
static void cdd_hock_irq(running_machine *machine,UINT8 dir)
{
int i,cdd_crc;
if((segacd_cdd.ctrl & 4 || dir) && segacd_irq_mask & 0x10) // export status, check if bit 2 (HOst ClocK) and irq is enabled
{
// TODO: this shouldn't be instant, CDD should first fill receive data.
segacd_cdd.ctrl &= 0x103; // clear HOCK flag
segacd_cdd_rx[0] = (segacd_cdd.status & 0xf0) >> 4;
segacd_cdd_rx[1] = (segacd_cdd.status & 0x0f) >> 0;
segacd_cdd_rx[2] = (segacd_cdd.minute & 0xf0) >> 4;
segacd_cdd_rx[3] = (segacd_cdd.minute & 0x0f) >> 0;
segacd_cdd_rx[4] = (segacd_cdd.seconds & 0xf0) >> 4;
segacd_cdd_rx[5] = (segacd_cdd.seconds & 0x0f) >> 0;
segacd_cdd_rx[6] = (segacd_cdd.frame & 0xf0) >> 4;
segacd_cdd_rx[7] = (segacd_cdd.frame & 0x0f) >> 0;
segacd_cdd_rx[8] = (segacd_cdd.ext & 0x0f) >> 0;
/* Do checksum calculation of the above registers */
cdd_crc = 0;
for(i=0;i<9;i++)
cdd_crc += segacd_cdd_rx[i];
segacd_cdd_rx[9] = ((cdd_crc & 0xf) ^ 0xf);
cputag_set_input_line(machine, "segacd_68k", 4, HOLD_LINE);
}
}
static READ16_HANDLER( segacd_irq_mask_r )
{
return segacd_irq_mask;
}
static WRITE16_HANDLER( segacd_irq_mask_w )
{
segacd_irq_mask = data & 0x7e;
cdd_hock_irq(space->machine,0);
// check here other pending IRQs
}
static READ16_HANDLER( segacd_cdd_ctrl_r )
{
return segacd_cdd.ctrl;
}
static WRITE16_HANDLER( segacd_cdd_ctrl_w )
{
segacd_cdd.ctrl = data;
cdd_hock_irq(space->machine,0);
}
/* 68k <- CDD communication comms are 4-bit wide */
static READ8_HANDLER( segacd_cdd_rx_r )
{
return segacd_cdd_rx[offset] & 0xf;
}
static const char *const segacd_cdd_cmd[] =
{
"Status",
"Stop All",
"Get TOC Info",
"Read",
"Seek",
"Pause/Stop",
"Resume",
"Fast Forward",
"Fast Rewind",
"Recover Initial state",
"Close Tray",
"Open Tray",
"Unknown 0xE",
"Unknown 0xF"
};
static const char *const segacd_cdd_get_toc_cmd[] =
{
"Get Current Position",
"Get Elapsed Time of Current Track",
"Get Current Track",
"Get Total Length",
"Get First and Last Track Number",
"Get Track Addresses",
"Invalid 0x6",
"Invalid 0x7",
"Invalid 0x8",
"Invalid 0x9",
"Invalid 0xA",
"Invalid 0xB",
"Invalid 0xC",
"Invalid 0xD",
"Invalid 0xE",
"Invalid 0xF",
};
static void segacd_cdd_get_status(running_machine *machine)
{
// ...
cdd_hock_irq(machine,1);
}
static void segacd_cdd_stop_all(running_machine *machine)
{
// ...
segacd_cdd.ctrl |= 0x100; // set data bit
//cdd_hock_irq(machine,1); // doesn't work?
}
static void segacd_cdd_get_toc_info(running_machine *machine)
{
segacd_cdd.status = ((segacd_cdd_tx[3] & 0xf) << 4) | (segacd_cdd.status & 0xf);
switch(segacd_cdd_tx[3] & 0xf)
{
default: printf("CDD: unhandled TOC command %s issued\n",segacd_cdd_get_toc_cmd[segacd_cdd_tx[3] & 0xf]);
}
cdd_hock_irq(machine,1);
}
static WRITE8_HANDLER( segacd_cdd_tx_w )
{
//printf("CDD Communication write %02x -> [%02x]\n",data,offset);
segacd_cdd_tx[offset] = data & 0xf;
if(offset == 9) //execute the command when crc is sent (TODO: I wonder if we need to check if crc is valid. Plus obviously this shouldn't be instant)
{
switch(segacd_cdd_tx[0] & 0xf)
{
case 0x0: segacd_cdd_get_status(space->machine); break;
case 0x1: segacd_cdd_stop_all(space->machine); break;
case 0x2: segacd_cdd_get_toc_info(space->machine); break;
default: printf("CDD: unhandled command %s issued\n",segacd_cdd_cmd[segacd_cdd_tx[0] & 0xf]);
}
}
}
int segacd_stampsize;
static READ16_HANDLER( segacd_stampsize_r )
{
UINT16 retdata = 0x0000;
retdata |= segacd_conversion_active<<15;
retdata |= segacd_stampsize & 0x7;
return retdata;
}
static WRITE16_HANDLER( segacd_stampsize_w )
{
printf("segacd_stampsize_w %04x %04x\n",data, mem_mask);
if (ACCESSING_BITS_0_7)
{
segacd_stampsize = data & 0x07;
if (data & 0xf8)
printf(" unused bits (LSB) set in stampsize!\n");
if (data&1) printf(" Repeat On\n");
else printf(" Repeat Off\n");
if (data&2) printf(" 32x32 dots\n");
else printf(" 16x16 dots\n");
if (data&4) printf(" 16x16 screens\n");
else printf(" 1x1 screen\n");
}
if (ACCESSING_BITS_8_15)
{
if (data&0xff00) printf(" unused bits (MSB) set in stampsize!\n");
}
}
// this triggers the conversion operation, which will cause an IRQ1 when finished
WRITE16_HANDLER( segacd_trace_vector_base_address_w )
{
if (segacd_ram_mode==1)
{
printf("ILLEGAL: segacd_trace_vector_base_address_w %04x %04x in mode 1!\n",data,mem_mask);
}
printf("segacd_trace_vector_base_address_w %04x %04x\n",data,mem_mask);
segacd_conversion_active = 1;
timer_adjust_oneshot(segacd_gfx_conversion_timer, ATTOTIME_IN_HZ(1), 0);
}
static ADDRESS_MAP_START( segacd_map, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0x000000, 0x07ffff) AM_RAM AM_BASE(&segacd_4meg_prgram)
@ -4421,9 +4660,9 @@ static ADDRESS_MAP_START( segacd_map, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0x080000, 0x0bffff) AM_READWRITE(segacd_sub_dataram_part1_r, segacd_sub_dataram_part1_w) AM_BASE(&segacd_dataram)
AM_RANGE(0x0c0000, 0x0dffff) AM_READWRITE(segacd_sub_dataram_part2_r, segacd_sub_dataram_part2_w) AM_BASE(&segacd_dataram2)
// AM_RANGE(0xfe0000, 0xfe3fff) // backup RAM, odd bytes only!
AM_RANGE(0xfe0000, 0xfe3fff) AM_RAM // backup RAM, odd bytes only!
// AM_RANGE(0xff0000, 0xff7fff) // PCM, RF5C164
AM_RANGE(0xff0000, 0xff7fff) AM_RAM // PCM, RF5C164
AM_RANGE(0xff8000 ,0xff8001) AM_READWRITE(segacd_sub_led_ready_r, segacd_sub_led_ready_w)
AM_RANGE(0xff8002 ,0xff8003) AM_READWRITE(segacd_sub_memory_mode_r, segacd_sub_memory_mode_w)
@ -4436,25 +4675,26 @@ static ADDRESS_MAP_START( segacd_map, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0xff8010 ,0xff801f) AM_READWRITE(segacd_comms_sub_part1_r, segacd_comms_sub_part1_w)
AM_RANGE(0xff8020 ,0xff802f) AM_READWRITE(segacd_comms_sub_part2_r, segacd_comms_sub_part2_w)
// AM_RANGE(0xff8030, 0xff8031) // Timer W/INT3
// AM_RANGE(0xff8032, 0xff8033) // IRQ Mask
// AM_RANGE(0xff8034, 0xff8035) // CD Fader
// AM_RANGE(0xff8036, 0xff8037) // CDD Control
// AM_RANGE(0xff8038, 0xff804b) // CDD Communication ports 0-9
AM_RANGE(0xff8032, 0xff8033) AM_READWRITE(segacd_irq_mask_r,segacd_irq_mask_w)
AM_RANGE(0xff8034, 0xff8035) AM_NOP // CD Fader
AM_RANGE(0xff8036, 0xff8037) AM_READWRITE(segacd_cdd_ctrl_r,segacd_cdd_ctrl_w)
AM_RANGE(0xff8038, 0xff8041) AM_READ8(segacd_cdd_rx_r,0xffff)
AM_RANGE(0xff8042, 0xff804b) AM_WRITE8(segacd_cdd_tx_w,0xffff)
// AM_RANGE(0xff804c, 0xff804d) // Font Color
// AM_RANGE(0xff804e, 0xff804f) // Font bit
// AM_RANGE(0xff8050, 0xff8057) // Font data (read only)
// AM_RANGE(0xff8058, 0xff8059) // Stamp size
AM_RANGE(0xff8058, 0xff8059) AM_READWRITE(segacd_stampsize_r, segacd_stampsize_w) // Stamp size
// AM_RANGE(0xff805a, 0xff805b) // Stamp map base address
// AM_RANGE(0xff805c, 0xff805d) // Image buffer V cell size
// AM_RANGE(0xff805e, 0xff805f) // Image buffer start address
// AM_RANGE(0xff8060, 0xff8061) // Image buffer offset
// AM_RANGE(0xff8062, 0xff8063) // Image buffer H dot size
// AM_RANGE(0xff8064, 0xff8065) // Image buffer V dot size
// AM_RANGE(0xff8066, 0xff8067) // Trace vector base address
AM_RANGE(0xff8066, 0xff8067) AM_WRITE(segacd_trace_vector_base_address_w)// Trace vector base address
// AM_RANGE(0xff8068, 0xff8069) // Subcode address
// AM_RANGE(0xff8100, 0xff817f) // Subcode buffer area
// AM_RANGE(0xff8180, 0xff81ff) // Image of subcode buffer area
// AM_RANGE(0xff8180, 0xff81ff) // mirror of subcode buffer area
ADDRESS_MAP_END