DEV9: Improved SPEED emulation, also hookup ATA emulation

This commit is contained in:
TheLastRar 2020-11-16 20:26:56 +00:00 committed by refractionpcsx2
parent afc9412191
commit 31a3ee3cbc
2 changed files with 455 additions and 127 deletions

View File

@ -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

View File

@ -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