Merge pull request #151 from Happy-yappH/master

(MESS)Adding support for the N64DD [Happy]
This commit is contained in:
Miodrag Milanović 2015-03-25 11:12:10 +01:00
commit 09ee79273f
3 changed files with 452 additions and 50 deletions

View File

@ -120,6 +120,8 @@ public:
UINT32 cart_length;
bool dd_present;
bool disk_present;
bool cart_present;
void poll_reset_button(bool button);
@ -186,9 +188,14 @@ private:
UINT32 sp_semaphore;
// Disk Drive (DD) registers and functions
void dd_set_zone_and_track_offset();
void dd_update_bm();
void dd_write_sector();
void dd_read_sector();
void dd_read_C2();
UINT32 dd_buffer[256];
UINT32 dd_sector_data[32]; // ?
UINT32 dd_ram_seq_data[32]; // ?
UINT32 dd_sector_data[64];
UINT32 dd_ram_seq_data[16];
UINT32 dd_data_reg;
UINT32 dd_status_reg;
UINT32 dd_track_reg;
@ -196,7 +203,18 @@ private:
UINT32 dd_sector_err_reg;
UINT32 dd_seq_status_reg;
UINT32 dd_seq_ctrl_reg;
UINT32 dd_sector_reg;
UINT32 dd_reset_reg;
UINT32 dd_current_reg;
bool dd_bm_reset_held;
bool dd_write;
UINT8 dd_int;
UINT8 dd_start_block;
UINT8 dd_start_sector;
UINT8 dd_sectors_per_block;
UINT8 dd_sector_size;
UINT8 dd_zone;
UINT32 dd_track_offset;
// Peripheral Interface (PI) registers and functions
void pi_dma();
@ -275,6 +293,65 @@ extern const device_type N64PERIPH;
#define DP_STATUS_FREEZE 0x02
#define DP_STATUS_FLUSH 0x04
#define DD_ASIC_STATUS_DISK_CHANGE 0x00010000
#define DD_ASIC_STATUS_MECHA_ERR 0x00020000
#define DD_ASIC_STATUS_WRPROTECT_ERR 0x00040000
#define DD_ASIC_STATUS_HEAD_RETRACT 0x00080000
#define DD_ASIC_STATUS_MOTOR_OFF 0x00100000
#define DD_ASIC_STATUS_RESET 0x00400000
#define DD_ASIC_STATUS_BUSY 0x00800000
#define DD_ASIC_STATUS_DISK 0x01000000
#define DD_ASIC_STATUS_MECHA_INT 0x02000000
#define DD_ASIC_STATUS_BM_INT 0x04000000
#define DD_ASIC_STATUS_BM_ERROR 0x08000000
#define DD_ASIC_STATUS_C2_XFER 0x10000000
#define DD_ASIC_STATUS_DREQ 0x40000000
#define DD_TRACK_INDEX_LOCK 0x60000000
#define DD_BM_MECHA_INT_RESET 0x01000000
#define DD_BM_XFERBLOCKS 0x02000000
#define DD_BM_DISABLE_C1 0x04000000
#define DD_BM_DISABLE_OR_CHK 0x08000000
#define DD_BM_RESET 0x10000000
#define DD_BM_INT_MASK 0x20000000
#define DD_BM_MODE 0x40000000
#define DD_BM_START 0x80000000
#define DD_BMST_RUNNING 0x80000000
#define DD_BMST_ERROR 0x04000000
#define DD_BMST_MICRO_STATUS 0x02000000
#define DD_BMST_BLOCKS 0x01000000
#define DD_BMST_C1_CORRECT 0x00800000
#define DD_BMST_C1_DOUBLE 0x00400000
#define DD_BMST_C1_SINGLE 0x00200000
#define DD_BMST_C1_ERROR 0x00010000
#define DD_ASIC_ERR_AM_FAIL 0x80000000
#define DD_ASIC_ERR_MICRO_FAIL 0x40000000
#define DD_ASIC_ERR_SPINDLE_FAIL 0x20000000
#define DD_ASIC_ERR_OVER_RUN 0x10000000
#define DD_ASIC_ERR_OFFTRACK 0x08000000
#define DD_ASIC_ERR_NO_DISK 0x04000000
#define DD_ASIC_ERR_CLOCK_UNLOCK 0x02000000
#define DD_ASIC_ERR_SELF_STOP 0x01000000
#define DD_SEQ_MICRO_INT_MASK 0x80000000
#define DD_SEQ_MICRO_PC_ENABLE 0x40000000
#define SECTORS_PER_BLOCK 85
#define BLOCKS_PER_TRACK 2
const unsigned int ddZoneSecSize[16] = {232,216,208,192,176,160,144,128,
216,208,192,176,160,144,128,112};
const unsigned int ddZoneTrackSize[16] = {158,158,149,149,149,149,149,114,
158,158,149,149,149,149,149,114};
const unsigned int ddStartOffset[16] =
{0x0,0x5F15E0,0xB79D00,0x10801A0,0x1523720,0x1963D80,0x1D414C0,0x20BBCE0,
0x23196E0,0x28A1E00,0x2DF5DC0,0x3299340,0x36D99A0,0x3AB70E0,0x3E31900,0x4149200};
extern UINT32 *n64_sram;
extern UINT32 *rdram;
extern UINT32 *rsp_imem;

