diff --git a/ZealOS-2021-07-09-04_16_41.iso b/ZealOS-2021-07-09-16_43_17.iso
similarity index 99%
rename from ZealOS-2021-07-09-04_16_41.iso
rename to ZealOS-2021-07-09-16_43_17.iso
index 802f71dd..5d50cbec 100755
Binary files a/ZealOS-2021-07-09-04_16_41.iso and b/ZealOS-2021-07-09-16_43_17.iso differ
diff --git a/docs/Home/Net/Drivers/E1000.CC.html b/docs/Home/Net/Drivers/E1000.CC.html
index b9dde380..eb6bfb64 100755
--- a/docs/Home/Net/Drivers/E1000.CC.html
+++ b/docs/Home/Net/Drivers/E1000.CC.html
@@ -136,264 +136,448 @@ body {background-color:#000000;}
 <a name="l109"></a>
 <a name="l110"></a>    </span><span class=cF1>U8</span><span class=cF0>  mac_address[</span><span class=cFE>6</span><span class=cF0>];
 <a name="l111"></a>    </span><span class=cF9>U64</span><span class=cF0> mmio_address;
-<a name="l112"></a>    </span><span class=cF1>U8</span><span class=cF0> *rx_de_buffer;           </span><span class=cF2>// Uncached-alias of pointer to the buffer of RX Descriptor Entries.</span><span class=cF0>
-<a name="l113"></a>    </span><span class=cF1>U8</span><span class=cF0> *tx_de_buffer;           </span><span class=cF2>// Uncached-alias of pointer to the buffer of TX Descriptor Entries.</span><span class=cF0>
-<a name="l114"></a>    </span><span class=cF1>U8</span><span class=cF0> *rx_de_buffer_phys;      </span><span class=cF2>// Pointer to the buffer of RX Descriptor Entries. (Code Heap, lower 2Gb)</span><span class=cF0>
-<a name="l115"></a>    </span><span class=cF1>U8</span><span class=cF0> *tx_de_buffer_phys;      </span><span class=cF2>// Pointer to the buffer of TX Descriptor Entries. (Code Heap, lower 2Gb)</span><span class=cF0>
-<a name="l116"></a>    </span><span class=cF9>U64</span><span class=cF0> rx_buffer_addr;         </span><span class=cF2>// Uncached-alias of address of receive buffers.</span><span class=cF0>
-<a name="l117"></a>    </span><span class=cF9>U64</span><span class=cF0> tx_buffer_addr;         </span><span class=cF2>// Uncached-alias of address of transmit buffers.</span><span class=cF0>
-<a name="l118"></a>    </span><span class=cF9>U64</span><span class=cF0> rx_buffer_addr_phys;    </span><span class=cF2>// Physical address of actual receive buffers  (&lt; 4 Gb)</span><span class=cF0>
-<a name="l119"></a>    </span><span class=cF9>U64</span><span class=cF0> tx_buffer_addr_phys;    </span><span class=cF2>// Physical address of actual transmit buffers (&lt; 4 Gb)</span><span class=cF0>
+<a name="l112"></a>
+<a name="l113"></a>    </span><span class=cF9>I64</span><span class=cF0> current_rx_de_index;    </span><span class=cF2>// Current Receive DE being processed.  Gets incremented, wrapped to 0 at max of E1000_RX_BUFF_COUNT.</span><span class=cF0>
+<a name="l114"></a>    </span><span class=cF9>I64</span><span class=cF0> current_tx_de_index;    </span><span class=cF2>// Current Transmit DE being processed. Gets incremented, wrapped to 0 at max of E1000_TX_BUFF_COUNT.</span><span class=cF0>
+<a name="l115"></a>
+<a name="l116"></a>    </span><span class=cF1>U8</span><span class=cF0> *rx_de_buffer;           </span><span class=cF2>// Uncached-alias of pointer to the buffer of RX Descriptor Entries.</span><span class=cF0>
+<a name="l117"></a>    </span><span class=cF1>U8</span><span class=cF0> *tx_de_buffer;           </span><span class=cF2>// Uncached-alias of pointer to the buffer of TX Descriptor Entries.</span><span class=cF0>
+<a name="l118"></a>    </span><span class=cF1>U8</span><span class=cF0> *rx_de_buffer_phys;      </span><span class=cF2>// Pointer to the buffer of RX Descriptor Entries. (Code Heap, lower 2Gb)</span><span class=cF0>
+<a name="l119"></a>    </span><span class=cF1>U8</span><span class=cF0> *tx_de_buffer_phys;      </span><span class=cF2>// Pointer to the buffer of TX Descriptor Entries. (Code Heap, lower 2Gb)</span><span class=cF0>
 <a name="l120"></a>
-<a name="l121"></a>} e1000; </span><span class=cF2>// e1000 is the global variable we store all of this into.</span><span class=cF0>
-<a name="l122"></a>
-<a name="l123"></a></span><span class=cF9>CPCIDev</span><span class=cF0> *E1000PCIDevFind()
-<a name="l124"></a>{</span><span class=cF2>// Find and return E1000 card as a CPCIDev pointer.</span><span class=cF0>
+<a name="l121"></a>    </span><span class=cF9>U64</span><span class=cF0> rx_buffer_addr;         </span><span class=cF2>// Uncached-alias of address of receive buffers.</span><span class=cF0>
+<a name="l122"></a>    </span><span class=cF9>U64</span><span class=cF0> tx_buffer_addr;         </span><span class=cF2>// Uncached-alias of address of transmit buffers.</span><span class=cF0>
+<a name="l123"></a>    </span><span class=cF9>U64</span><span class=cF0> rx_buffer_addr_phys;    </span><span class=cF2>// Physical address of actual receive buffers  (&lt; 4 Gb)</span><span class=cF0>
+<a name="l124"></a>    </span><span class=cF9>U64</span><span class=cF0> tx_buffer_addr_phys;    </span><span class=cF2>// Physical address of actual transmit buffers (&lt; 4 Gb)</span><span class=cF0>
 <a name="l125"></a>
-<a name="l126"></a>    </span><span class=cF9>CPCIDev</span><span class=cF0> *pci = </span><span class=cF5>PCIDevFind</span><span class=cF0>(</span><span class=cF3>PCIC_NETWORK</span><span class=cF0>,, PCIV_E1000);
-<a name="l127"></a>
-<a name="l128"></a>    </span><span class=cF1>if</span><span class=cF0> (!pci)
-<a name="l129"></a>        </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>NULL</span><span class=cF0>;
-<a name="l130"></a>
-<a name="l131"></a>    </span><span class=cF5>ClassRep</span><span class=cF0>(pci);
-<a name="l132"></a>
-<a name="l133"></a>    </span><span class=cF1>switch</span><span class=cF0> (pci-&gt;device_id)
-<a name="l134"></a>    </span><span class=cF7>{</span><span class=cF0>
-<a name="l135"></a>        </span><span class=cF1>case</span><span class=cF0> PCID_82545EM:
-<a name="l136"></a>            </span><span class=cF1>break</span><span class=cF0>;
-<a name="l137"></a>
-<a name="l138"></a>        </span><span class=cF1>default</span><span class=cF0>:
-<a name="l139"></a>            pci = </span><span class=cF3>NULL</span><span class=cF0>;
-<a name="l140"></a>    </span><span class=cF7>}</span><span class=cF0>
-<a name="l141"></a>
-<a name="l142"></a>    </span><span class=cF1>return</span><span class=cF0> pci;
-<a name="l143"></a>}
-<a name="l144"></a>
-<a name="l145"></a></span><span class=cF9>U32</span><span class=cF0> E1000MMIORead(</span><span class=cF9>U32</span><span class=cF0> </span><span class=cF1>offset</span><span class=cF0>)
-<a name="l146"></a>{
-<a name="l147"></a>    </span><span class=cF9>U32</span><span class=cF0> *val = e1000.mmio_address + </span><span class=cF1>offset</span><span class=cF0>;
-<a name="l148"></a>
-<a name="l149"></a>    </span><span class=cF1>return</span><span class=cF0> *val;
-<a name="l150"></a>}
-<a name="l151"></a>
-<a name="l152"></a></span><span class=cF1>U0</span><span class=cF0> E1000MMIOWrite(</span><span class=cF9>U32</span><span class=cF0> </span><span class=cF1>offset</span><span class=cF0>, </span><span class=cF9>U32</span><span class=cF0> val)
-<a name="l153"></a>{
-<a name="l154"></a>    </span><span class=cF9>U32</span><span class=cF0> *addr = e1000.mmio_address + </span><span class=cF1>offset</span><span class=cF0>;
-<a name="l155"></a>
-<a name="l156"></a>    *addr = val;
-<a name="l157"></a>}
-<a name="l158"></a>
-<a name="l159"></a></span><span class=cF9>U16</span><span class=cF0> E1000EEPROMRead(</span><span class=cF1>U8</span><span class=cF0> word)
-<a name="l160"></a>{ </span><span class=cF2>// word arg is which U16 to read</span><span class=cF0>
-<a name="l161"></a>    </span><span class=cF9>U16</span><span class=cF0> data;
-<a name="l162"></a>    </span><span class=cF9>U32</span><span class=cF0> temp;
-<a name="l163"></a>
-<a name="l164"></a>    E1000MMIOWrite(E1000_REG_EERD, </span><span class=cFE>1</span><span class=cF0> | word &lt;&lt; </span><span class=cFE>8</span><span class=cF0>);
-<a name="l165"></a>
-<a name="l166"></a>    </span><span class=cF1>while</span><span class=cF0> (!</span><span class=cF7>(</span><span class=cF0>(temp = E1000MMIORead</span><span class=cF7>(</span><span class=cF0>E1000_REG_EERD</span><span class=cF7>)</span><span class=cF0>) &amp; (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; </span><span class=cFE>4</span><span class=cF0>)</span><span class=cF7>)</span><span class=cF0>)
-<a name="l167"></a>        </span><span class=cF5>Sleep</span><span class=cF0>(</span><span class=cFE>1</span><span class=cF0>);
-<a name="l168"></a>
-<a name="l169"></a>    data = (temp &gt;&gt; </span><span class=cFE>16</span><span class=cF0>) &amp; </span><span class=cFE>0xFFFF</span><span class=cF0>;
-<a name="l170"></a>    </span><span class=cF1>return</span><span class=cF0> data;
-<a name="l171"></a>}
-<a name="l172"></a>
-<a name="l173"></a></span><span class=cF1>U0</span><span class=cF0> E1000MACGet()
-<a name="l174"></a>{
-<a name="l175"></a>    </span><span class=cF9>I64</span><span class=cF0> i;
-<a name="l176"></a>    </span><span class=cF9>U16</span><span class=cF0> mac;
-<a name="l177"></a>
-<a name="l178"></a>    NetLog(</span><span class=cF6>&quot;E1000 GET MAC: Getting VM MAC.&quot;</span><span class=cF0>);
-<a name="l179"></a>
-<a name="l180"></a>    </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i &lt; </span><span class=cFE>3</span><span class=cF0>; i++)
-<a name="l181"></a>    </span><span class=cF7>{</span><span class=cF0>
-<a name="l182"></a>        mac = E1000EEPROMRead(i);
-<a name="l183"></a>        e1000.mac_address[</span><span class=cFE>2</span><span class=cF0>*i]   = mac &amp; </span><span class=cFE>0xFF</span><span class=cF0>;
-<a name="l184"></a>        e1000.mac_address[</span><span class=cFE>2</span><span class=cF0>*i+</span><span class=cFE>1</span><span class=cF0>] = (mac &gt;&gt; </span><span class=cFE>8</span><span class=cF0>) &amp; </span><span class=cFE>0xFF</span><span class=cF0>;
-<a name="l185"></a>        NetLog(</span><span class=cF6>&quot; %02X %02X&quot;</span><span class=cF0>, mac.u8[</span><span class=cFE>0</span><span class=cF0>], mac.u8[</span><span class=cFE>1</span><span class=cF0>]);
-<a name="l186"></a>    </span><span class=cF7>}</span><span class=cF0>
-<a name="l187"></a>    
-<a name="l188"></a>}
-<a name="l189"></a>
-<a name="l190"></a></span><span class=cF1>U0</span><span class=cF0> EthernetFrameFinish(</span><span class=cF9>I64</span><span class=cF0> de_index)
-<a name="l191"></a>{</span><span class=cF2>//Alias for driver Finish TX function.</span><span class=cF0>
-<a name="l192"></a>    </span><span class=cF2>//E1000TransmitPacketFinish(de_index);</span><span class=cF0>
-<a name="l193"></a>    </span><span class=cF1>no_warn</span><span class=cF0> de_index;
-<a name="l194"></a>    NetErr(</span><span class=cF6>&quot;TODO E1000&quot;</span><span class=cF0>);
-<a name="l195"></a>}
-<a name="l196"></a>
-<a name="l197"></a></span><span class=cF2>/*</span><span class=cF0>
-<a name="l198"></a></span><span class=cF2>U0 PCIInterruptsReroute(I64 base)</span><span class=cF0>
-<a name="l199"></a></span><span class=cF2>{ // todo: comments explaining process, maybe better var names</span><span class=cF0>
-<a name="l200"></a>    </span><span class=cF2>I64</span><span class=cF0> </span><span class=cF2> i;</span><span class=cF0>
-<a name="l201"></a>    </span><span class=cF2>U8</span><span class=cF0>  </span><span class=cF2>*da = dev.uncached_alias + IOAPIC_REG;</span><span class=cF0>
-<a name="l202"></a>    </span><span class=cF2>U32 *_d = dev.uncached_alias + IOAPIC_DATA;</span><span class=cF0>
-<a name="l203"></a>
-<a name="l204"></a>    </span><span class=cF2>for (i = 0; i &lt; 4; i++)</span><span class=cF0>
-<a name="l205"></a>    </span><span class=cF2>{</span><span class=cF0>
-<a name="l206"></a>        </span><span class=cF2>*da = IOREDTAB + i * 2 + 1;</span><span class=cF0>
-<a name="l207"></a>        </span><span class=cF2>*_d = dev.mp_apic_ids[INT_DEST_CPU] &lt;&lt; 24;</span><span class=cF0>
-<a name="l208"></a>        </span><span class=cF2>*da = IOREDTAB + i * 2;</span><span class=cF0>
-<a name="l209"></a>        </span><span class=cF2>*_d = 0x4000 + base + i;</span><span class=cF0>
-<a name="l210"></a>    </span><span class=cF2>}</span><span class=cF0>
-<a name="l211"></a></span><span class=cF2>}</span><span class=cF0>
-<a name="l212"></a>
+<a name="l126"></a>
+<a name="l127"></a>} e1000; </span><span class=cF2>// e1000 is the global variable we store all of this into.</span><span class=cF0>
+<a name="l128"></a>
+<a name="l129"></a></span><span class=cF9>CPCIDev</span><span class=cF0> *E1000PCIDevFind()
+<a name="l130"></a>{</span><span class=cF2>// Find and return E1000 card as a CPCIDev pointer.</span><span class=cF0>
+<a name="l131"></a>
+<a name="l132"></a>    </span><span class=cF9>CPCIDev</span><span class=cF0> *pci = </span><span class=cF5>PCIDevFind</span><span class=cF0>(</span><span class=cF3>PCIC_NETWORK</span><span class=cF0>,, PCIV_E1000);
+<a name="l133"></a>
+<a name="l134"></a>    </span><span class=cF1>if</span><span class=cF0> (!pci)
+<a name="l135"></a>        </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>NULL</span><span class=cF0>;
+<a name="l136"></a>
+<a name="l137"></a>    </span><span class=cF5>ClassRep</span><span class=cF0>(pci);
+<a name="l138"></a>
+<a name="l139"></a>    </span><span class=cF1>switch</span><span class=cF0> (pci-&gt;device_id)
+<a name="l140"></a>    </span><span class=cF7>{</span><span class=cF0>
+<a name="l141"></a>        </span><span class=cF1>case</span><span class=cF0> PCID_82545EM:
+<a name="l142"></a>            </span><span class=cF1>break</span><span class=cF0>;
+<a name="l143"></a>
+<a name="l144"></a>        </span><span class=cF1>default</span><span class=cF0>:
+<a name="l145"></a>            pci = </span><span class=cF3>NULL</span><span class=cF0>;
+<a name="l146"></a>    </span><span class=cF7>}</span><span class=cF0>
+<a name="l147"></a>
+<a name="l148"></a>    </span><span class=cF1>return</span><span class=cF0> pci;
+<a name="l149"></a>}
+<a name="l150"></a>
+<a name="l151"></a></span><span class=cF9>U32</span><span class=cF0> E1000MMIORead(</span><span class=cF9>U32</span><span class=cF0> </span><span class=cF1>offset</span><span class=cF0>)
+<a name="l152"></a>{
+<a name="l153"></a>    </span><span class=cF9>U32</span><span class=cF0> *val = e1000.mmio_address + </span><span class=cF1>offset</span><span class=cF0>;
+<a name="l154"></a>
+<a name="l155"></a>    </span><span class=cF1>return</span><span class=cF0> *val;
+<a name="l156"></a>}
+<a name="l157"></a>
+<a name="l158"></a></span><span class=cF1>U0</span><span class=cF0> E1000MMIOWrite(</span><span class=cF9>U32</span><span class=cF0> </span><span class=cF1>offset</span><span class=cF0>, </span><span class=cF9>U32</span><span class=cF0> val)
+<a name="l159"></a>{
+<a name="l160"></a>    </span><span class=cF9>U32</span><span class=cF0> *addr = e1000.mmio_address + </span><span class=cF1>offset</span><span class=cF0>;
+<a name="l161"></a>
+<a name="l162"></a>    *addr = val;
+<a name="l163"></a>}
+<a name="l164"></a>
+<a name="l165"></a></span><span class=cF9>U16</span><span class=cF0> E1000EEPROMRead(</span><span class=cF1>U8</span><span class=cF0> word)
+<a name="l166"></a>{ </span><span class=cF2>// word arg is which U16 to read</span><span class=cF0>
+<a name="l167"></a>    </span><span class=cF9>U16</span><span class=cF0> data;
+<a name="l168"></a>    </span><span class=cF9>U32</span><span class=cF0> temp;
+<a name="l169"></a>
+<a name="l170"></a>    E1000MMIOWrite(E1000_REG_EERD, </span><span class=cFE>1</span><span class=cF0> | word &lt;&lt; </span><span class=cFE>8</span><span class=cF0>);
+<a name="l171"></a>
+<a name="l172"></a>    </span><span class=cF1>while</span><span class=cF0> (!</span><span class=cF7>(</span><span class=cF0>(temp = E1000MMIORead</span><span class=cF7>(</span><span class=cF0>E1000_REG_EERD</span><span class=cF7>)</span><span class=cF0>) &amp; (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; </span><span class=cFE>4</span><span class=cF0>)</span><span class=cF7>)</span><span class=cF0>)
+<a name="l173"></a>        </span><span class=cF5>Sleep</span><span class=cF0>(</span><span class=cFE>1</span><span class=cF0>);
+<a name="l174"></a>
+<a name="l175"></a>    data = (temp &gt;&gt; </span><span class=cFE>16</span><span class=cF0>) &amp; </span><span class=cFE>0xFFFF</span><span class=cF0>;
+<a name="l176"></a>    </span><span class=cF1>return</span><span class=cF0> data;
+<a name="l177"></a>}
+<a name="l178"></a>
+<a name="l179"></a></span><span class=cF1>U0</span><span class=cF0> E1000MACGet()
+<a name="l180"></a>{
+<a name="l181"></a>    </span><span class=cF9>I64</span><span class=cF0> i;
+<a name="l182"></a>    </span><span class=cF9>U16</span><span class=cF0> mac;
+<a name="l183"></a>
+<a name="l184"></a>    NetLog(</span><span class=cF6>&quot;E1000 MAC GET: Getting MAC Address.&quot;</span><span class=cF0>);
+<a name="l185"></a>
+<a name="l186"></a>    </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i &lt; </span><span class=cFE>3</span><span class=cF0>; i++)
+<a name="l187"></a>    </span><span class=cF7>{</span><span class=cF0>
+<a name="l188"></a>        mac = E1000EEPROMRead(i);
+<a name="l189"></a>        e1000.mac_address[</span><span class=cFE>2</span><span class=cF0>*i]   = mac &amp; </span><span class=cFE>0xFF</span><span class=cF0>;
+<a name="l190"></a>        e1000.mac_address[</span><span class=cFE>2</span><span class=cF0>*i+</span><span class=cFE>1</span><span class=cF0>] = (mac &gt;&gt; </span><span class=cFE>8</span><span class=cF0>) &amp; </span><span class=cFE>0xFF</span><span class=cF0>;
+<a name="l191"></a>        NetLog(</span><span class=cF6>&quot; %02X %02X&quot;</span><span class=cF0>, mac.u8[</span><span class=cFE>0</span><span class=cF0>], mac.u8[</span><span class=cFE>1</span><span class=cF0>]);
+<a name="l192"></a>    </span><span class=cF7>}</span><span class=cF0>
+<a name="l193"></a>    
+<a name="l194"></a>}
+<a name="l195"></a>
+<a name="l196"></a></span><span class=cF9>I64</span><span class=cF0> E1000PacketReceive(</span><span class=cF1>U8</span><span class=cF0> **packet_buffer_out, </span><span class=cF9>U16</span><span class=cF0> *packet_length_out)
+<a name="l197"></a>{
+<a name="l198"></a>    </span><span class=cF9>I64</span><span class=cF0> de_index = e1000.current_rx_de_index;
+<a name="l199"></a>    CE1000DescriptorEntryRX *entry = &amp;e1000.rx_de_buffer[de_index * </span><span class=cF1>sizeof</span><span class=cF0>(CE1000DescriptorEntryRX)];
+<a name="l200"></a>    </span><span class=cF1>Bool</span><span class=cF0> drop = </span><span class=cF3>FALSE</span><span class=cF0>;
+<a name="l201"></a>
+<a name="l202"></a>    </span><span class=cF1>if</span><span class=cF0> (entry-&gt;length &lt; </span><span class=cFE>60</span><span class=cF0>)
+<a name="l203"></a>    </span><span class=cF7>{</span><span class=cF0>
+<a name="l204"></a>        NetErr(</span><span class=cF6>&quot;E1000 PACKET RECEIVE: Short Packet&quot;</span><span class=cF0>);
+<a name="l205"></a>        drop = </span><span class=cF3>TRUE</span><span class=cF0>;
+<a name="l206"></a>    </span><span class=cF7>}</span><span class=cF0>
+<a name="l207"></a>
+<a name="l208"></a>    </span><span class=cF1>if</span><span class=cF0> (entry-&gt;status &amp; </span><span class=cF7>(</span><span class=cFE>1</span><span class=cF0> &lt;&lt; </span><span class=cFE>1</span><span class=cF7>)</span><span class=cF0>) </span><span class=cF2>// EOP ?? TODO #define</span><span class=cF0>
+<a name="l209"></a>    </span><span class=cF7>{</span><span class=cF0>
+<a name="l210"></a>        NetErr(</span><span class=cF6>&quot;E1000 PACKET RECEIVE: No EOP Set&quot;</span><span class=cF0>);
+<a name="l211"></a>        drop = </span><span class=cF3>TRUE</span><span class=cF0>;
+<a name="l212"></a>    </span><span class=cF7>}</span><span class=cF0>
 <a name="l213"></a>
-<a name="l214"></a></span><span class=cF2>U0 E1000InterruptsSetup()</span><span class=cF0>
-<a name="l215"></a></span><span class=cF2>{</span><span class=cF0>
-<a name="l216"></a></span><span class=cF2>//</span><span class=cF0>  </span><span class=cF2>PCIInterruptsReroute(I_E1000);</span><span class=cF0>
-<a name="l217"></a>    </span><span class=cF2>NetErr(&quot;TODO E1000&quot;);</span><span class=cF0>
-<a name="l218"></a></span><span class=cF2>}</span><span class=cF0>
-<a name="l219"></a></span><span class=cF2>*/</span><span class=cF0>
-<a name="l220"></a>
-<a name="l221"></a></span><span class=cF1>U0</span><span class=cF0> E1000RXInit()
-<a name="l222"></a>{
-<a name="l223"></a>    </span><span class=cF9>I64</span><span class=cF0> de_index;
-<a name="l224"></a>
-<a name="l225"></a>    e1000.rx_de_buffer_phys = </span><span class=cF5>CAllocAligned</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CE1000DescriptorEntryRX</span><span class=cF7>)</span><span class=cF0> * E1000_RX_BUFF_COUNT,
-<a name="l226"></a>                                            </span><span class=cFE>16</span><span class=cF0>, 
-<a name="l227"></a>                                            </span><span class=cF5>Fs</span><span class=cF0>-&gt;code_heap);
-<a name="l228"></a>
-<a name="l229"></a>    e1000.rx_de_buffer = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + e1000.rx_de_buffer_phys;
-<a name="l230"></a>
-<a name="l231"></a>    e1000.rx_buffer_addr_phys = </span><span class=cF5>CAlloc</span><span class=cF0>(ETHERNET_FRAME_SIZE * E1000_RX_BUFF_COUNT, </span><span class=cF5>Fs</span><span class=cF0>-&gt;code_heap);
+<a name="l214"></a>    </span><span class=cF1>if</span><span class=cF0> (entry-&gt;errors)
+<a name="l215"></a>    </span><span class=cF7>{</span><span class=cF0>
+<a name="l216"></a>        NetErr(</span><span class=cF6>&quot;E1000 PACKET RECEIVE: RX DE Error Bits Set&quot;</span><span class=cF0>);
+<a name="l217"></a>        drop = </span><span class=cF3>TRUE</span><span class=cF0>;
+<a name="l218"></a>    </span><span class=cF7>}</span><span class=cF0>
+<a name="l219"></a>
+<a name="l220"></a>    e1000.current_rx_de_index = (e1000.current_rx_de_index + </span><span class=cFE>1</span><span class=cF0>) &amp; (E1000_RX_BUFF_COUNT - </span><span class=cFE>1</span><span class=cF0>);
+<a name="l221"></a>
+<a name="l222"></a>    </span><span class=cF1>if</span><span class=cF0> (!drop)
+<a name="l223"></a>    </span><span class=cF7>{</span><span class=cF0>
+<a name="l224"></a>        *packet_buffer_out = entry-&gt;address;
+<a name="l225"></a>        *packet_length_out = entry-&gt;length;
+<a name="l226"></a>    </span><span class=cF7>}</span><span class=cF0>
+<a name="l227"></a>    </span><span class=cF1>else</span><span class=cF0>
+<a name="l228"></a>    </span><span class=cF7>{</span><span class=cF0>
+<a name="l229"></a>        NetErr(</span><span class=cF6>&quot;E1000 PACKET RECEIVE: Dropping packet.&quot;</span><span class=cF0>);
+<a name="l230"></a>        de_index = -</span><span class=cFE>1</span><span class=cF0>;
+<a name="l231"></a>    </span><span class=cF7>}</span><span class=cF0>
 <a name="l232"></a>
