Exemple #1
0
        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);
        }
Exemple #2
0
        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
        }
Exemple #3
0
        //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
        }