summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorroot <root@lab.panaceas.james.local>2013-10-12 12:13:58 +0100
committerroot <root@lab.panaceas.james.local>2013-10-12 12:13:58 +0100
commit3b3237c2ba1bb29f7d43fda9fdbc08bd0c32e5f9 (patch)
tree1ca30cdbd30e7de4407d3a35838318b146cad3b9 /src
parent8b91c2f0452ce241a2f69481e156d5fd313955dc (diff)
downloadpong-3b3237c2ba1bb29f7d43fda9fdbc08bd0c32e5f9.tar.gz
pong-3b3237c2ba1bb29f7d43fda9fdbc08bd0c32e5f9.tar.bz2
pong-3b3237c2ba1bb29f7d43fda9fdbc08bd0c32e5f9.zip
first_full_makefile
Diffstat (limited to 'src')
-rw-r--r--src/DM9000A.C239
-rw-r--r--src/DM9000A.H72
-rw-r--r--src/GPU.h31
-rw-r--r--src/hello_led.c148
-rw-r--r--src/pong3.c280
5 files changed, 770 insertions, 0 deletions
diff --git a/src/DM9000A.C b/src/DM9000A.C
new file mode 100644
index 0000000..7380729
--- /dev/null
+++ b/src/DM9000A.C
@@ -0,0 +1,239 @@
+#include <stdio.h>
+#include "DM9000A.H"
+
+#define msleep(msec) usleep(1000*msec);
+
+
+#if 0
+//-------------------------------------------------------------------------
+void iow(unsigned int reg, unsigned int data)
+{
+ IOWR(DM9000A_0_BASE,IO_addr,reg);
+ //usleep(STD_DELAY);
+ IOWR(DM9000A_0_BASE,IO_data,data);
+}
+//-------------------------------------------------------------------------
+unsigned int ior(unsigned int reg)
+{
+ IOWR(DM9000A_0_BASE,IO_addr,reg);
+ //usleep(STD_DELAY);
+ return IORD(DM9000A_0_BASE,IO_data);
+}
+//-------------------------------------------------------------------------
+void phy_write (unsigned int reg, unsigned int value)
+{
+ /* set PHY register address into EPAR REG. 0CH */
+ iow(0x0C, reg | 0x40); /* PHY register address setting, and DM9000_PHY offset = 0x40 */
+
+ /* fill PHY WRITE data into EPDR REG. 0EH & REG. 0DH */
+ iow(0x0E, ((value >> 8) & 0xFF)); /* PHY data high_byte */
+ iow(0x0D, value & 0xFF); /* PHY data low_byte */
+
+ /* issue PHY + WRITE command = 0xa into EPCR REG. 0BH */
+ iow(0x0B, 0x8); /* clear PHY command first */
+ IOWR(DM9000A_0_BASE, IO_data, 0x0A); /* issue PHY + WRITE command */
+ usleep(STD_DELAY);
+ IOWR(DM9000A_0_BASE, IO_data, 0x08); /* clear PHY command again */
+ usleep(50); /* wait 1~30 us (>20 us) for PHY + WRITE completion */
+}
+//-------------------------------------------------------------------------
+/* DM9000_init I/O routine */
+unsigned int DM9000_init (void) /* initialize DM9000 LAN chip */
+{
+ unsigned int i;
+
+ /* set the internal PHY power-on (GPIOs normal settings) */
+ iow(0x1E, 0x01); /* GPCR REG. 1EH = 1 selected GPIO0 "output" port for internal PHY */
+ iow(0x1F, 0x00); /* GPR REG. 1FH GEPIO0 Bit [0] = 0 to activate internal PHY */
+ msleep(5); /* wait > 2 ms for PHY power-up ready */
+
+ /* software-RESET NIC */
+ iow(NCR, 0x03); /* NCR REG. 00 RST Bit [0] = 1 reset on, and LBK Bit [2:1] = 01b MAC loopback on */
+ usleep(20); /* wait > 10us for a software-RESET ok */
+ iow(NCR, 0x00); /* normalize */
+ iow(NCR, 0x03);
+ usleep(20);
+ iow(NCR, 0x00);
+
+ /* set GPIO0=1 then GPIO0=0 to turn off and on the internal PHY */
+ iow(0x1F, 0x01); /* GPR PHYPD Bit [0] = 1 turn-off PHY */
+ iow(0x1F, 0x00); /* PHYPD Bit [0] = 0 activate phyxcer */
+ msleep(10); /* wait >4 ms for PHY power-up */
+
+ /* set PHY operation mode */
+ phy_write(0,PHY_reset); /* reset PHY: registers back to the default states */
+ usleep(50); /* wait >30 us for PHY software-RESET ok */
+ phy_write(16, 0x404); /* turn off PHY reduce-power-down mode only */
+ phy_write(4, PHY_txab); /* set PHY TX advertised ability: ALL + Flow_control */
+ phy_write(0, 0x1200); /* PHY auto-NEGO re-start enable (RESTART_AUTO_NEGOTIATION + AUTO_NEGOTIATION_ENABLE) to auto sense and recovery PHY registers */
+ //phy_write(0, 0x2000);
+ msleep(5); /* wait >2 ms for PHY auto-sense linking to partner */
+
+ /* store MAC address into NIC */
+ for (i = 0; i < 6; i++)
+ iow(16 + i, ether_addr[i]);
+
+ /* clear any pending interrupt */
+ iow(ISR, 0x3F); /* clear the ISR status: PRS, PTS, ROS, ROOS 4 bits, by RW/C1 */
+ iow(NSR, 0x2C); /* clear the TX status: TX1END, TX2END, WAKEUP 3 bits, by RW/C1 */
+
+ /* program operating registers~ */
+ iow(NCR, NCR_set); /* NCR REG. 00 enable the chip functions (and disable this MAC loopback mode back to normal) */
+ iow(0x08, BPTR_set); /* BPTR REG.08 (if necessary) RX Back Pressure Threshold in Half duplex moe only: High Water 3KB, 200 us */
+ iow(0x09, FCTR_set); /* FCTR REG.09 (if necessary) Flow Control Threshold setting High/ Low Water Overflow 3KB/ 8KB */
+ iow(0x0A, RTFCR_set); /* RTFCR REG.0AH (if necessary) RX/TX Flow Control Register enable TXPEN, BKPM (TX_Half), FLCE (RX) */
+ iow(0x0F, 0x00); /* Clear the all Event */
+ iow(0x2D, 0x80); /* Switch LED to mode 1 */
+ iow(OTCR, OTCR_set); /* 100Mhz Internal clock */
+
+ //dong added
+ //iow(0x31, 0x01);//checksum generation enable
+ //iow(0x32, 0x02);//checksum checking enable, package will not be disscard even if CRC error
+
+ /* set other registers depending on applications */
+ iow(ETXCSR, ETXCSR_set); /* Early Transmit 12.5% */
+ //iow(TCSCR, TCSCR_set); /* UDP and not IP Checksum activ. */
+
+ /* enable interrupts to activate DM9000 ~on */
+ iow(IMR, INTR_set); /* IMR REG. FFH PAR=1 only, or + PTM=1& PRM=1 enable RxTx interrupts */
+
+ /* enable RX (Broadcast/ ALL_MULTICAST) ~go */
+ iow(RCR , RCR_set | RX_ENABLE | PASS_MULTICAST); /* RCR REG. 05 RXEN Bit [0] = 1 to enable the RX machine/ filter */
+
+ /* RETURN "DEVICE_SUCCESS" back to upper layer */
+ return (ior(0x2D)==0x80) ? DMFE_SUCCESS : DMFE_FAIL;
+}
+//-------------------------------------------------------------------------
+/* Transmit one Packet TX I/O routine */
+unsigned int TransmitPacket(unsigned char *data_ptr,unsigned int tx_len)
+{
+ unsigned int i;
+
+ /* mask NIC interrupts IMR: PAR only */
+ iow(IMR, PAR_set);
+
+ /* issue TX packet's length into TXPLH REG. FDH & TXPLL REG. FCH */
+ iow(0xFD, (tx_len >> 8) & 0xFF); /* TXPLH High_byte length */
+ iow(0xFC, tx_len & 0xFF); /* TXPLL Low_byte length */
+
+ /* wirte transmit data to chip SRAM */
+ IOWR(DM9000A_0_BASE, IO_addr, MWCMD); /* set MWCMD REG. F8H TX I/O port ready */
+ for (i = 0; i < tx_len; i += 2)
+ {
+ usleep(STD_DELAY);
+ IOWR(DM9000A_0_BASE, IO_data, (data_ptr[i+1]<<8)|data_ptr[i] );
+ }
+
+ usleep(100);
+
+ /* issue TX polling command activated */
+ iow(TCR , TCR_set | TX_REQUEST); /* TXCR Bit [0] TXREQ auto clear after TX completed */
+
+ /* wait TX transmit done */
+ char tx_done = 0;
+ do
+ {
+ tx_done = ior(NSR)&0x0C;
+ }
+ while(!tx_done);
+ //usleep(STD_DELAY);
+
+ /* clear the NSR Register */
+ //iow(NSR,0x00);
+
+ /* re-enable NIC interrupts */
+ iow(IMR, INTR_set);
+
+ /* RETURN "TX_SUCCESS" to upper layer */
+ return DMFE_SUCCESS;
+}
+//-------------------------------------------------------------------------
+/* Receive One Packet I/O routine */
+unsigned int ReceivePacket (unsigned char *data_ptr,unsigned int *rx_len)
+{
+ unsigned char rx_READY,GoodPacket;
+ unsigned int Tmp, RxStatus, i;
+
+ RxStatus = rx_len[0] = 0;
+ GoodPacket=FALSE;
+
+ iow(ISR, 0x01);
+
+ /* mask NIC interrupts IMR: PAR only */
+ iow(IMR, PAR_set);
+
+ /* dummy read a byte from MRCMDX REG. F0H */
+ rx_READY = ior(MRCMDX)&0x03;
+
+ /* got most updated byte: rx_READY */
+ rx_READY = IORD(DM9000A_0_BASE,IO_data)&0x03;
+ usleep(STD_DELAY);
+
+ /* check if (rx_READY == 0x01): Received Packet READY? */
+ if (rx_READY == DM9000_PKT_READY)
+ {
+ /* got RX_Status & RX_Length from RX SRAM */
+ IOWR(DM9000A_0_BASE, IO_addr, MRCMD); /* set MRCMD REG. F2H RX I/O port ready */
+ usleep(STD_DELAY);
+ RxStatus = IORD(DM9000A_0_BASE,IO_data);
+ usleep(STD_DELAY);
+ rx_len[0] = IORD(DM9000A_0_BASE,IO_data);
+
+ /* Check this packet_status GOOD or BAD? */
+ if ( !(RxStatus & 0xBF00) && (rx_len[0] < MAX_PACKET_SIZE) )
+ {
+ /* read 1 received packet from RX SRAM into RX buffer */
+ for (i = 0; i < rx_len[0]; i += 2)
+ {
+ usleep(STD_DELAY);
+ Tmp = IORD(DM9000A_0_BASE, IO_data);
+ data_ptr[i] = Tmp&0xFF;
+ data_ptr[i+1] = (Tmp>>8)&0xFF;
+ }
+ GoodPacket=TRUE;
+ } /* end if (GoodPacket) */
+ else
+ {
+ printf("\nError\n");
+ /* this packet is bad, dump it from RX SRAM */
+ for (i = 0; i < rx_len[0]; i += 2)
+ {
+ usleep(STD_DELAY);
+ Tmp = IORD(DM9000A_0_BASE, IO_data);
+ }
+ rx_len[0] = 0;
+ } /* end if (!GoodPacket) */
+ } /* end if (rx_READY == DM9000_PKT_READY) ok */
+ else if(rx_READY) /* status check first byte: rx_READY Bit[1:0] must be "00"b or "01"b */
+ {
+ printf(" RX failure!\n");
+ /* software-RESET NIC */
+ iow(NCR, 0x03); /* NCR REG. 00 RST Bit [0] = 1 reset on, and LBK Bit [2:1] = 01b MAC loopback on */
+ usleep(20); /* wait > 10us for a software-RESET ok */
+ iow(NCR, 0x00); /* normalize */
+ iow(NCR, 0x03);
+ usleep(20);
+ iow(NCR, 0x00);
+ /* program operating registers~ */
+ iow(NCR, NCR_set); /* NCR REG. 00 enable the chip functions (and disable this MAC loopback mode back to normal) */
+ iow(0x08, BPTR_set); /* BPTR REG.08 (if necessary) RX Back Pressure Threshold in Half duplex moe only: High Water 3KB, 600 us */
+ iow(0x09, FCTR_set); /* FCTR REG.09 (if necessary) Flow Control Threshold setting High/ Low Water Overflow 5KB/ 10KB */
+ iow(0x0A, RTFCR_set); /* RTFCR REG.0AH (if necessary) RX/TX Flow Control Register enable TXPEN, BKPM (TX_Half), FLCE (RX) */
+ iow(0x0F, 0x00); /* Clear the all Event */
+ iow(0x2D, 0x80); /* Switch LED to mode 1 */
+ iow(OTCR, OTCR_set); /* 100Mhz Internal clock */
+ /* set other registers depending on applications */
+ iow(ETXCSR, ETXCSR_set); /* Early Transmit 12.5% */
+ /* enable interrupts to activate DM9000 ~on */
+ iow(IMR, INTR_set); /* IMR REG. FFH PAR=1 only, or + PTM=1& PRM=1 enable RxTx interrupts */
+ /* enable RX (Broadcast/ ALL_MULTICAST) ~go */
+ iow(RCR , RCR_set | RX_ENABLE | PASS_MULTICAST); /* RCR REG. 05 RXEN Bit [0] = 1 to enable the RX machine/ filter */
+ } /* end NIC H/W system Data-Bus error */
+
+ /* re-enable NIC interrupts */
+ iow(IMR, INTR_set);
+
+ return GoodPacket ? DMFE_SUCCESS : DMFE_FAIL;
+}
+//-------------------------------------------------------------------------
+#endif
diff --git a/src/DM9000A.H b/src/DM9000A.H
new file mode 100644
index 0000000..47401f1
--- /dev/null
+++ b/src/DM9000A.H
@@ -0,0 +1,72 @@
+#ifndef __DM9000A_H__
+#define __DM9000A_H__
+
+#define IO_addr 0
+#define IO_data 1
+
+#define NCR 0x00 /* Network Control Register REG. 00 */
+#define NSR 0x01 /* Network Status Register REG. 01 */
+#define TCR 0x02 /* Transmit Control Register REG. 02 */
+#define RCR 0x05 /* Receive Control Register REG. 05 */
+#define ETXCSR 0x30 /* TX early Control Register REG. 30 */
+#define MRCMDX 0xF0 /* RX FIFO I/O port command READ for dummy read a byte from RX SRAM */
+#define MRCMD 0xF2 /* RX FIFO I/O port command READ from RX SRAM */
+#define MWCMD 0xF8 /* TX FIFO I/O port command WRITE into TX FIFO */
+#define ISR 0xFE /* NIC Interrupt Status Register REG. FEH */
+#define IMR 0xFF /* NIC Interrupt Mask Register REG. FFH */
+#define OTCR 0x2E /* NIC Operation Test Control Register REG. 2EH */
+#define TCSCR 0x31 /* Transmit Check Sum Control Register REG. 31H */
+
+#define NCR_set 0x00
+#define TCR_set 0x00
+#define TX_REQUEST 0x01 /* TCR REG. 02 TXREQ Bit [0] = 1 polling Transmit Request command */
+#define TCR_long 0x40 /* packet disable TX Jabber Timer */
+#define RCR_set 0x30 /* skip CRC_packet and skip LONG_packet */
+#define RX_ENABLE 0x01 /* RCR REG. 05 RXEN Bit [0] = 1 to enable RX machine */
+#define RCR_long 0x40 /* packet disable RX Watchdog Timer */
+#define PASS_MULTICAST 0x08 /* RCR REG. 05 PASS_ALL_MULTICAST Bit [3] = 1: RCR_set value ORed 0x08 */
+#define BPTR_set 0x37 /* BPTR REG. 08 RX Back Pressure Threshold: High Water Overflow Threshold setting 3KB and Jam_Pattern_Time = 200 us */
+#define FCTR_set 0x38 /* FCTR REG. 09 High/ Low Water Overflow Threshold setting 3KB/ 8KB */
+#define RTFCR_set 0x29 /* RTFCR REG. 0AH RX/TX Flow Control Register enable TXPEN + BKPM(TX_Half) + FLCE(RX) */
+#define ETXCSR_set 0x80 /* Early Transmit Bit [7] Enable and Threshold 0~3: 12.5%, 25%, 50%, 75% */
+#define INTR_set 0x81 /* IMR REG. FFH: PAR +PRM, or 0x81: PAR + PRM + PTM */
+#define PAR_set 0x80 /* IMR REG. FFH: PAR only, RX/TX FIFO R/W Pointer Auto Return enable */
+#define OTCR_set 0x80 /* System Clock set = 100Mhz */
+#define TCSCR_set 0x00 /* UDP TCP IP auto send check */
+
+#define PHY_reset 0x8000 /* PHY reset: some registers back to default value */
+#define PHY_txab 0x05e1 /* set PHY TX advertised ability: Full-capability + Flow-control (if necessary) */
+#define PHY_mode 0x3100 /* set PHY media mode: Auto negotiation (AUTO sense) */
+
+#define STD_DELAY 20 /* standard delay 20 us */
+
+#define DMFE_SUCCESS 0
+#define DMFE_FAIL 1
+
+#define TRUE 1
+#define FALSE 0
+
+#define DM9000_PKT_READY 0x01 /* packets ready to receive */
+#define PACKET_MIN_SIZE 0x40 /* Received packet min size */
+#define MAX_PACKET_SIZE 1522 /* RX largest legal size packet with fcs & QoS */
+#define DM9000_PKT_MAX 3072 /* TX 1 packet max size without 4-byte CRC */
+//-------------------------------------------------------------------------
+unsigned char ether_addr[6]={ 0x01, 0x60, 0x6E, 0x11, 0x02, 0x0F };
+//-------------------------------------------------------------------------
+void iow(unsigned int reg, unsigned int data);
+unsigned int ior(unsigned int reg);
+void phy_write(unsigned int reg, unsigned int value);
+/* DM9000_init I/O routine */
+unsigned int DM9000_init (void);
+/* Transmit One Packet TX I/O routine */
+unsigned int TransmitPacket(unsigned char *data_ptr,unsigned int tx_len);
+/* Receive One Packet I/O routine */
+unsigned int ReceivePacket (unsigned char *data_ptr,unsigned int *rx_len);
+//-------------------------------------------------------------------------
+
+#endif
+
+
+
+
+
diff --git a/src/GPU.h b/src/GPU.h
new file mode 100644
index 0000000..fef1499
--- /dev/null
+++ b/src/GPU.h
@@ -0,0 +1,31 @@
+/*
+ * GPU.h
+ *
+ * Created on: Oct 11, 2013
+ * Author: root
+ */
+
+#ifndef GPU_H_
+#define GPU_H_
+
+#define GPU_OFFSET 0x80
+#if 0
+#define GPU_WIDTH 640
+#define GPU_HEIGHT 480
+#else
+#define GPU_WIDTH 800
+#define GPU_HEIGHT 600
+#endif
+
+#define GPU_REG_BLANK 0x0
+#define GPU_REG_SPRITE_X 0x1
+#define GPU_REG_SPRITE_Y 0x2
+#define GPU_REG_BAT0_Y 0x3
+#define GPU_REG_BAT1_Y 0x4
+#define GPU_REG_SPRITE_COLOUR 0x5
+#define GPU_REG_SPRITE_BASE 0x10
+
+#define GPU_RGB(r,g,b) (((r) << 6) | ((g) << 3) | (b))
+
+
+#endif /* GPU_H_ */
diff --git a/src/hello_led.c b/src/hello_led.c
new file mode 100644
index 0000000..9f472d7
--- /dev/null
+++ b/src/hello_led.c
@@ -0,0 +1,148 @@
+/*
+ *
+ *
+ *
+ *
+ */
+#include <io.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include "system.h"
+#include "DM9000A.H"
+#include "DM9000A.C"
+//#include "sys/alt_irq.h"
+#include <../src/alt_irq_register.c>
+
+#if 0
+unsigned int rx_len,i,packet_num,rx_cnt,tx_cnt;
+
+
+#define data_lenght 1468 // Maximun Data lenght 1468 bytes
+#define flenght (data_lenght+0x2E) //Total packet lenght
+
+ unsigned char SND[flenght]; // Payload buffer
+
+ unsigned char RX_DATA[flenght]; // Payload buffer
+
+//-------------------------------------------------------------------------
+/* DM9000_init I/O routine */
+
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+
+void UDP_Init(void)
+ {
+ unsigned int IPsource_1,IPsource_2,IPsource_3,IPsource_4;
+ unsigned int IPdestination_1,IPdestination_2,IPdestination_3,IPdestination_4;
+ unsigned int IPchecksum1,IPchecksum2,IPchecksum3,IPchecksum4,IPchecksum5;
+ unsigned int Mac_source1, Mac_source2, Mac_source3, Mac_source4, Mac_source5, Mac_source6;
+ unsigned int Mac_dest1, Mac_dest2, Mac_dest3, Mac_dest4, Mac_dest5, Mac_dest6;
+ unsigned int lenght_h, lenght_l;
+ unsigned int IPlenght_h, IPlenght_l, IPlenght;
+
+ IPsource_1 = 192; // Assign ie: 192.168.0.44 IP for the CD0
+ IPsource_2 = 168;
+ IPsource_3 = 0;
+ IPsource_4 = 44;
+
+ IPdestination_1 = 192; // Insert your IP data here
+ IPdestination_2 = 168;
+ IPdestination_3 = 0;
+ IPdestination_4 = 55;
+
+ Mac_dest1 = 0xF4; // Insert your MAC address data here
+ Mac_dest2 = 0x6D;
+ Mac_dest3 = 0x04;
+ Mac_dest4 = 0x20;
+ Mac_dest5 = 0x9F;
+ Mac_dest6 = 0xF1;
+// Mac_dest1 = 0XFF; // Insert your MAC address data here
+// Mac_dest2 = 0xFF;
+// Mac_dest3 = 0xFF;
+// Mac_dest4 = 0xFF;
+// Mac_dest5 = 0xFF;
+// Mac_dest6 = 0xFF;
+ Mac_source1 = 0x01; // Assign an MAC address for DE2
+ Mac_source2 = 0x60;
+ Mac_source3 = 0x6E;
+ Mac_source4 = 0x11;
+ Mac_source5 = 0x02;
+ Mac_source6 = 0x0F;
+
+ lenght_h = ((data_lenght+8) & 0xFF00)>>8; // Convert in H byte and L byte
+ lenght_l = ((data_lenght+8) & 0x00FF);
+
+ IPlenght = data_lenght + 8 + 20; // IP Lenght for IP header
+ IPlenght_h = (IPlenght & 0xFF00)>>8; // Convert in H byte and L byte
+ IPlenght_l = (IPlenght & 0x00FF);
+ // Calculating the IP checksum
+ IPchecksum1 = 0x0000C511 + (IPsource_1<<8)+IPsource_2+(IPsource_3<<8)+IPsource_4+
+ (IPdestination_1<<8)+IPdestination_2+(IPdestination_3<<8)+(IPdestination_4)+
+ (IPlenght_h<<8) + IPlenght_l;
+ IPchecksum2 = ((IPchecksum1&0x0000FFFF)+(IPchecksum1>>16));
+ IPchecksum3 = 0x0000FFFF - IPchecksum2;
+ IPchecksum4 = (IPchecksum3 & 0xFF00)>>8;
+ IPchecksum5 = (IPchecksum3 & 0x00FF);
+
+ unsigned char TXT[flenght] = { Mac_dest1, Mac_dest2, Mac_dest3, Mac_dest4 ,Mac_dest5, Mac_dest6,
+ Mac_source1, Mac_source2, Mac_source3, Mac_source4, Mac_source5, Mac_source6,
+ 0x08, 0x00, 0x45, 0x00, IPlenght_h, IPlenght_l,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x11,
+ IPchecksum4, IPchecksum5, IPsource_1, IPsource_2, IPsource_3, IPsource_4,
+ IPdestination_1, IPdestination_2, IPdestination_3, IPdestination_4, 0x04, 0x00,
+ 0x04, 0x00, lenght_h, lenght_l, 0x00, 0x00};
+
+ for (i = 0; i < 42; i++) // Load the TXT[] in the SND (ethernet packet).
+ SND[i] = TXT[i];
+
+ for (i = 42; i < flenght-4; i++) // generating the data to send.
+ SND[i] = i-42;
+
+ SND[i++] = 0x35; // This checksum is not correct... but also the net recieve the packets correctly.
+ SND[i++] = 0x15; // To do, calculate checksum.
+ SND[i++] = 0xF0;
+ SND[i++] = 0x13;
+
+
+ }
+
+void ethernet_interrupts(void)
+{
+
+ ReceivePacket(RX_DATA,&rx_len);
+ rx_cnt++;
+ int j;
+ for(j=0;j<rx_len;j++)
+ {
+ printf("%x ",RX_DATA[j]);
+ }
+ printf("\n\n");
+}
+
+int main(void)
+{
+ UDP_Init();
+ printf("Working...\n");
+ msleep(500);
+ DM9000_init();//Initialize the DM9000A.
+ alt_irq_register( DM9000A_0_IRQ, NULL, (void*)ethernet_interrupts );
+
+ rx_cnt = 0;
+ tx_cnt = 0;
+ while (1)
+ {
+ tx_cnt++;
+ TransmitPacket(SND,flenght);
+ printf("Tx %5d frame\n",tx_cnt);
+ printf("Rx %5d frame\n\n",rx_cnt);
+ msleep(500);
+ }
+
+}
+//-------------------------------------------------------------------------
+
+
+#endif
diff --git a/src/pong3.c b/src/pong3.c
new file mode 100644
index 0000000..aba6ae6
--- /dev/null
+++ b/src/pong3.c
@@ -0,0 +1,280 @@
+#include <io.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include "system.h"
+
+#include "GPU.h"
+
+#define msleep(msec) usleep(1000*msec);
+
+
+static void
+pio_write (unsigned int data)
+{
+ IOWR (PIO_0_BASE, 0, data);
+}
+
+
+static void
+gpu_write (unsigned int reg, unsigned int data)
+{
+ IOWR (GPU_0_BASE, reg << 2, data);
+}
+
+
+static void
+update_gpu (int x, int y, int bat0, int bat1)
+{
+ // set locations
+ gpu_write (GPU_REG_SPRITE_X, x + GPU_OFFSET);
+ gpu_write (GPU_REG_SPRITE_Y, y + GPU_OFFSET);
+ gpu_write (GPU_REG_BAT0_Y, bat0 + GPU_OFFSET);
+ gpu_write (GPU_REG_BAT1_Y, bat1 + GPU_OFFSET);
+
+
+ // enable video
+ gpu_write (GPU_REG_BLANK, 0);
+}
+
+
+static void
+show_score (int score)
+{
+ // int to seven segment lookup: MSB dp g f e d c b a LSB
+ const uint8_t lookup[10] =
+ { 0x3F, 0x6, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x7, 0x7F, 0x6F };
+
+ uint8_t ss = 0;
+
+ // show negative with DP
+ if (score < 0)
+ {
+ ss |= 0x80;
+ score = -score;
+ }
+
+ if (score > 9)
+ score = 9;
+
+ ss |= lookup[score];
+
+ pio_write (ss);
+}
+
+static void
+load_sprite (void)
+{
+ const uint16_t sprite[16] =
+ { 0x00C0, 0x03E0, 0x0FF8, 0x1FFE, 0x3FC7, 0x3F83, 0x3933, 0x3987, 0x3D37,
+ 0x3D37, 0x3D87, 0x3FFF, 0x1FFE, 0x07F8, 0x01E0, 0x00C0
+ };
+ const unsigned int n = sizeof (sprite) / sizeof (uint16_t);
+ unsigned int i;
+
+ gpu_write (GPU_REG_SPRITE_COLOUR, GPU_RGB(7,2,0));
+
+ // squirt the bromium logo into the sprite
+ for (i = 0; i < n; ++i)
+ gpu_write (GPU_REG_SPRITE_BASE + i, sprite[i]);
+}
+
+
+static int
+dir (int a, int b)
+{
+ if (a > b)
+ return 1;
+ if (a < b)
+ return -1;
+ return 0;
+}
+
+static void
+move_bat (int *b, int db)
+{
+ *b += dir (db, *b);
+}
+
+static int
+squish (int *v, int min, int max)
+{
+ if (*v < min)
+ {
+ *v = min;
+ return 1;
+ }
+ if (*v >= max)
+ {
+ *v = max - 1;
+ return 1;
+ }
+ return 0;
+}
+
+static int
+find_intersection (int x, int y, int xd, int yd, int t)
+{
+
+ // super lazy - we should use the power of MATHS
+
+ while (x != t)
+ {
+ x += xd;
+ y += yd;
+
+ if (squish (&y, 0, GPU_HEIGHT))
+ yd = -yd;
+
+ if (squish (&x, 0, GPU_WIDTH))
+ xd = -xd;
+ }
+
+ return y;
+}
+
+static int
+has_missed (int y1, int y2)
+{
+ y1 = y1 - y2;
+ if (y1 < 0)
+ y1 = -y1;
+ if (y1 > 20)
+ return 1;
+ return 0;
+}
+
+static int
+x_speed (void)
+{
+ return (rand () % 10) + 1;
+}
+
+static int
+y_speed (void)
+{
+ return (rand () % 9) - 4;
+}
+
+
+int
+main (void)
+{
+ int x, y, xd, yd;
+ int bat0, dbat0;
+ int bat1, dbat1;
+ int score = 0;
+ int serve = 0;
+ int i;
+
+ printf ("Working...\n");
+
+ srand (12392184);
+
+ bat0 = GPU_HEIGHT / 2;
+ bat1 = GPU_HEIGHT / 2;
+
+ load_sprite ();
+
+ for (;;)
+ {
+ xd = x_speed ();
+ yd = y_speed ();
+
+ show_score (score);
+
+ if (!serve)
+ {
+ x = 1;
+ y = bat0;
+ dbat0 = GPU_HEIGHT / 2;
+ dbat1 = find_intersection (x + xd, y + yd, xd, yd, GPU_WIDTH - 1);
+ }
+ else
+ {
+ x = GPU_WIDTH - 2;
+ y = bat1;
+ yd = -yd;
+ dbat0 = find_intersection (x + xd, y + yd, xd, yd, 0);
+ dbat1 = GPU_HEIGHT / 2;
+ }
+ serve = !serve;
+
+ for (;;)
+ {
+ x += xd;
+ y += yd;
+
+
+ if (squish (&y, 0, GPU_HEIGHT))
+ yd = -yd;
+
+ if (squish (&x, 0, GPU_WIDTH))
+ {
+ xd = x_speed ();
+ if (x)
+ xd = -xd;
+ yd = y_speed ();
+
+ if (x)
+ {
+
+ if (has_missed (y, bat1))
+ {
+ score++;
+ break;
+ }
+ dbat0 = find_intersection (x + xd, y + yd, xd, yd, 0);
+ dbat1 = GPU_HEIGHT / 2;
+
+ }
+ else
+ {
+
+ if (has_missed (y, bat0))
+ {
+ score--;
+ break;
+ }
+ dbat0 = GPU_HEIGHT / 2;
+ dbat1 =
+ find_intersection (x + xd, y + yd, xd, yd, GPU_WIDTH - 1);
+
+ }
+ }
+
+ move_bat (&bat0, dbat0);
+ move_bat (&bat1, dbat1);
+
+ update_gpu (x, y, bat0, bat1);
+
+ msleep (2);
+ }
+
+ if (!serve)
+ {
+ dbat1 = GPU_HEIGHT / 2;
+ dbat0 = bat0;
+ }
+ else
+ {
+ dbat0 = GPU_HEIGHT / 2;
+ dbat1 = bat1;
+ }
+
+ for (i = 0; i < 200; ++i)
+ {
+ if (i == 100)
+ show_score (score);
+
+ move_bat (&bat0, dbat0);
+ move_bat (&bat1, dbat1);
+
+ update_gpu (x, y, bat0, bat1);
+ msleep (2);
+
+ }
+ }
+}