public SMAP_State(DEV9_State parDev9) { dev9 = parDev9; //Init SMAP int rxbi; for (rxbi = 0; rxbi < (DEV9Header.SMAP_BD_SIZE / 8); rxbi++) { SMAP_bd pbd; pbd = new SMAP_bd(dev9.dev9R, (int)((DEV9Header.SMAP_BD_RX_BASE & 0xffff) + (SMAP_bd.GetSize() * rxbi))); pbd.CtrlStat = (UInt16)DEV9Header.SMAP_BD_RX_EMPTY; pbd.Length = 0; } adapter = new AdapterLoader(this, dev9); }
public void RxProcess(ref NetPacket pk) { if (!RxFifoCanRx()) { Log_Error("ERROR : !rx_fifo_can_rx at rx_process"); return; } //smap_bd_t* pbd = ((smap_bd_t*)&dev9.dev9R[SMAP_BD_RX_BASE & 0xffff]) + dev9.rxbdi; int soff = (int)((DEV9Header.SMAP_BD_RX_BASE & 0xffff) + dev9.rxbdi * SMAP_bd.GetSize()); SMAP_bd pbd = new SMAP_bd(dev9.dev9R, soff); int bytes = (pk.size + 3) & (~3); if (!((pbd.CtrlStat & DEV9Header.SMAP_BD_RX_EMPTY) != 0)) { Log_Info("(!(pbd->ctrl_stat & SMAP_BD_RX_EMPTY))"); Log_Info("Discarding " + bytes + " bytes (RX" + dev9.rxbdi + " not ready)"); return; } int pstart = (dev9.rxFifoWrPtr) & 16383; int i = 0; while (i < bytes) { dev9.Dev9RxFifoWrite(pk.buffer[i++]); dev9.rxFifoWrPtr &= 16383; } lock (resetSentry) { //increase RXBD dev9.rxbdi++; dev9.rxbdi &= ((DEV9Header.SMAP_BD_SIZE / 8u) - 1u); //Fill the BD with info ! pbd.Length = (ushort)pk.size; pbd.Pointer = (ushort)(0x4000 + pstart); unchecked //Allow -int to uint { pbd.CtrlStat &= (ushort)~DEV9Header.SMAP_BD_RX_EMPTY; } //increase frame count lock (counterSentry) { byte framecount = dev9.Dev9Ru8((int)DEV9Header.SMAP_R_RXFIFO_FRAME_CNT); framecount++; dev9.Dev9Wu8((int)DEV9Header.SMAP_R_RXFIFO_FRAME_CNT, framecount); } } //spams// emu_printf("Got packet, %d bytes (%d fifo)\n", pk->size,bytes); fireIntR = true; //DEV9._DEV9irq(DEV9Header.SMAP_INTR_RXEND, 0);//now ? or when the fifo is full ? i guess now atm //note that this _is_ wrong since the IOP interrupt system is not thread safe.. but nothing i can do about that }
//tx_process private void TxProcess() { //Error.WriteLine("TX"); //we loop based on count ? or just *use* it ? UInt32 cnt = dev9.Dev9Ru8((int)DEV9Header.SMAP_R_TXFIFO_FRAME_CNT); //spams// printf("tx_process : %d cnt frames !\n",cnt); NetPacket pk = new NetPacket(); 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; SMAP_bd pbd; pbd = new SMAP_bd(dev9.dev9R, (int)((DEV9Header.SMAP_BD_TX_BASE & 0xffff) + (SMAP_bd.GetSize() * dev9.txbdi))); if (!((pbd.CtrlStat & DEV9Header.SMAP_BD_TX_READY) != 0)) { Log_Error("ERROR : !pbd->ctrl_stat&SMAP_BD_TX_READY\n"); break; } if ((pbd.Length & 3) != 0) { //spams// emu_printf("WARN : pbd->length not alligned %d\n",pbd->length); } if (pbd.Length > 1514) { Log_Error("ERROR : Trying to send packet too big.\n"); } else { UInt32 _base = (UInt32)((pbd.Pointer - 0x1000) & 16383); Log_Verb("Sending Packet from base " + _base.ToString("X") + ", size " + pbd.Length); //The 1st packet we send should be base 0, size 1514 //spams// emu_printf("Sending Packet from base %x, size %d\n", base, pbd->length); pk.size = pbd.Length; if (!(pbd.Pointer >= 0x1000)) { Log_Error("ERROR: odd , !pbd->pointer>0x1000 | 0x" + pbd.Pointer.ToString("X") + " " + pbd.Length.ToString()); } if (_base + pbd.Length > 16384) { UInt32 was = 16384 - _base; Utils.memcpy(ref pk.buffer, 0, dev9.txFifo, (int)_base, (int)was); Utils.memcpy(ref pk.buffer, (int)was, dev9.txFifo, 0, (int)(pbd.Length - was)); //I thingk this was a bug in the original plugin Log_Verb("Warped read, was=" + was + ", sz=" + pbd.Length + ", sz-was=" + (pbd.Length - was)); } else { Utils.memcpy(ref pk.buffer, 0, dev9.txFifo, (int)_base, (int)pbd.Length); } adapter.net.TxPut(ref pk); } unchecked { pbd.CtrlStat &= (UInt16)(~DEV9Header.SMAP_BD_TX_READY); } //increase TXBD dev9.txbdi++; dev9.txbdi &= (DEV9Header.SMAP_BD_SIZE / 8) - 1; //decrease frame count -- this is not thread safe //dev9Ru8(SMAP_R_TXFIFO_FRAME_CNT)--; dev9.Dev9Wu8((int)DEV9Header.SMAP_R_TXFIFO_FRAME_CNT, (byte)(dev9.Dev9Ru8((int)DEV9Header.SMAP_R_TXFIFO_FRAME_CNT) - 1)); } //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) { Log_Error("WARN : (fc!=cnt || cnt==0) but packet send request was made oO.."); dev9.DEV9irq(DEV9Header.SMAP_INTR_TXDNV, 0); } //if we actualy send something send TXEND if (fc != 0) dev9.DEV9irq(DEV9Header.SMAP_INTR_TXEND, 100);//now ? or when the fifo is empty ? i guess now atm }