-<a name="l233"></a>    e1000.rx_buffer_addr = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + e1000.rx_buffer_addr_phys;
-<a name="l234"></a>
-<a name="l235"></a>    </span><span class=cF2>// iterate de's and make packet buffers for each</span><span class=cF0>
-<a name="l236"></a>    CE1000DescriptorEntryRX *entry = e1000.rx_de_buffer;
-<a name="l237"></a>    </span><span class=cF1>for</span><span class=cF0> (de_index = </span><span class=cFE>0</span><span class=cF0>; de_index &lt; E1000_RX_BUFF_COUNT; de_index++)
-<a name="l238"></a>    </span><span class=cF7>{</span><span class=cF0>
-<a name="l239"></a>        entry-&gt;address = e1000.rx_buffer_addr + de_index * ETHERNET_FRAME_SIZE; </span><span class=cF2>// is this right? might need to change ?..</span><span class=cF0>
-<a name="l240"></a>                                                                                </span><span class=cF2>// 01000101 MAlloc's 8208 for each DE</span><span class=cF0>
-<a name="l241"></a></span><span class=cF2>//</span><span class=cF0>      </span><span class=cF2>PCNetDescriptorEntryInit(&amp;entry[de_index],</span><span class=cF0>
-<a name="l242"></a></span><span class=cF2>//</span><span class=cF0>                              </span><span class=cF2> pcnet.rx_buffer_addr + de_index * ETHERNET_FRAME_SIZE,</span><span class=cF0>
-<a name="l243"></a></span><span class=cF2>//</span><span class=cF0>                              </span><span class=cF2> TRUE); // TRUE for is_rx.</span><span class=cF0>
-<a name="l244"></a>    </span><span class=cF7>}</span><span class=cF0>
-<a name="l245"></a>
-<a name="l246"></a>    </span><span class=cF2>// setup rx de ring buffer</span><span class=cF0>
-<a name="l247"></a>    E1000MMIOWrite(E1000_REG_RDBAH, e1000.rx_de_buffer &gt;&gt; </span><span class=cFE>32</span><span class=cF0>);          </span><span class=cF2>// should we be using uncached addr here ?</span><span class=cF0>
-<a name="l248"></a>    E1000MMIOWrite(E1000_REG_RDBAL, e1000.rx_de_buffer &amp; </span><span class=cFE>0xFFFFFFFF</span><span class=cF0>);
-<a name="l249"></a>
-<a name="l250"></a>    </span><span class=cF2>// set receive buffer length</span><span class=cF0>
-<a name="l251"></a>    E1000MMIOWrite(E1000_REG_RDLEN, E1000_RX_BUFF_COUNT * </span><span class=cFE>16</span><span class=cF0>);
-<a name="l252"></a>
-<a name="l253"></a>    </span><span class=cF2>// set head tail pointers</span><span class=cF0>
-<a name="l254"></a>    E1000MMIOWrite(E1000_REG_RDH, </span><span class=cFE>0</span><span class=cF0>);
-<a name="l255"></a>    E1000MMIOWrite(E1000_REG_RDT, E1000_RX_BUFF_COUNT);
-<a name="l256"></a>
-<a name="l257"></a>    </span><span class=cF2>// set receive control reg</span><span class=cF0>
-<a name="l258"></a>    E1000MMIOWrite(E1000_REG_RCTL,  E1000_RCTLF_SBP         |
-<a name="l259"></a></span><span class=cF2>//</span><span class=cF0>                                  </span><span class=cF2>E1000_RCTLF_UPE</span><span class=cF0>         </span><span class=cF2>|</span><span class=cF0>
-<a name="l260"></a></span><span class=cF2>//</span><span class=cF0>                                  </span><span class=cF2>E1000_RCTLF_RDMTS_HALF</span><span class=cF0>  </span><span class=cF2>|</span><span class=cF0>
-<a name="l261"></a></span><span class=cF2>//</span><span class=cF0>                                  </span><span class=cF2>E1000_RCTLF_BSIZE_2048</span><span class=cF0>  </span><span class=cF2>|</span><span class=cF0>
-<a name="l262"></a></span><span class=cF2>//</span><span class=cF0>                                  </span><span class=cF2>E1000_RCTLF_MPE</span><span class=cF0>         </span><span class=cF2>|</span><span class=cF0>
-<a name="l263"></a>                                    E1000_RCTLF_SECRC       |
-<a name="l264"></a>                                    E1000_RCTLF_LPE         |
-<a name="l265"></a>                                    E1000_RCTLF_BAM);
-<a name="l266"></a>}
-<a name="l267"></a>
-<a name="l268"></a></span><span class=cF1>U0</span><span class=cF0> E1000TXInit()
-<a name="l269"></a>{
-<a name="l270"></a>    e1000.tx_de_buffer_phys = </span><span class=cF5>CAllocAligned</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CE1000DescriptorEntryTX</span><span class=cF7>)</span><span class=cF0> * E1000_TX_BUFF_COUNT,
-<a name="l271"></a>                                            </span><span class=cFE>16</span><span class=cF0>, 
-<a name="l272"></a>                                            </span><span class=cF5>Fs</span><span class=cF0>-&gt;code_heap);
-<a name="l273"></a>
-<a name="l274"></a>    e1000.tx_de_buffer = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + e1000.tx_de_buffer_phys;
-<a name="l275"></a>
-<a name="l276"></a>    e1000.tx_buffer_addr_phys = </span><span class=cF5>CAlloc</span><span class=cF0>(ETHERNET_FRAME_SIZE * E1000_TX_BUFF_COUNT, </span><span class=cF5>Fs</span><span class=cF0>-&gt;code_heap);
+<a name="l233"></a>    </span><span class=cF1>return</span><span class=cF0> de_index;
+<a name="l234"></a>}
+<a name="l235"></a>
+<a name="l236"></a></span><span class=cF1>U0</span><span class=cF0> E1000ReceivePacketRelease(</span><span class=cF9>I64</span><span class=cF0> de_index)
+<a name="l237"></a>{
+<a name="l238"></a>    CE1000DescriptorEntryRX *entry = &amp;e1000.rx_de_buffer[de_index * </span><span class=cF1>sizeof</span><span class=cF0>(CE1000DescriptorEntryRX)];
+<a name="l239"></a>    entry-&gt;status = </span><span class=cFE>0</span><span class=cF0>;
+<a name="l240"></a>
+<a name="l241"></a>    E1000MMIOWrite(E1000_REG_RDT, e1000.current_rx_de_index);
+<a name="l242"></a>}
+<a name="l243"></a>
+<a name="l244"></a></span><span class=cF1>Bool</span><span class=cF0> E1000DriverOwnsRX(CE1000DescriptorEntryRX *entry)
+<a name="l245"></a>{
+<a name="l246"></a>    </span><span class=cF1>return</span><span class=cF0> </span><span class=cF5>Bt</span><span class=cF0>(&amp;entry-&gt;status, </span><span class=cFE>0</span><span class=cF0>); </span><span class=cF2>// ?? TODO #define</span><span class=cF0>
+<a name="l247"></a>}
+<a name="l248"></a>
+<a name="l249"></a></span><span class=cF9>I64</span><span class=cF0> E1000TransmitPacketAllocate(</span><span class=cF1>U8</span><span class=cF0> **packet_buffer_out, </span><span class=cF9>I64</span><span class=cF0> length)
+<a name="l250"></a>{   </span><span class=cF9>I64</span><span class=cF0> de_index = e1000.current_tx_de_index;
+<a name="l251"></a>
+<a name="l252"></a>    CE1000DescriptorEntryTX *entry = &amp;e1000.tx_de_buffer[de_index * </span><span class=cF1>sizeof</span><span class=cF0>(CE1000DescriptorEntryTX)];
+<a name="l253"></a>
+<a name="l254"></a>    *packet_buffer_out = e1000.tx_buffer_addr + de_index * ETHERNET_FRAME_SIZE;
+<a name="l255"></a>
+<a name="l256"></a>    </span><span class=cF5>MemSet</span><span class=cF0>(*packet_buffer_out, </span><span class=cFE>0</span><span class=cF0>, ETHERNET_FRAME_SIZE); </span><span class=cF2>// Clear buffer contents in advance.</span><span class=cF0>
+<a name="l257"></a>
+<a name="l258"></a>    entry-&gt;address  = *packet_buffer_out;
+<a name="l259"></a>    entry-&gt;length   = length;
+<a name="l260"></a>    entry-&gt;cmd      = (</span><span class=cFE>1</span><span class=cF0> &lt;&lt; </span><span class=cFE>3</span><span class=cF0>) | </span><span class=cFE>3</span><span class=cF0>; </span><span class=cF2>// ??? TODO #define</span><span class=cF0>
+<a name="l261"></a>
+<a name="l262"></a>    NetLog(</span><span class=cF6>&quot;E1000 ALLOCATE TX PACKET: de_index: %X.&quot;</span><span class=cF0>, de_index);
+<a name="l263"></a>    </span><span class=cF1>return</span><span class=cF0> de_index;
+<a name="l264"></a>}
+<a name="l265"></a>
+<a name="l266"></a></span><span class=cF1>U0</span><span class=cF0> E1000TransmitPacketFinish(</span><span class=cF9>I64</span><span class=cF0> de_index)
+<a name="l267"></a>{
+<a name="l268"></a>    CE1000DescriptorEntryTX *entry = &amp;e1000.tx_de_buffer[de_index * </span><span class=cF1>sizeof</span><span class=cF0>(CE1000DescriptorEntryTX)];
+<a name="l269"></a>
+<a name="l270"></a>    e1000.current_tx_de_index = (e1000.current_tx_de_index + </span><span class=cFE>1</span><span class=cF0>) &amp; (E1000_TX_BUFF_COUNT - </span><span class=cFE>1</span><span class=cF0>);
+<a name="l271"></a>    E1000MMIOWrite(E1000_REG_TDT, e1000.current_tx_de_index);
+<a name="l272"></a>
+<a name="l273"></a>    </span><span class=cF5>ClassRep</span><span class=cF0>(entry);
+<a name="l274"></a>
+<a name="l275"></a>    </span><span class=cF1>while</span><span class=cF0> (!</span><span class=cF7>(</span><span class=cF0>entry-&gt;sta &amp; </span><span class=cFE>0xF</span><span class=cF7>)</span><span class=cF0>) </span><span class=cF2>// ???</span><span class=cF0>
+<a name="l276"></a>        </span><span class=cF5>Yield</span><span class=cF0>;
 <a name="l277"></a>
-<a name="l278"></a>    e1000.tx_buffer_addr = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + e1000.tx_buffer_addr_phys;
-<a name="l279"></a>
-<a name="l280"></a>    </span><span class=cF2>// setup tx de ring buffer</span><span class=cF0>
-<a name="l281"></a>    E1000MMIOWrite(E1000_REG_TDBAH, e1000.tx_de_buffer &gt;&gt; </span><span class=cFE>32</span><span class=cF0>);          </span><span class=cF2>// should we be using uncached addr here ?</span><span class=cF0>
-<a name="l282"></a>    E1000MMIOWrite(E1000_REG_TDBAL, e1000.tx_de_buffer &amp; </span><span class=cFE>0xFFFFFFFF</span><span class=cF0>);
-<a name="l283"></a>
-<a name="l284"></a>    </span><span class=cF2>// set tx buffer length</span><span class=cF0>
-<a name="l285"></a>    E1000MMIOWrite(E1000_REG_TDLEN, E1000_TX_BUFF_COUNT * </span><span class=cFE>16</span><span class=cF0>);
-<a name="l286"></a>
-<a name="l287"></a>    </span><span class=cF2>// set head tail pointers</span><span class=cF0>
-<a name="l288"></a>    E1000MMIOWrite(E1000_REG_TDH, </span><span class=cFE>0</span><span class=cF0>);
-<a name="l289"></a>    E1000MMIOWrite(E1000_REG_TDT, E1000_RX_BUFF_COUNT);
-<a name="l290"></a>
-<a name="l291"></a>    </span><span class=cF2>// set transmit control reg</span><span class=cF0>
-<a name="l292"></a>    E1000MMIOWrite(E1000_REG_TCTL, E1000_TCTLF_EN | E1000_TCTLF_PSP);
-<a name="l293"></a>
-<a name="l294"></a>}
-<a name="l295"></a>
+<a name="l278"></a>    NetLog(</span><span class=cF6>&quot;E1000 FINISH TX PACKET: TX DE index: %X.&quot;</span><span class=cF0>, de_index);
+<a name="l279"></a>}
+<a name="l280"></a>
+<a name="l281"></a></span><span class=cF1>U0</span><span class=cF0> EthernetFrameFinish(</span><span class=cF9>I64</span><span class=cF0> de_index)
+<a name="l282"></a>{</span><span class=cF2>//Alias for driver Finish TX function.</span><span class=cF0>
+<a name="l283"></a>    E1000TransmitPacketFinish(de_index);
+<a name="l284"></a>}
+<a name="l285"></a>
+<a name="l286"></a></span><span class=cF1>interrupt</span><span class=cF0> </span><span class=cF1>U0</span><span class=cF0> E1000IRQ()
+<a name="l287"></a>{ </span><span class=cF2>// TODO need #defines</span><span class=cF0>
+<a name="l288"></a>    </span><span class=cF9>U32</span><span class=cF0> icr = E1000MMIORead(</span><span class=cFE>0xC0</span><span class=cF0>); </span><span class=cF2>// ???</span><span class=cF0>
+<a name="l289"></a>    </span><span class=cF1>Bool</span><span class=cF0> poll = </span><span class=cF3>FALSE</span><span class=cF0>;
+<a name="l290"></a>    CE1000DescriptorEntryRX *entry = e1000.rx_de_buffer;
+<a name="l291"></a>    </span><span class=cF1>U8</span><span class=cF0> *packet_buffer;
+<a name="l292"></a>    </span><span class=cF9>U16</span><span class=cF0> packet_length;
+<a name="l293"></a>    </span><span class=cF9>I64</span><span class=cF0> de_index;
+<a name="l294"></a>
+<a name="l295"></a>    icr &amp;= ~</span><span class=cFE>3</span><span class=cF0>; </span><span class=cF2>// ??</span><span class=cF0>
 <a name="l296"></a>
-<a name="l297"></a></span><span class=cF1>U0</span><span class=cF0> E1000Init()
-<a name="l298"></a>{
-<a name="l299"></a>    </span><span class=cF9>I64</span><span class=cF0> i;
-<a name="l300"></a>
-<a name="l301"></a>    </span><span class=cF5>MemSet</span><span class=cF0>(&amp;e1000, </span><span class=cFE>0</span><span class=cF0>, </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CE1000</span><span class=cF7>)</span><span class=cF0>); </span><span class=cF2>// e1000 global var will hold member data the driver uses often.</span><span class=cF0>
-<a name="l302"></a>    </span><span class=cF6>&quot;\nE1000 driver WIP\n\n&quot;</span><span class=cF0>;
-<a name="l303"></a>
-<a name="l304"></a>    e1000.pci = E1000PCIDevFind;
-<a name="l305"></a>    </span><span class=cF1>if</span><span class=cF0> (!e1000.pci)
-<a name="l306"></a>        </span><span class=cF1>return</span><span class=cF0>; </span><span class=cF2>// if we don't find the card, quit.</span><span class=cF0>
-<a name="l307"></a>
-<a name="l308"></a>
-<a name="l309"></a>    e1000.mmio_address = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + e1000.pci-&gt;base[</span><span class=cFE>0</span><span class=cF0>] &amp; ~</span><span class=cFE>0xF</span><span class=cF0>;
-<a name="l310"></a>    </span><span class=cF2>// Assuming card supports MMIO... lower 4 bits are hardwired zero (?)</span><span class=cF0>
-<a name="l311"></a>
-<a name="l312"></a>    </span><span class=cF6>&quot;\nMMIO address: 0x%0X\n&quot;</span><span class=cF0>, e1000.mmio_address;
+<a name="l297"></a>    </span><span class=cF1>if</span><span class=cF0> (icr &amp; </span><span class=cF7>(</span><span class=cFE>1</span><span class=cF0> &lt;&lt; </span><span class=cFE>2</span><span class=cF7>)</span><span class=cF0>) </span><span class=cF2>// ?? 'link status change' ??</span><span class=cF0>
+<a name="l298"></a>    </span><span class=cF7>{</span><span class=cF0>
+<a name="l299"></a>        icr &amp;= ~(</span><span class=cFE>1</span><span class=cF0> &lt;&lt; </span><span class=cFE>2</span><span class=cF0>);
+<a name="l300"></a>        E1000MMIOWrite(E1000_REG_CTRL, E1000MMIORead</span><span class=cF7>(</span><span class=cF0>E1000_REG_CTRL</span><span class=cF7>)</span><span class=cF0> | E1000_CTRLF_SLU);
+<a name="l301"></a>    </span><span class=cF7>}</span><span class=cF0>
+<a name="l302"></a>
+<a name="l303"></a>    </span><span class=cF1>if</span><span class=cF0> (icr &amp; </span><span class=cF7>(</span><span class=cFE>1</span><span class=cF0> &lt;&lt; </span><span class=cFE>6</span><span class=cF7>)</span><span class=cF0> || icr &amp; </span><span class=cF7>(</span><span class=cFE>1</span><span class=cF0> &lt;&lt; </span><span class=cFE>4</span><span class=cF7>)</span><span class=cF0>) </span><span class=cF2>// ?? 'rx underrun / min threshold' ??</span><span class=cF0>
+<a name="l304"></a>    </span><span class=cF7>{</span><span class=cF0>
+<a name="l305"></a>        icr = ~(</span><span class=cF7>(</span><span class=cFE>1</span><span class=cF0> &lt;&lt; </span><span class=cFE>6</span><span class=cF7>)</span><span class=cF0> | </span><span class=cF7>(</span><span class=cFE>1</span><span class=cF0> &lt;&lt; </span><span class=cFE>4</span><span class=cF7>)</span><span class=cF0>); </span><span class=cF2>// ??</span><span class=cF0>
+<a name="l306"></a>
+<a name="l307"></a>        poll = </span><span class=cF3>TRUE</span><span class=cF0>;
+<a name="l308"></a>    </span><span class=cF7>}</span><span class=cF0>
+<a name="l309"></a>
+<a name="l310"></a>    </span><span class=cF1>if</span><span class=cF0> (icr &amp; </span><span class=cF7>(</span><span class=cFE>1</span><span class=cF0> &lt;&lt; </span><span class=cFE>7</span><span class=cF7>)</span><span class=cF0>) </span><span class=cF2>// ?? 'packet pending?</span><span class=cF0>
+<a name="l311"></a>    </span><span class=cF7>{</span><span class=cF0>
+<a name="l312"></a>        icr &amp;= ~(</span><span class=cFE>1</span><span class=cF0> &lt;&lt; </span><span class=cFE>7</span><span class=cF0>);
 <a name="l313"></a>
-<a name="l314"></a>    </span><span class=cF2>// init rx/tx addrs? (linux)</span><span class=cF0>
-<a name="l315"></a>
-<a name="l316"></a>    </span><span class=cF2>// eeprom? MAC ?</span><span class=cF0>
-<a name="l317"></a>    E1000MACGet;
-<a name="l318"></a>
-<a name="l319"></a>    </span><span class=cF2>// setup link? (01000101's driver)</span><span class=cF0>
-<a name="l320"></a>    E1000MMIOWrite(E1000_REG_CTRL, E1000MMIORead</span><span class=cF7>(</span><span class=cF0>E1000_REG_CTRL</span><span class=cF7>)</span><span class=cF0> | E1000_CTRLF_SLU);
-<a name="l321"></a>
-<a name="l322"></a>    </span><span class=cF2>// zero out multicast hash? (linux)</span><span class=cF0>
-<a name="l323"></a>    </span><span class=cF2>// zero out multicast table array (01000101's driver)</span><span class=cF0>
-<a name="l324"></a>    </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i &lt; </span><span class=cFE>128</span><span class=cF0>; i++)
-<a name="l325"></a>        E1000MMIOWrite(E1000_REG_MTA + i*</span><span class=cFE>4</span><span class=cF0>, </span><span class=cFE>0</span><span class=cF0>);
-<a name="l326"></a>
-<a name="l327"></a>    </span><span class=cF2>// setup link? (linux)</span><span class=cF0>
-<a name="l328"></a>
-<a name="l329"></a>    </span><span class=cF2>// clear all statistics regs after link establish attempt (linux)</span><span class=cF0>
-<a name="l330"></a>
-<a name="l331"></a>    </span><span class=cF2>// enable &amp; clear existing interupts (01000101's driver)</span><span class=cF0>
-<a name="l332"></a>    E1000MMIOWrite(E1000_REG_IMS, </span><span class=cFE>0x1F6DC</span><span class=cF0>); </span><span class=cF2>// TODO: WHAT IS THIS</span><span class=cF0>
-<a name="l333"></a>    E1000MMIORead(</span><span class=cFE>0xC0</span><span class=cF0>); </span><span class=cF2>// TODO : WHAT IS THIS ???</span><span class=cF0>
-<a name="l334"></a>
-<a name="l335"></a>    </span><span class=cF2>// start rx tx?</span><span class=cF0>
-<a name="l336"></a>    E1000RXInit;
-<a name="l337"></a>    E1000TXInit;
-<a name="l338"></a>
-<a name="l339"></a>
-<a name="l340"></a>    NetErr(</span><span class=cF6>&quot;TODO E1000&quot;</span><span class=cF0>);
-<a name="l341"></a>    </span><span class=cF6>&quot;\n&quot;</span><span class=cF0>;
-<a name="l342"></a>    </span><span class=cF5>ClassRep</span><span class=cF0>(&amp;e1000);
-<a name="l343"></a>}
+<a name="l314"></a>        poll = </span><span class=cF3>TRUE</span><span class=cF0>;
+<a name="l315"></a>    </span><span class=cF7>}</span><span class=cF0>
+<a name="l316"></a>
+<a name="l317"></a>    </span><span class=cF1>if</span><span class=cF0> (poll)
+<a name="l318"></a>    </span><span class=cF7>{</span><span class=cF0>
+<a name="l319"></a>        </span><span class=cF1>while</span><span class=cF0> (E1000DriverOwnsRX</span><span class=cF7>(</span><span class=cF0>&amp;entry[e1000.current_rx_de_index]</span><span class=cF7>)</span><span class=cF0>)
+<a name="l320"></a>        {
+<a name="l321"></a>            NetLog(</span><span class=cF6>&quot;$BG,LTCYAN$$FG,WHITE$&quot;</span><span class=cF0>
+<a name="l322"></a>                   </span><span class=cF6>&quot;==== E1000 IRQ ====&quot;</span><span class=cF0>
+<a name="l323"></a>                   </span><span class=cF6>&quot;$BG$$FG$&quot;</span><span class=cF0>);
+<a name="l324"></a>
+<a name="l325"></a>            NetLog(</span><span class=cF6>&quot;$BD,CYAN$$FD,WHITE$&quot;</span><span class=cF0>
+<a name="l326"></a>                   </span><span class=cF6>&quot;E1000 IRQ: Saw owned RX DE index %d.&quot;</span><span class=cF0>, e1000.current_rx_de_index);
+<a name="l327"></a>
+<a name="l328"></a>            de_index = E1000PacketReceive(&amp;packet_buffer, &amp;packet_length);
+<a name="l329"></a>
+<a name="l330"></a>            </span><span class=cF1>if</span><span class=cF0> (de_index &gt;= </span><span class=cFE>0</span><span class=cF0>)
+<a name="l331"></a>            </span><span class=cF7>{</span><span class=cF0>
+<a name="l332"></a>                NetLog(</span><span class=cF6>&quot;E1000 IRQ: Pushing copy into Net Queue, releasing receive packet.&quot;</span><span class=cF0>);
+<a name="l333"></a>                NetQueuePush(packet_buffer, packet_length);
+<a name="l334"></a>                E1000ReceivePacketRelease(de_index);
+<a name="l335"></a>            </span><span class=cF7>}</span><span class=cF0>
+<a name="l336"></a>
+<a name="l337"></a>        NetLog(</span><span class=cF6>&quot;E1000 IRQ: Exiting.\n&quot;</span><span class=cF0>
+<a name="l338"></a>               </span><span class=cF6>&quot;$BD,WHITE$$FD,LTGRAY$&quot;</span><span class=cF0>
+<a name="l339"></a>               </span><span class=cF6>&quot;$BG,LTCYAN$$FG,WHITE$&quot;</span><span class=cF0>
+<a name="l340"></a>               </span><span class=cF6>&quot;===================&quot;</span><span class=cF0>
+<a name="l341"></a>               </span><span class=cF6>&quot;$BG$$FG$&quot;</span><span class=cF0>);
+<a name="l342"></a>        }
+<a name="l343"></a>    </span><span class=cF7>}</span><span class=cF0>
 <a name="l344"></a>
