diff -urN pearpc/src/io/prom/promdt.cc pearpc-verbose11/src/io/prom/promdt.cc
--- pearpc/src/io/prom/promdt.cc	2004-05-23 19:34:24.000000000 -0500
+++ pearpc-verbose11/src/io/prom/promdt.cc	2004-05-24 08:51:02.000000000 -0500
@@ -34,6 +34,9 @@
 
 #include "info.h"
 
+#include "configparser.h"
+#include "io/rtl8139/rtl8139.h"
+
 PromNode *gPromRoot;
 AVLTree *gPromPackages;
 AVLTree *gPromInstances;
@@ -1371,6 +1374,8 @@
 	/*
 	 *	Eth0
 	 */
+	/* should be switched to if (gCon...(3C90X_KEY_INSTALLED) */
+	if (!gConfig->getConfigInt(RTL8139_KEY_INSTALLED)) {
 #if 1
 	PromNode *eth0 = new PromNode("pci10b7,9200@4");
 	bridge->addNode(eth0);
@@ -1406,7 +1411,9 @@
 	};
 	eth0->addProp(new PromPropMemory("assigned-addresses", &eth0aa, sizeof eth0aa));
 #endif
+	}
 
+	if (gConfig->getConfigInt(RTL8139_KEY_INSTALLED)) {
 	/*
 	 *	Eth1
 	 */
@@ -1443,6 +1450,7 @@
 	0x00,0x00,0x01,0x00,
 	};
 	eth1->addProp(new PromPropMemory("assigned-addresses", &eth1aa, sizeof eth1aa));
+	}
 
 	/*
 	 *	USB
diff -urN pearpc/src/io/rtl8139/rtl8139.cc pearpc-verbose11/src/io/rtl8139/rtl8139.cc
--- pearpc/src/io/rtl8139/rtl8139.cc	2004-05-24 07:13:33.000000000 -0500
+++ pearpc-verbose11/src/io/rtl8139/rtl8139.cc	2004-05-24 08:51:28.000000000 -0500
@@ -45,6 +45,8 @@
 #include "rtl8139.h"
 
 #define MAX_PACKET_SIZE		6000
+#define MAX_PACKETS		128
+
 
 enum RxHeaderBits {
 	Rx_ROK =  1<<0, // recieve okay
@@ -129,6 +131,10 @@
 	uint8  PHY2 PACKED; // 0x80
 };
 
+struct Packet {
+	uint16	size;
+	byte	packet[MAX_PACKET_SIZE];
+};
 
 // IEEE 802.3 MAC, Ethernet-II
 struct EthFrameII {
@@ -189,25 +195,6 @@
 	}
 }
 
-#if 0
-static void dumpClientMem(uint32 addr, uint16 len)
-{
-	byte *p;
-	if (ppc_direct_physical_memory_handle(addr, p) != PPC_MMU_OK) return;
-	if (mVerbose) {
-		dumpMem(p, len);
-	}
-}
-
-static int compareMACs(byte a[6], byte b[6])
-{
-	for (uint i=0; i<6; i++) {
-		if (a[i] != b[i]) return a[i] - b[i];
-	}
-	return 0;
-}
-#endif
-
 /*
  *
  */
@@ -225,10 +212,12 @@
 	uint		mRxPacketSize;
 	int		mRingBufferSize;
 	bool	 	mGoodBSA;
-	int		mPackets;
 	enet_iface_t	mENetIf;
 	sys_mutex	mLock;
 	int		mVerbose;
+	byte		mHead;
+	byte		mTail;
+	Packet		mPackets[MAX_PACKETS];
 
 
 void PCIReset()
@@ -245,7 +234,7 @@
 
 	mConfig[0x0e] = 0x00;	// header-type (single-function PCI device)
 
-	mConfig[0x3c] = IO_PIC_IRQ_ETHERNET1;	// interrupt line
+	mConfig[0x3c] = IO_PIC_IRQ_ETHERNET0;	// interrupt line
 	mConfig[0x3d] = 1;	// interrupt pin (default is 1)
 	mConfig[0x3e] = 5;	// MinGnt (default is 5 = 0x05 = 0101b)
 	mConfig[0x3f] = 48;	// MaxLat (default is 48 = 0x30 = 110000b)
@@ -271,8 +260,9 @@
 	memset(&mRegisters, 0, sizeof mRegisters);
 	mIntStatus = 0;
 	mRingBufferSize = 8192;