View File

@ -23,6 +23,9 @@ n64_periphs::n64_periphs(const machine_config &mconfig, const char *tag, device_
: device_t(mconfig, N64PERIPH, "N64 Periphal Chips", tag, owner, clock, "n64_periphs", __FILE__)
, device_video_interface(mconfig, *this)
, m_nvram_image(NULL)
, dd_present(false)
, disk_present(false)
, cart_present(false)
{
}
@ -171,7 +174,6 @@ void n64_periphs::device_reset()
pi_bsd_dom2_rls = 0;
pi_dma_dir = 0;
dd_int = 0;
memset(dd_buffer, 0, sizeof(dd_buffer));
memset(dd_sector_data, 0, sizeof(dd_sector_data));
memset(dd_ram_seq_data, 0, sizeof(dd_ram_seq_data));
@ -183,6 +185,10 @@ void n64_periphs::device_reset()
dd_seq_status_reg = 0;
dd_seq_ctrl_reg = 0;
dd_int = 0;
dd_bm_reset_held = false;
dd_write = false;
dd_zone = 0;
dd_track_offset = 0;
memset(ri_regs, 0, sizeof(ri_regs));
@ -217,7 +223,6 @@ void n64_periphs::device_reset()
pif_ram[0x25] = 0x00;
pif_ram[0x26] = 0x3f;
pif_ram[0x27] = 0x3f;
dd_present = false;
cic_type=2;
mem_map->write_dword(0x00000318, 0x800000);
@ -227,7 +232,6 @@ void n64_periphs::device_reset()
pif_ram[0x25] = 0x08;
pif_ram[0x26] = 0xdd;
pif_ram[0x27] = 0x3f;
dd_present = true;
cic_type=0xd;
}
else if (boot_checksum == U64(0x000000cffb830843) || boot_checksum == U64(0x000000d0027fdf31))
@ -1374,13 +1378,26 @@ TIMER_CALLBACK_MEMBER(n64_periphs::pi_dma_callback)
void n64_periphs::pi_dma_tick()
{
bool update_bm = false;
UINT16 *cart16;
UINT16 *dram16 = (UINT16*)rdram;
UINT32 cart_addr = (pi_cart_addr & 0x0fffffff) >> 1;
UINT32 dram_addr = (pi_dram_addr & 0x007fffff) >> 1;
if((cart_addr & 0x04000000) == 0x04000000)
if(pi_cart_addr == 0x05000000 && dd_present)
{
update_bm = true;
cart16 = (UINT16*)dd_buffer;
cart_addr = (pi_cart_addr & 0x000003ff) >> 1;
}
else if(pi_cart_addr == 0x05000400 && dd_present)
{
update_bm = true;
cart16 = (UINT16*)dd_sector_data;
cart_addr = (pi_cart_addr & 0x000000ff) >> 1;
}
else if((cart_addr & 0x04000000) == 0x04000000)
{
cart16 = (UINT16*)n64_sram;
cart_addr = (pi_cart_addr & 0x0001ffff) >> 1;
@ -1399,6 +1416,7 @@ void n64_periphs::pi_dma_tick()
if(pi_dma_dir == 1)
{
UINT32 dma_length = pi_wr_len + 1;
//logerror("PI Write, %X, %X, %X\n", pi_cart_addr, pi_dram_addr, pi_wr_len);
if (dma_length & 7)
{
dma_length = (dma_length + 7) & ~7;
@ -1418,6 +1436,7 @@ void n64_periphs::pi_dma_tick()
else
{
UINT32 dma_length = pi_rd_len + 1;
//logerror("PI Read, %X, %X, %X\n", pi_cart_addr, pi_dram_addr, pi_rd_len);
if (dma_length & 7)
{
dma_length = (dma_length + 7) & ~7;
@ -1436,7 +1455,10 @@ void n64_periphs::pi_dma_tick()
}
pi_status &= ~1; // Clear DMA_BUSY
pi_status |= 8; // Set INTERRUPT
//pi_status |= 8; // Set INTERRUPT ?? Does this bit exist ??
if(update_bm)
dd_update_bm();
signal_rcp_interrupt(PI_INTERRUPT);
@ -1513,11 +1535,26 @@ WRITE32_MEMBER( n64_periphs::pi_reg_w )
case 0x04/4: // PI_CART_ADDR_REG
{
pi_cart_addr = data;
if(pi_cart_addr == 0x05000400 && dd_present)
{
dd_status_reg &= ~DD_ASIC_STATUS_DREQ;
dd_status_reg &= ~DD_ASIC_STATUS_BM_INT;
//logerror("Clearing DREQ, INT\n");
machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE);
}
if(pi_cart_addr == 0x05000000 && dd_present)
{
dd_status_reg &= ~DD_ASIC_STATUS_C2_XFER;
dd_status_reg &= ~DD_ASIC_STATUS_BM_INT;
//logerror("Clearing C2, INT\n");
machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE);
}
break;
}
case 0x08/4: // PI_RD_LEN_REG
{
//logerror("Start PI Read\n");
pi_rd_len = data;
pi_dma_dir = 0;
pi_status |= 1;
@ -1530,6 +1567,7 @@ WRITE32_MEMBER( n64_periphs::pi_reg_w )
case 0x0c/4: // PI_WR_LEN_REG
{
//logerror("Start PI Write\n");
pi_wr_len = data;
pi_dma_dir = 1;
pi_status |= 1;
@ -1545,7 +1583,9 @@ WRITE32_MEMBER( n64_periphs::pi_reg_w )
{
if (data & 0x2)
{
pi_status &= ~8; // Clear INTERRUPT
//pi_status &= ~8; // Clear INTERRUPT ?? Does this bit exist ??
pi_status = 0; // Reset all bits
pi_dma_timer->adjust(attotime::never); // Cancel Pending Transfer
clear_rcp_interrupt(PI_INTERRUPT);
}
break;
@ -2049,7 +2089,193 @@ WRITE32_MEMBER( n64_periphs::si_reg_w )
}
}
#define DD_STATUS_INTR (1 << 25)
void n64_periphs::dd_set_zone_and_track_offset()
{
UINT16 head = (dd_track_reg & 0x1000) >> 9; // Head * 8
UINT16 track = dd_track_reg & 0xFFF;
UINT16 tr_off = 0;
if(track >= 0x425)
{
dd_zone = 7 + head;
tr_off = track - 0x425;
}
else if (track >= 0x390)
{
dd_zone = 6 + head;
tr_off = track - 0x390;
}
else if (track >= 0x2FB)
{
dd_zone = 5 + head;
tr_off = track - 0x2FB;
}
else if (track >= 0x266)
{
dd_zone = 4 + head;
tr_off = track - 0x266;
}
else if (track >= 0x1D1)
{
dd_zone = 3 + head;
tr_off = track - 0x1D1;
}
else if (track >= 0x13C)
{
dd_zone = 2 + head;
tr_off = track - 0x13C;
}
else if (track >= 0x9E)
{
dd_zone = 1 + head;
tr_off = track - 0x9E;
}
else
{
dd_zone = 0 + head;
tr_off = track;
}
dd_track_offset = ddStartOffset[dd_zone] + tr_off*ddZoneSecSize[dd_zone]*SECTORS_PER_BLOCK*BLOCKS_PER_TRACK;
//logerror("Zone %d, Head %d, Offset %x\n", dd_zone, head/8, dd_track_offset);
}
void n64_periphs::dd_update_bm()
{
if(!(dd_buf_status_reg & DD_BMST_RUNNING))
return;
if(dd_write) // dd write, BM Mode 0
{
if((dd_current_reg == 0))
{
dd_current_reg += 1;
dd_status_reg |= DD_ASIC_STATUS_DREQ;
}
else if(dd_current_reg < SECTORS_PER_BLOCK)
{
dd_write_sector();
dd_current_reg += 1;
dd_status_reg |= DD_ASIC_STATUS_DREQ;
}
else if(dd_current_reg < SECTORS_PER_BLOCK + 1)
{
if(dd_buf_status_reg & DD_BMST_BLOCKS)
{
dd_write_sector();
dd_current_reg += 1;
//logerror("DD Write, Start Next Block\n");
dd_start_block = 1 - dd_start_block;
dd_current_reg = 1;
dd_buf_status_reg &= ~DD_BMST_BLOCKS;
dd_status_reg |= DD_ASIC_STATUS_DREQ;
}
else
{
dd_write_sector();
dd_current_reg += 1;
dd_buf_status_reg &= ~DD_BMST_RUNNING;
}
}
else
{
logerror("DD Write, Sector Overrun\n");
}
//logerror("DD Write, Sending Interrupt\n");
dd_status_reg |= DD_ASIC_STATUS_BM_INT;
machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE);
return;
}
else // dd read, BM Mode 1
{
if(((dd_track_reg & 0xFFF) == 6) && (dd_start_block == 0))
{
dd_status_reg &= ~DD_ASIC_STATUS_DREQ;
}
else if(dd_current_reg < SECTORS_PER_BLOCK)
{
dd_read_sector();
dd_current_reg += 1;
dd_status_reg |= DD_ASIC_STATUS_DREQ;
}
else if(dd_current_reg < SECTORS_PER_BLOCK + 4)
{
dd_read_C2();
dd_current_reg += 1;
if(dd_current_reg == SECTORS_PER_BLOCK + 4)
dd_status_reg |= DD_ASIC_STATUS_C2_XFER;
}
else if(dd_current_reg == SECTORS_PER_BLOCK + 4) // Gap Sector
{
if(dd_buf_status_reg & DD_BMST_BLOCKS)
{
//logerror("DD Read, Start Next Block\n");
dd_start_block = 1 - dd_start_block;
dd_current_reg = 0;
dd_buf_status_reg &= ~DD_BMST_BLOCKS;
}
else
{
dd_buf_status_reg &= ~DD_BMST_RUNNING;
}
}
else
{
logerror("DD Read, Sector Overrun\n");
}
//logerror("DD Read, Sending Interrupt\n");
dd_status_reg |= DD_ASIC_STATUS_BM_INT;
machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE);
return;
}
}
void n64_periphs::dd_write_sector()
{
UINT8* sector;
sector = (UINT8*)machine().root_device().memregion("disk")->base();
sector += dd_track_offset;
sector += dd_start_block * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone];
sector += (dd_current_reg - 1) * ddZoneSecSize[dd_zone];
//logerror("Write Block %d, Sector %d\n", dd_start_block, dd_current_reg - 1);
for(int i = 0; i < ddZoneSecSize[dd_zone]/4; i++)
{
sector[i*4 + 0] = (dd_sector_data[i] >> 24) & 0xFF;
sector[i*4 + 1] = (dd_sector_data[i] >> 16) & 0xFF;
sector[i*4 + 2] = (dd_sector_data[i] >> 8) & 0xFF;
sector[i*4 + 3] = (dd_sector_data[i] >> 0) & 0xFF;
}
return;
}
void n64_periphs::dd_read_sector()
{
UINT8* sector;
sector = (UINT8*)machine().root_device().memregion("disk")->base();
sector += dd_track_offset;
sector += dd_start_block * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone];
sector += (dd_current_reg) * ddZoneSecSize[dd_zone];
//logerror("Read Block %d, Sector %d\n", dd_start_block, dd_current_reg);
for(int i = 0; i < ddZoneSecSize[dd_zone]/4; i++)
{
dd_sector_data[i] = sector[(i*4 + 0)] << 24 | sector[(i*4 + 1)] << 16 |
sector[(i*4 + 2)] << 8 | sector[(i*4 + 3)];
}
return;
}
void n64_periphs::dd_read_C2()
{
for(int i = 0; i < ddZoneSecSize[dd_zone]/4; i++)
dd_buffer[(dd_current_reg - SECTORS_PER_BLOCK)*0x40 + i] = 0;
//logerror("Read C2, Sector %d", dd_current_reg);
return;
}
READ32_MEMBER( n64_periphs::dd_reg_r )
{
@ -2058,14 +2284,14 @@ READ32_MEMBER( n64_periphs::dd_reg_r )
return dd_buffer[offset];
}
if(offset < 0x480/4)
{
return dd_sector_data[(offset - 0x400/4) / 4];
}
if(offset < 0x500/4)
{
return dd_ram_seq_data[(offset - 0x480/4) / 4];
return dd_sector_data[(offset - 0x400/4)];
}
if((offset < 0x5C0/4) && (0x580/4 <= offset))
{
return dd_ram_seq_data[(offset - 0x580/4)];
}
offset -= 0x500/4;
@ -2081,7 +2307,19 @@ READ32_MEMBER( n64_periphs::dd_reg_r )
break;
case 0x08/4: // DD Status
if(disk_present)
dd_status_reg |= DD_ASIC_STATUS_DISK;
else
dd_status_reg &= ~DD_ASIC_STATUS_DISK;
ret = dd_status_reg;
// For Read, Gap Sector
if((dd_status_reg & DD_ASIC_STATUS_BM_INT) && (SECTORS_PER_BLOCK < dd_current_reg))
{
dd_status_reg &= ~DD_ASIC_STATUS_BM_INT;
//logerror("DD Read Gap, Clearing INT\n");
machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE);
dd_update_bm();
}
break;
case 0x0c/4: // Current Track
@ -2103,6 +2341,9 @@ READ32_MEMBER( n64_periphs::dd_reg_r )
case 0x1c/4: // Sequence Control
ret = dd_seq_ctrl_reg;
break;
case 0x40/4: // ASIC ID
ret = 0x00030000; // Japan Retail Drive
break;
}
//logerror("dd_reg_r: %08x (%08x)\n", offset << 2, ret);
@ -2119,15 +2360,15 @@ WRITE32_MEMBER( n64_periphs::dd_reg_w )
return;
}
if(offset < 0x480/4)
if(offset < 0x500/4)
{
COMBINE_DATA(&dd_sector_data[(offset - 0x400/4) / 4]);
COMBINE_DATA(&dd_sector_data[(offset - 0x400/4)]);
return;
}
if(offset < 0x500/4)
if((offset < 0x5C0/4) && (0x580/4 <= offset))
{
COMBINE_DATA(&dd_ram_seq_data[(offset - 0x480/4) / 4]);
COMBINE_DATA(&dd_ram_seq_data[(offset - 0x580/4)]);
return;
}
@ -2143,10 +2384,18 @@ WRITE32_MEMBER( n64_periphs::dd_reg_w )
switch((data >> 16) & 0xff)
{
case 0x01: // Seek Read
logerror("dd command: Seek Read\n");
dd_track_reg = dd_data_reg >> 16;
logerror("dd command: Seek Read %d\n", dd_track_reg);
dd_set_zone_and_track_offset();
dd_track_reg |= DD_TRACK_INDEX_LOCK;
dd_write = false;
break;
case 0x02: // Seek Write
logerror("dd command: Seek Write\n");
dd_track_reg = dd_data_reg >> 16;
logerror("dd command: Seek Write %d\n", dd_track_reg);
dd_set_zone_and_track_offset();
dd_track_reg |= DD_TRACK_INDEX_LOCK;
dd_write = true;
break;
case 0x03: // Re-Zero / Recalibrate
logerror("dd command: Re-Zero\n");
@ -2157,29 +2406,29 @@ WRITE32_MEMBER( n64_periphs::dd_reg_w )
case 0x05: // Start Motor
logerror("dd command: Start Motor\n");
break;
case 0x06: // Standby
logerror("dd command: Standby\n");
case 0x06: // Set Standby Time
logerror("dd command: Set Standby Time\n");
break;
case 0x07: // Set Sleep Mode
logerror("dd command: Set Sleep Mode\n");
case 0x07: // Set Sleep Time
logerror("dd command: Set Sleep Time\n");
break;
case 0x08: // Unknown
logerror("dd command: Unknown\n");
case 0x08: // Clear Disk Change Flag
logerror("dd command: Clear Disk Change Flag\n");
break;
case 0x09: // Initialize Drive(?)
logerror("dd command: Initialize Drive\n");
case 0x09: // Clear Reset Flag
logerror("dd command: Clear Reset Flag\n");
break;
case 0x0B: // Select Disk Type
logerror("dd command: Select Disk Type\n");
break;
case 0x0C: // ASIC Command Inquiry
logerror("dd command: ASIC Commadn Inquiry\n");
logerror("dd command: ASIC Command Inquiry\n");
break;
case 0x0D: // Standby Mode (?)
logerror("dd command: Standby Mode(?)\n");
break;
case 0x0E: // Detect Disk Index
logerror("dd command: Detect Disk Index\n");
case 0x0E: // (Track Seek) Index Lock Retry
logerror("dd command: Index Lock Retry\n");
break;
case 0x0F: // Set RTC Year / Month
logerror("dd command: Set RTC Year / Month\n");
@ -2198,9 +2447,6 @@ WRITE32_MEMBER( n64_periphs::dd_reg_w )
machine().base_datetime(systime);
dd_data_reg = (convert_to_bcd(systime.local_time.year % 100) << 24) | (convert_to_bcd(systime.local_time.month + 1) << 16);
machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE);
dd_status_reg |= DD_STATUS_INTR;
break;
}
@ -2212,9 +2458,6 @@ WRITE32_MEMBER( n64_periphs::dd_reg_w )
machine().base_datetime(systime);
dd_data_reg = (convert_to_bcd(systime.local_time.mday) << 24) | (convert_to_bcd(systime.local_time.hour) << 16);
machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE);
dd_status_reg |= DD_STATUS_INTR;
break;
}
@ -2226,28 +2469,90 @@ WRITE32_MEMBER( n64_periphs::dd_reg_w )
machine().base_datetime(systime);
dd_data_reg = (convert_to_bcd(systime.local_time.minute) << 24) | (convert_to_bcd(systime.local_time.second) << 16);
machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE);
dd_status_reg |= DD_STATUS_INTR;
break;
}
case 0x15: // Set LED On/Off Time
{
logerror("dd command: Set LED On/Off Time\n");
break;
}
case 0x1B: // Disk Inquiry
{
logerror("dd command: Disk Inquiry\n");
dd_data_reg = 0x00000000;
break;
}
// Do something here
}
//logerror("Sending MECHA Int\n");
dd_status_reg |= DD_ASIC_STATUS_MECHA_INT;
machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE);
break;
case 0x10/4: // Interrupt Clear
logerror("dd interrupt clear\n");
case 0x10/4: // BM Status
logerror("dd BM Status write\n");
dd_start_sector = (data >> 16) & 0xFF;
if(dd_start_sector == 0x00)
{
dd_start_block = 0;
dd_current_reg = 0;
}
else if (dd_start_sector == 0x5A)
{
dd_start_block = 1;
dd_current_reg = 0;
}
else
{
logerror("dd: start sector not aligned\n");
}
if(data & DD_BM_XFERBLOCKS)
dd_buf_status_reg |= DD_BMST_BLOCKS;
if(data & DD_BM_MECHA_INT_RESET)
dd_status_reg &= ~DD_ASIC_STATUS_MECHA_INT;
if(data & DD_BM_RESET)
dd_bm_reset_held = true;
if(!(data & DD_BM_RESET) && dd_bm_reset_held)
{
dd_bm_reset_held = false;
dd_status_reg &= ~DD_ASIC_STATUS_BM_INT;
dd_status_reg &= ~DD_ASIC_STATUS_BM_ERROR;
dd_status_reg &= ~DD_ASIC_STATUS_DREQ;
dd_status_reg &= ~DD_ASIC_STATUS_C2_XFER;
dd_buf_status_reg = 0;
dd_current_reg = 0;
dd_start_block = 0;
logerror("dd: BM RESET\n");
}
if(!(dd_status_reg & DD_ASIC_STATUS_BM_INT) && !(dd_status_reg & DD_ASIC_STATUS_MECHA_INT))
{
//logerror("DD Status, Clearing INT\n");
machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE);
dd_status_reg &= ~DD_STATUS_INTR;
}
if(data & DD_BM_START)
{
if(dd_write && (data & DD_BM_MODE))
popmessage("Attempt to write disk with BM Mode 1\n");
if(!dd_write && !(data & DD_BM_MODE))
popmessage("Attempt to read disk with BM Mode 0\n");
dd_buf_status_reg |= DD_BMST_RUNNING;
logerror("dd: Start BM\n");
dd_update_bm();
}
break;
case 0x1c/4: // Sequence Control
dd_seq_ctrl_reg = data;
break;
case 0x28/4: // Host Sector Byte
dd_sector_size = (data >> 16) & 0xFF;
if((dd_sector_size + 1) != ddZoneSecSize[dd_zone])
popmessage("Sector size %d set different than expected %d\n", dd_sector_size + 1, ddZoneSecSize[dd_zone]);
break;
case 0x30/4: // Sector Byte
dd_sectors_per_block = (data >> 24) & 0xFF;
if(dd_sectors_per_block != SECTORS_PER_BLOCK + 4)
popmessage("Sectors per block %d set different than expected %d\n", dd_sectors_per_block, SECTORS_PER_BLOCK + 4);
}
}

