s32 CALLBACK DEV9open(void *pDsp) { DEV9_LOG("DEV9open\n"); LoadConf(); DEV9_LOG("open r+: %s\n", config.Hdd); config.HddSize = 8*1024; iopPC = (u32*)pDsp; #ifdef ENABLE_ATA ata_init(); #endif return _DEV9open(); }
long sockOpen(char *Device) { lpAdapter = PacketOpenAdapter(Device); if (lpAdapter == NULL) return -1; #ifdef DEV9_LOG DEV9_LOG("PacketOpenAdapter %s: %p\n", Device, lpAdapter); #endif if(PacketSetHwFilter(lpAdapter,NDIS_PACKET_TYPE_PROMISCUOUS)==FALSE){ SysMessage("Warning: unable to set promiscuous mode!"); } if(PacketSetBuff(lpAdapter,512000)==FALSE){ SysMessage("Unable to set the kernel buffer!"); return -1; } if(PacketSetReadTimeout(lpAdapter,100)==FALSE){ SysMessage("Warning: unable to set the read tiemout!"); } if((lpRecvPacket = PacketAllocatePacket())==NULL){ SysMessage("Error: failed to allocate the LPPACKET structure."); return (-1); } if((lpSendPacket = PacketAllocatePacket())==NULL){ SysMessage("Error: failed to allocate the LPPACKET structure."); return (-1); } lbytes=0; tbytes=0; return 0; }
s32 CALLBACK DEV9open(void *pDsp) { DEV9_LOG("DEV9open\n"); LoadConf(); DEV9_LOG("open r+: %s\n", config.Hdd); config.HddSize = 8*1024; tx_p_first=false; // reset stack init hack so it works on game reboots iopPC = (u32*)pDsp; #ifdef ENABLE_ATA ata_init(); #endif return _DEV9open(); }
int CALLBACK _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)) return 1; return 0; }
void CALLBACK DEV9close() { DEV9_LOG("DEV9close\n"); #ifdef ENABLE_ATA ata_term(); #endif _DEV9close(); }
void _DEV9irq(int cause, int cycles) { DEV9_LOG("_DEV9irq %x, %x\n", cause, dev9Ru16(SPD_R_INTR_MASK)); dev9.irqcause|= cause; if(cycles<1) DEV9irq(1); else DEV9irq(cycles); }
void CALLBACK DEV9shutdown() { DEV9_LOG("DEV9shutdown\n"); #ifdef DEV9_LOG_ENABLE fclose(dev9Log); #endif }
s32 CALLBACK DEV9init() { #ifdef DEV9_LOG_ENABLE dev9Log = fopen("logs/dev9Log.txt", "w"); setvbuf(dev9Log, NULL, _IONBF, 0); DEV9_LOG("DEV9init\n"); #endif memset(&dev9, 0, sizeof(dev9)); DEV9_LOG("DEV9init2\n"); DEV9_LOG("DEV9init3\n"); FLASHinit(); hEeprom = CreateFile( "eeprom.dat", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL ); if(hEeprom==INVALID_HANDLE_VALUE) { dev9.eeprom=(u16*)eeprom; } else { mapping=CreateFileMapping(hEeprom,NULL,PAGE_READWRITE,0,0,NULL); if(mapping==INVALID_HANDLE_VALUE) { CloseHandle(hEeprom); dev9.eeprom=(u16*)eeprom; } else { dev9.eeprom = (u16*)MapViewOfFile(mapping,FILE_MAP_WRITE,0,0,0); if(dev9.eeprom==NULL) { CloseHandle(mapping); CloseHandle(hEeprom); dev9.eeprom=(u16*)eeprom; } } } { int rxbi; for(rxbi=0;rxbi<(SMAP_BD_SIZE/8);rxbi++) { smap_bd_t *pbd = (smap_bd_t *)&dev9.dev9R[SMAP_BD_RX_BASE & 0xffff]; pbd = &pbd[rxbi]; pbd->ctrl_stat = SMAP_BD_RX_EMPTY; pbd->length = 0; } } DEV9_LOG("DEV9init ok\n"); return 0; }
void CALLBACK DEV9shutdown() { DEV9_LOG("DEV9shutdown\n"); #ifdef DEV9_LOG_ENABLE DEV9Log.Close(); #endif }
void emac3_write(u32 addr) { u32 value=wswap(dev9Ru32(addr)); switch(addr) { case SMAP_R_EMAC3_MODE0_L: DEV9_LOG("SMAP: SMAP_R_EMAC3_MODE0 write %x\n", value); value = (value & (~SMAP_E3_SOFT_RESET)) | SMAP_E3_TXMAC_IDLE | SMAP_E3_RXMAC_IDLE; dev9Ru16(SMAP_R_EMAC3_STA_CTRL_H)|= SMAP_E3_PHY_OP_COMP; break; case SMAP_R_EMAC3_TxMODE0_L: DEV9_LOG("SMAP: SMAP_R_EMAC3_TxMODE0_L write %x\n", value); //spams// emu_printf("SMAP: SMAP_R_EMAC3_TxMODE0_L write %x\n", value); //Process TX here ? if (!value&SMAP_E3_TX_GNP_0) emu_printf("SMAP_R_EMAC3_TxMODE0_L: SMAP_E3_TX_GNP_0 not set\n"); tx_process(); value = value& ~SMAP_E3_TX_GNP_0; if (value) emu_printf("SMAP_R_EMAC3_TxMODE0_L: extra bits set !\n"); break; case SMAP_R_EMAC3_TxMODE1_L: emu_printf("SMAP_R_EMAC3_TxMODE1_L 32bit write %x\n", value); break; case SMAP_R_EMAC3_STA_CTRL_L: DEV9_LOG("SMAP: SMAP_R_EMAC3_STA_CTRL write %x\n", value); { if (value & (SMAP_E3_PHY_READ)) { value|= SMAP_E3_PHY_OP_COMP; int reg = value & (SMAP_E3_PHY_REG_ADDR_MSK); u16 val = dev9.phyregs[reg]; switch (reg) { case SMAP_DsPHYTER_BMSR: if (has_link) val|= SMAP_PHY_BMSR_LINK | SMAP_PHY_BMSR_ANCP; break; case SMAP_DsPHYTER_PHYSTS: if (has_link) val|= SMAP_PHY_STS_LINK |SMAP_PHY_STS_100M | SMAP_PHY_STS_FDX | SMAP_PHY_STS_ANCP; break; } DEV9_LOG("phy_read %d: %x\n", reg, val); value=(value&0xFFFF)|(val<<16); } if (value & (SMAP_E3_PHY_WRITE)) { value|= SMAP_E3_PHY_OP_COMP; int reg = value & (SMAP_E3_PHY_REG_ADDR_MSK); u16 val = value>>16; switch (reg) { case SMAP_DsPHYTER_BMCR: val&= ~SMAP_PHY_BMCR_RST; val|= 0x1; break; } DEV9_LOG("phy_write %d: %x\n", reg, val); dev9.phyregs[reg] = val; } } break; default: DEV9_LOG("SMAP: emac3 write %x=%x\n",addr, value); }
void tx_process() { //we loop based on count ? or just *use* it ? u32 cnt=dev9Ru8(SMAP_R_TXFIFO_FRAME_CNT); //spams// printf("tx_process : %d cnt frames !\n",cnt); //Hack needed for GT4. Game fails to init the adapter otherwise (and notices about that via IOP kprintf on bootup). //Reseting SMAP_R_TXFIFO_FRAME_CNT to 0 however breaks OPL. Thankfully not doing that fixes the problem while GT4 still works. if (!tx_p_first) { //dev9Ru8(SMAP_R_TXFIFO_FRAME_CNT)=0; tx_p_first=true; //THIS IS A HACK.without that the stack wont init, i guess its missing e3/emac emulation .. emu_printf("WARN : First packet interrupt hack ..\n"); _DEV9irq(SMAP_INTR_RXEND|SMAP_INTR_TXEND|SMAP_INTR_TXDNV,100); return; } NetPacket pk; int fc=0; for (fc=0;fc<cnt;fc++) { smap_bd_t *pbd= ((smap_bd_t *)&dev9.dev9R[SMAP_BD_TX_BASE & 0xffff])+dev9.txbdi; if (! (pbd->ctrl_stat&SMAP_BD_TX_READY)) { emu_printf("ERROR : !pbd->ctrl_stat&SMAP_BD_TX_READY\n"); break; } if (pbd->length&3) { //spams// emu_printf("WARN : pbd->length not alligned %d\n",pbd->length); } if(pbd->length>1514) { emu_printf("ERROR : Trying to send packet too big.\n"); } else { u32 base=(pbd->pointer-0x1000)&16383; DEV9_LOG("Sending Packet from base %x, size %d\n", base, pbd->length); //spams// emu_printf("Sending Packet from base %x, size %d\n", base, pbd->length); pk.size=pbd->length; if (!(pbd->pointer>=0x1000)) { emu_printf("ERROR: odd , !pbd->pointer>0x1000 | 0x%X %d\n", pbd->pointer, pbd->length); } //increase fifo pointer(s) //uh does that even exist on real h/w ? /* if(dev9.txfifo_rd_ptr+pbd->length >= 16383) { //warp around ! //first part u32 was=16384-dev9.txfifo_rd_ptr; memcpy(pk.buffer,dev9.txfifo+dev9.txfifo_rd_ptr,was); //warp dev9.txfifo_rd_ptr+=pbd->length; dev9.txfifo_rd_ptr&=16383; if (pbd->length!=was+dev9.txfifo_rd_ptr) { emu_printf("ERROR ON TX FIFO HANDLING, %x\n", dev9.txfifo_rd_ptr); } //second part memcpy(pk.buffer+was,dev9.txfifo,pbd->length-was); } else { //no warp or 'perfect' warp (reads end, resets to start memcpy(pk.buffer,dev9.txfifo+dev9.txfifo_rd_ptr,pbd->length); dev9.txfifo_rd_ptr+=pbd->length; if (dev9.txfifo_rd_ptr==16384) dev9.txfifo_rd_ptr=0; } if (dev9.txfifo_rd_ptr&(~16383)) { emu_printf("ERROR ON TX FIFO HANDLING, %x\n", dev9.txfifo_rd_ptr); } */ if(base+pbd->length > 16384) { u32 was=16384-base; memcpy(pk.buffer,dev9.txfifo+base,was); memcpy(pk.buffer,dev9.txfifo,pbd->length-was); printf("Warped read, was=%d, sz=%d, sz-was=%d\n",was,pbd->length,pbd->length-was); } else { memcpy(pk.buffer,dev9.txfifo+base,pbd->length); } tx_put(&pk); } pbd->ctrl_stat&= ~SMAP_BD_TX_READY; //increase TXBD dev9.txbdi++; dev9.txbdi&=(SMAP_BD_SIZE/8)-1; //decrease frame count -- this is not thread safe dev9Ru8(SMAP_R_TXFIFO_FRAME_CNT)--; } //spams// emu_printf("processed %d frames, %d count, cnt = %d\n",fc,dev9Ru8(SMAP_R_TXFIFO_FRAME_CNT),cnt); //if some error/early exit signal TXDNV if (fc!=cnt || cnt==0) { printf("WARN : (fc!=cnt || cnt==0) but packet send request was made oO..\n"); _DEV9irq(SMAP_INTR_TXDNV,0); } //if we actualy send something send TXEND if(fc!=0) _DEV9irq(SMAP_INTR_TXEND,100);//now ? or when the fifo is empty ? i guess now atm }