-	mPackets = 0;
-	mGoodBSA = 0;
+	mHead = 0;
+	mTail = 0;
+	mGoodBSA = false;
 	mRxEnabled = false;
 	mTxEnabled = false;
 	mUpStalled = false;
@@ -292,6 +282,8 @@
 	mRegisters.CommandRegister = 0x01;
 	mRegisters.TxConfiguration = 0x63000000; // rtl8139
 	mRegisters.MediaStatus = 0x90;
+	mRegisters.CBA = 0;
+	mRegisters.CAPR = 0xfff0;
 
 	memset(mEEPROM, 0, sizeof mEEPROM);
 	mEEPROM[EEPROM_DeviceID] =		0x8139; //0x9200;
@@ -353,11 +345,11 @@
 
 void TxPacket(uint32 address, uint32 size)
 {
-	byte *	ppc_addr;
-	byte	pbuf[MAX_PACKET_SIZE];
-	byte *	p;
-	uint32	crc;
-	uint32	psize;
+	byte*	ppc_addr;
+	byte	 pbuf[MAX_PACKET_SIZE];
+	byte*	p;
+	uint32 crc;
+	uint32 psize;
 	uint	 w;
 
 	p = pbuf;
@@ -401,7 +393,7 @@
 
 public:
 rtl8139_NIC(enet_iface_t &aENetIf)
-: PCI_Device("rtl8139 Network interface card", 0x1, 0xd)
+: PCI_Device("rtl8139 Network interface card", 0x1, 0xc)
 {
 	int e;
 	if ((e = sys_create_mutex(&mLock))) throw IOException(e);
@@ -410,6 +402,37 @@
 	totalReset();
 }
 
+void transferPacket(bool raiseIntr)
+{
+	byte*		addr;
+	byte*           base;
+
+	if (ppc_direct_physical_memory_handle(mRegisters.RxBufferStartAddr, base) == PPC_MMU_OK) {
+		addr = base + mRegisters.CBA;
+		if ((mRegisters.CBA) > mRingBufferSize) {
+			if (mVerbose) IO_RTL8139_TRACE("client ring buffer wrap around [%d]\n", raiseIntr);
+			addr = base;
+			mRegisters.CBA = 0;
+			mRegisters.CAPR = 0xfff0;
+//			mRegisters.CommandRegister |= 1;
+			return;
+		}
+		memcpy(addr, mPackets[mTail].packet, mPackets[mTail].size);
+		if (mVerbose) IO_RTL8139_TRACE("wrote %04x bytes to the ring buffer\n", mPackets[mTail].size);
+		mRegisters.EarlyRxByteCount = mPackets[mTail].size;
+		mRegisters.EarlyRxStatus = 8;
+		mRegisters.CBA += mPackets[mTail].size;
+		mRegisters.CommandRegister &= 0xfe; // RxBuffer has data
+		mTail = (mTail+1) % MAX_PACKETS;
+		if (raiseIntr) {
+			mIntStatus |= 1;
+			maybeRaiseIntr();
+		}
+	} else {
+		IO_RTL8139_ERR("ppc_direct_physical_memory_handle called failed in transferPacket\n");
+	}
+}
+
 void verbose(int level)
 {
 	mVerbose = level;
@@ -465,9 +488,10 @@
 		case 0x48:
 			if (mVerbose) IO_RTL8139_TRACE("read Timer = %08x\n", data);
 			break;
-		case 0x37:
+		case 0x37: {
 			if (mVerbose) IO_RTL8139_TRACE("read Command Register = %02x\n", data);
 			break;
+		}
 		default:
 			if (mVerbose) IO_RTL8139_TRACE("read reg %04x (size %d) = %08x\n", port, size, data);
 			break;
@@ -556,18 +580,29 @@
 			mRegisters.CBA = 0;
 			mRegisters.CAPR = 0xfff0;
 			mRegisters.CommandRegister |= 1;
-			mPackets = 0;
 			mGoodBSA = true;
+			if (mTail != mHead) {
+				transferPacket(true);
+			}
 			break;
 		}
 		case 0x38: {
 			if (mVerbose) IO_RTL8139_TRACE("update to CAPR: CAPR %04x, CBA %04x\n", data, mRegisters.CBA);
 			mRegisters.CAPR = data;
-			mPackets--;
-			if (mPackets < 1) {
-				mPackets = 0;
-				//mRegisters.CBA = mRegisters.CAPR;
-				mRegisters.CommandRegister |= 1; // buffer is empty again
+			if (mRegisters.CAPR > mRingBufferSize) { //client knows about wrap, so wrap
+				mIntStatus |= 1; // fake send
+				maybeRaiseIntr();
+				/*
+				mRegisters.CAPR = 0xfff0;
+				mRegisters.CommandRegister |= 1;
+				mRegisters.CBA = 0;
+				*/
+			} else {
+				if (mTail != mHead) {
+					transferPacket(false);
+				} else {
+					mRegisters.CommandRegister |= 1;
+				}
 			}
 			break;
 		}
@@ -578,6 +613,7 @@
 			case 0x0800: mRingBufferSize = 16384; break;
 			case 0x1000: mRingBufferSize = 32768; break;
 			case 0x1800: mRingBufferSize = 65536; break;
+			default: mRingBufferSize = 8192;
 			};
 			if (mVerbose) IO_RTL8139_TRACE("RingBuffer Size: %08x\n", mRingBufferSize);
 			break;
@@ -601,14 +637,11 @@
 
 void handlePacket()
 {
-	int		err;
-	byte*		addr;
 	uint16		header;
 	uint16		psize;
-	byte*		base;
+	byte		tmp;
 	byte		broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
-	sys_lock_mutex(mLock);
 	mRxPacketSize = read(mENetIf.fd, mRxPacket, sizeof mRxPacket);
 	if (!mGoodBSA) {
 		mRxPacketSize = 0;
@@ -617,67 +650,49 @@
 		if (mVerbose > 1) {
 			dumpMem(mRxPacket, mRxPacketSize);
 		}
-		// should really do a crc check and all that good stuff
-		if (ppc_direct_physical_memory_handle(mRegisters.RxBufferStartAddr, addr) == PPC_MMU_OK) {
-			header = 0;
-			if (mRxPacketSize < 64) {
-				for ( ; mRxPacketSize < 60; mRxPacketSize++) {
-					mRxPacket[mRxPacketSize] = 0;
-				}
-				//header |= Rx_RUNT; // set runt status
-			}
-			/* pad to a 4 byte boundary */
-			for (int i = 4-(mRxPacketSize % 4); i != 0; i--) {
-				mRxPacket[mRxPacketSize++] = 0;
-			}
-			if (memcmp(addr, (byte*)&mRegisters, 6) == 0) {
-				//	if (mVerbose) IO_RTL8139_TRACE("Physical Address Match\n");
-				header |= Rx_PAM;
-			}
-			if (memcmp(addr, broadcast, 6) == 0) {
-				header |= Rx_BAR;
-			}
-			// check crc?
-			header |= Rx_ROK;
-#if 0
-			uint32 crc = ether_crc(mRxPacketSize, mRxPacket);
-			mRxPacket[mRxPacketSize+0] = crc;
-			mRxPacket[mRxPacketSize+1] = crc>>8;
-			mRxPacket[mRxPacketSize+2] = crc>>16;
-			mRxPacket[mRxPacketSize+3] = crc>>24;
-			mRxPacketSize += 4;
-#endif
-			psize = mRxPacketSize;
-			base = addr;
-			addr += mRegisters.CBA;
-			if ((addr - base) > mRingBufferSize) {
-				if (mVerbose) IO_RTL8139_TRACE("RING BUFFER WRAPPED\n");
-				// wrapped should check how to handle wrap
-				addr = base;
-				mRegisters.CBA = 0;
+		header = 0;
+		if (mRxPacketSize < 64) {
+			for ( ; mRxPacketSize < 60; mRxPacketSize++) {
+				mRxPacket[mRxPacketSize] = 0;
 			}
-			addr[0] = header;
-			addr[1] = header>>8;
-			addr[2] = psize;
-			addr[3] = psize>>8;
-			
-			memcpy(addr+4, mRxPacket, mRxPacketSize);
-			err = memcmp(addr+4, mRxPacket, mRxPacketSize);
-			if (err) {
-				IO_RTL8139_WARN("memcpy of rx packet to rx buffer failed\n");
+			//header |= Rx_RUNT; // set runt status
+		}
+		/* pad to a 4 byte boundary */
+		for (int i = 4-(mRxPacketSize % 4); i != 0; i--) {
+			mRxPacket[mRxPacketSize++] = 0;
+		}
+		if (memcmp((byte*)&(mRxPacket[0]), (byte*)&(mRegisters.id0), 6) == 0) {
+			//	if (mVerbose) IO_RTL8139_TRACE("Physical Address Match\n");
+			header |= Rx_PAM;
+		}
+		if (memcmp((byte*)&(mRxPacket[0]), broadcast, 6) == 0) {
+			header |= Rx_BAR;
+		}
+		// check crc?
+		header |= Rx_ROK;
+		psize = mRxPacketSize;
+		mPackets[mHead].packet[0] = header;
+		mPackets[mHead].packet[1] = header>>8;
+		mPackets[mHead].packet[2] = psize;
+		mPackets[mHead].packet[3] = psize>>8;
+		memcpy(&(mPackets[mHead].packet[4]), mRxPacket, mRxPacketSize);
+		mPackets[mHead].size = mRxPacketSize+4;
+		if (mHead == mTail) { /* first recent packet buffer */
+			mHead = (mHead+1) % MAX_PACKETS;
+		} else {
+			tmp = mHead;
+			mHead = (mHead+1) % MAX_PACKETS;
+			if (mHead == mTail) {
+				mHead = tmp; // reset it back 
+				IO_RTL8139_WARN("Internal Buffer wrapped around\n");
 			}
-			if (mVerbose) IO_RTL8139_TRACE("wrote %04x bytes to the ring buffer\n", mRxPacketSize+4);
-			mIntStatus |= 1;
-			mRegisters.EarlyRxStatus = 8;
-			mRegisters.EarlyRxByteCount = mRxPacketSize+4;
-			mRegisters.CBA += mRxPacketSize+4;
-			mRegisters.CommandRegister &= 0xfe; // RxBuffer has data
-			mPackets++;
-			maybeRaiseIntr();
-			mRxPacketSize = 0; // reset packet stuff
+		}
+		if (mRegisters.CommandRegister & 1) { /* no packets in process, kick one out */
+			sys_lock_mutex(mLock);
+			transferPacket(true);
+			sys_unlock_mutex(mLock);
 		}
 	}
-	sys_unlock_mutex(mLock);
 }
 
 /* new */
@@ -712,15 +727,14 @@
 #include "configparser.h"
 #include "tools/strtools.h"
 
-#define RTL8139_KEY_INSTALLED	"pci_rtl8139_installed"
-#define RTL8139_KEY_MAC	"pci_rtl8139_mac"
-#define RTL8139_KEY_VERBOSE	"pci_rtl8139_verbose"
-
 void rtl8139_init()
 {
+	String tunstr_;
+	char   tun_name[1024];
+
 	int verbose = 0;
-	verbose = gConfig->getConfigInt(RTL8139_KEY_VERBOSE); 
 
+	verbose = gConfig->getConfigInt(RTL8139_KEY_VERBOSE); 
 	if (gConfig->getConfigInt(RTL8139_KEY_INSTALLED)) {
 		byte mac[6];
 		mac[0] = 0xde;
@@ -740,9 +754,7 @@
 				if (!bnstr(macstr, v, 16) || (v>255) || ((*macstr != ':') && (i!=5))) {
 					IO_RTL8139_ERR("error in config key %s:"
 					"expected format: XX:XX:XX:XX:XX:XX, "
-					"where X stands for any digit or the "
-					"letters a-f, A-F (error at: %s)\n",
-					RTL8139_KEY_MAC, macstr);
+					"where X stands for any digit or the letters a-f, A-F (error at: %s)\n",RTL8139_KEY_MAC, macstr);
 				}
 				macstr++;
 				cfgmac[i] = v;
@@ -757,7 +769,7 @@
 		} else if (e) {
 			IO_RTL8139_ERR("Open enetif failed: %s\n", strerror(e));
 			exit(1);
-		}
+                }
 		printf("creating RealTek rtl8139 NIC emulation with eth_addr = ");
 		for (uint i=0; i<6; i++) {
 			if (i<5) {
diff -urN pearpc/src/io/rtl8139/rtl8139.h pearpc-verbose11/src/io/rtl8139/rtl8139.h
--- pearpc/src/io/rtl8139/rtl8139.h	2004-05-24 07:13:33.000000000 -0500
+++ pearpc-verbose11/src/io/rtl8139/rtl8139.h	2004-05-24 08:51:02.000000000 -0500
@@ -22,6 +22,10 @@
 #ifndef __IO_RTL8139_H__
 #define __IO_RTL8139_H__
 
+#define RTL8139_KEY_INSTALLED   "pci_rtl8139_installed"
+#define RTL8139_KEY_MAC         "pci_rtl8139_mac"
+#define RTL8139_KEY_VERBOSE     "pci_rtl8139_verbose"
+
 void rtl8139_init();
 void rtl8139_init_config();
 