-<a name="l345"></a></span><span class=cF9>I64</span><span class=cF0> EthernetFrameAllocate(</span><span class=cF1>U8</span><span class=cF0> **packet_buffer_out,
-<a name="l346"></a>                          </span><span class=cF1>U8</span><span class=cF0> *source_address,
-<a name="l347"></a>                          </span><span class=cF1>U8</span><span class=cF0> *destination_address,
-<a name="l348"></a>                          </span><span class=cF9>U16</span><span class=cF0> ethertype,
-<a name="l349"></a>                          </span><span class=cF9>I64</span><span class=cF0> packet_length)
-<a name="l350"></a>{
-<a name="l351"></a>    </span><span class=cF1>no_warn</span><span class=cF0> packet_buffer_out, source_address, destination_address, ethertype, packet_length;
-<a name="l352"></a>    NetErr(</span><span class=cF6>&quot;TODO E1000&quot;</span><span class=cF0>);
-<a name="l353"></a>    </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
-<a name="l354"></a>}
-<a name="l355"></a>
-<a name="l356"></a></span><span class=cF1>U8</span><span class=cF0> *EthernetMACGet()
-<a name="l357"></a>{
-<a name="l358"></a>    </span><span class=cF1>return</span><span class=cF0> e1000.mac_address;
-<a name="l359"></a>}
-<a name="l360"></a>
-<a name="l361"></a></span><span class=cF1>U0</span><span class=cF0> NetStop()
-<a name="l362"></a>{
-<a name="l363"></a>
-<a name="l364"></a>}
-<a name="l365"></a>
-<a name="l366"></a></span><span class=cF1>U0</span><span class=cF0> NetStart()
-<a name="l367"></a>{
+<a name="l345"></a>
+<a name="l346"></a>
+<a name="l347"></a>    E1000MMIORead(</span><span class=cFE>0xC0</span><span class=cF0>); </span><span class=cF2>// ?? 'clear pending interrupts' ??</span><span class=cF0>
+<a name="l348"></a>
+<a name="l349"></a>    *(</span><span class=cFB>dev</span><span class=cF0>.uncached_alias + </span><span class=cF3>LAPIC_EOI</span><span class=cF0>)(</span><span class=cF9>U32</span><span class=cF0>*) = </span><span class=cFE>0</span><span class=cF0>;
+<a name="l350"></a>
+<a name="l351"></a>}
+<a name="l352"></a>
+<a name="l353"></a></span><span class=cF1>U0</span><span class=cF0> PCIInterruptsReroute(</span><span class=cF9>I64</span><span class=cF0> base)
+<a name="l354"></a>{ </span><span class=cF2>// todo: comments explaining process, maybe better var names</span><span class=cF0>
+<a name="l355"></a>    </span><span class=cF9>I64</span><span class=cF0>  i;
+<a name="l356"></a>    </span><span class=cF1>U8</span><span class=cF0>  *da = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + </span><span class=cF3>IOAPIC_REG</span><span class=cF0>;
+<a name="l357"></a>    </span><span class=cF9>U32</span><span class=cF0> *_d = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + </span><span class=cF3>IOAPIC_DATA</span><span class=cF0>;
+<a name="l358"></a>
+<a name="l359"></a>    </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i &lt; </span><span class=cFE>4</span><span class=cF0>; i++)
+<a name="l360"></a>    </span><span class=cF7>{</span><span class=cF0>
+<a name="l361"></a>        *da = </span><span class=cF3>IOREDTAB</span><span class=cF0> + i * </span><span class=cFE>2</span><span class=cF0> + </span><span class=cFE>1</span><span class=cF0>;
+<a name="l362"></a>        *_d = </span><span class=cFB>dev</span><span class=cF0>.mp_apic_ids[INT_DEST_CPU] &lt;&lt; </span><span class=cFE>24</span><span class=cF0>;
+<a name="l363"></a>        *da = </span><span class=cF3>IOREDTAB</span><span class=cF0> + i * </span><span class=cFE>2</span><span class=cF0>;
+<a name="l364"></a>        *_d = </span><span class=cFE>0x4000</span><span class=cF0> + base + i;
+<a name="l365"></a>    </span><span class=cF7>}</span><span class=cF0>
+<a name="l366"></a>}
+<a name="l367"></a>
 <a name="l368"></a>
