mirror of
https://github.com/holub/mame
synced 2025-10-08 09:30:17 +03:00
Refactored dreamcast to use an ATA interface [smf]
This commit is contained in:
parent
a3eb1c6917
commit
1657fcfa43
@ -11,6 +11,17 @@
|
||||
#include "gdrom.h"
|
||||
#include "debugger.h"
|
||||
|
||||
#define GDROM_BUSY_STATE 0x00
|
||||
#define GDROM_PAUSE_STATE 0x01
|
||||
#define GDROM_STANDBY_STATE 0x02
|
||||
#define GDROM_PLAY_STATE 0x03
|
||||
#define GDROM_SEEK_STATE 0x04
|
||||
#define GDROM_SCAN_STATE 0x05
|
||||
#define GDROM_OPEN_STATE 0x06
|
||||
#define GDROM_NODISC_STATE 0x07
|
||||
#define GDROM_RETRY_STATE 0x08
|
||||
#define GDROM_ERROR_STATE 0x09
|
||||
|
||||
static const UINT8 GDROM_Cmd71_Reply[] =
|
||||
{
|
||||
0x0b,0x96,0xf0,0x45,0xff,0x7e,0x06,0x3d,0x7d,0x4d,0xbf,0x10,0x00,0x07,0xcf,0x73,
|
||||
@ -89,15 +100,15 @@ static void phys_frame_to_msf(int phys_frame, int *m, int *s, int *f)
|
||||
}
|
||||
|
||||
// device type definition
|
||||
const device_type GDROM = &device_creator<gdrom_device>;
|
||||
const device_type SCSI_GDROM = &device_creator<scsi_gdrom_device>;
|
||||
|
||||
gdrom_device::gdrom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: scsihle_device(mconfig, GDROM, "GDROM", tag, owner, clock, "gdrom", __FILE__),
|
||||
scsi_gdrom_device::scsi_gdrom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: scsihle_device(mconfig, SCSI_GDROM, "SCSI GDROM", tag, owner, clock, "scsi_gdrom", __FILE__),
|
||||
m_cdda(*this, "cdda")
|
||||
{
|
||||
}
|
||||
|
||||
void gdrom_device::device_start()
|
||||
void scsi_gdrom_device::device_start()
|
||||
{
|
||||
save_item( NAME( lba ) );
|
||||
save_item( NAME( blocks ) );
|
||||
@ -108,7 +119,7 @@ void gdrom_device::device_start()
|
||||
save_item( NAME( play_err_flag ) );
|
||||
}
|
||||
|
||||
void gdrom_device::device_reset()
|
||||
void scsi_gdrom_device::device_reset()
|
||||
{
|
||||
scsihle_device::device_reset();
|
||||
|
||||
@ -148,7 +159,7 @@ void gdrom_device::device_reset()
|
||||
play_err_flag = 0;
|
||||
}
|
||||
|
||||
void gdrom_device::device_stop()
|
||||
void scsi_gdrom_device::device_stop()
|
||||
{
|
||||
if (!is_file)
|
||||
{
|
||||
@ -159,13 +170,14 @@ void gdrom_device::device_stop()
|
||||
}
|
||||
}
|
||||
|
||||
cdrom_interface gdrom_device::cd_intf = { 0, 0 };
|
||||
cdrom_interface scsi_gdrom_device::cd_intf = { 0, 0 };
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT(scsi_cdrom)
|
||||
MCFG_CDROM_ADD("image", gdrom_device::cd_intf)
|
||||
MCFG_CDROM_ADD("image", scsi_gdrom_device::cd_intf)
|
||||
MCFG_SOUND_ADD("cdda", CDDA, 0)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
machine_config_constructor gdrom_device::device_mconfig_additions() const
|
||||
machine_config_constructor scsi_gdrom_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME(scsi_cdrom);
|
||||
}
|
||||
@ -174,7 +186,7 @@ machine_config_constructor gdrom_device::device_mconfig_additions() const
|
||||
//
|
||||
// Execute a SCSI command.
|
||||
|
||||
void gdrom_device::ExecCommand( int *transferLength )
|
||||
void scsi_gdrom_device::ExecCommand( int *transferLength )
|
||||
{
|
||||
int trk;
|
||||
|
||||
@ -565,7 +577,7 @@ void gdrom_device::ExecCommand( int *transferLength )
|
||||
//
|
||||
// Read data from the device resulting from the execution of a command
|
||||
|
||||
void gdrom_device::ReadData( UINT8 *data, int dataLength )
|
||||
void scsi_gdrom_device::ReadData( UINT8 *data, int dataLength )
|
||||
{
|
||||
int i;
|
||||
UINT32 last_phys_frame;
|
||||
@ -994,7 +1006,7 @@ void gdrom_device::ReadData( UINT8 *data, int dataLength )
|
||||
//
|
||||
// Write data to the CD-ROM device as part of the execution of a command
|
||||
|
||||
void gdrom_device::WriteData( UINT8 *data, int dataLength )
|
||||
void scsi_gdrom_device::WriteData( UINT8 *data, int dataLength )
|
||||
{
|
||||
switch (command[ 0 ])
|
||||
{
|
||||
@ -1038,17 +1050,91 @@ void gdrom_device::WriteData( UINT8 *data, int dataLength )
|
||||
}
|
||||
}
|
||||
|
||||
void gdrom_device::GetDevice( void **_cdrom )
|
||||
void scsi_gdrom_device::GetDevice( void **_cdrom )
|
||||
{
|
||||
*(cdrom_file **)_cdrom = cdrom;
|
||||
}
|
||||
|
||||
void gdrom_device::SetDevice( void *_cdrom )
|
||||
void scsi_gdrom_device::SetDevice( void *_cdrom )
|
||||
{
|
||||
cdrom = (cdrom_file *) _cdrom;
|
||||
}
|
||||
|
||||
int gdrom_device::GetSectorBytes()
|
||||
int scsi_gdrom_device::GetSectorBytes()
|
||||
{
|
||||
return bytes_per_sector;
|
||||
}
|
||||
|
||||
// device type definition
|
||||
const device_type GDROM = &device_creator<gdrom_device>;
|
||||
|
||||
gdrom_device::gdrom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: atapi_hle_device(mconfig, GDROM, "GDROM", tag, owner, clock, "gdrom", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( gdrom )
|
||||
MCFG_DEVICE_ADD("device", SCSI_GDROM, 0)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
//-------------------------------------------------
|
||||
// machine_config_additions - device-specific
|
||||
// machine configurations
|
||||
//-------------------------------------------------
|
||||
|
||||
machine_config_constructor gdrom_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( gdrom );
|
||||
}
|
||||
|
||||
void gdrom_device::device_start()
|
||||
{
|
||||
memset(m_identify_buffer, 0, sizeof(m_identify_buffer));
|
||||
|
||||
m_identify_buffer[ 0 ] = 0x8600; // ATAPI device, cmd set 6 compliant, DRQ within 3 ms of PACKET command
|
||||
|
||||
m_identify_buffer[ 23 ] = ('S' << 8) | 'E';
|
||||
m_identify_buffer[ 24 ] = (' ' << 8) | ' ';
|
||||
m_identify_buffer[ 25 ] = (' ' << 8) | ' ';
|
||||
m_identify_buffer[ 26 ] = (' ' << 8) | ' ';
|
||||
|
||||
m_identify_buffer[ 27 ] = ('C' << 8) | 'D';
|
||||
m_identify_buffer[ 28 ] = ('-' << 8) | 'R';
|
||||
m_identify_buffer[ 29 ] = ('O' << 8) | 'M';
|
||||
m_identify_buffer[ 30 ] = (' ' << 8) | 'D';
|
||||
m_identify_buffer[ 31 ] = ('R' << 8) | 'I';
|
||||
m_identify_buffer[ 32 ] = ('V' << 8) | 'E';
|
||||
m_identify_buffer[ 33 ] = (' ' << 8) | ' ';
|
||||
m_identify_buffer[ 34 ] = (' ' << 8) | ' ';
|
||||
m_identify_buffer[ 35 ] = ('6' << 8) | '.';
|
||||
m_identify_buffer[ 36 ] = ('4' << 8) | '2';
|
||||
m_identify_buffer[ 37 ] = (' ' << 8) | ' ';
|
||||
m_identify_buffer[ 38 ] = (' ' << 8) | ' ';
|
||||
m_identify_buffer[ 39 ] = (' ' << 8) | ' ';
|
||||
m_identify_buffer[ 40 ] = (' ' << 8) | ' ';
|
||||
m_identify_buffer[ 41 ] = (' ' << 8) | ' ';
|
||||
m_identify_buffer[ 42 ] = (' ' << 8) | ' ';
|
||||
m_identify_buffer[ 43 ] = (' ' << 8) | ' ';
|
||||
m_identify_buffer[ 44 ] = (' ' << 8) | ' ';
|
||||
m_identify_buffer[ 45 ] = (' ' << 8) | ' ';
|
||||
m_identify_buffer[ 46 ] = (' ' << 8) | ' ';
|
||||
|
||||
m_identify_buffer[ 49 ] = 0x0400; // IORDY may be disabled
|
||||
|
||||
atapi_hle_device::device_start();
|
||||
}
|
||||
|
||||
void gdrom_device::perform_diagnostic()
|
||||
{
|
||||
m_error = IDE_ERROR_DIAGNOSTIC_PASSED;
|
||||
}
|
||||
|
||||
void gdrom_device::process_buffer()
|
||||
{
|
||||
atapi_hle_device::process_buffer();
|
||||
m_sector_number = 0x80 | GDROM_PAUSE_STATE; /// HACK: find out when this should be updated
|
||||
}
|
||||
|
||||
void gdrom_device::identify_packet_device()
|
||||
{
|
||||
}
|
||||
|
@ -7,15 +7,17 @@
|
||||
#ifndef _GDROM_H_
|
||||
#define _GDROM_H_
|
||||
|
||||
#include "machine/atapihle.h"
|
||||
#include "machine/scsihle.h"
|
||||
#include "sound/cdda.h"
|
||||
#include "cdrom.h"
|
||||
|
||||
// Sega GD-ROM handler
|
||||
class gdrom_device : public scsihle_device
|
||||
class scsi_gdrom_device : public scsihle_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
gdrom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
scsi_gdrom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
virtual void SetDevice( void *device );
|
||||
@ -45,11 +47,29 @@ private:
|
||||
UINT32 data_select; // for command 0x30 only
|
||||
UINT32 transferOffset;
|
||||
cdrom_file *cdrom;
|
||||
optional_device<cdda_device> m_cdda;
|
||||
required_device<cdda_device> m_cdda;
|
||||
bool is_file;
|
||||
UINT8 GDROM_Cmd11_Reply[32];
|
||||
};
|
||||
|
||||
// device type definition
|
||||
extern const device_type SCSI_GDROM;
|
||||
|
||||
class gdrom_device : public atapi_hle_device
|
||||
{
|
||||
public:
|
||||
gdrom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
virtual void device_start();
|
||||
|
||||
virtual void perform_diagnostic();
|
||||
virtual void identify_packet_device();
|
||||
virtual void process_buffer();
|
||||
};
|
||||
|
||||
// device type definition
|
||||
extern const device_type GDROM;
|
||||
|
||||
|
@ -365,7 +365,8 @@ static ADDRESS_MAP_START( dc_map, AS_PROGRAM, 64, dc_cons_state )
|
||||
AM_RANGE(0x00200000, 0x0021ffff) AM_ROM AM_REGION("dcflash",0)//AM_READWRITE8(dc_flash_r,dc_flash_w, U64(0xffffffffffffffff))
|
||||
AM_RANGE(0x005f6800, 0x005f69ff) AM_READWRITE(dc_sysctrl_r, dc_sysctrl_w )
|
||||
AM_RANGE(0x005f6c00, 0x005f6cff) AM_DEVICE32( "maple_dc", maple_dc_device, amap, U64(0xffffffffffffffff) )
|
||||
AM_RANGE(0x005f7000, 0x005f70ff) AM_READWRITE32(dc_mess_gdrom_r, dc_mess_gdrom_w, U64(0xffffffffffffffff) )
|
||||
AM_RANGE(0x005f7000, 0x005f701f) AM_DEVREADWRITE16("ata", ata_interface_device, read_cs1, write_cs1, U64(0x0000ffff0000ffff) )
|
||||
AM_RANGE(0x005f7080, 0x005f709f) AM_DEVREADWRITE16("ata", ata_interface_device, read_cs0, write_cs0, U64(0x0000ffff0000ffff) )
|
||||
AM_RANGE(0x005f7400, 0x005f74ff) AM_READWRITE32(dc_mess_g1_ctrl_r, dc_mess_g1_ctrl_w, U64(0xffffffffffffffff) )
|
||||
AM_RANGE(0x005f7800, 0x005f78ff) AM_READWRITE(dc_g2_ctrl_r, dc_g2_ctrl_w )
|
||||
AM_RANGE(0x005f7c00, 0x005f7cff) AM_DEVICE32("powervr2", powervr2_device, pd_dma_map, U64(0xffffffffffffffff))
|
||||
@ -562,7 +563,6 @@ MACHINE_RESET_MEMBER(dc_cons_state,dc_console)
|
||||
device_t *aica = machine().device("aica");
|
||||
dc_state::machine_reset();
|
||||
aica_set_ram_base(aica, dc_sound_ram, 2*1024*1024);
|
||||
dreamcast_atapi_reset();
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(dc_cons_state::aica_irq)
|
||||
@ -590,6 +590,16 @@ static const aica_interface dc_aica_interface =
|
||||
|
||||
static const struct sh4_config sh4cpu_config = { 1, 0, 1, 0, 0, 0, 1, 1, 0, CPU_CLOCK };
|
||||
|
||||
SLOT_INTERFACE_START(dccons_ata_devices)
|
||||
SLOT_INTERFACE("gdrom", GDROM)
|
||||
SLOT_INTERFACE_END
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( gdrom_config )
|
||||
MCFG_DEVICE_MODIFY("device:cdda")
|
||||
MCFG_SOUND_ROUTE(0, "^^^^^lspeaker", 1.0)
|
||||
MCFG_SOUND_ROUTE(1, "^^^^^rspeaker", 1.0)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_START( dc, dc_cons_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu", SH4LE, CPU_CLOCK)
|
||||
@ -624,7 +634,11 @@ static MACHINE_CONFIG_START( dc, dc_cons_state )
|
||||
MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
|
||||
MCFG_SOUND_ROUTE(0, "rspeaker", 1.0)
|
||||
|
||||
MCFG_DEVICE_ADD("cdrom", GDROM, 0)
|
||||
MCFG_ATA_INTERFACE_ADD("ata", dccons_ata_devices, "gdrom", NULL, true)
|
||||
MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(dc_cons_state, ata_interrupt))
|
||||
|
||||
MCFG_DEVICE_MODIFY("ata:0")
|
||||
MCFG_DEVICE_CARD_MACHINE_CONFIG( "gdrom", gdrom_config )
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
/*
|
||||
|
@ -1,15 +1,18 @@
|
||||
#include "imagedev/chd_cd.h"
|
||||
#include "machine/gdrom.h"
|
||||
#include "machine/ataintf.h"
|
||||
#include "machine/intelfsh.h"
|
||||
|
||||
class dc_cons_state : public dc_state
|
||||
{
|
||||
public:
|
||||
dc_cons_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: dc_state(mconfig, type, tag)
|
||||
: dc_state(mconfig, type, tag),
|
||||
m_ata(*this, "ata")
|
||||
// m_dcflash(*this, "dcflash")
|
||||
{ }
|
||||
|
||||
required_device<ata_interface_device> m_ata;
|
||||
// required_device<macronix_29lv160tmc_device> m_dcflash;
|
||||
|
||||
DECLARE_DRIVER_INIT(dc);
|
||||
@ -26,23 +29,11 @@ public:
|
||||
DECLARE_WRITE64_MEMBER(dc_arm_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(aica_irq);
|
||||
DECLARE_WRITE_LINE_MEMBER(sh4_aica_irq);
|
||||
void gdrom_raise_irq();
|
||||
void gdrom_set_status(UINT8 flag,bool state);
|
||||
void gdrom_set_error(UINT8 flag,bool state);
|
||||
DECLARE_WRITE_LINE_MEMBER(ata_interrupt);
|
||||
|
||||
TIMER_CALLBACK_MEMBER( atapi_xfer_end );
|
||||
TIMER_CALLBACK_MEMBER( atapi_cmd_exec );
|
||||
UINT8 cur_atapi_cmd;
|
||||
void atapi_cmd_nop();
|
||||
void atapi_cmd_packet();
|
||||
void atapi_cmd_identify_packet();
|
||||
void atapi_cmd_set_features();
|
||||
|
||||
void dreamcast_atapi_init();
|
||||
void dreamcast_atapi_reset();
|
||||
inline int decode_reg32_64(UINT32 offset, UINT64 mem_mask, UINT64 *shift);
|
||||
DECLARE_READ32_MEMBER( dc_mess_gdrom_r );
|
||||
DECLARE_WRITE32_MEMBER( dc_mess_gdrom_w );
|
||||
DECLARE_READ32_MEMBER( dc_mess_g1_ctrl_r );
|
||||
DECLARE_WRITE32_MEMBER( dc_mess_g1_ctrl_w );
|
||||
// DECLARE_READ8_MEMBER( dc_flash_r );
|
||||
@ -50,13 +41,6 @@ public:
|
||||
|
||||
private:
|
||||
UINT64 PDTRA, PCTRA;
|
||||
|
||||
UINT8 *atapi_regs;
|
||||
emu_timer *atapi_timer,*atapi_cmd_timer;
|
||||
gdrom_device *gdrom;
|
||||
UINT8 *atapi_data;
|
||||
int atapi_data_ptr, atapi_data_len, atapi_xferlen, atapi_xferbase, atapi_cdata_wait, atapi_xfermod;
|
||||
UINT8 xfer_mode;
|
||||
int atapi_pio_ptr;
|
||||
UINT8 pio_sector_buffer[2048];
|
||||
emu_timer *atapi_timer;
|
||||
int atapi_xferlen, atapi_xferbase;
|
||||
};
|
||||
|
@ -26,233 +26,39 @@
|
||||
|
||||
#define ATAPI_CYCLES_PER_SECTOR (5000) // TBD for Dreamcast
|
||||
|
||||
#define ATAPI_STAT_BSY 0x80
|
||||
#define ATAPI_STAT_DRDY 0x40
|
||||
#define ATAPI_STAT_DMARDDF 0x20
|
||||
#define ATAPI_STAT_SERVDSC 0x10
|
||||
#define ATAPI_STAT_DRQ 0x08
|
||||
#define ATAPI_STAT_CORR 0x04
|
||||
#define ATAPI_STAT_CHECK 0x01
|
||||
|
||||
#define ATAPI_ERR_ABORT 0x04
|
||||
|
||||
#define ATAPI_INTREASON_COMMAND 0x01
|
||||
#define ATAPI_INTREASON_IO 0x02
|
||||
#define ATAPI_INTREASON_RELEASE 0x04
|
||||
|
||||
#define ATAPI_REG_DATA 0
|
||||
#define ATAPI_REG_FEATURES 1
|
||||
#define ATAPI_REG_INTREASON 2
|
||||
#define ATAPI_REG_SAMTAG 3
|
||||
#define ATAPI_REG_COUNTLOW 4
|
||||
#define ATAPI_REG_COUNTHIGH 5
|
||||
#define ATAPI_REG_DRIVESEL 6
|
||||
#define ATAPI_REG_CMDSTATUS 7
|
||||
#define ATAPI_REG_ERROR 16 // read-only ERROR (write is FEATURES)
|
||||
|
||||
#define GDROM_BUSY_STATE 0x00
|
||||
#define GDROM_PAUSE_STATE 0x01
|
||||
#define GDROM_STANDBY_STATE 0x02
|
||||
#define GDROM_PLAY_STATE 0x03
|
||||
#define GDROM_SEEK_STATE 0x04
|
||||
#define GDROM_SCAN_STATE 0x05
|
||||
#define GDROM_OPEN_STATE 0x06
|
||||
#define GDROM_NODISC_STATE 0x07
|
||||
#define GDROM_RETRY_STATE 0x08
|
||||
#define GDROM_ERROR_STATE 0x09
|
||||
|
||||
#define ATAPI_REG_MAX 24
|
||||
|
||||
#define ATAPI_XFER_PIO 0x00
|
||||
#define ATAPI_XFER_PIO_FLOW 0x08
|
||||
#define ATAPI_XFER_SINGLE_DMA 0x10
|
||||
#define ATAPI_XFER_MULTI_DMA 0x20
|
||||
#define ATAPI_XFER_ULTRA_DMA 0x40
|
||||
|
||||
#define ATAPI_DATA_SIZE ( 64 * 1024 )
|
||||
|
||||
#define MAX_TRANSFER_SIZE ( 63488 )
|
||||
|
||||
void dc_cons_state::gdrom_set_status(UINT8 flag,bool state)
|
||||
WRITE_LINE_MEMBER(dc_cons_state::ata_interrupt)
|
||||
{
|
||||
if(flag & ATAPI_STAT_DRQ)
|
||||
printf("DRQ %02x\n",state);
|
||||
|
||||
if(state)
|
||||
atapi_regs[ATAPI_REG_CMDSTATUS] |= flag;
|
||||
if (state)
|
||||
dc_sysctrl_regs[SB_ISTEXT] |= IST_EXT_GDROM;
|
||||
else
|
||||
atapi_regs[ATAPI_REG_CMDSTATUS] &= ~flag;
|
||||
}
|
||||
dc_sysctrl_regs[SB_ISTEXT] &= ~IST_EXT_GDROM;
|
||||
|
||||
void dc_cons_state::gdrom_set_error(UINT8 flag,bool state)
|
||||
{
|
||||
if(state)
|
||||
atapi_regs[ATAPI_REG_ERROR] |= flag;
|
||||
else
|
||||
atapi_regs[ATAPI_REG_ERROR] &= ~flag;
|
||||
}
|
||||
|
||||
|
||||
void dc_cons_state::gdrom_raise_irq()
|
||||
{
|
||||
dc_sysctrl_regs[SB_ISTEXT] |= IST_EXT_GDROM;
|
||||
dc_update_interrupt_status();
|
||||
}
|
||||
|
||||
void dc_cons_state::atapi_cmd_nop()
|
||||
{
|
||||
gdrom_set_status(ATAPI_STAT_BSY,false);
|
||||
gdrom_set_status(ATAPI_STAT_DRDY,true);
|
||||
|
||||
gdrom_set_status(ATAPI_STAT_CHECK,true);
|
||||
gdrom_set_error(ATAPI_ERR_ABORT,true);
|
||||
|
||||
atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_COMMAND;
|
||||
gdrom_raise_irq();
|
||||
}
|
||||
|
||||
void dc_cons_state::atapi_cmd_packet()
|
||||
{
|
||||
atapi_data_ptr = 0;
|
||||
atapi_data_len = 0;
|
||||
|
||||
/* we have no data */
|
||||
atapi_xferlen = 0;
|
||||
atapi_xfermod = 0;
|
||||
atapi_cdata_wait = 0;
|
||||
|
||||
gdrom_set_status(ATAPI_STAT_BSY,false);
|
||||
gdrom_set_status(ATAPI_STAT_DRQ,true);
|
||||
atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_COMMAND;
|
||||
/* TODO: raise irq? */
|
||||
}
|
||||
|
||||
void dc_cons_state::atapi_cmd_identify_packet()
|
||||
{
|
||||
atapi_data_ptr = 0;
|
||||
atapi_data_len = 512;
|
||||
/* we have no data */
|
||||
atapi_xferlen = 0;
|
||||
atapi_xfermod = 0;
|
||||
|
||||
memset( atapi_data, 0, atapi_data_len );
|
||||
|
||||
atapi_data[ 0 ^ 1 ] = 0x86; // ATAPI device, cmd set 6 compliant, DRQ within 3 ms of PACKET command
|
||||
atapi_data[ 1 ^ 1 ] = 0x00;
|
||||
|
||||
memset( &atapi_data[ 46 ], ' ', 8 );
|
||||
atapi_data[ 46 ^ 1 ] = 'S';
|
||||
atapi_data[ 47 ^ 1 ] = 'E';
|
||||
|
||||
memset( &atapi_data[ 54 ], ' ', 40 );
|
||||
atapi_data[ 54 ^ 1 ] = 'C';
|
||||
atapi_data[ 55 ^ 1 ] = 'D';
|
||||
atapi_data[ 56 ^ 1 ] = '-';
|
||||
atapi_data[ 57 ^ 1 ] = 'R';
|
||||
atapi_data[ 58 ^ 1 ] = 'O';
|
||||
atapi_data[ 59 ^ 1 ] = 'M';
|
||||
atapi_data[ 60 ^ 1 ] = ' ';
|
||||
atapi_data[ 61 ^ 1 ] = 'D';
|
||||
atapi_data[ 62 ^ 1 ] = 'R';
|
||||
atapi_data[ 63 ^ 1 ] = 'I';
|
||||
atapi_data[ 64 ^ 1 ] = 'V';
|
||||
atapi_data[ 65 ^ 1 ] = 'E';
|
||||
atapi_data[ 66 ^ 1 ] = ' ';
|
||||
atapi_data[ 67 ^ 1 ] = ' ';
|
||||
atapi_data[ 68 ^ 1 ] = ' ';
|
||||
atapi_data[ 69 ^ 1 ] = ' ';
|
||||
atapi_data[ 70 ^ 1 ] = '6';
|
||||
atapi_data[ 71 ^ 1 ] = '.';
|
||||
atapi_data[ 72 ^ 1 ] = '4';
|
||||
atapi_data[ 73 ^ 1 ] = '2';
|
||||
|
||||
atapi_data[ 98 ^ 1 ] = 0x04; // IORDY may be disabled
|
||||
atapi_data[ 99 ^ 1 ] = 0x00;
|
||||
|
||||
atapi_regs[ATAPI_REG_COUNTLOW] = 0;
|
||||
atapi_regs[ATAPI_REG_COUNTHIGH] = 2;
|
||||
|
||||
gdrom_set_status(ATAPI_STAT_BSY,false);
|
||||
gdrom_set_status(ATAPI_STAT_DRQ,true);
|
||||
atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO; /* ok? */
|
||||
gdrom_raise_irq();
|
||||
}
|
||||
|
||||
void dc_cons_state::atapi_cmd_set_features()
|
||||
{
|
||||
//TODO: error ABORT flag clear
|
||||
|
||||
// set xfer mode?
|
||||
if (atapi_regs[ATAPI_REG_FEATURES] == 0x03)
|
||||
{
|
||||
printf("Set transfer mode to %x\n", atapi_regs[ATAPI_REG_COUNTLOW] & 0xf8);
|
||||
xfer_mode = atapi_regs[ATAPI_REG_COUNTLOW] & 0xf8;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ATAPI: Unknown set features %x\n", atapi_regs[ATAPI_REG_FEATURES]);
|
||||
}
|
||||
|
||||
gdrom_set_status(ATAPI_STAT_BSY,false);
|
||||
gdrom_set_error(ATAPI_ERR_ABORT,false);
|
||||
gdrom_set_status(ATAPI_STAT_SERVDSC,false);
|
||||
gdrom_set_status(ATAPI_STAT_DMARDDF,false);
|
||||
gdrom_set_status(ATAPI_STAT_CHECK,false);
|
||||
gdrom_set_status(ATAPI_STAT_DRDY,true);
|
||||
|
||||
atapi_data_ptr = 0;
|
||||
atapi_data_len = 0;
|
||||
|
||||
gdrom_raise_irq();
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(dc_cons_state::atapi_cmd_exec )
|
||||
{
|
||||
atapi_cmd_timer->adjust(attotime::never);
|
||||
|
||||
gdrom_set_status(ATAPI_STAT_CHECK,false);
|
||||
gdrom_set_error(ATAPI_ERR_ABORT,false);
|
||||
|
||||
switch (cur_atapi_cmd)
|
||||
{
|
||||
case 0x00:
|
||||
atapi_cmd_nop();
|
||||
break;
|
||||
|
||||
case 0xa0: // PACKET
|
||||
atapi_cmd_packet();
|
||||
break;
|
||||
|
||||
case 0xa1: // IDENTIFY PACKET DEVICE
|
||||
atapi_cmd_identify_packet();
|
||||
break;
|
||||
|
||||
case 0xef: // SET FEATURES
|
||||
atapi_cmd_set_features();
|
||||
break;
|
||||
|
||||
default:
|
||||
mame_printf_debug("ATAPI: Unknown IDE command %x\n", cur_atapi_cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(dc_cons_state::atapi_xfer_end )
|
||||
{
|
||||
UINT8 sector_buffer[ 4096 ];
|
||||
|
||||
atapi_timer->adjust(attotime::never);
|
||||
|
||||
printf("atapi_xfer_end atapi_xferlen = %d, atapi_xfermod=%d\n", atapi_xfermod, atapi_xferlen );
|
||||
printf("atapi_xfer_end atapi_xferlen = %d\n", atapi_xferlen );
|
||||
|
||||
mame_printf_debug("ATAPI: xfer_end. xferlen = %d, atapi_xfermod = %d\n", atapi_xferlen, atapi_xfermod);
|
||||
//mame_printf_debug("ATAPI: xfer_end. xferlen = %d\n", atapi_xferlen);
|
||||
|
||||
address_space &space = m_maincpu->space(AS_PROGRAM);
|
||||
|
||||
while (atapi_xferlen > 0 )
|
||||
{
|
||||
struct sh4_ddt_dma ddtdata;
|
||||
|
||||
// get a sector from the SCSI device
|
||||
gdrom->ReadData( sector_buffer, 2048 );
|
||||
for (int i = 0; i < 2048/2; i++)
|
||||
{
|
||||
int d = m_ata->read_cs0(space, 0, 0xffff);
|
||||
sector_buffer[ i*2 ] = d & 0xff;
|
||||
sector_buffer[ (i*2)+1 ] = d >> 8;
|
||||
}
|
||||
|
||||
atapi_xferlen -= 2048;
|
||||
|
||||
@ -270,93 +76,17 @@ TIMER_CALLBACK_MEMBER(dc_cons_state::atapi_xfer_end )
|
||||
atapi_xferbase += 2048;
|
||||
}
|
||||
|
||||
if (atapi_xfermod > MAX_TRANSFER_SIZE)
|
||||
{
|
||||
atapi_xferlen = MAX_TRANSFER_SIZE;
|
||||
atapi_xfermod = atapi_xfermod - MAX_TRANSFER_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
atapi_xferlen = atapi_xfermod;
|
||||
atapi_xfermod = 0;
|
||||
}
|
||||
|
||||
if (atapi_xferlen > 0)
|
||||
{
|
||||
printf("ATAPI: starting next piece of multi-part transfer\n");
|
||||
atapi_regs[ATAPI_REG_COUNTLOW] = atapi_xferlen & 0xff;
|
||||
atapi_regs[ATAPI_REG_COUNTHIGH] = (atapi_xferlen>>8)&0xff;
|
||||
|
||||
atapi_timer->adjust(m_maincpu->cycles_to_attotime((ATAPI_CYCLES_PER_SECTOR * (atapi_xferlen/2048))));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ATAPI: Transfer completed, dropping DRQ\n");
|
||||
gdrom_set_status(ATAPI_STAT_DRDY,true);
|
||||
gdrom_set_status(ATAPI_STAT_DRQ,false);
|
||||
gdrom_set_status(ATAPI_STAT_BSY,false);
|
||||
atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO | ATAPI_INTREASON_COMMAND;
|
||||
atapi_regs[ATAPI_REG_SAMTAG] = GDROM_PAUSE_STATE | 0x80;
|
||||
|
||||
g1bus_regs[SB_GDST]=0;
|
||||
dc_sysctrl_regs[SB_ISTNRM] |= IST_DMA_GDROM;
|
||||
dc_update_interrupt_status();
|
||||
}
|
||||
|
||||
gdrom_raise_irq();
|
||||
|
||||
printf( "atapi_xfer_end: %d %d\n", atapi_xferlen, atapi_xfermod );
|
||||
g1bus_regs[SB_GDST]=0;
|
||||
dc_sysctrl_regs[SB_ISTNRM] |= IST_DMA_GDROM;
|
||||
dc_update_interrupt_status();
|
||||
}
|
||||
|
||||
void dc_cons_state::dreamcast_atapi_init()
|
||||
{
|
||||
xfer_mode = ATAPI_XFER_PIO;
|
||||
|
||||
atapi_regs = auto_alloc_array_clear(machine(), UINT8, ATAPI_REG_MAX);
|
||||
|
||||
atapi_regs[ATAPI_REG_CMDSTATUS] = 0;
|
||||
atapi_regs[ATAPI_REG_ERROR] = 1;
|
||||
atapi_regs[ATAPI_REG_COUNTLOW] = 0x14;
|
||||
atapi_regs[ATAPI_REG_COUNTHIGH] = 0xeb;
|
||||
|
||||
atapi_data_ptr = 0;
|
||||
atapi_data_len = 0;
|
||||
atapi_cdata_wait = 0;
|
||||
|
||||
atapi_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dc_cons_state::atapi_xfer_end),this));
|
||||
atapi_timer->adjust(attotime::never);
|
||||
atapi_cmd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dc_cons_state::atapi_cmd_exec),this));
|
||||
atapi_cmd_timer->adjust(attotime::never);
|
||||
|
||||
gdrom = NULL;
|
||||
|
||||
atapi_data = auto_alloc_array(machine(), UINT8, ATAPI_DATA_SIZE );
|
||||
|
||||
save_pointer(NAME(atapi_regs), ATAPI_REG_MAX );
|
||||
save_pointer(NAME(atapi_data), ATAPI_DATA_SIZE / 2 );
|
||||
save_item(NAME(atapi_data_ptr));
|
||||
save_item(NAME(atapi_data_len));
|
||||
save_item(NAME(atapi_xferlen));
|
||||
save_item(NAME(atapi_xferbase));
|
||||
save_item(NAME(atapi_cdata_wait));
|
||||
save_item(NAME(atapi_xfermod));
|
||||
|
||||
gdrom = machine().device<gdrom_device>( "cdrom" );
|
||||
}
|
||||
|
||||
void dc_cons_state::dreamcast_atapi_reset()
|
||||
{
|
||||
atapi_regs[ATAPI_REG_CMDSTATUS] = 0;
|
||||
atapi_regs[ATAPI_REG_ERROR] = 1;
|
||||
atapi_regs[ATAPI_REG_COUNTLOW] = 0x14;
|
||||
atapi_regs[ATAPI_REG_COUNTHIGH] = 0xeb;
|
||||
|
||||
atapi_data_ptr = 0;
|
||||
atapi_data_len = 0;
|
||||
atapi_cdata_wait = 0;
|
||||
|
||||
atapi_xferlen = 0;
|
||||
atapi_xfermod = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -379,330 +109,6 @@ c000776 - DMA triggered to c008000
|
||||
|
||||
*/
|
||||
|
||||
READ32_MEMBER(dc_cons_state::dc_mess_gdrom_r)
|
||||
{
|
||||
// printf("gdrom_r: @ %x (off %x), mask %llx (PC %x)\n", offset, off, mem_mask, space.device().safe_pc());
|
||||
|
||||
switch(offset)
|
||||
{
|
||||
case 0x18/4:
|
||||
return atapi_regs[ATAPI_REG_CMDSTATUS] | 0x10;
|
||||
case 0x80/4:
|
||||
UINT32 data;
|
||||
if (atapi_data_ptr == 0 && atapi_data_len == 0)
|
||||
{
|
||||
// get the data from the device
|
||||
if( atapi_xferlen > 0 )
|
||||
{
|
||||
gdrom->ReadData( atapi_data, atapi_xferlen );
|
||||
atapi_data_len = atapi_xferlen;
|
||||
}
|
||||
|
||||
if (atapi_xfermod > MAX_TRANSFER_SIZE)
|
||||
{
|
||||
atapi_xferlen = MAX_TRANSFER_SIZE;
|
||||
atapi_xfermod = atapi_xfermod - MAX_TRANSFER_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
atapi_xferlen = atapi_xfermod;
|
||||
atapi_xfermod = 0;
|
||||
}
|
||||
|
||||
// printf( "atapi_r: atapi_xferlen=%d\n", atapi_xferlen );
|
||||
if( atapi_xferlen != 0 )
|
||||
{
|
||||
//atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRQ | ATAPI_STAT_SERVDSC;
|
||||
//atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ATAPI: dropping DRQ\n");
|
||||
//gdrom_set_status(ATAPI_STAT_DRQ,false);
|
||||
//atapi_regs[ATAPI_REG_CMDSTATUS] = 0;
|
||||
//atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO;
|
||||
}
|
||||
|
||||
atapi_regs[ATAPI_REG_COUNTLOW] = atapi_xferlen & 0xff;
|
||||
atapi_regs[ATAPI_REG_COUNTHIGH] = (atapi_xferlen>>8)&0xff;
|
||||
|
||||
gdrom_raise_irq();
|
||||
}
|
||||
|
||||
if( atapi_cdata_wait )
|
||||
{
|
||||
data = atapi_data[atapi_data_ptr++];
|
||||
data |= ( atapi_data[atapi_data_ptr++] << 8 );
|
||||
atapi_cdata_wait-=2;
|
||||
if( atapi_cdata_wait == 0 )
|
||||
{
|
||||
// printf( "atapi_r: read all bytes\n" );
|
||||
atapi_data_ptr = 0;
|
||||
atapi_data_len = 0;
|
||||
|
||||
if( atapi_xferlen == 0 )
|
||||
{
|
||||
printf("Read from SCSI\n");
|
||||
//debugger_break(machine());
|
||||
gdrom_set_status(ATAPI_STAT_DRQ,false);
|
||||
atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO;
|
||||
gdrom_raise_irq();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* GD-Rom transfer via PIO, preliminary */
|
||||
UINT8 pio_tr_size;
|
||||
|
||||
if(atapi_pio_ptr == 0)
|
||||
{
|
||||
gdrom->ReadData( pio_sector_buffer, 2048 );
|
||||
}
|
||||
data = 0;
|
||||
pio_tr_size = 0;
|
||||
|
||||
for(int i=0;i<4;i++)
|
||||
{
|
||||
if(mem_mask & (0xff << i*8))
|
||||
{
|
||||
data|= pio_sector_buffer[atapi_pio_ptr+pio_tr_size]<<i*8;
|
||||
pio_tr_size++;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Read from PIO SCSI queue %08x %08x %08x\n",atapi_xferlen,atapi_pio_ptr,mem_mask);
|
||||
atapi_xferlen -= pio_tr_size;
|
||||
atapi_pio_ptr += pio_tr_size;
|
||||
atapi_pio_ptr &=0x7ff;
|
||||
|
||||
atapi_regs[ATAPI_REG_COUNTLOW] = atapi_xferlen & 0xff;
|
||||
atapi_regs[ATAPI_REG_COUNTHIGH] = (atapi_xferlen>>8)&0xff;
|
||||
if(atapi_pio_ptr == 0)
|
||||
{
|
||||
gdrom_set_status(ATAPI_STAT_DRDY,true);
|
||||
gdrom_set_status(ATAPI_STAT_DRQ,false);
|
||||
gdrom_set_status(ATAPI_STAT_BSY,false);
|
||||
atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO | ATAPI_INTREASON_COMMAND;
|
||||
atapi_regs[ATAPI_REG_SAMTAG] = GDROM_PAUSE_STATE | 0x80;
|
||||
|
||||
// g1bus_regs[SB_GDST]=0;
|
||||
gdrom_raise_irq();
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
case 0x84/4:
|
||||
return atapi_regs[ATAPI_REG_ERROR];
|
||||
case 0x88/4:
|
||||
return atapi_regs[ATAPI_REG_INTREASON];
|
||||
case 0x8c/4:
|
||||
return atapi_regs[ATAPI_REG_SAMTAG];
|
||||
case 0x90/4:
|
||||
return atapi_regs[ATAPI_REG_COUNTLOW];
|
||||
case 0x94/4:
|
||||
return atapi_regs[ATAPI_REG_COUNTHIGH];
|
||||
case 0x98/4:
|
||||
return atapi_regs[ATAPI_REG_DRIVESEL];
|
||||
case 0x9c/4:
|
||||
dc_sysctrl_regs[SB_ISTEXT] &= ~IST_EXT_GDROM;
|
||||
dc_update_interrupt_status();
|
||||
return atapi_regs[ATAPI_REG_CMDSTATUS] | 0x10;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(dc_cons_state::dc_mess_gdrom_w )
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
case 0x18/4:
|
||||
/* Device Control */
|
||||
//COMBINE_DATA(&atapi_regs[ATAPI_REG_CMDSTATUS]);
|
||||
return;
|
||||
/* TODO: move this behind a timer */
|
||||
case 0x80/4:
|
||||
{
|
||||
// printf("atapi_w: data=%04x\n", data );
|
||||
|
||||
// printf("ATAPI: packet write %04x\n", data);
|
||||
atapi_data[atapi_data_ptr++] = data & 0xff;
|
||||
atapi_data[atapi_data_ptr++] = data >> 8;
|
||||
|
||||
//printf("%02x %02x %d\n",data & 0xff, data >> 8,atapi_data_ptr);
|
||||
|
||||
if (atapi_cdata_wait)
|
||||
{
|
||||
// printf("ATAPI: waiting, ptr %d wait %d\n", atapi_data_ptr, atapi_cdata_wait);
|
||||
if (atapi_data_ptr == atapi_cdata_wait)
|
||||
{
|
||||
// send it to the device
|
||||
gdrom->WriteData( atapi_data, atapi_cdata_wait );
|
||||
|
||||
// assert IRQ
|
||||
gdrom_raise_irq();
|
||||
|
||||
// not sure here, but clear DRQ at least?
|
||||
gdrom_set_status(ATAPI_STAT_DRQ,false);
|
||||
printf("cdata wait status\n");
|
||||
atapi_cdata_wait = 0;
|
||||
}
|
||||
}
|
||||
else if ( atapi_data_ptr == 12 )
|
||||
{
|
||||
int phase;
|
||||
|
||||
// printf("atapi_w: command %02x\n", atapi_data[0]&0xff );
|
||||
|
||||
// reset data pointer for reading SCSI results
|
||||
atapi_data_ptr = 0;
|
||||
atapi_data_len = 0;
|
||||
|
||||
// send it to the SCSI device
|
||||
gdrom->SetCommand( atapi_data, 12 );
|
||||
gdrom->ExecCommand( &atapi_xferlen );
|
||||
gdrom->GetPhase( &phase );
|
||||
|
||||
if (atapi_xferlen != -1)
|
||||
{
|
||||
printf("ATAPI: SCSI command %02x returned %d bytes from the device\n", atapi_data[0]&0xff, atapi_xferlen);
|
||||
|
||||
// store the returned command length in the ATAPI regs, splitting into
|
||||
// multiple transfers if necessary
|
||||
atapi_xfermod = 0;
|
||||
if (atapi_xferlen > MAX_TRANSFER_SIZE)
|
||||
{
|
||||
atapi_xfermod = atapi_xferlen - MAX_TRANSFER_SIZE;
|
||||
atapi_xferlen = MAX_TRANSFER_SIZE;
|
||||
}
|
||||
|
||||
atapi_regs[ATAPI_REG_COUNTLOW] = atapi_xferlen & 0xff;
|
||||
atapi_regs[ATAPI_REG_COUNTHIGH] = (atapi_xferlen>>8)&0xff;
|
||||
|
||||
if (atapi_xferlen == 0)
|
||||
{
|
||||
// if no data to return, set the registers properly
|
||||
//atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRDY;
|
||||
gdrom_set_status(ATAPI_STAT_DRDY,true);
|
||||
gdrom_set_status(ATAPI_STAT_DRQ,false);
|
||||
atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO|ATAPI_INTREASON_COMMAND;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ATAPI features %02x\n",atapi_regs[ATAPI_REG_FEATURES]);
|
||||
// indicate data ready: set DRQ and DMA ready, and IO in INTREASON
|
||||
if (atapi_regs[ATAPI_REG_FEATURES] & 0x01) // DMA feature
|
||||
{
|
||||
//gdrom_set_status(ATAPI_STAT_BSY | ATAPI_STAT_DRDY | ATAPI_STAT_SERVDSC,true);
|
||||
//atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_BSY | ATAPI_STAT_DRDY | ATAPI_STAT_SERVDSC;
|
||||
}
|
||||
else
|
||||
{
|
||||
//gdrom_set_status(ATAPI_STAT_SERVDSC,true);
|
||||
/* Ok? */
|
||||
gdrom_set_status(ATAPI_STAT_DRQ,true);
|
||||
//atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRQ | ATAPI_STAT_SERVDSC | ATAPI_STAT_DRQ;
|
||||
}
|
||||
atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO;
|
||||
}
|
||||
|
||||
switch( phase )
|
||||
{
|
||||
case SCSI_PHASE_DATAOUT:
|
||||
case SCSI_PHASE_DATAIN:
|
||||
atapi_cdata_wait = atapi_xferlen;
|
||||
break;
|
||||
}
|
||||
|
||||
// perform special ATAPI processing of certain commands
|
||||
switch (atapi_data[0]&0xff)
|
||||
{
|
||||
case 0x00: // BUS RESET / TEST UNIT READY
|
||||
case 0xbb: // SET CDROM SPEED
|
||||
//atapi_regs[ATAPI_REG_CMDSTATUS] = 0;
|
||||
break;
|
||||
|
||||
case 0x45: // PLAY
|
||||
gdrom_set_status(ATAPI_STAT_BSY,true);
|
||||
atapi_timer->adjust( downcast<cpu_device *>(&space.device())->cycles_to_attotime(ATAPI_CYCLES_PER_SECTOR ) );
|
||||
break;
|
||||
}
|
||||
|
||||
// assert IRQ
|
||||
gdrom_raise_irq();
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ATAPI: SCSI device returned error!\n");
|
||||
|
||||
//atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRQ | ATAPI_STAT_CHECK;
|
||||
//atapi_regs[ATAPI_REG_ERROR] = 0x50; // sense key = ILLEGAL REQUEST
|
||||
atapi_regs[ATAPI_REG_COUNTLOW] = 0;
|
||||
atapi_regs[ATAPI_REG_COUNTHIGH] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
case 0x84/4:
|
||||
COMBINE_DATA(&atapi_regs[ATAPI_REG_FEATURES]);
|
||||
return;
|
||||
case 0x88/4:
|
||||
COMBINE_DATA(&atapi_regs[ATAPI_REG_INTREASON]);
|
||||
return;
|
||||
case 0x8c/4:
|
||||
COMBINE_DATA(&atapi_regs[ATAPI_REG_SAMTAG]);
|
||||
return;
|
||||
case 0x90/4:
|
||||
COMBINE_DATA(&atapi_regs[ATAPI_REG_COUNTLOW]);
|
||||
return;
|
||||
case 0x94/4:
|
||||
COMBINE_DATA(&atapi_regs[ATAPI_REG_COUNTHIGH]);
|
||||
return;
|
||||
case 0x98/4:
|
||||
COMBINE_DATA(&atapi_regs[ATAPI_REG_DRIVESEL]);
|
||||
return;
|
||||
case 0x9c/4:
|
||||
{
|
||||
printf("ATAPI command %x issued! (PC=%x)\n", data, space.device().safe_pc());
|
||||
|
||||
gdrom_set_status(ATAPI_STAT_BSY,true);
|
||||
gdrom_set_status(ATAPI_STAT_DRQ,false);
|
||||
gdrom_set_status(ATAPI_STAT_DRDY,false);
|
||||
cur_atapi_cmd = data;
|
||||
/* TODO: timing of this */
|
||||
atapi_cmd_timer->adjust(m_maincpu->cycles_to_attotime(ATAPI_CYCLES_PER_SECTOR));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// register decode helpers
|
||||
|
||||
// this accepts only 32-bit accesses
|
||||
int dc_cons_state::decode_reg32_64( UINT32 offset, UINT64 mem_mask, UINT64 *shift)
|
||||
{
|
||||
int reg = offset * 2;
|
||||
|
||||
*shift = 0;
|
||||
|
||||
// non 32-bit accesses have not yet been seen here, we need to know when they are
|
||||
if ((mem_mask != U64(0xffffffff00000000)) && (mem_mask != U64(0x00000000ffffffff)))
|
||||
{
|
||||
mame_printf_verbose("%s:Wrong mask!\n", machine().describe_context());
|
||||
// debugger_break(machine);
|
||||
}
|
||||
|
||||
if (mem_mask == U64(0xffffffff00000000))
|
||||
{
|
||||
reg++;
|
||||
*shift = 32;
|
||||
}
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
READ32_MEMBER(dc_cons_state::dc_mess_g1_ctrl_r )
|
||||
{
|
||||
switch(offset)
|
||||
@ -740,14 +146,19 @@ WRITE32_MEMBER(dc_cons_state::dc_mess_g1_ctrl_w )
|
||||
|
||||
atapi_xferbase = g1bus_regs[SB_GDSTAR];
|
||||
atapi_timer->adjust(m_maincpu->cycles_to_attotime((ATAPI_CYCLES_PER_SECTOR * (atapi_xferlen/2048))));
|
||||
atapi_regs[ATAPI_REG_SAMTAG] = GDROM_PAUSE_STATE | 0x80;
|
||||
// atapi_regs[ATAPI_REG_SAMTAG] = GDROM_PAUSE_STATE | 0x80;
|
||||
}
|
||||
break;
|
||||
// The following is required to unlock the GD-ROM. The original Japanese BIOS doesn't need it
|
||||
|
||||
case SB_GDLEN:
|
||||
atapi_xferlen = data;
|
||||
break;
|
||||
|
||||
// The following is required to unlock the GD-ROM. The original Japanese BIOS doesn't need it
|
||||
case GD_UNLOCK:
|
||||
if (data==0 || data==0x001fffff || data==0x42fe)
|
||||
{
|
||||
atapi_regs[ATAPI_REG_SAMTAG] = GDROM_PAUSE_STATE | 0x80;
|
||||
// atapi_regs[ATAPI_REG_SAMTAG] = GDROM_PAUSE_STATE | 0x80;
|
||||
printf("Unlocking GD-ROM! %x\n", data);
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user