View File

@ -16,6 +16,7 @@
#include "includes/n64.h"
#include "bus/generic/slot.h"
#include "bus/generic/carts.h"
#include "imagedev/snapquik.h"
class n64_mess_state : public n64_state
{
@ -29,6 +30,8 @@ public:
INTERRUPT_GEN_MEMBER(n64_reset_poll);
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(n64_cart);
void mempak_format(UINT8* pak);
int quickload(device_image_interface &image, const char *file_type, int quickload_size);
DECLARE_QUICKLOAD_LOAD_MEMBER( n64dd );
};
READ32_MEMBER(n64_mess_state::dd_null_r)
@ -254,7 +257,7 @@ DEVICE_IMAGE_LOAD_MEMBER(n64_mess_state,n64_cart)
MACHINE_START_MEMBER(n64_mess_state,n64dd)
{
machine_start();
machine().device<n64_periphs>("rcp")->dd_present = true;
UINT8 *ipl = memregion("ddipl")->base();
for (int i = 0; i < 0x400000; i += 4)
@ -270,6 +273,20 @@ MACHINE_START_MEMBER(n64_mess_state,n64dd)
}
}
QUICKLOAD_LOAD_MEMBER(n64_mess_state,n64dd)
{
return quickload(image, file_type, quickload_size);
}
int n64_mess_state::quickload(device_image_interface &image, const char *file_type, int quickload_size)
{
image.fseek(0, SEEK_SET);
image.fread(memregion("disk")->base(), quickload_size);
machine().device<n64_periphs>("rcp")->disk_present = true;
return IMAGE_INIT_PASS;
}
INTERRUPT_GEN_MEMBER(n64_mess_state::n64_reset_poll)
{
n64_periphs *periphs = machine().device<n64_periphs>("rcp");
@ -336,6 +353,7 @@ static MACHINE_CONFIG_DERIVED( n64dd, n64 )
MCFG_GENERIC_EXTENSIONS("v64,z64,rom,n64,bin")
MCFG_GENERIC_LOAD(n64_mess_state, n64_cart)
MCFG_QUICKLOAD_ADD("quickload", n64_mess_state, n64dd, "bin,dsk", 0)
MACHINE_CONFIG_END
ROM_START( n64 )
@ -364,6 +382,8 @@ ROM_START( n64dd )
ROM_REGION32_BE( 0x400000, "ddipl", ROMREGION_ERASEFF)
ROM_LOAD( "64ddipl.bin", 0x000000, 0x400000, CRC(7f933ce2) SHA1(bf861922dcb78c316360e3e742f4f70ff63c9bc3) )
ROM_REGION32_LE( 0x4400000, "disk", ROMREGION_ERASEFF)
ROM_REGION16_BE( 0x80, "normpoint", 0 )
ROM_LOAD( "normpnt.rom", 0x00, 0x80, CRC(e7f2a005) SHA1(c27b4a364a24daeee6e99fd286753fd6216362b4) )