-<a name="l369"></a>}
-<a name="l370"></a>
-<a name="l371"></a>E1000Init;</span></pre></body>
+<a name="l369"></a></span><span class=cF1>U0</span><span class=cF0> E1000InterruptsSetup()
+<a name="l370"></a>{ </span><span class=cF2>// .. ?</span><span class=cF0>
+<a name="l371"></a>    </span><span class=cF5>IntEntrySet</span><span class=cF0>(I_E1000_0, &amp;E1000IRQ);
+<a name="l372"></a>    </span><span class=cF5>IntEntrySet</span><span class=cF0>(I_E1000_1, &amp;E1000IRQ);
+<a name="l373"></a>    </span><span class=cF5>IntEntrySet</span><span class=cF0>(I_E1000_2, &amp;E1000IRQ);
+<a name="l374"></a>    </span><span class=cF5>IntEntrySet</span><span class=cF0>(I_E1000_3, &amp;E1000IRQ);
+<a name="l375"></a>    PCIInterruptsReroute(I_E1000_0);
+<a name="l376"></a>}
+<a name="l377"></a>
+<a name="l378"></a></span><span class=cF1>U0</span><span class=cF0> E1000InitRX()
+<a name="l379"></a>{
+<a name="l380"></a>    </span><span class=cF9>I64</span><span class=cF0> de_index;
+<a name="l381"></a>
+<a name="l382"></a>    e1000.rx_de_buffer_phys = </span><span class=cF5>CAllocAligned</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CE1000DescriptorEntryRX</span><span class=cF7>)</span><span class=cF0> * E1000_RX_BUFF_COUNT,
+<a name="l383"></a>                                            </span><span class=cFE>16</span><span class=cF0>, 
+<a name="l384"></a>                                            </span><span class=cF5>Fs</span><span class=cF0>-&gt;code_heap);
+<a name="l385"></a>
+<a name="l386"></a>    e1000.rx_de_buffer = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + e1000.rx_de_buffer_phys;
+<a name="l387"></a>
+<a name="l388"></a>    e1000.rx_buffer_addr_phys = </span><span class=cF5>CAlloc</span><span class=cF0>(ETHERNET_FRAME_SIZE * E1000_RX_BUFF_COUNT, </span><span class=cF5>Fs</span><span class=cF0>-&gt;code_heap);
+<a name="l389"></a>
+<a name="l390"></a>    e1000.rx_buffer_addr = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + e1000.rx_buffer_addr_phys;
+<a name="l391"></a>
+<a name="l392"></a>    </span><span class=cF2>// iterate de's and make packet buffers for each</span><span class=cF0>
+<a name="l393"></a>    CE1000DescriptorEntryRX *entry = e1000.rx_de_buffer;
+<a name="l394"></a>    </span><span class=cF1>for</span><span class=cF0> (de_index = </span><span class=cFE>0</span><span class=cF0>; de_index &lt; E1000_RX_BUFF_COUNT; de_index++)
+<a name="l395"></a>    </span><span class=cF7>{</span><span class=cF0>
+<a name="l396"></a>        entry-&gt;address = e1000.rx_buffer_addr + de_index * ETHERNET_FRAME_SIZE; </span><span class=cF2>// is this right? might need to change ?..</span><span class=cF0>
+<a name="l397"></a>                                                                                </span><span class=cF2>// 01000101 MAlloc's 8208 for each DE</span><span class=cF0>
+<a name="l398"></a></span><span class=cF2>//</span><span class=cF0>      </span><span class=cF2>PCNetDescriptorEntryInit(&amp;entry[de_index],</span><span class=cF0>
+<a name="l399"></a></span><span class=cF2>//</span><span class=cF0>                              </span><span class=cF2> pcnet.rx_buffer_addr + de_index * ETHERNET_FRAME_SIZE,</span><span class=cF0>
+<a name="l400"></a></span><span class=cF2>//</span><span class=cF0>                              </span><span class=cF2> TRUE); // TRUE for is_rx.</span><span class=cF0>
+<a name="l401"></a>    </span><span class=cF7>}</span><span class=cF0>
+<a name="l402"></a>
+<a name="l403"></a>    </span><span class=cF2>// setup rx de ring buffer</span><span class=cF0>
+<a name="l404"></a>    E1000MMIOWrite(E1000_REG_RDBAH, e1000.rx_de_buffer &gt;&gt; </span><span class=cFE>32</span><span class=cF0>);          </span><span class=cF2>// should we be using uncached addr here ?</span><span class=cF0>
+<a name="l405"></a>    E1000MMIOWrite(E1000_REG_RDBAL, e1000.rx_de_buffer &amp; </span><span class=cFE>0xFFFFFFFF</span><span class=cF0>);
+<a name="l406"></a>
+<a name="l407"></a>    </span><span class=cF2>// set receive buffer length</span><span class=cF0>
+<a name="l408"></a>    E1000MMIOWrite(E1000_REG_RDLEN, E1000_RX_BUFF_COUNT * </span><span class=cFE>16</span><span class=cF0>);
+<a name="l409"></a>
+<a name="l410"></a>    </span><span class=cF2>// set head tail pointers</span><span class=cF0>
+<a name="l411"></a>    E1000MMIOWrite(E1000_REG_RDH, </span><span class=cFE>0</span><span class=cF0>);
+<a name="l412"></a>    E1000MMIOWrite(E1000_REG_RDT, E1000_RX_BUFF_COUNT);
+<a name="l413"></a>
+<a name="l414"></a>    </span><span class=cF2>// set receive control reg</span><span class=cF0>
+<a name="l415"></a>    E1000MMIOWrite(E1000_REG_RCTL,  E1000_RCTLF_SBP         |
+<a name="l416"></a></span><span class=cF2>//</span><span class=cF0>                                  </span><span class=cF2>E1000_RCTLF_UPE</span><span class=cF0>         </span><span class=cF2>|</span><span class=cF0>
+<a name="l417"></a></span><span class=cF2>//</span><span class=cF0>                                  </span><span class=cF2>E1000_RCTLF_RDMTS_HALF</span><span class=cF0>  </span><span class=cF2>|</span><span class=cF0>
+<a name="l418"></a></span><span class=cF2>//</span><span class=cF0>                                  </span><span class=cF2>E1000_RCTLF_BSIZE_2048</span><span class=cF0>  </span><span class=cF2>|</span><span class=cF0>
+<a name="l419"></a></span><span class=cF2>//</span><span class=cF0>                                  </span><span class=cF2>E1000_RCTLF_MPE</span><span class=cF0>         </span><span class=cF2>|</span><span class=cF0>
+<a name="l420"></a>                                    E1000_RCTLF_SECRC       |
+<a name="l421"></a>                                    E1000_RCTLF_LPE         |
+<a name="l422"></a>                                    E1000_RCTLF_BAM);
+<a name="l423"></a>}
+<a name="l424"></a>
+<a name="l425"></a></span><span class=cF1>U0</span><span class=cF0> E1000InitTX()
+<a name="l426"></a>{
+<a name="l427"></a>    e1000.tx_de_buffer_phys = </span><span class=cF5>CAllocAligned</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CE1000DescriptorEntryTX</span><span class=cF7>)</span><span class=cF0> * E1000_TX_BUFF_COUNT,
+<a name="l428"></a>                                            </span><span class=cFE>16</span><span class=cF0>, 
+<a name="l429"></a>                                            </span><span class=cF5>Fs</span><span class=cF0>-&gt;code_heap);
+<a name="l430"></a>
+<a name="l431"></a>    e1000.tx_de_buffer = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + e1000.tx_de_buffer_phys;
+<a name="l432"></a>
+<a name="l433"></a>    e1000.tx_buffer_addr_phys = </span><span class=cF5>CAlloc</span><span class=cF0>(ETHERNET_FRAME_SIZE * E1000_TX_BUFF_COUNT, </span><span class=cF5>Fs</span><span class=cF0>-&gt;code_heap);
+<a name="l434"></a>
+<a name="l435"></a>    e1000.tx_buffer_addr = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + e1000.tx_buffer_addr_phys;
+<a name="l436"></a>
+<a name="l437"></a>    </span><span class=cF2>// setup tx de ring buffer</span><span class=cF0>
+<a name="l438"></a>    E1000MMIOWrite(E1000_REG_TDBAH, e1000.tx_de_buffer &gt;&gt; </span><span class=cFE>32</span><span class=cF0>);          </span><span class=cF2>// should we be using uncached addr here ?</span><span class=cF0>
+<a name="l439"></a>    E1000MMIOWrite(E1000_REG_TDBAL, e1000.tx_de_buffer &amp; </span><span class=cFE>0xFFFFFFFF</span><span class=cF0>);
+<a name="l440"></a>
+<a name="l441"></a>    </span><span class=cF2>// set tx buffer length</span><span class=cF0>
+<a name="l442"></a>    E1000MMIOWrite(E1000_REG_TDLEN, E1000_TX_BUFF_COUNT * </span><span class=cFE>16</span><span class=cF0>);
+<a name="l443"></a>
+<a name="l444"></a>    </span><span class=cF2>// set head tail pointers</span><span class=cF0>
+<a name="l445"></a>    E1000MMIOWrite(E1000_REG_TDH, </span><span class=cFE>0</span><span class=cF0>);
+<a name="l446"></a>    E1000MMIOWrite(E1000_REG_TDT, E1000_RX_BUFF_COUNT);
+<a name="l447"></a>
+<a name="l448"></a>    </span><span class=cF2>// set transmit control reg</span><span class=cF0>
+<a name="l449"></a>    E1000MMIOWrite(E1000_REG_TCTL, E1000_TCTLF_EN | E1000_TCTLF_PSP);
+<a name="l450"></a>
+<a name="l451"></a>}
+<a name="l452"></a>
+<a name="l453"></a>
+<a name="l454"></a></span><span class=cF1>U0</span><span class=cF0> E1000Init()
+<a name="l455"></a>{
+<a name="l456"></a>    </span><span class=cF9>I64</span><span class=cF0> i;
+<a name="l457"></a>
+<a name="l458"></a>    </span><span class=cF5>MemSet</span><span class=cF0>(&amp;e1000, </span><span class=cFE>0</span><span class=cF0>, </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CE1000</span><span class=cF7>)</span><span class=cF0>); </span><span class=cF2>// e1000 global var will hold member data the driver uses often.</span><span class=cF0>
+<a name="l459"></a>    </span><span class=cF6>&quot;\nE1000 driver WIP\n\n&quot;</span><span class=cF0>;
+<a name="l460"></a>
+<a name="l461"></a>    e1000.pci = E1000PCIDevFind;
+<a name="l462"></a>    </span><span class=cF1>if</span><span class=cF0> (!e1000.pci)
+<a name="l463"></a>        </span><span class=cF1>return</span><span class=cF0>; </span><span class=cF2>// if we don't find the card, quit.</span><span class=cF0>
+<a name="l464"></a>
+<a name="l465"></a>
+<a name="l466"></a>    e1000.mmio_address = </span><span class=cFB>dev</span><span class=cF0>.uncached_alias + e1000.pci-&gt;base[</span><span class=cFE>0</span><span class=cF0>] &amp; ~</span><span class=cFE>0xF</span><span class=cF0>;
+<a name="l467"></a>    </span><span class=cF2>// Assuming card supports MMIO... lower 4 bits are hardwired zero (?)</span><span class=cF0>
+<a name="l468"></a>
+<a name="l469"></a>    </span><span class=cF6>&quot;\nMMIO address: 0x%0X\n&quot;</span><span class=cF0>, e1000.mmio_address;
+<a name="l470"></a>
+<a name="l471"></a>    </span><span class=cF2>// init rx/tx addrs? (linux)</span><span class=cF0>
+<a name="l472"></a>
+<a name="l473"></a>    </span><span class=cF2>// eeprom? MAC ?</span><span class=cF0>
+<a name="l474"></a>    E1000MACGet;
+<a name="l475"></a>
+<a name="l476"></a>    </span><span class=cF2>// setup link? (01000101's driver)</span><span class=cF0>
+<a name="l477"></a>    E1000MMIOWrite(E1000_REG_CTRL, E1000MMIORead</span><span class=cF7>(</span><span class=cF0>E1000_REG_CTRL</span><span class=cF7>)</span><span class=cF0> | E1000_CTRLF_SLU);
+<a name="l478"></a>
+<a name="l479"></a>    </span><span class=cF2>// zero out multicast hash? (linux)</span><span class=cF0>
+<a name="l480"></a>    </span><span class=cF2>// zero out multicast table array (01000101's driver)</span><span class=cF0>
+<a name="l481"></a>    </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i &lt; </span><span class=cFE>128</span><span class=cF0>; i++)
+<a name="l482"></a>        E1000MMIOWrite(E1000_REG_MTA + i*</span><span class=cFE>4</span><span class=cF0>, </span><span class=cFE>0</span><span class=cF0>);
+<a name="l483"></a>
+<a name="l484"></a>    </span><span class=cF2>// setup link? (linux)</span><span class=cF0>
+<a name="l485"></a>
+<a name="l486"></a>    </span><span class=cF2>// clear all statistics regs after link establish attempt (linux)</span><span class=cF0>
+<a name="l487"></a>
+<a name="l488"></a>    </span><span class=cF2>// enable &amp; clear existing interupts (01000101's driver)</span><span class=cF0>
+<a name="l489"></a>    E1000MMIOWrite(E1000_REG_IMS, </span><span class=cFE>0x1F6DC</span><span class=cF0>); </span><span class=cF2>// TODO: WHAT IS THIS</span><span class=cF0>
+<a name="l490"></a>    E1000MMIORead(</span><span class=cFE>0xC0</span><span class=cF0>); </span><span class=cF2>// TODO : WHAT IS THIS ???</span><span class=cF0>
+<a name="l491"></a>
+<a name="l492"></a>    </span><span class=cF2>// start rx tx?</span><span class=cF0>
+<a name="l493"></a>    E1000InitRX;
+<a name="l494"></a>    E1000InitTX;
+<a name="l495"></a>
+<a name="l496"></a>    E1000InterruptsSetup;
+<a name="l497"></a>
+<a name="l498"></a>
+<a name="l499"></a>    NetErr(</span><span class=cF6>&quot;TODO E1000&quot;</span><span class=cF0>);
+<a name="l500"></a>    </span><span class=cF6>&quot;\n&quot;</span><span class=cF0>;
+<a name="l501"></a>    </span><span class=cF5>ClassRep</span><span class=cF0>(&amp;e1000);
+<a name="l502"></a>}
+<a name="l503"></a>
+<a name="l504"></a></span><span class=cF9>I64</span><span class=cF0> EthernetFrameAllocate(</span><span class=cF1>U8</span><span class=cF0> **packet_buffer_out,
+<a name="l505"></a>                          </span><span class=cF1>U8</span><span class=cF0> *source_address,
+<a name="l506"></a>                          </span><span class=cF1>U8</span><span class=cF0> *destination_address,
+<a name="l507"></a>                          </span><span class=cF9>U16</span><span class=cF0> ethertype,
+<a name="l508"></a>                          </span><span class=cF9>I64</span><span class=cF0> packet_length)
+<a name="l509"></a>{
+<a name="l510"></a>    </span><span class=cF1>U8</span><span class=cF0> *ethernet_frame;
+<a name="l511"></a>    </span><span class=cF9>I64</span><span class=cF0> de_index;
+<a name="l512"></a>
+<a name="l513"></a>    </span><span class=cF2>//need to see if 3 years later VirtualBox supports APAD_XMT!</span><span class=cF0>
+<a name="l514"></a>    </span><span class=cF1>if</span><span class=cF0> (packet_length &lt; ETHERNET_MIN_FRAME_SIZE)
+<a name="l515"></a>    </span><span class=cF7>{</span><span class=cF0>
+<a name="l516"></a>        NetWarn(</span><span class=cF6>&quot;ETHERNET FRAME ALLOCATE: Truncating length&quot;</span><span class=cF0>);
+<a name="l517"></a>        packet_length = ETHERNET_MIN_FRAME_SIZE;
+<a name="l518"></a>    </span><span class=cF7>}</span><span class=cF0>
+<a name="l519"></a>
+<a name="l520"></a>    de_index = E1000TransmitPacketAllocate(&amp;ethernet_frame, ETHERNET_MAC_HEADER_LENGTH + packet_length);
+<a name="l521"></a>
+<a name="l522"></a>    </span><span class=cF1>if</span><span class=cF0> (de_index &lt; </span><span class=cFE>0</span><span class=cF0>)
+<a name="l523"></a>    </span><span class=cF7>{</span><span class=cF0>
+<a name="l524"></a>        NetErr(</span><span class=cF6>&quot;ETHERNET FRAME ALLOCATE: Failure&quot;</span><span class=cF0>);
+<a name="l525"></a>        </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>; </span><span class=cF2>// Positive value expected. Functions calling this must factor this in.</span><span class=cF0>
+<a name="l526"></a>    </span><span class=cF7>}</span><span class=cF0>
+<a name="l527"></a>
+<a name="l528"></a>    </span><span class=cF5>MemCopy</span><span class=cF0>(ethernet_frame,                      destination_address, MAC_ADDRESS_LENGTH);
+<a name="l529"></a>    </span><span class=cF5>MemCopy</span><span class=cF0>(ethernet_frame + MAC_ADDRESS_LENGTH, source_address,      MAC_ADDRESS_LENGTH);
+<a name="l530"></a>
+<a name="l531"></a>    ethernet_frame[ETHERNET_ETHERTYPE_OFFSET]       = ethertype &gt;&gt; </span><span class=cFE>8</span><span class=cF0>;
+<a name="l532"></a>    ethernet_frame[ETHERNET_ETHERTYPE_OFFSET + </span><span class=cFE>1</span><span class=cF0>]   = ethertype &amp; </span><span class=cFE>0xFF</span><span class=cF0>;
+<a name="l533"></a>
+<a name="l534"></a>    *packet_buffer_out = ethernet_frame + ETHERNET_MAC_HEADER_LENGTH;
+<a name="l535"></a>
+<a name="l536"></a>    </span><span class=cF1>return</span><span class=cF0> de_index;
+<a name="l537"></a>
+<a name="l538"></a>}
+<a name="l539"></a>
+<a name="l540"></a></span><span class=cF1>U8</span><span class=cF0> *EthernetMACGet()
+<a name="l541"></a>{
+<a name="l542"></a>    </span><span class=cF1>return</span><span class=cF0> e1000.mac_address;
+<a name="l543"></a>}
+<a name="l544"></a>
+<a name="l545"></a></span><span class=cF1>U0</span><span class=cF0> NetStop()
+<a name="l546"></a>{
+<a name="l547"></a>
+<a name="l548"></a>}
+<a name="l549"></a>
+<a name="l550"></a></span><span class=cF1>U0</span><span class=cF0> NetStart()
+<a name="l551"></a>{
+<a name="l552"></a>
+<a name="l553"></a>}
+<a name="l554"></a>
+<a name="l555"></a>E1000Init;</span></pre></body>
 </html>
