mirror of https://github.com/PCSX2/pcsx2.git
DEV9: Improved SPEED emulation, also hookup ATA emulation
This commit is contained in:
parent
afc9412191
commit
31a3ee3cbc
|
@ -157,6 +157,7 @@ s32 DEV9init()
|
|||
DEV9_LOG("DEV9init\n");
|
||||
|
||||
memset(&dev9, 0, sizeof(dev9));
|
||||
dev9.ata = new ATA();
|
||||
DEV9_LOG("DEV9init2\n");
|
||||
|
||||
DEV9_LOG("DEV9init3\n");
|
||||
|
@ -235,7 +236,7 @@ s32 DEV9init()
|
|||
void DEV9shutdown()
|
||||
{
|
||||
DEV9_LOG("DEV9shutdown\n");
|
||||
|
||||
delete dev9.ata;
|
||||
if (logFile)
|
||||
DEV9Log.Close();
|
||||
}
|
||||
|
@ -259,6 +260,9 @@ s32 DEV9open(void* pDsp)
|
|||
ghc::filesystem::path hddPath(config.Hdd);
|
||||
#endif
|
||||
|
||||
if (hddPath.empty())
|
||||
config.hddEnable = false;
|
||||
|
||||
if (hddPath.is_relative())
|
||||
{
|
||||
//GHC uses UTF8 on all platforms
|
||||
|
@ -266,33 +270,35 @@ s32 DEV9open(void* pDsp)
|
|||
hddPath = path / hddPath;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ATA
|
||||
ata_init();
|
||||
#endif
|
||||
if (config.hddEnable)
|
||||
{
|
||||
if (dev9.ata->Open(hddPath) != 0)
|
||||
config.hddEnable = false;
|
||||
}
|
||||
|
||||
return _DEV9open();
|
||||
}
|
||||
|
||||
void DEV9close()
|
||||
{
|
||||
DEV9_LOG("DEV9close\n");
|
||||
#ifdef ENABLE_ATA
|
||||
ata_term();
|
||||
#endif
|
||||
|
||||
dev9.ata->Close();
|
||||
_DEV9close();
|
||||
}
|
||||
|
||||
int DEV9irqHandler(void)
|
||||
{
|
||||
//dev9Ru16(SPD_R_INTR_STAT)|= dev9.irqcause;
|
||||
DEV9_LOG("_DEV9irqHandler %x, %x\n", dev9.irqcause, dev9Ru16(SPD_R_INTR_MASK));
|
||||
if (dev9.irqcause & dev9Ru16(SPD_R_INTR_MASK))
|
||||
DEV9_LOG("_DEV9irqHandler %x, %x\n", dev9.irqcause, dev9.irqmask);
|
||||
if (dev9.irqcause & dev9.irqmask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _DEV9irq(int cause, int cycles)
|
||||
{
|
||||
DEV9_LOG("_DEV9irq %x, %x\n", cause, dev9Ru16(SPD_R_INTR_MASK));
|
||||
DEV9_LOG("_DEV9irq %x, %x\n", cause, dev9.irqmask);
|
||||
|
||||
dev9.irqcause |= cause;
|
||||
|
||||
|
@ -302,6 +308,66 @@ void _DEV9irq(int cause, int cycles)
|
|||
dev9Irq(cycles);
|
||||
}
|
||||
|
||||
//Fakes SPEED FIFO
|
||||
void HDDWriteFIFO()
|
||||
{
|
||||
if (dev9.ata->dmaReady && (dev9.if_ctrl & SPD_IF_ATA_DMAEN))
|
||||
{
|
||||
const int unread = (dev9.fifo_bytes_write - dev9.fifo_bytes_read);
|
||||
const int spaceSectors = (SPD_DBUF_AVAIL_MAX * 512 - unread) / 512;
|
||||
if (spaceSectors < 0)
|
||||
{
|
||||
DEV9_LOG_ERROR("No Space on SPEED FIFO");
|
||||
pxAssert(false);
|
||||
abort();
|
||||
}
|
||||
|
||||
const int readSectors = dev9.ata->nsectorLeft < spaceSectors ? dev9.ata->nsectorLeft : spaceSectors;
|
||||
dev9.fifo_bytes_write += readSectors * 512;
|
||||
dev9.ata->nsectorLeft -= readSectors;
|
||||
}
|
||||
//FIFOIntr();
|
||||
}
|
||||
void HDDReadFIFO()
|
||||
{
|
||||
if (dev9.ata->dmaReady && (dev9.if_ctrl & SPD_IF_ATA_DMAEN))
|
||||
{
|
||||
const int writeSectors = (dev9.fifo_bytes_write - dev9.fifo_bytes_read) / 512;
|
||||
dev9.fifo_bytes_read += writeSectors * 512;
|
||||
dev9.ata->nsectorLeft -= writeSectors;
|
||||
}
|
||||
//FIFOIntr();
|
||||
}
|
||||
void IOPReadFIFO(int bytes)
|
||||
{
|
||||
dev9.fifo_bytes_read += bytes;
|
||||
if (dev9.fifo_bytes_read > dev9.fifo_bytes_write)
|
||||
DEV9_LOG_ERROR("UNDERFLOW BY IOP\n");
|
||||
//FIFOIntr();
|
||||
}
|
||||
void IOPWriteFIFO(int bytes)
|
||||
{
|
||||
dev9.fifo_bytes_write += bytes;
|
||||
if (dev9.fifo_bytes_write - SPD_DBUF_AVAIL_MAX * 512 > dev9.fifo_bytes_read)
|
||||
DEV9_LOG_ERROR("OVERFLOW BY IOP\n");
|
||||
//FIFOIntr();
|
||||
}
|
||||
void FIFOIntr()
|
||||
{
|
||||
//FIFO Buffer Full/Empty
|
||||
const int unread = (dev9.fifo_bytes_write - dev9.fifo_bytes_read);
|
||||
|
||||
if (unread == 0)
|
||||
{
|
||||
if ((dev9.irqcause & SPD_INTR_ATA_FIFO_EMPTY) == 0)
|
||||
_DEV9irq(SPD_INTR_ATA_FIFO_EMPTY, 1);
|
||||
}
|
||||
if (unread == SPD_DBUF_AVAIL_MAX * 512)
|
||||
{
|
||||
//Log_Error("FIFO Full");
|
||||
//INTR Full?
|
||||
}
|
||||
}
|
||||
|
||||
u8 DEV9read8(u32 addr)
|
||||
{
|
||||
|
@ -311,17 +377,18 @@ u8 DEV9read8(u32 addr)
|
|||
u8 hard;
|
||||
if (addr >= ATA_DEV9_HDD_BASE && addr < ATA_DEV9_HDD_END)
|
||||
{
|
||||
#ifdef ENABLE_ATA
|
||||
return ata_read<1>(addr);
|
||||
#else
|
||||
DEV9_LOG_ERROR("ATA does not support 8bit reads %lx\n", addr);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
if (addr >= SMAP_REGBASE && addr < FLASH_REGBASE)
|
||||
{
|
||||
//smap
|
||||
return smap_read8(addr);
|
||||
}
|
||||
if ((addr >= FLASH_REGBASE) && (addr < (FLASH_REGBASE + FLASH_REGSIZE)))
|
||||
{
|
||||
return (u8)FLASHread32(addr, 1);
|
||||
}
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
|
@ -353,25 +420,19 @@ u8 DEV9read8(u32 addr)
|
|||
}
|
||||
else
|
||||
hard = 0;
|
||||
DEV9_LOG_VERB("SPD_R_PIO_DATA 8bit read %x\n", hard);
|
||||
return hard;
|
||||
|
||||
case DEV9_R_REV:
|
||||
hard = 0x32; // expansion bay
|
||||
break;
|
||||
DEV9_LOG_VERB("DEV9_R_REV 8bit read %x\n", hard);
|
||||
return hard;
|
||||
|
||||
default:
|
||||
if ((addr >= FLASH_REGBASE) && (addr < (FLASH_REGBASE + FLASH_REGSIZE)))
|
||||
{
|
||||
return (u8)FLASHread32(addr, 1);
|
||||
}
|
||||
|
||||
hard = dev9Ru8(addr);
|
||||
DEV9_LOG("*Unknown 8bit read at address %lx value %x\n", addr, hard);
|
||||
DEV9_LOG_ERROR("*Unknown 8bit read at address %lx value %x\n", addr, hard);
|
||||
return hard;
|
||||
}
|
||||
|
||||
DEV9_LOG("*Known 8bit read at address %lx value %x\n", addr, hard);
|
||||
return hard;
|
||||
}
|
||||
|
||||
u16 DEV9read16(u32 addr)
|
||||
|
@ -382,23 +443,28 @@ u16 DEV9read16(u32 addr)
|
|||
u16 hard;
|
||||
if (addr >= ATA_DEV9_HDD_BASE && addr < ATA_DEV9_HDD_END)
|
||||
{
|
||||
#ifdef ENABLE_ATA
|
||||
return ata_read<2>(addr);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
return dev9.ata->Read16(addr);
|
||||
}
|
||||
if (addr >= SMAP_REGBASE && addr < FLASH_REGBASE)
|
||||
{
|
||||
//smap
|
||||
return smap_read16(addr);
|
||||
}
|
||||
if ((addr >= FLASH_REGBASE) && (addr < (FLASH_REGBASE + FLASH_REGSIZE)))
|
||||
{
|
||||
return (u16)FLASHread32(addr, 2);
|
||||
}
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case SPD_R_INTR_STAT:
|
||||
DEV9_LOG_VERB("SPD_R_INTR_STAT 16bit read %x\n", dev9.irqcause);
|
||||
return dev9.irqcause;
|
||||
|
||||
case SPD_R_INTR_MASK:
|
||||
DEV9_LOG("SPD_R_INTR_MASK 16bit read %x\n", dev9.irqmask);
|
||||
return dev9.irqmask;
|
||||
|
||||
case SPD_R_PIO_DATA:
|
||||
|
||||
/*if(dev9.eeprom_dir!=1)
|
||||
|
@ -427,48 +493,86 @@ u16 DEV9read16(u32 addr)
|
|||
}
|
||||
else
|
||||
hard = 0;
|
||||
DEV9_LOG_VERB("SPD_R_PIO_DATA 16bit read %x\n", hard);
|
||||
return hard;
|
||||
|
||||
case DEV9_R_REV:
|
||||
hard = 0x0030; // expansion bay
|
||||
break;
|
||||
//hard = 0x0030; // expansion bay
|
||||
DEV9_LOG_VERB("DEV9_R_REV 16bit read %x\n", dev9.irqmask);
|
||||
hard = 0x0032;
|
||||
return hard;
|
||||
|
||||
case SPD_R_REV_1:
|
||||
DEV9_LOG_VERB("SPD_R_REV_1 16bit read %x\n", 0);
|
||||
return 0;
|
||||
|
||||
case SPD_R_REV_2:
|
||||
hard = 0x0011;
|
||||
DEV9_LOG("STD_R_REV_1 16bit read %x\n", hard);
|
||||
DEV9_LOG_VERB("STD_R_REV_1 16bit read %x\n", hard);
|
||||
return hard;
|
||||
|
||||
case SPD_R_REV_3:
|
||||
// bit 0: smap
|
||||
// bit 1: hdd
|
||||
// bit 5: flash
|
||||
hard = 0;
|
||||
/*if (config.hddEnable) {
|
||||
hard|= 0x2;
|
||||
}*/
|
||||
if (config.hddEnable)
|
||||
hard |= SPD_CAPS_ATA;
|
||||
if (config.ethEnable)
|
||||
{
|
||||
hard |= 0x1;
|
||||
}
|
||||
hard |= 0x20; //flash
|
||||
break;
|
||||
hard |= SPD_CAPS_SMAP;
|
||||
hard |= SPD_CAPS_FLASH;
|
||||
DEV9_LOG_VERB("SPD_R_REV_3 16bit read %x\n", hard);
|
||||
return hard;
|
||||
|
||||
case SPD_R_0e:
|
||||
hard = 0x0002;
|
||||
break;
|
||||
default:
|
||||
if ((addr >= FLASH_REGBASE) && (addr < (FLASH_REGBASE + FLASH_REGSIZE)))
|
||||
hard = 0x0002; //Have HDD inserted
|
||||
DEV9_LOG_VERB("SPD_R_0e 16bit read %x\n", hard);
|
||||
return hard;
|
||||
case SPD_R_XFR_CTRL:
|
||||
DEV9_LOG_VERB("SPD_R_XFR_CTRL 16bit read %x\n", dev9.xfr_ctrl);
|
||||
return dev9.xfr_ctrl;
|
||||
case SPD_R_DBUF_STAT:
|
||||
{
|
||||
return (u16)FLASHread32(addr, 2);
|
||||
hard = 0;
|
||||
if (dev9.if_ctrl & SPD_IF_READ) //Semi async
|
||||
{
|
||||
HDDWriteFIFO(); //Yes this is not a typo
|
||||
}
|
||||
else
|
||||
{
|
||||
HDDReadFIFO();
|
||||
}
|
||||
FIFOIntr();
|
||||
|
||||
const u8 count = (u8)((dev9.fifo_bytes_write - dev9.fifo_bytes_read) / 512);
|
||||
if (dev9.xfr_ctrl & SPD_XFR_WRITE) //or ifRead?
|
||||
{
|
||||
hard = (u8)(SPD_DBUF_AVAIL_MAX - count);
|
||||
hard |= (count == 0) ? SPD_DBUF_STAT_1 : (u16)0;
|
||||
hard |= (count > 0) ? SPD_DBUF_STAT_2 : (u16)0;
|
||||
}
|
||||
else
|
||||
{
|
||||
hard = count;
|
||||
hard |= (count < SPD_DBUF_AVAIL_MAX) ? SPD_DBUF_STAT_1 : (u16)0;
|
||||
hard |= (count == 0) ? SPD_DBUF_STAT_2 : (u16)0;
|
||||
//If overflow (HDD->SPEED), set both SPD_DBUF_STAT_2 & SPD_DBUF_STAT_FULL
|
||||
//and overflow INTR set
|
||||
}
|
||||
|
||||
if (count == SPD_DBUF_AVAIL_MAX)
|
||||
{
|
||||
hard |= SPD_DBUF_STAT_FULL;
|
||||
}
|
||||
|
||||
DEV9_LOG_VERB("SPD_R_DBUF_STAT 16bit read %x\n", hard);
|
||||
return hard;
|
||||
}
|
||||
case SPD_R_IF_CTRL:
|
||||
DEV9_LOG_VERB("SPD_R_IF_CTRL 16bit read %x\n", dev9.if_ctrl);
|
||||
return dev9.if_ctrl;
|
||||
default:
|
||||
hard = dev9Ru16(addr);
|
||||
DEV9_LOG("*Unknown 16bit read at address %lx value %x\n", addr, hard);
|
||||
DEV9_LOG_ERROR("*Unknown 16bit read at address %lx value %x\n", addr, hard);
|
||||
return hard;
|
||||
}
|
||||
|
||||
DEV9_LOG("*Known 16bit read at address %lx value %x\n", addr, hard);
|
||||
return hard;
|
||||
}
|
||||
|
||||
u32 DEV9read32(u32 addr)
|
||||
|
@ -479,32 +583,22 @@ u32 DEV9read32(u32 addr)
|
|||
u32 hard;
|
||||
if (addr >= ATA_DEV9_HDD_BASE && addr < ATA_DEV9_HDD_END)
|
||||
{
|
||||
#ifdef ENABLE_ATA
|
||||
return ata_read<4>(addr);
|
||||
#else
|
||||
DEV9_LOG_ERROR("ATA does not support 32bit reads %lx\n", addr);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
if (addr >= SMAP_REGBASE && addr < FLASH_REGBASE)
|
||||
{
|
||||
//smap
|
||||
return smap_read32(addr);
|
||||
}
|
||||
// switch (addr) {
|
||||
|
||||
// default:
|
||||
if ((addr >= FLASH_REGBASE) && (addr < (FLASH_REGBASE + FLASH_REGSIZE)))
|
||||
{
|
||||
return (u32)FLASHread32(addr, 4);
|
||||
}
|
||||
|
||||
hard = dev9Ru32(addr);
|
||||
DEV9_LOG("*Unknown 32bit read at address %lx value %x\n", addr, hard);
|
||||
DEV9_LOG_ERROR("*Unknown 32bit read at address %lx value %x\n", addr, hard);
|
||||
return hard;
|
||||
// }
|
||||
|
||||
// DEV9_LOG("*Known 32bit read at address %lx: %lx\n", addr, hard);
|
||||
// return hard;
|
||||
}
|
||||
|
||||
void DEV9write8(u32 addr, u8 value)
|
||||
|
@ -525,21 +619,28 @@ void DEV9write8(u32 addr, u8 value)
|
|||
smap_write8(addr, value);
|
||||
return;
|
||||
}
|
||||
if ((addr >= FLASH_REGBASE) && (addr < (FLASH_REGBASE + FLASH_REGSIZE)))
|
||||
{
|
||||
FLASHwrite32(addr, (u32)value, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x10000020:
|
||||
DEV9_LOG_ERROR("SPD_R_INTR_CAUSE, WTFH ?\n");
|
||||
dev9.irqcause = 0xff;
|
||||
break;
|
||||
case SPD_R_INTR_STAT:
|
||||
emu_printf("SPD_R_INTR_STAT , WTFH ?\n");
|
||||
DEV9_LOG_ERROR("SPD_R_INTR_STAT, WTFH ?\n");
|
||||
dev9.irqcause = value;
|
||||
return;
|
||||
case SPD_R_INTR_MASK:
|
||||
emu_printf("SPD_R_INTR_MASK8 , WTFH ?\n");
|
||||
DEV9_LOG_ERROR("SPD_R_INTR_MASK8, WTFH ?\n");
|
||||
break;
|
||||
|
||||
case SPD_R_PIO_DIR:
|
||||
//DEV9_LOG("SPD_R_PIO_DIR 8bit write %x\n", value);
|
||||
DEV9_LOG_VERB("SPD_R_PIO_DIR 8bit write %x\n", value);
|
||||
|
||||
if ((value & 0xc0) != 0xc0)
|
||||
return;
|
||||
|
@ -553,7 +654,7 @@ void DEV9write8(u32 addr, u8 value)
|
|||
return;
|
||||
|
||||
case SPD_R_PIO_DATA:
|
||||
//DEV9_LOG("SPD_R_PIO_DATA 8bit write %x\n", value);
|
||||
DEV9_LOG_VERB("SPD_R_PIO_DATA 8bit write %x\n", value);
|
||||
|
||||
if ((value & 0xc0) != 0xc0)
|
||||
return;
|
||||
|
@ -600,23 +701,16 @@ void DEV9write8(u32 addr, u8 value)
|
|||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
default:
|
||||
if ((addr >= FLASH_REGBASE) && (addr < (FLASH_REGBASE + FLASH_REGSIZE)))
|
||||
{
|
||||
FLASHwrite32(addr, (u32)value, 1);
|
||||
DEV9_LOG_ERROR("Unkown EEPROM COMMAND\n");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
default:
|
||||
dev9Ru8(addr) = value;
|
||||
DEV9_LOG_ERROR("*Unknown 8bit write at address %lx value %x\n", addr, value);
|
||||
return;
|
||||
}
|
||||
|
||||
dev9Ru8(addr) = value;
|
||||
DEV9_LOG("*Unknown 8bit write at address %lx value %x\n", addr, value);
|
||||
return;
|
||||
}
|
||||
dev9Ru8(addr) = value;
|
||||
DEV9_LOG("*Known 8bit write at address %lx value %x\n", addr, value);
|
||||
}
|
||||
|
||||
void DEV9write16(u32 addr, u16 value)
|
||||
|
@ -626,9 +720,7 @@ void DEV9write16(u32 addr, u16 value)
|
|||
|
||||
if (addr >= ATA_DEV9_HDD_BASE && addr < ATA_DEV9_HDD_END)
|
||||
{
|
||||
#ifdef ENABLE_ATA
|
||||
ata_write<2>(addr, value);
|
||||
#endif
|
||||
dev9.ata->Write16(addr, value);
|
||||
return;
|
||||
}
|
||||
if (addr >= SMAP_REGBASE && addr < FLASH_REGBASE)
|
||||
|
@ -637,18 +729,26 @@ void DEV9write16(u32 addr, u16 value)
|
|||
smap_write16(addr, value);
|
||||
return;
|
||||
}
|
||||
if ((addr >= FLASH_REGBASE) && (addr < (FLASH_REGBASE + FLASH_REGSIZE)))
|
||||
{
|
||||
FLASHwrite32(addr, (u32)value, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case SPD_R_INTR_MASK:
|
||||
if ((dev9Ru16(SPD_R_INTR_MASK) != value) && ((dev9Ru16(SPD_R_INTR_MASK) | value) & dev9.irqcause))
|
||||
DEV9_LOG_VERB("SPD_R_INTR_MASK 16bit write %x , checking for masked/unmasked interrupts\n", value);
|
||||
if ((dev9.irqmask != value) && ((dev9.irqmask | value) & dev9.irqcause))
|
||||
{
|
||||
DEV9_LOG("SPD_R_INTR_MASK16=0x%X , checking for masked/unmasked interrupts\n", value);
|
||||
DEV9_LOG_VERB("SPD_R_INTR_MASK16 firing unmasked interrupts\n");
|
||||
dev9Irq(1);
|
||||
}
|
||||
dev9.irqmask = value;
|
||||
break;
|
||||
|
||||
case SPD_R_PIO_DIR:
|
||||
//DEV9_LOG("SPD_R_PIO_DIR 16bit write %x\n", value);
|
||||
DEV9_LOG_VERB("SPD_R_PIO_DIR 16bit write %x\n", value);
|
||||
|
||||
if ((value & 0xc0) != 0xc0)
|
||||
return;
|
||||
|
@ -662,7 +762,7 @@ void DEV9write16(u32 addr, u16 value)
|
|||
return;
|
||||
|
||||
case SPD_R_PIO_DATA:
|
||||
//DEV9_LOG("SPD_R_PIO_DATA 16bit write %x\n", value);
|
||||
DEV9_LOG_VERB("SPD_R_PIO_DATA 16bit write %x\n", value);
|
||||
|
||||
if ((value & 0xc0) != 0xc0)
|
||||
return;
|
||||
|
@ -709,24 +809,220 @@ void DEV9write16(u32 addr, u16 value)
|
|||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEV9_LOG_ERROR("Unkown EEPROM COMMAND\n");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
case SPD_R_DMA_CTRL:
|
||||
DEV9_LOG_VERB("SPD_R_IF_CTRL 16bit write %x\n", value);
|
||||
dev9.dma_ctrl = value;
|
||||
|
||||
if (value & SPD_DMA_TO_SMAP)
|
||||
DEV9_LOG_VERB("SPD_R_DMA_CTRL DMA For SMAP\n");
|
||||
else
|
||||
DEV9_LOG_VERB("SPD_R_DMA_CTRL DMA For ATA\n");
|
||||
|
||||
if ((value & SPD_DMA_FASTEST) != 0)
|
||||
DEV9_LOG_VERB("SPD_R_DMA_CTRL Fastest DMA Mode\n");
|
||||
else
|
||||
DEV9_LOG_VERB("SPD_R_DMA_CTRL Slower DMA Mode\n");
|
||||
|
||||
if ((value & SPD_DMA_WIDE) != 0)
|
||||
DEV9_LOG_VERB("SPD_R_DMA_CTRL Wide(32bit) DMA Mode Set\n");
|
||||
else
|
||||
DEV9_LOG_VERB("SPD_R_DMA_CTRL 16bit DMA Mode\n");
|
||||
|
||||
if ((value & SPD_DMA_PAUSE) != 0)
|
||||
DEV9_LOG_ERROR("SPD_R_DMA_CTRL Pause DMA\n");
|
||||
|
||||
if ((value & 0b1111111111101000) != 0)
|
||||
DEV9_LOG_ERROR("SPD_R_DMA_CTRL Unkown value written %x\n", value);
|
||||
|
||||
break;
|
||||
case SPD_R_XFR_CTRL:
|
||||
DEV9_LOG_VERB("SPD_R_IF_CTRL 16bit write %x\n", value);
|
||||
dev9.xfr_ctrl = value;
|
||||
|
||||
if (value & SPD_XFR_WRITE)
|
||||
DEV9_LOG_VERB("SPD_R_XFR_CTRL Set Write\n");
|
||||
else
|
||||
DEV9_LOG_VERB("SPD_R_XFR_CTRL Set Read\n");
|
||||
|
||||
if ((value & (1 << 1)) != 0)
|
||||
DEV9_LOG_VERB("SPD_R_XFR_CTRL Unkown Bit 1\n");
|
||||
|
||||
if ((value & (1 << 2)) != 0)
|
||||
DEV9_LOG_VERB("SPD_R_XFR_CTRL Unkown Bit 2\n");
|
||||
|
||||
if (value & SPD_XFR_DMAEN)
|
||||
DEV9_LOG_VERB("SPD_R_XFR_CTRL For DMA Enabled\n");
|
||||
else
|
||||
DEV9_LOG_VERB("SPD_R_XFR_CTRL For DMA Disabled\n");
|
||||
|
||||
if ((value & 0b1111111101111000) != 0)
|
||||
{
|
||||
DEV9_LOG_ERROR("SPD_R_XFR_CTRL Unkown value written %x\n", value);
|
||||
}
|
||||
|
||||
return;
|
||||
break;
|
||||
case SPD_R_DBUF_STAT:
|
||||
DEV9_LOG_VERB("SPD_R_DBUF_STAT 16bit write %x\n", value);
|
||||
|
||||
if ((value & SPD_DBUF_RESET_FIFO) != 0)
|
||||
{
|
||||
DEV9_LOG_VERB("SPD_R_XFR_CTRL Reset FIFO\n");
|
||||
dev9.fifo_bytes_write = 0;
|
||||
dev9.fifo_bytes_read = 0;
|
||||
dev9.xfr_ctrl &= ~SPD_XFR_WRITE; //?
|
||||
dev9.if_ctrl |= SPD_IF_READ; //?
|
||||
|
||||
FIFOIntr();
|
||||
}
|
||||
|
||||
if (value != 3)
|
||||
DEV9_LOG_ERROR("SPD_R_38 16bit write %x Which != 3!!!", value);
|
||||
break;
|
||||
|
||||
case SPD_R_IF_CTRL:
|
||||
DEV9_LOG_VERB("SPD_R_IF_CTRL 16bit write %x\n", value);
|
||||
dev9.if_ctrl = value;
|
||||
|
||||
if (value & SPD_IF_UDMA)
|
||||
DEV9_LOG_VERB("IF_CTRL UDMA Enabled\n");
|
||||
else
|
||||
DEV9_LOG_VERB("IF_CTRL UDMA Disabled\n");
|
||||
if (value & SPD_IF_READ)
|
||||
DEV9_LOG_VERB("IF_CTRL DMA Is ATA Read\n");
|
||||
else
|
||||
DEV9_LOG_VERB("IF_CTRL DMA Is ATA Write\n");
|
||||
|
||||
if (value & SPD_IF_ATA_DMAEN)
|
||||
{
|
||||
DEV9_LOG_VERB("IF_CTRL ATA DMA Enabled\n");
|
||||
if (value & SPD_IF_READ) //Semi async
|
||||
{
|
||||
HDDWriteFIFO(); //Yes this is not a typo
|
||||
}
|
||||
else
|
||||
{
|
||||
HDDReadFIFO();
|
||||
}
|
||||
FIFOIntr();
|
||||
}
|
||||
else
|
||||
DEV9_LOG_VERB("IF_CTRL ATA DMA Disabled\n");
|
||||
|
||||
if (value & (1 << 3))
|
||||
DEV9_LOG_VERB("IF_CTRL Unkown Bit 3 Set\n");
|
||||
|
||||
if (value & (1 << 4))
|
||||
DEV9_LOG_ERROR("IF_CTRL Unkown Bit 4 Set\n");
|
||||
if (value & (1 << 5))
|
||||
DEV9_LOG_ERROR("IF_CTRL Unkown Bit 5 Set\n");
|
||||
|
||||
if ((value & SPD_IF_HDD_RESET) == 0) //Maybe?
|
||||
{
|
||||
DEV9_LOG_INFO("IF_CTRL HDD Hard Reset\n");
|
||||
dev9.ata->ATA_HardReset();
|
||||
}
|
||||
if ((value & SPD_IF_ATA_RESET) != 0)
|
||||
{
|
||||
DEV9_LOG_INFO("IF_CTRL ATA Reset\n");
|
||||
//0x62 0x0020
|
||||
dev9.if_ctrl = 0x001A;
|
||||
//0x66 0x0001
|
||||
dev9.pio_mode = 0x24;
|
||||
dev9.mdma_mode = 0x45;
|
||||
dev9.udma_mode = 0x83;
|
||||
//0x76 0x4ABA (And consequently 0x78 = 0x4ABA.)
|
||||
}
|
||||
|
||||
if ((value & 0xFF00) > 0)
|
||||
DEV9_LOG_ERROR("IF_CTRL Unkown Bit(s) %x\n", (value & 0xFF00));
|
||||
|
||||
break;
|
||||
case SPD_R_PIO_MODE: //ATA only? or includes EEPROM?
|
||||
DEV9_LOG_VERB("SPD_R_PIO_MODE 16bit write %x\n", value);
|
||||
dev9.pio_mode = value;
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case 0x92:
|
||||
DEV9_LOG_INFO("SPD_R_PIO_MODE 0\n");
|
||||
break;
|
||||
case 0x72:
|
||||
DEV9_LOG_INFO("SPD_R_PIO_MODE 1\n");
|
||||
break;
|
||||
case 0x32:
|
||||
DEV9_LOG_INFO("SPD_R_PIO_MODE 2\v");
|
||||
break;
|
||||
case 0x24:
|
||||
DEV9_LOG_INFO("SPD_R_PIO_MODE 3\n");
|
||||
break;
|
||||
case 0x23:
|
||||
DEV9_LOG_INFO("SPD_R_PIO_MODE 4\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
DEV9_LOG_ERROR("SPD_R_PIO_MODE UNKOWN MODE %x\n", value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SPD_R_MDMA_MODE: //ATA only? or includes EEPROM?
|
||||
DEV9_LOG_VERB("SPD_R_MDMA_MODE 16bit write %x\n", value);
|
||||
dev9.mdma_mode = value;
|
||||
|
||||
if ((addr >= FLASH_REGBASE) && (addr < (FLASH_REGBASE + FLASH_REGSIZE)))
|
||||
switch (value)
|
||||
{
|
||||
FLASHwrite32(addr, (u32)value, 2);
|
||||
return;
|
||||
case 0xFF:
|
||||
DEV9_LOG_INFO("SPD_R_MDMA_MODE 0\n");
|
||||
break;
|
||||
case 0x45:
|
||||
DEV9_LOG_INFO("SPD_R_MDMA_MODE 1\n");
|
||||
break;
|
||||
case 0x24:
|
||||
DEV9_LOG_INFO("SPD_R_MDMA_MODE 2\n");
|
||||
break;
|
||||
default:
|
||||
DEV9_LOG_ERROR("SPD_R_MDMA_MODE UNKOWN MODE %x\n", value);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case SPD_R_UDMA_MODE: //ATA only?
|
||||
DEV9_LOG_VERB("SPD_R_UDMA_MODE 16bit write %x\n", value);
|
||||
dev9.udma_mode = value;
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case 0xa7:
|
||||
DEV9_LOG_VERB("SPD_R_UDMA_MODE 0\n");
|
||||
break;
|
||||
case 0x85:
|
||||
DEV9_LOG_VERB("SPD_R_UDMA_MODE 1\n");
|
||||
break;
|
||||
case 0x63:
|
||||
DEV9_LOG_VERB("SPD_R_UDMA_MODE 2\n");
|
||||
break;
|
||||
case 0x62:
|
||||
DEV9_LOG_VERB("SPD_R_UDMA_MODE 3\n");
|
||||
break;
|
||||
case 0x61:
|
||||
DEV9_LOG_VERB("SPD_R_UDMA_MODE 4\n");
|
||||
break;
|
||||
default:
|
||||
DEV9_LOG_ERROR("SPD_R_UDMA_MODE UNKOWN MODE %x\n", value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
dev9Ru16(addr) = value;
|
||||
DEV9_LOG("*Unknown 16bit write at address %lx value %x\n", addr, value);
|
||||
DEV9_LOG_ERROR("*Unknown 16bit write at address %lx value %x\n", addr, value);
|
||||
return;
|
||||
}
|
||||
dev9Ru16(addr) = value;
|
||||
DEV9_LOG("*Known 16bit write at address %lx value %x\n", addr, value);
|
||||
}
|
||||
|
||||
void DEV9write32(u32 addr, u32 value)
|
||||
|
@ -747,24 +1043,22 @@ void DEV9write32(u32 addr, u32 value)
|
|||
smap_write32(addr, value);
|
||||
return;
|
||||
}
|
||||
switch (addr)
|
||||
{
|
||||
case SPD_R_INTR_MASK:
|
||||
emu_printf("SPD_R_INTR_MASK , WTFH ?\n");
|
||||
break;
|
||||
default:
|
||||
if ((addr >= FLASH_REGBASE) && (addr < (FLASH_REGBASE + FLASH_REGSIZE)))
|
||||
{
|
||||
FLASHwrite32(addr, (u32)value, 4);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case SPD_R_INTR_MASK:
|
||||
DEV9_LOG_ERROR("SPD_R_INTR_MASK , WTFH ?\n");
|
||||
break;
|
||||
default:
|
||||
dev9Ru32(addr) = value;
|
||||
DEV9_LOG("*Unknown 32bit write at address %lx write %x\n", addr, value);
|
||||
DEV9_LOG_ERROR("*Unknown 32bit write at address %lx write %x\n", addr, value);
|
||||
return;
|
||||
}
|
||||
dev9Ru32(addr) = value;
|
||||
DEV9_LOG("*Known 32bit write at address %lx value %lx\n", addr, value);
|
||||
}
|
||||
|
||||
void DEV9readDMA8Mem(u32* pMem, int size)
|
||||
|
@ -772,14 +1066,26 @@ void DEV9readDMA8Mem(u32* pMem, int size)
|
|||
if (!config.ethEnable & !config.hddEnable)
|
||||
return;
|
||||
|
||||
DEV9_LOG("*DEV9readDMA8Mem: size %x\n", size);
|
||||
emu_printf("rDMA\n");
|
||||
size >>= 1;
|
||||
|
||||
DEV9_LOG_VERB("*DEV9readDMA8Mem: size %x\n", size);
|
||||
DEV9_LOG_INFO("rDMA\n");
|
||||
|
||||
if (dev9.dma_ctrl & SPD_DMA_TO_SMAP)
|
||||
smap_readDMA8Mem(pMem, size);
|
||||
#ifdef ENABLE_ATA
|
||||
ata_readDMA8Mem(pMem, size);
|
||||
#endif
|
||||
else
|
||||
{
|
||||
if (dev9.xfr_ctrl & SPD_XFR_DMAEN &&
|
||||
!(dev9.xfr_ctrl & SPD_XFR_WRITE))
|
||||
{
|
||||
HDDWriteFIFO();
|
||||
IOPReadFIFO(size);
|
||||
dev9.ata->ATAreadDMA8Mem((u8*)pMem, size);
|
||||
FIFOIntr();
|
||||
}
|
||||
}
|
||||
|
||||
//TODO, track if read was successful
|
||||
}
|
||||
|
||||
void DEV9writeDMA8Mem(u32* pMem, int size)
|
||||
|
@ -787,20 +1093,32 @@ void DEV9writeDMA8Mem(u32* pMem, int size)
|
|||
if (!config.ethEnable & !config.hddEnable)
|
||||
return;
|
||||
|
||||
DEV9_LOG("*DEV9writeDMA8Mem: size %x\n", size);
|
||||
emu_printf("wDMA\n");
|
||||
size >>= 1;
|
||||
|
||||
smap_writeDMA8Mem(pMem, size);
|
||||
#ifdef ENABLE_ATA
|
||||
ata_writeDMA8Mem(pMem, size);
|
||||
#endif
|
||||
}
|
||||
DEV9_LOG_VERB("*DEV9writeDMA8Mem: size %x\n", size);
|
||||
DEV9_LOG_INFO("wDMA\n");
|
||||
|
||||
if (dev9.dma_ctrl & SPD_DMA_TO_SMAP)
|
||||
smap_writeDMA8Mem(pMem, size);
|
||||
else
|
||||
{
|
||||
if (dev9.xfr_ctrl & SPD_XFR_DMAEN &&
|
||||
dev9.xfr_ctrl & SPD_XFR_WRITE)
|
||||
{
|
||||
IOPWriteFIFO(size);
|
||||
HDDReadFIFO();
|
||||
dev9.ata->ATAwriteDMA8Mem((u8*)pMem, size);
|
||||
FIFOIntr();
|
||||
}
|
||||
}
|
||||
|
||||
//TODO, track if write was successful
|
||||
}
|
||||
|
||||
void DEV9async(u32 cycles)
|
||||
{
|
||||
smap_async(cycles);
|
||||
dev9.ata->Async(cycles);
|
||||
}
|
||||
|
||||
// extended funcs
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "PS2Edefs.h"
|
||||
#include "PS2Eext.h"
|
||||
#include "net.h"
|
||||
#include "ATA/ATA.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
|
@ -82,6 +83,8 @@ EXTERN Config config;
|
|||
|
||||
typedef struct
|
||||
{
|
||||
ATA* ata;
|
||||
|
||||
s8 dev9R[0x10000];
|
||||
u8 eeprom_state;
|
||||
u8 eeprom_command;
|
||||
|
@ -99,14 +102,21 @@ typedef struct
|
|||
u16 txfifo_rd_ptr;
|
||||
|
||||
u8 bd_swap;
|
||||
u16 atabuf[1024];
|
||||
u32 atacount;
|
||||
u32 atasize;
|
||||
u16 phyregs[32];
|
||||
int irqcause;
|
||||
u8 atacmd;
|
||||
u32 atasector;
|
||||
u32 atansector;
|
||||
|
||||
u16 irqcause;
|
||||
u16 irqmask;
|
||||
u16 dma_ctrl;
|
||||
u16 xfr_ctrl;
|
||||
u16 if_ctrl;
|
||||
|
||||
u16 pio_mode;
|
||||
u16 mdma_mode;
|
||||
u16 udma_mode;
|
||||
|
||||
//Non-Regs
|
||||
int fifo_bytes_read;
|
||||
int fifo_bytes_write;
|
||||
} dev9Struct;
|
||||
|
||||
//EEPROM states
|
||||
|
|
Loading…
Reference in New Issue