diff --git a/docs/Home/Net/Load.CC.html b/docs/Home/Net/Load.CC.html
index a2779df2..ad8bfaf4 100755
--- a/docs/Home/Net/Load.CC.html
+++ b/docs/Home/Net/Load.CC.html
@@ -25,7 +25,7 @@ body {background-color:#000000;}
 </head>
 <body>
 <pre style="font-family:monospace;font-size:12pt">
-<a name="l1"></a><span class=cF5>Cd</span><span class=cF0>(</span><span class=cF3>__DIR__</span><span class=cF0>);
+<a name="l1"></a><span class=cF5>Cd</span><span class=cF0>(</span><span class=cF3>__DIR__</span><span class=cF0>);;
 <a name="l2"></a>#</span><span class=cF1>include</span><span class=cF0> </span><span class=cF6>&quot;Utilities/Net.HH&quot;</span><span class=cF0>
 <a name="l3"></a>
 <a name="l4"></a>#</span><span class=cF1>include</span><span class=cF0> </span><span class=cF6>&quot;Utilities/NetLog&quot;</span><span class=cF0>
diff --git a/docs/Home/Net/Utilities/Net.HH.html b/docs/Home/Net/Utilities/Net.HH.html
index 4c1498f5..c948f39e 100755
--- a/docs/Home/Net/Utilities/Net.HH.html
+++ b/docs/Home/Net/Utilities/Net.HH.html
@@ -58,8 +58,14 @@ body {background-color:#000000;}
 <a name="l31"></a>#</span><span class=cF1>define</span><span class=cF0> I_PCNET1        </span><span class=cF3>I_USER</span><span class=cF0> + </span><span class=cFE>1</span><span class=cF0>
 <a name="l32"></a>#</span><span class=cF1>define</span><span class=cF0> I_PCNET2        </span><span class=cF3>I_USER</span><span class=cF0> + </span><span class=cFE>2</span><span class=cF0>
 <a name="l33"></a>#</span><span class=cF1>define</span><span class=cF0> I_PCNET3        </span><span class=cF3>I_USER</span><span class=cF0> + </span><span class=cFE>3</span><span class=cF0>
-<a name="l34"></a>#</span><span class=cF1>define</span><span class=cF0> I_NETHANDLER    </span><span class=cF3>I_USER</span><span class=cF0> + </span><span class=cFE>4</span><span class=cF0>
-<a name="l35"></a>
-<a name="l36"></a>#</span><span class=cF1>define</span><span class=cF0> INT_DEST_CPU    </span><span class=cFE>0</span><span class=cF0>
+<a name="l34"></a>
+<a name="l35"></a>#</span><span class=cF1>define</span><span class=cF0> I_E1000_0       </span><span class=cF3>I_USER</span><span class=cF0> + </span><span class=cFE>0</span><span class=cF0>
+<a name="l36"></a>#</span><span class=cF1>define</span><span class=cF0> I_E1000_1       </span><span class=cF3>I_USER</span><span class=cF0> + </span><span class=cFE>1</span><span class=cF0>
+<a name="l37"></a>#</span><span class=cF1>define</span><span class=cF0> I_E1000_2       </span><span class=cF3>I_USER</span><span class=cF0> + </span><span class=cFE>2</span><span class=cF0>
+<a name="l38"></a>#</span><span class=cF1>define</span><span class=cF0> I_E1000_3       </span><span class=cF3>I_USER</span><span class=cF0> + </span><span class=cFE>3</span><span class=cF0>
+<a name="l39"></a>
+<a name="l40"></a>#</span><span class=cF1>define</span><span class=cF0> I_NETHANDLER    </span><span class=cF3>I_USER</span><span class=cF0> + </span><span class=cFE>4</span><span class=cF0>
+<a name="l41"></a>
+<a name="l42"></a>#</span><span class=cF1>define</span><span class=cF0> INT_DEST_CPU    </span><span class=cFE>0</span><span class=cF0>
 </span></pre></body>
 </html>
diff --git a/docs/index.html b/docs/index.html
index fb4b945b..9bc1cf9e 100755
--- a/docs/index.html
+++ b/docs/index.html
@@ -1296,7 +1296,7 @@ body {background-color:#000000;}
 <a name="l1268"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/KDefine.CC.html#l108"><span class=cF4>DD_MEM_MIN_MEG      </span></a><span class=cF0>256Meg        0000 0000000008 DefineStr </span><span class=cF4>
 <a name="l1269"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/KDefine.CC.html#l108"><span class=cF4>DD_MP_VECT          </span></a><span class=cF0>00097000      0000 0000000010 DefineStr </span><span class=cF4>
 <a name="l1270"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/KDefine.CC.html#l108"><span class=cF4>DD_MP_VECT_END      </span></a><span class=cF0>00097030      0000 0000000010 DefineStr </span><span class=cF4>
-<a name="l1271"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/KDefine.CC.html#l108"><span class=cF4>DD_OS_NAME_VERSION  </span></a><span class=cF0>ZealOS V0.    0142 0000000010 DefineStr </span><span class=cF4>
+<a name="l1271"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/KDefine.CC.html#l108"><span class=cF4>DD_OS_NAME_VERSION  </span></a><span class=cF0>ZealOS V0.    0154 0000000010 DefineStr </span><span class=cF4>
 <a name="l1272"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/KDefine.CC.html#l108"><span class=cF4>DD_PHYSICAL_SPACE_END</span></a><span class=cF0>011EBFFFFF    0000 0000000010 DefineStr </span><span class=cF4>
 <a name="l1273"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/KDefine.CC.html#l108"><span class=cF4>DD_SYS_FIXED_AREA_BASE</span></a><span class=cF0>00100000      0000 0000000010 DefineStr </span><span class=cF4>
 <a name="l1274"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/KDefine.CC.html#l108"><span class=cF4>DD_SYS_FIXED_AREA_END</span></a><span class=cF0>00101FFF      0000 0000000010 DefineStr </span><span class=cF4>
@@ -1686,7 +1686,7 @@ body {background-color:#000000;}
 <a name="l1658"></a></span><a href="https://tomawezome.github.io/ZealOS/System/BlkDev/FileMgr.CC.html#l2"><span class=cF4>DirFileDoc          </span></a><span class=cF0>003794D028    0002 0000000108 Funct </span><span class=cF4>
 <a name="l1659"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/BlkDev/DiskDirA.CC.html#l152"><span class=cF4>DirFilesFlatten     </span></a><span class=cF0>000002844B    0001            ExportSysSym Imm </span><span class=cF4>
 <a name="l1660"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/BlkDev/DiskDirA.CC.html#l99"><span class=cF4>DirFilesSort        </span></a><span class=cF0>0000028313    0001            ExportSysSym Imm </span><span class=cF4>
-<a name="l1661"></a></span><a href="https://tomawezome.github.io/ZealOS/Demo/ToHtmlToTXTDemo/HtmlDirList.CC.html#l1"><span class=cF4>DirIndexList        </span></a><span class=cF0>00378798D8    0001 0000000193 Funct </span><span class=cF4>
+<a name="l1661"></a></span><a href="https://tomawezome.github.io/ZealOS/Demo/ToHtmlToTXTDemo/HtmlDirList.CC.html#l1"><span class=cF4>DirIndexList        </span></a><span class=cF0>00378834D8    0001 0000000193 Funct </span><span class=cF4>
 <a name="l1662"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/BlkDev/FileSysFAT.CC.html#l213"><span class=cF4>DirLongNameFill     </span></a><span class=cF0>000002AD68    0001            ExportSysSym Imm </span><span class=cF4>
 <a name="l1663"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/BlkDev/DiskDirB.CC.html#l184"><span class=cF4>DirMake             </span></a><span class=cF0>000002E500    000D 0000000171 Funct Public </span><span class=cF4>
 <a name="l1664"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/BlkDev/DiskStrA.CC.html#l118"><span class=cF4>DirNameAbs          </span></a><span class=cF0>0000020FCA    0009 0000000304 Funct Public </span><span class=cF4>
@@ -4772,8 +4772,8 @@ body {background-color:#000000;}
 <a name="l4744"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/KDefine.CC.html#l246"><span class=cF4>ST_COLORS           </span></a><span class=cF0>BLACK      10 0001 0000000068 DefineStr </span><span class=cF4>
 <a name="l4745"></a></span><a href="https://tomawezome.github.io/ZealOS/System/Utils/SysRep.CC.html#l250"><span class=cF4>ST_CPUID_1_ECX_FLAGS</span></a><span class=cF0>SSE3       13B 0000 00000011D8 DefineStr </span><span class=cF4>
 <a name="l4746"></a></span><a href="https://tomawezome.github.io/ZealOS/System/Utils/SysRep.CC.html#l215"><span class=cF4>ST_CPUID_1_EDX_FLAGS</span></a><span class=cF0>x87 FPU    20 0000 00000001D0 DefineStr </span><span class=cF4>
-<a name="l4747"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/KDefine.CC.html#l159"><span class=cF4>ST_DAYS_OF_WEEK     </span></a><span class=cF0>Sunday     07 0005 0000000040 DefineStr </span><span class=cF4>
-<a name="l4748"></a></span><a href="https://tomawezome.github.io/ZealOS/System/DolDoc/DocInit.CC.html#l14"><span class=cF4>ST_DOC_CMDS         </span></a><span class=cF0>TX         2B 018C 0000000088 DefineStr </span><span class=cF4>
+<a name="l4747"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/KDefine.CC.html#l159"><span class=cF4>ST_DAYS_OF_WEEK     </span></a><span class=cF0>Sunday     07 0006 0000000040 DefineStr </span><span class=cF4>
+<a name="l4748"></a></span><a href="https://tomawezome.github.io/ZealOS/System/DolDoc/DocInit.CC.html#l14"><span class=cF4>ST_DOC_CMDS         </span></a><span class=cF0>TX         2B 019F 0000000088 DefineStr </span><span class=cF4>
 <a name="l4749"></a></span><a href="https://tomawezome.github.io/ZealOS/System/DolDoc/DocInit.CC.html#l20"><span class=cF4>ST_DOC_FLAGS        </span></a><span class=cF0>T          3E 0007 00000000C0 DefineStr </span><span class=cF4>
 <a name="l4750"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/KDefine.CC.html#l228"><span class=cF4>ST_DRIVE_TYPES      </span></a><span class=cF0>NULL       06 0002 0000000028 DefineStr </span><span class=cF4>
 <a name="l4751"></a></span><a href="https://tomawezome.github.io/ZealOS/Kernel/KernelA.HH.html#l4125"><span class=cF4>ST_ERR_ST           </span></a><span class=cF0>\&quot;\d\dRED\    0003 0000000028 DefineStr </span><span class=cF4>
diff --git a/src/Home/Net/Drivers/E1000.CC b/src/Home/Net/Drivers/E1000.CC
index 5f68c8e6..91ff3276 100755
--- a/src/Home/Net/Drivers/E1000.CC
+++ b/src/Home/Net/Drivers/E1000.CC
@@ -109,15 +109,21 @@ class CE1000
 
 	U8	mac_address[6];
 	U64	mmio_address;
+
+	I64 current_rx_de_index;	// Current Receive DE being processed.  Gets incremented, wrapped to 0 at max of E1000_RX_BUFF_COUNT.
+	I64 current_tx_de_index;	// Current Transmit DE being processed. Gets incremented, wrapped to 0 at max of E1000_TX_BUFF_COUNT.
+
 	U8 *rx_de_buffer;			// Uncached-alias of pointer to the buffer of RX Descriptor Entries.
 	U8 *tx_de_buffer;			// Uncached-alias of pointer to the buffer of TX Descriptor Entries.
 	U8 *rx_de_buffer_phys;		// Pointer to the buffer of RX Descriptor Entries. (Code Heap, lower 2Gb)
 	U8 *tx_de_buffer_phys;		// Pointer to the buffer of TX Descriptor Entries. (Code Heap, lower 2Gb)
+
 	U64 rx_buffer_addr;			// Uncached-alias of address of receive buffers.
 	U64 tx_buffer_addr;			// Uncached-alias of address of transmit buffers.
 	U64 rx_buffer_addr_phys;	// Physical address of actual receive buffers  (< 4 Gb)
 	U64 tx_buffer_addr_phys;	// Physical address of actual transmit buffers (< 4 Gb)
 
+
 } e1000; // e1000 is the global variable we store all of this into.
 
 CPCIDev *E1000PCIDevFind()
@@ -175,7 +181,7 @@ U0 E1000MACGet()
 	I64 i;
 	U16 mac;
 
-	NetLog("E1000 GET MAC: Getting VM MAC.");
+	NetLog("E1000 MAC GET: Getting MAC Address.");
 
 	for (i = 0; i < 3; i++)
 	{
@@ -187,14 +193,163 @@ U0 E1000MACGet()
 	
 }
 
-U0 EthernetFrameFinish(I64 de_index)
-{//Alias for driver Finish TX function.
-	//E1000TransmitPacketFinish(de_index);
-	no_warn de_index;
-	NetErr("TODO E1000");
+I64 E1000PacketReceive(U8 **packet_buffer_out, U16 *packet_length_out)
+{
+	I64 de_index = e1000.current_rx_de_index;
+	CE1000DescriptorEntryRX *entry = &e1000.rx_de_buffer[de_index * sizeof(CE1000DescriptorEntryRX)];
+	Bool drop = FALSE;
+
+	if (entry->length < 60)
+	{
+		NetErr("E1000 PACKET RECEIVE: Short Packet");
+		drop = TRUE;
+	}
+
+	if (entry->status & (1 << 1)) // EOP ?? TODO #define
+	{
+		NetErr("E1000 PACKET RECEIVE: No EOP Set");
+		drop = TRUE;
+	}
+
+	if (entry->errors)
+	{
+		NetErr("E1000 PACKET RECEIVE: RX DE Error Bits Set");
+		drop = TRUE;
+	}
+
+	e1000.current_rx_de_index = (e1000.current_rx_de_index + 1) & (E1000_RX_BUFF_COUNT - 1);
+
+	if (!drop)
+	{
+		*packet_buffer_out = entry->address;
+		*packet_length_out = entry->length;
+	}
+	else
+	{
+		NetErr("E1000 PACKET RECEIVE: Dropping packet.");
+		de_index = -1;
+	}
+
+	return de_index;
+}
+
+U0 E1000ReceivePacketRelease(I64 de_index)
+{
+	CE1000DescriptorEntryRX *entry = &e1000.rx_de_buffer[de_index * sizeof(CE1000DescriptorEntryRX)];
+	entry->status = 0;
+
+	E1000MMIOWrite(E1000_REG_RDT, e1000.current_rx_de_index);
+}
+
+Bool E1000DriverOwnsRX(CE1000DescriptorEntryRX *entry)
+{
+	return Bt(&entry->status, 0); // ?? TODO #define
+}
+
+I64 E1000TransmitPacketAllocate(U8 **packet_buffer_out, I64 length)
+{	I64 de_index = e1000.current_tx_de_index;
+
+	CE1000DescriptorEntryTX *entry = &e1000.tx_de_buffer[de_index * sizeof(CE1000DescriptorEntryTX)];
+
+	*packet_buffer_out = e1000.tx_buffer_addr + de_index * ETHERNET_FRAME_SIZE;
+
+	MemSet(*packet_buffer_out, 0, ETHERNET_FRAME_SIZE); // Clear buffer contents in advance.
+
+	entry->address	= *packet_buffer_out;
+	entry->length	= length;
+	entry->cmd		= (1 << 3) | 3; // ??? TODO #define
+
+	NetLog("E1000 ALLOCATE TX PACKET: de_index: %X.", de_index);
+	return de_index;
+}
+
+U0 E1000TransmitPacketFinish(I64 de_index)
+{
+	CE1000DescriptorEntryTX *entry = &e1000.tx_de_buffer[de_index * sizeof(CE1000DescriptorEntryTX)];
+
+	e1000.current_tx_de_index = (e1000.current_tx_de_index + 1) & (E1000_TX_BUFF_COUNT - 1);
+	E1000MMIOWrite(E1000_REG_TDT, e1000.current_tx_de_index);
+
+	ClassRep(entry);
+
+	while (!(entry->sta & 0xF)) // ???
+		Yield;
+
+	NetLog("E1000 FINISH TX PACKET: TX DE index: %X.", de_index);
+}
+
+U0 EthernetFrameFinish(I64 de_index)
+{//Alias for driver Finish TX function.
+	E1000TransmitPacketFinish(de_index);
+}
+
+interrupt U0 E1000IRQ()
+{ // TODO need #defines
+	U32 icr = E1000MMIORead(0xC0); // ???
+	Bool poll = FALSE;
+	CE1000DescriptorEntryRX *entry = e1000.rx_de_buffer;
+	U8 *packet_buffer;
+	U16 packet_length;
+	I64 de_index;
+
+	icr &= ~3; // ??
+
+	if (icr & (1 << 2)) // ?? 'link status change' ??
+	{
+		icr &= ~(1 << 2);
+		E1000MMIOWrite(E1000_REG_CTRL, E1000MMIORead(E1000_REG_CTRL) | E1000_CTRLF_SLU);
+	}
+
+	if (icr & (1 << 6) || icr & (1 << 4)) // ?? 'rx underrun / min threshold' ??
+	{
+		icr = ~((1 << 6) | (1 << 4)); // ??
+
+		poll = TRUE;
+	}
+
+	if (icr & (1 << 7)) // ?? 'packet pending?
+	{
+		icr &= ~(1 << 7);
+
+		poll = TRUE;
+	}
+
+	if (poll)
+	{
+		while (E1000DriverOwnsRX(&entry[e1000.current_rx_de_index]))
+		{
+			NetLog("$$BG,LTCYAN$$$$FG,WHITE$$"
+				   "==== E1000 IRQ ===="
+				   "$$BG$$$$FG$$");
+
+			NetLog("$$BD,CYAN$$$$FD,WHITE$$"
+				   "E1000 IRQ: Saw owned RX DE index %d.", e1000.current_rx_de_index);
+
+			de_index = E1000PacketReceive(&packet_buffer, &packet_length);
+
+			if (de_index >= 0)
+			{
+				NetLog("E1000 IRQ: Pushing copy into Net Queue, releasing receive packet.");
+				NetQueuePush(packet_buffer, packet_length);
+				E1000ReceivePacketRelease(de_index);
+			}
+
+		NetLog("E1000 IRQ: Exiting.\n"
+			   "$$BD,WHITE$$$$FD,LTGRAY$$"
+			   "$$BG,LTCYAN$$$$FG,WHITE$$"
+			   "==================="
+			   "$$BG$$$$FG$$");
+		}
+	}
+
+
+
+	E1000MMIORead(0xC0); // ?? 'clear pending interrupts' ??
+
+	*(dev.uncached_alias + LAPIC_EOI)(U32*) = 0;
+
 }
 
-/*
 U0 PCIInterruptsReroute(I64 base)
 { // todo: comments explaining process, maybe better var names
 	I64	 i;
@@ -212,13 +367,15 @@ U0 PCIInterruptsReroute(I64 base)
 
 
 U0 E1000InterruptsSetup()
-{
-//	PCIInterruptsReroute(I_E1000);
-	NetErr("TODO E1000");
+{ // .. ?
+	IntEntrySet(I_E1000_0, &E1000IRQ);
+	IntEntrySet(I_E1000_1, &E1000IRQ);
+	IntEntrySet(I_E1000_2, &E1000IRQ);
+	IntEntrySet(I_E1000_3, &E1000IRQ);
+	PCIInterruptsReroute(I_E1000_0);
 }
-*/
 
-U0 E1000RXInit()
+U0 E1000InitRX()
 {
 	I64 de_index;
 
@@ -265,7 +422,7 @@ U0 E1000RXInit()
 									E1000_RCTLF_BAM);
 }
 
-U0 E1000TXInit()
+U0 E1000InitTX()
 {
 	e1000.tx_de_buffer_phys = CAllocAligned(sizeof(CE1000DescriptorEntryTX) * E1000_TX_BUFF_COUNT,
 											16, 
@@ -333,8 +490,10 @@ U0 E1000Init()
 	E1000MMIORead(0xC0); // TODO : WHAT IS THIS ???
 
 	// start rx tx?
-	E1000RXInit;
-	E1000TXInit;
+	E1000InitRX;
+	E1000InitTX;
+
+	E1000InterruptsSetup;
 
 
 	NetErr("TODO E1000");
@@ -348,9 +507,34 @@ I64 EthernetFrameAllocate(U8 **packet_buffer_out,
 						  U16 ethertype,
 						  I64 packet_length)
 {
-	no_warn packet_buffer_out, source_address, destination_address, ethertype, packet_length;
-	NetErr("TODO E1000");
-	return -1;
+	U8 *ethernet_frame;
+	I64 de_index;
+
+	//need to see if 3 years later VirtualBox supports APAD_XMT!
+	if (packet_length < ETHERNET_MIN_FRAME_SIZE)
+	{
+		NetWarn("ETHERNET FRAME ALLOCATE: Truncating length");
+		packet_length = ETHERNET_MIN_FRAME_SIZE;
+	}
+
+	de_index = E1000TransmitPacketAllocate(&ethernet_frame, ETHERNET_MAC_HEADER_LENGTH + packet_length);
+
+	if (de_index < 0)
+	{
+		NetErr("ETHERNET FRAME ALLOCATE: Failure");
+		return -1; // Positive value expected. Functions calling this must factor this in.
+	}
+
+	MemCopy(ethernet_frame,						 destination_address, MAC_ADDRESS_LENGTH);
+	MemCopy(ethernet_frame + MAC_ADDRESS_LENGTH, source_address,	  MAC_ADDRESS_LENGTH);
+
+	ethernet_frame[ETHERNET_ETHERTYPE_OFFSET]		= ethertype >> 8;
+	ethernet_frame[ETHERNET_ETHERTYPE_OFFSET + 1]	= ethertype & 0xFF;
+
+	*packet_buffer_out = ethernet_frame + ETHERNET_MAC_HEADER_LENGTH;
+
+	return de_index;
+
 }
 
 U8 *EthernetMACGet()
diff --git a/src/Home/Net/Load.CC b/src/Home/Net/Load.CC
index d884a799..890456bc 100755
--- a/src/Home/Net/Load.CC
+++ b/src/Home/Net/Load.CC
@@ -1,4 +1,4 @@
-Cd(__DIR__);
+Cd(__DIR__);;
 #include "Utilities/Net.HH"
 
 #include "Utilities/NetLog"
diff --git a/src/Home/Net/Utilities/Net.HH b/src/Home/Net/Utilities/Net.HH
index 41ee1416..043732bd 100755
--- a/src/Home/Net/Utilities/Net.HH
+++ b/src/Home/Net/Utilities/Net.HH
@@ -31,6 +31,12 @@
 #define I_PCNET1		I_USER + 1
 #define I_PCNET2		I_USER + 2
 #define I_PCNET3		I_USER + 3
+
+#define I_E1000_0		I_USER + 0
+#define I_E1000_1		I_USER + 1
+#define I_E1000_2		I_USER + 2
+#define I_E1000_3		I_USER + 3
+
 #define I_NETHANDLER	I_USER + 4
 
 #define INT_DEST_CPU	0