'----------------------------------------------------------------------------------
' Embedded UDP&WebServer   -   Atmega32 and RTL8019AS    -   Embedded UDP&WebServer
'----------------------------------------------------------------------------------
'
' Version 1 - April 1 2005 - Ben Zijlstra - Netherlands - https://benshobbycorner.nl/bzijlstra



$crystal = 7372800
$regfile = "M32def.dat"
$baud = 57600

Declare Sub Write_rtl8019as(byval Regaddr As Byte , Byval Regdata As Byte)
Declare Sub Read_rtl8019as(byval Regaddr As Byte)
Declare Sub Init_rtl8019as
'Declare Sub Showregs
Declare Sub Getpacket
Declare Sub Overrun
Declare Sub Arp
Declare Sub Icmp
Declare Sub Icmp_checksum
Declare Sub Tcp
Declare Sub Write_dest_mac
Declare Sub Packetshape
Declare Sub Echopacket
Declare Sub Setipaddrs
Declare Sub Ip_header_checksum
Declare Sub Udp
Declare Sub Udp_checksum
'
Declare Sub General_part_checksum(byval Val1 As Byte , Byval Val2 As Word)
'
'
Declare Sub Lcd_init
Declare Sub Lcd_char(byval Lcd_c As Byte)
Declare Sub Lcd_txt
Declare Sub Lcdhome                                         ' CLS/Home
Declare Sub Firstline                                       ' goto 0/0 of LCD
Declare Sub Secondline


Declare Sub Http
Declare Sub Tcp_checksum
Declare Sub Send_tcp_packet
Declare Sub Setup_packet
Declare Sub Assemble_ack
Declare Sub Tcpseqtomyseq


Declare Sub Relayon(byval X As Byte)
Declare Sub Relayoff(byval X As Byte)
Declare Sub Status

Dim Myip(4) As Byte At &H64
Dim My_ip As Long At &H64 Overlay


Dim Client_seqnum As Long At &H8E
Dim Client_seqnum0 As Byte At &H8E Overlay
Dim Client_seqnum1 As Byte At &H8F Overlay
Dim Client_seqnum2 As Byte At &H90 Overlay
Dim Client_seqnum3 As Byte At &H91 Overlay

Dim Incoming_ack As Long At &H92
Dim Incoming_ack0 As Byte At &H92 Overlay
Dim Incoming_ack1 As Byte At &H93 Overlay
Dim Incoming_ack2 As Byte At &H94 Overlay
Dim Incoming_ack3 As Byte At &H95 Overlay

Dim My_seqnum As Long At &HB7
Dim My_seqnum0 As Byte At &HB7 Overlay
Dim My_seqnum1 As Byte At &HB8 Overlay
Dim My_seqnum2 As Byte At &HB9 Overlay
Dim My_seqnum3 As Byte At &HBA Overlay
'
Dim Tempword As Word At &H60
Dim Tempwordh As Byte At &H61 Overlay
Dim Tempwordl As Byte At &H60 Overlay

Dim Val1 As Byte
Dim Val2 As Word                                            ' up to 65535 characters
Dim Val3 As Byte
Dim Val4 As Byte


Dim Regaddr As Byte
Dim Regdata As Byte
'Ethernet header layout
Dim Byte_read As Byte
Dim Hulp1 As Byte
Dim Mymac(6) As Byte
Dim I As Integer
Dim Rxlen As Word
Dim Hulp2 As Word
Dim Hulp3 As Word
Dim Hulp4 As Byte
Dim Data_l As Byte
Dim Data_h As Byte
'RTL8019AS
Dim Txstart As Byte
Dim Txlen As Word

Dim I_header_length As Word
Dim I_odd As Byte
Dim I_chksum32 As Long
Dim Hulp6 As Word At &HAF
Dim Hulp6h As Byte At &HB0 Overlay
Dim Hulp6l As Byte At &HAF Overlay
Dim I_x As Word
Dim I_checksum16 As Word

Dim I_value16 As Word At &HB1
Dim I_value16h As Byte At &HB2 Overlay
Dim I_value16l As Byte At &HB1 Overlay

Dim Result16 As Word At &HB5
Dim Result16h As Byte At &HB6 Overlay
Dim Result16l As Byte At &HB5 Overlay

'variables with overlays
Dim Pageheader(4) As Byte At &HAB
Dim T_enetpacketlenl As Byte At &HAD Overlay
Dim T_enetpacketlenh As Byte At &HAE Overlay
Dim Resend As Byte
Dim T As Byte


Dim Packet(1500) As Byte At &HC0
'Ethernet packet destination
Dim T_enetpacketdest0 As Byte At &HC0 Overlay
Dim T_enetpacketdest1 As Byte At &HC1 Overlay
Dim T_enetpacketdest2 As Byte At &HC2 Overlay
Dim T_enetpacketdest3 As Byte At &HC3 Overlay
Dim T_enetpacketdest4 As Byte At &HC4 Overlay
Dim T_enetpacketdest5 As Byte At &HC5 Overlay
'Ethernet packet source
Dim T_enetpacketsrc0 As Byte At &HC6 Overlay
Dim T_enetpacketsrc1 As Byte At &HC7 Overlay
Dim T_enetpacketsrc2 As Byte At &HC8 Overlay
Dim T_enetpacketsrc3 As Byte At &HC9 Overlay
Dim T_enetpacketsrc4 As Byte At &HCA Overlay
Dim T_enetpacketsrc5 As Byte At &HCB Overlay
'Ethernet packet type
Dim T_enetpackettype As Word At &HCC Overlay
Dim T_arp_hwtype1 As Byte At &HCF Overlay
'Arp
Dim T_arp_prttype1 As Byte At &HD1 Overlay
Dim T_arp_hwlen As Byte At &HD2 Overlay
Dim T_arp_prlen As Byte At &HD3 Overlay
Dim T_arp_op1 As Byte At &HD5 Overlay
'arp source ip address
Dim T_arp_sipaddr0 As Byte At &HDC Overlay
Dim T_arp_sipaddr1 As Byte At &HDD Overlay
Dim T_arp_sipaddr2 As Byte At &HDE Overlay
Dim T_arp_sipaddr3 As Byte At &HDF Overlay
'arp target IP address
Dim T_arp_tipaddr As Long At &HE6 Overlay
'IP header layout IP version and header length
Dim T_ip_vers_len As Byte At &HCE Overlay
'packet length
Dim T_ip_pktlen0 As Byte At &HD0 Overlay
Dim T_ip_pktlen1 As Byte At &HD1 Overlay
'protocol (ICMP=1, TCP=6, UDP=11)
Dim T_ip_proto As Byte At &HD7 Overlay
'header checksum
Dim T_ip_hdr_cksum0 As Byte At &HD8 Overlay
Dim T_ip_hdr_cksum1 As Byte At &HD9 Overlay
Dim T_ip_hdr_cksum As Word At &HD8 Overlay
'IP address of source
Dim T_ip_srcaddr0 As Byte At &HDA Overlay
Dim T_ip_srcaddr1 As Byte At &HDB Overlay
Dim T_ip_srcaddr2 As Byte At &HDC Overlay
Dim T_ip_srcaddr3 As Byte At &HDD Overlay

Dim T_ip_srcaddr As Long At &HDA Overlay

'IP address of destination
Dim T_ip_destaddr0 As Byte At &HDE Overlay
Dim T_ip_destaddr1 As Byte At &HDF Overlay
Dim T_ip_destaddr2 As Byte At &HE0 Overlay
Dim T_ip_destaddr3 As Byte At &HE1 Overlay

Dim T_ip_destaddr As Long At &HDE Overlay

Dim T_icmp_type As Byte At &HE2 Overlay
Dim T_icmp_code As Byte At &HE3 Overlay
Dim T_icmp_cksum0 As Byte At &HE4 Overlay
Dim T_icmp_cksum1 As Byte At &HE5 Overlay
Dim T_icmp_cksum As Word At &HE4 Overlay

Dim Tcp_srcporth As Byte At &HE2 Overlay
Dim Tcp_srcportl As Byte At &HE3 Overlay

Dim Tcp_destporth As Byte At &HE4 Overlay
Dim Tcp_destportl As Byte At &HE5 Overlay

Dim Tcp_seqnum3 As Byte At &HE6 Overlay
Dim Tcp_seqnum2 As Byte At &HE7 Overlay
Dim Tcp_seqnum1 As Byte At &HE8 Overlay
Dim Tcp_seqnum0 As Byte At &HE9 Overlay

Dim Tcp_acknum3 As Byte At &HEA Overlay
Dim Tcp_acknum2 As Byte At &HEB Overlay
Dim Tcp_acknum1 As Byte At &HEC Overlay
Dim Tcp_acknum0 As Byte At &HED Overlay

Dim Tcp_hdr As Byte At &HEE Overlay
Dim Tcp_flags As Byte At &HEF Overlay
Dim Tcp_cksumh As Byte At &HF2 Overlay
Dim Tcp_cksuml As Byte At &HF3 Overlay
Dim Tcp_cksum As Word At &HF2 Overlay
'UDP header
Dim T_udp_srcport0 As Byte At &HE2 Overlay
Dim T_udp_srcport1 As Byte At &HE3 Overlay
Dim T_udp_destport0 As Byte At &HE4 Overlay
Dim T_udp_destport1 As Byte At &HE5 Overlay
Dim T_udp_destport As Word At &HE4 Overlay
Dim T_udp_len0 As Byte At &HE6 Overlay
Dim T_udp_len1 As Byte At &HE7 Overlay
Dim T_udp_chksum0 As Byte At &HE8 Overlay
Dim T_udp_chksum1 As Byte At &HE9 Overlay
Dim T_udp_data As Byte At &HEA Overlay
'LCD variables
Dim Lcd_t As String * 40
Dim Lcd_tempstr As String * 1
Dim Lcd_temp As Byte
Dim Lcd_x As Byte
Dim Lcd_hulp As Byte
Dim Lcd_h As Byte

Dim Lcdpresent As Byte

Dim Tcp_fin As Bit
Dim Tcp_syn As Bit
Dim Tcp_rst As Bit
Dim Tcp_psh As Bit
Dim Tcp_ack As Bit
Dim Tcp_urg As Bit
Dim Tcpdatalen_in As Word
Dim Tcpdatalen_out As Word
Dim Ip_packet_len As Word
Dim Flags As Byte
Dim Msg_temp As String * 55
Dim Y As Word
Dim Tempstring1 As String * 1
Dim Expected_ack As Long

Dim Triggerstr As String * 20
Dim Tempstring As String * 10

Dim Portpntr As Byte At &HEA Overlay
Dim Portval As String * 4 At &HEB Overlay
Dim Relaypntr As Byte At &HEF Overlay
Dim Relval As String * 4 At &HF0 Overlay
'Dim Temppntr As Byte At &HF4 Overlay
'Dim Tempval As String * 5 At &HF5 Overlay
Dim Relaystatus As Byte
'idle time
Dim Idletime As Long


Const Debug = 0                                             ' put 1 for debug, 0 for no debug
Const Rstport = &H18
Const Isr = &H07
Const Msg_initfail = "Init failed"
Const Cr = &H00
Const Dcrval = &H58
Const Dcr = &H0E
Const Rbcr0 = &H0A
Const Rbcr1 = &H0B
Const Rcr = &H0C
Const Tpsr = &H04
Const Txtstart = &H40
Const Tcr = &H0D
Const Pstart = &H01
Const Rxstart = &H46
Const Bnry = &H03
Const Pstop = &H02
Const Rxstop = &H60
Const Curr = &H07
Const Imr = &H0F
Const Imrval = &H11
Const Tcrval = &H00
Const Rdmaport = &H10
Const Rsar0 = &H08
Const Rsar1 = &H09
Const Tbcr0 = &H05
Const Tbcr1 = &H06

'IP protocol types
'icmp
Const Prot_icmp = &H01
'tcp
Const Prot_tcp = &H06
'udp
Const Prot_udp = &H11

Const Synflag = 0
Const Finflag = 1

'LCD
Const Rs = 4
Const E = 7
Const Pcf8574 = &H40


Const Triggerstring = "SEND INFORMATION NOW"

'RTL8019AS ISR Register definitions
Const Rdc = &H40

Config Int0 = Rising
'I2c
Config Scl = Portc.0
Config Sda = Portc.1

Lcdpresent = 1

Mymac(1) = &H00
Mymac(2) = &H10
Mymac(3) = &H20
Mymac(4) = &H30
Mymac(5) = &H40
Mymac(6) = &H50

Myip(1) = 192
Myip(2) = 168
Myip(3) = 0
Myip(4) = 100

#if Debug = 1
Print "Hello world"
#endif

Databus Alias Porta
_databus Alias Pina
Rtldata Alias Porta
Databus_ddr Alias Ddra

Addrbus Alias Portb
Addrbus_ddr Alias Ddrb

Resetport Alias Portd
Eeprom Alias Portd
Ior_pin Alias Portd.6
Iow_pin Alias Portd.7
Resetport_ddr Alias Ddrd

Inputport1 Alias Pinc
Inputport2 Alias Portc

Latch Alias Portd.3
Resetport_ddr = &HF8                                        ' leave RXD and TXD

Main:
Reset Latch
Databus_ddr = &HFF
Databus = 0                                                 ' put zero's on relays-port
Set Latch
Reset Latch
Relaystatus = 0                                             ' put zero's in the relaystatus byte
Call Lcd_init
Lcd_t = "VA3TO/EIO-board"
Call Lcd_txt
Call Secondline
Lcd_t = "Tutorial"
Call Lcd_txt
Call Init_rtl8019as

'Call Showregs

Enable Interrupts
Enable Int0
On Int0 Rtl8019as_interrupt
'start the NIC
Call Write_rtl8019as(cr , &H22)
Do
Loop
End


' Routine to handle an interrupt on the RTL8019AS
'
Rtl8019as_interrupt:
   #if Debug = 1
      Print "Interrupt from RTL8019as"
   #endif
   Disable Int0
   'read the interrupt status register
   Call Read_rtl8019as(isr)
   'if the receive buffer has been overrun
   If Byte_read.4 = 1 Then
      Call Overrun
   End If
   'if the receive buffer holds a good packet
   If Byte_read.0 = 1 Then
      Call Getpacket
   End If
   'make sure the receive buffer ring is empty. If BNRY = CURR, the buffer is empty
   Call Read_rtl8019as(bnry)
   Data_l = Byte_read
   Call Write_rtl8019as(cr , &H62)
   Call Read_rtl8019as(curr)
   Data_h = Byte_read
   Call Write_rtl8019as(cr , &H22)
   'buffer is not empty, get next packet
   If Data_l <> Data_h Then
      Call Getpacket
   End If
   'reset the interrupts bits
   Call Write_rtl8019as(isr , &HFF)
   Call Write_rtl8019as(cr , &H22)
   Enable Int0
Return


' Routine to Write to NIC Control register
'
Sub Write_rtl8019as(regaddr , Regdata)
   Addrbus = Regaddr
   Databus = Regdata
   Databus_ddr = &HFF
   nop
   Reset Iow_pin
   nop
   Set Iow_pin
   nop
   Databus_ddr = &H00
   Databus = &HFF
End Sub


' Routine to read from NIC Control register
'
Sub Read_rtl8019as(regaddr)
   Databus_ddr = &H00
   Databus = &HFF
   Addrbus = Regaddr
   Reset Ior_pin
   nop
   Byte_read = Pina
   nop
   Set Ior_pin
   nop
End Sub


' Routine to initialise the RTL8019AS ethernetchip
'
Sub Init_rtl8019as
Databus_ddr = &H00
Databus = &HFF
Addrbus_ddr = &HFF
Addrbus = &H00
Resetport_ddr = &HF8
Reset Eeprom.5
Set Iow_pin
Set Ior_pin
Set Resetport.4
Waitms 2
Reset Resetport.4
Call Read_rtl8019as(rstport)
Call Write_rtl8019as(rstport , Byte_read)
Waitms 10
'check for good soft reset
Call Read_rtl8019as(isr)
If Byte_read.7 = 0 Then
      Print Msg_initfail
End If
Call Write_rtl8019as(cr , &H21)
Waitms 2
Call Write_rtl8019as(dcr , Dcrval)
Call Write_rtl8019as(rbcr0 , &H00)
Call Write_rtl8019as(rbcr1 , &H00)
Call Write_rtl8019as(rcr , &H04)
Call Write_rtl8019as(tpsr , Txtstart)
Call Write_rtl8019as(tcr , &H02)
Call Write_rtl8019as(pstart , Rxstart)
Call Write_rtl8019as(bnry , Rxstart)
Call Write_rtl8019as(pstop , Rxstop)
Call Write_rtl8019as(cr , &H61)
Waitms 2
Call Write_rtl8019as(curr , Rxstart)
For Hulp1 = 1 To 6
     Call Write_rtl8019as(hulp1 , Mymac(hulp1))
Next Hulp1
Call Write_rtl8019as(cr , &H21)
Call Write_rtl8019as(dcr , Dcrval)
Call Write_rtl8019as(cr , &H22)
Call Write_rtl8019as(isr , &HFF)
Call Write_rtl8019as(imr , Imrval)
Call Write_rtl8019as(tcr , Tcrval)
End Sub


'(
' Routine show the contents of the RTL8019as registers
'
Sub Showregs
Local Cntr1 As Byte
Local Cntr2 As Byte
Call Write_rtl8019as(cr , &H21)
Print
Print "Realtek 8019AS Register dump"
Print
Print "REG  Page0 Page1 Page2 Page3"
Print
For Cntr1 = 0 To 15
   Cntr2 = Cntr1
   Print Hex(cntr2);
   Print "    ";
   Call Write_rtl8019as(cr , &H21)
   Cntr2 = Cntr1
   Call Read_rtl8019as(cntr2)
   Print Hex(byte_read);
   Print "    ";
   Call Write_rtl8019as(cr , &H61)
   Cntr2 = Cntr1
   Call Read_rtl8019as(cntr2)
   Print Hex(byte_read);
   Print "    ";
   Call Write_rtl8019as(cr , &HA1)
   Cntr2 = Cntr1
   Call Read_rtl8019as(cntr2)
   Print Hex(byte_read);
   Print "    ";
   Call Write_rtl8019as(cr , &HE1)
   Cntr2 = Cntr1
   Call Read_rtl8019as(cntr2)
   Print Hex(byte_read)
Next Cntr1
End Sub
')


Sub Overrun
   Call Read_rtl8019as(cr)
   Data_l = Byte_read
   Call Write_rtl8019as(cr , &H21)
   Waitms 2
   Call Write_rtl8019as(rbcr0 , &H00)
   Call Write_rtl8019as(rbcr1 , &H00)
   Hulp1 = Data_l And &H04
   If Hulp1 <> 0 Then
      Resend = 0
      Else
         If Hulp1 = 0 Then
            Call Read_rtl8019as(isr)
            Data_l = Byte_read
            Hulp1 = Data_l And &H02
            Hulp4 = Data_l And &H08
            Hulp3 = Hulp1 Or Hulp4
               If Hulp3 > 0 Then
                  Resend = 0
                  Else
                  Resend = 1
               End If
         End If
   End If
   Call Write_rtl8019as(tcr , &H02)
   Call Write_rtl8019as(cr , &H22)
   Call Write_rtl8019as(bnry , Rxstart)
   Call Write_rtl8019as(cr , &H62)
   Call Write_rtl8019as(curr , Rxstart)
   Call Write_rtl8019as(cr , &H22)
   Call Write_rtl8019as(isr , &H10)
   Call Write_rtl8019as(tcr , Tcrval)
End Sub


' Routine to execute send packet command to retrieve the packet
'
Sub Getpacket
   Call Write_rtl8019as(cr , &H1A)
   For I = 0 To 4
      Call Read_rtl8019as(rdmaport)
      Pageheader(i + 1) = Byte_read
   Next I
   'watch it. overlay variables
   Result16h = T_enetpacketlenh
   Result16l = T_enetpacketlenl
   Rxlen = Result16
   Hulp2 = Rxlen + 1
   For I = 1 To Hulp2
      Call Read_rtl8019as(rdmaport)
      'dump any bytes that will overrun the receive buffer
      If I < 1500 Then
         Packet(i + 1) = Byte_read
      End If
   Next I
   Hulp1 = Byte_read And Rdc
   If Hulp1 <> 64 Then
      Call Read_rtl8019as(isr)
   End If

   Call Write_rtl8019as(isr , &HFF)


   ' Routine to process an ARP packet
   '
   If T_enetpackettype = &H0608 Then
      If T_arp_hwtype1 = &H01 Then
         If T_arp_prttype1 = &H00 Then
            If T_arp_hwlen = &H06 Then
               If T_arp_prlen = &H04 Then
                  If T_arp_op1 = &H01 Then
                     If My_ip = T_arp_tipaddr Then
                        Call Arp
                     End If
                  End If
               End If
            End If
         End If
      End If
   End If


   ' Routine to go ahead with icmp or udp
   '
   If T_enetpackettype = &H0008 Then
         If T_ip_destaddr = My_ip Then
            Select Case T_ip_proto
               Case Prot_icmp : Call Icmp
               Case Prot_tcp : Call Tcp
               Case Prot_udp : Call Udp
            End Select
         End If
   End If
End Sub


' Routine to handle ARP-traffic
'
Sub Arp
   'Start the NIC
   Call Write_rtl8019as(cr , &H22)
   'load beginning page for transmit buffer
   Call Write_rtl8019as(tpsr , Txtstart)
   'set start address for remote DMA operation
   Call Write_rtl8019as(rsar0 , &H00)
   Call Write_rtl8019as(rsar1 , &H40)
   'clear the interrupts
   Call Write_rtl8019as(isr , &HFF)
   'load data byte count for remote DMA
   Call Write_rtl8019as(rbcr0 , &H3C)
   Call Write_rtl8019as(rbcr1 , &H00)
   'do remote write operation
   Call Write_rtl8019as(cr , &H12)
   'write destination MAC address
   Call Write_dest_mac
   'write source address
   For I = 1 To 6
       Call Write_rtl8019as(rdmaport , Mymac(i))
   Next I
   'arp target IP address
   'arp_op1 = packet(&h16)
   Packet(&H16) = &H02
   For I = 0 To 9
      Hulp1 = &HCC + I
      T = Peek(hulp1)
      Call Write_rtl8019as(rdmaport , T)
   Next I
   'write ethernet module mac address
   For I = 1 To 6
      Call Write_rtl8019as(rdmaport , Mymac(i))
   Next I
   'write myip
   For I = 1 To 4
      Call Write_rtl8019as(rdmaport , Myip(i))
   Next I
   'write remote mac address
   Call Write_dest_mac
   'write remote IP address
   Call Write_rtl8019as(rdmaport , T_arp_sipaddr0)
   Call Write_rtl8019as(rdmaport , T_arp_sipaddr1)
   Call Write_rtl8019as(rdmaport , T_arp_sipaddr2)
   Call Write_rtl8019as(rdmaport , T_arp_sipaddr3)
  'write som pad characters to fill out the packet to the minimum length
   For I = 0 To &H11
      Call Write_rtl8019as(rdmaport , &H00)
   Next I
   'make sure the DMA operation has succesfully completed
   Byte_read = 0
   Do
      Hulp1 = Byte_read And Rdc
      Call Read_rtl8019as(isr)
   Loop Until Hulp1 = 0
   'load numbers of bytes to be transmitted
   Call Write_rtl8019as(tbcr0 , &H3C)
   Call Write_rtl8019as(tbcr1 , &H00)
   'send the contents of the transmit buffer onto the network
   Call Write_rtl8019as(cr , &H24)
End Sub



Sub Write_dest_mac
   Call Write_rtl8019as(rdmaport , T_enetpacketsrc0)
   Call Write_rtl8019as(rdmaport , T_enetpacketsrc1)
   Call Write_rtl8019as(rdmaport , T_enetpacketsrc2)
   Call Write_rtl8019as(rdmaport , T_enetpacketsrc3)
   Call Write_rtl8019as(rdmaport , T_enetpacketsrc4)
   Call Write_rtl8019as(rdmaport , T_enetpacketsrc5)
End Sub


Sub Icmp
'set echo reply
T_icmp_type = &H00
T_icmp_code = &H00
'setup the IP-header
Call Setipaddrs
Call Icmp_checksum
Call Echopacket
End Sub



' Routine to handle the source/destination address
'
Sub Setipaddrs
T_ip_destaddr = T_ip_srcaddr
'make ethernet module IP address source address
T_ip_srcaddr = My_ip
Call Packetshape
Call Ip_header_checksum
End Sub


' Routine to echo a complete packet
'
Sub Echopacket
Call Write_rtl8019as(cr , &H22)
Call Write_rtl8019as(tpsr , Txtstart)
Call Write_rtl8019as(rsar0 , &H00)
Call Write_rtl8019as(rsar1 , &H40)
Call Write_rtl8019as(isr , &HFF)
Hulp1 = T_enetpacketlenl - 4
Call Write_rtl8019as(rbcr0 , Hulp1)
Call Write_rtl8019as(rbcr1 , T_enetpacketlenh)
Call Write_rtl8019as(cr , &H12)
Result16h = T_enetpacketlenh

Result16l = T_enetpacketlenl
Result16 = Result16 - 4
Txlen = Result16
'write the complete packet to the RTL8019AS from packet(1) to packet(txlen+1)
Hulp2 = Txlen + 1
For I = 1 To Hulp2
Call Write_rtl8019as(rdmaport , Packet(i))
Next I
Byte_read = 0
While Hulp1 <> 0
Hulp1 = Byte_read And Rdc
Call Read_rtl8019as(isr)
Wend
Hulp1 = T_enetpacketlenl - 4
Call Write_rtl8019as(tbcr0 , Hulp1)
Call Write_rtl8019as(tbcr1 , T_enetpacketlenh)
Call Write_rtl8019as(cr , &H24)
End Sub


Sub Packetshape
'move hardware source address to destination address
T_enetpacketdest0 = T_enetpacketsrc0
T_enetpacketdest1 = T_enetpacketsrc1
T_enetpacketdest2 = T_enetpacketsrc2
T_enetpacketdest3 = T_enetpacketsrc3
T_enetpacketdest4 = T_enetpacketsrc4
T_enetpacketdest5 = T_enetpacketsrc5
' 'Make ethernet module mac address the source address
T_enetpacketsrc0 = Mymac(1)
T_enetpacketsrc1 = Mymac(2)
T_enetpacketsrc2 = Mymac(3)
T_enetpacketsrc3 = Mymac(4)
T_enetpacketsrc4 = Mymac(5)
T_enetpacketsrc5 = Mymac(6)
End Sub


' Routine to calculate a ICMP-checksum
'
Sub Icmp_checksum
   'clear the ICMP checksum
   T_icmp_cksum = &H00
   'calculate the ICMP checksum
   I_header_length = T_ip_pktlen1 - 20
   'I_header_length = I_header_length - 20
   I_odd = I_header_length Mod 2
   '14 for MAC-part
   '20 for IP-header
   'start on 35
   'ip_pktlen = 00 3c (60)
   'icmp-packetlengte = ip_pktlen - ip_header
   I_chksum32 = 0
   'Total packetlength - ip_header - 1
   Hulp6h = T_ip_pktlen0
   Hulp6l = T_ip_pktlen1
   Val1 = 35
   Val2 = Hulp6 + 13
   Call General_part_checksum(val1 , Val2)
   T_icmp_cksum0 = Val3
   T_icmp_cksum1 = Val4
End Sub


' Routine to calculate a IP-header checksum
'
Sub Ip_header_checksum
   Local Ip_x As Byte
   Local Ip_hulp1 As Byte
   Local Ip_chksum32 As Long
   Local Ip_checksum16 As Word
   Local Ip_temp16 As Word
   Local Ip_header_length As Byte
   'calculate the IP header checksum
   T_ip_hdr_cksum = &H00
'   Hdr_chksum = 0
   I_chksum32 = 0
   Ip_header_length = T_ip_vers_len And &H0F
   Ip_header_length = 4 * Ip_header_length

   I_chksum32 = 0
   I_odd = 0

   Val1 = 15
   Val2 = &H0E + Ip_header_length
   Call General_part_checksum(val1 , Val2)
   T_ip_hdr_cksum0 = Val3
   T_ip_hdr_cksum1 = Val4
End Sub


' Routine to handle UDP-traffic
'
Sub Udp
Triggerstr = ""
Hulp1 = &HEA
For Hulp2 = 1 To 20
   Hulp3 = Peek(hulp1)
   Triggerstr = Triggerstr + Chr(hulp3)
   Incr Hulp1
Next Hulp2
      'From within a VB-program
      If T_udp_destport = &H8813 Then
            Select Case T_udp_data
               Case &H01 : Call Relayon(1)
               Case &H02 : Call Relayon(2)
               Case &H03 : Call Relayon(3)
               Case &H04 : Call Relayon(4)
               Case &HA1 : Call Relayoff(5)
               Case &HA2 : Call Relayoff(6)
               Case &HA3 : Call Relayoff(7)
               Case &HA4 : Call Relayoff(8)
            End Select
            If Triggerstr = Triggerstring Then
               If Lcdpresent = 1 Then
                  Lcd_t = "*UDP request#Sending: "
                  Call Lcd_txt
               End If
               Portpntr = Asc( "P")
               Tempstring = Bin(inputport1)
               Portval = Left(tempstring , 4)
               If Lcdpresent = 1 Then
                  Lcd_t = "P" + Portval
               End If
               Relaypntr = Asc( "R")
               Tempstring = Bin(relaystatus)
               Relval = Right(tempstring , 4)
               If Lcdpresent = 1 Then
                  Lcd_t = Lcd_t + "R"
                  Lcd_t = Lcd_t + Relval
                  Call Lcd_txt
                  Idletime = 0
               End If
               'Build The Ip Header
               Call Setipaddrs
               'swap the UDP source and destinations port
               Swap T_udp_srcport0 , T_udp_destport0
               Swap T_udp_srcport1 , T_udp_destport1
               Call Udp_checksum
               Call Write_rtl8019as(cr , &H22)
               Call Echopacket
            End If
      End If
End Sub


' Routine to calculate the Udp-checksum
'
Sub Udp_checksum
   T_udp_chksum0 = &H00
   T_udp_chksum1 = &H00
   'checksum TCP header
   I_chksum32 = 0
   I_value16h = T_ip_srcaddr0
   I_value16l = T_ip_srcaddr1
   I_chksum32 = I_chksum32 + I_value16
   I_value16h = T_ip_srcaddr2
   I_value16l = T_ip_srcaddr3
   I_chksum32 = I_chksum32 + I_value16
   I_value16h = T_ip_destaddr0
      I_value16l = T_ip_destaddr1
   I_chksum32 = I_chksum32 + I_value16
   I_value16h = T_ip_destaddr2
   I_value16l = T_ip_destaddr3
   I_chksum32 = I_chksum32 + I_value16
   'proto
   I_chksum32 = I_chksum32 + T_ip_proto
   'packet length
   I_value16h = T_udp_len0
   I_value16l = T_udp_len1
   I_chksum32 = I_chksum32 + I_value16
   I_odd = T_udp_len1 Mod 2
   Result16h = T_udp_len0
   Result16l = T_udp_len1
   'udp_srcport0 = packet(&h23)
   Val1 = &H23
   Val2 = &H23 + Result16
   Val2 = Val2 - 2
   Call General_part_checksum(val1 , Val2)
   T_udp_chksum0 = Val3
   T_udp_chksum1 = Val4
End Sub

Sub General_part_checksum(byval Val1 As Byte , Byval Val2 As Word)
   For I_x = Val1 To Val2 Step 2
      I_value16h = Packet(i_x)
      Hulp3 = I_x + 1
      I_value16l = Packet(hulp3)
      I_chksum32 = I_chksum32 + I_value16
   Next I_x
   If I_odd = 1 Then
      Incr Val2
      I_value16h = Packet(val2)
      I_value16l = 0
      I_chksum32 = I_chksum32 + I_value16
   End If
   I_checksum16 = Highw(i_chksum32)
   I_checksum16 = I_checksum16 + I_chksum32                 ' only 16 lower bits of i_chksum32 is taken...
   I_checksum16 = Not I_checksum16
   Val3 = High(i_checksum16)
   Val4 = Low(i_checksum16)
End Sub


' Subroutine to initialize the LCD-display

Sub Lcd_init
Waitms 15
'set 8-bit mode (attention)
'toggle the E -line
I2csend Pcf8574 , &B10000011
I2csend Pcf8574 , &B00000011
Waitms 4
'set 8-bit mode (attention)
I2csend Pcf8574 , &B10000011
I2csend Pcf8574 , &B00000011
Waitms 1
'set 8-bit mode (attention)
I2csend Pcf8574 , &B10000011
I2csend Pcf8574 , &B00000011
Waitms 4
'set 4-bit operation
I2csend Pcf8574 , &B10000010
I2csend Pcf8574 , &B00000010
Waitms 1
'set 8-bit mode (attention)
I2csend Pcf8574 , &B10000010
I2csend Pcf8574 , &B00000010
I2csend Pcf8574 , &B10001000
I2csend Pcf8574 , &B00001000
Waitms 1
I2csend Pcf8574 , &B10000000
I2csend Pcf8574 , &B00000000
'Display off, cursor off, blink off
I2csend Pcf8574 , &B10001000
I2csend Pcf8574 , &B00001000
Waitms 1
I2csend Pcf8574 , &B10000000
I2csend Pcf8574 , &B00000000
'display on, cursor off, blinking off
I2csend Pcf8574 , &B10001100
I2csend Pcf8574 , &B00001100
Waitms 1
I2csend Pcf8574 , &B10000000
I2csend Pcf8574 , &B00000000
'clear display and send cursor to address 0
I2csend Pcf8574 , &B10000001
I2csend Pcf8574 , &B00000001
Waitms 1
End Sub


' Routine to send a character to the LCD-display
'
Sub Lcd_char(lcd_c As Byte)
If Lcd_c = 42 Then                                          '* CLS/HOME
Call Lcdhome
Elseif Lcd_c = 35 Then                                      '# second line
Call Secondline
Else
Lcd_temp = Lcd_c And &HF0
Rotate Lcd_temp , Right , 4
I2csend Pcf8574 , Lcd_temp
Set Lcd_temp.e
Set Lcd_temp.rs
I2csend Pcf8574 , Lcd_temp
Reset Lcd_temp.e
Reset Lcd_temp.rs
I2csend Pcf8574 , Lcd_temp
Lcd_temp = Lcd_c And &H0F
I2csend Pcf8574 , Lcd_temp
Set Lcd_temp.e
Set Lcd_temp.rs
I2csend Pcf8574 , Lcd_temp
Reset Lcd_temp.e
Reset Lcd_temp.rs
I2csend Pcf8574 , Lcd_temp
End If
End Sub


' Routine to send a string to the LCD-display
'
' Fill lcd_t with the text and call lcd_txt
'
Sub Lcd_txt
Lcd_hulp = Len(lcd_t)
For Lcd_x = 1 To Lcd_hulp
Lcd_tempstr = Mid(lcd_t , Lcd_x , 1)
Lcd_temp = Asc(lcd_tempstr)
Call Lcd_char(lcd_temp)
Next Lcd_x
End Sub


Sub Lcdhome
I2csend Pcf8574 , &B10000000
I2csend Pcf8574 , &B00000000
Waitms 2
I2csend Pcf8574 , &B10000001
I2csend Pcf8574 , &B00000001
Waitms 2
End Sub


Sub Secondline
Call Firstline
For Lcd_h = 1 To 40
     I2csend Pcf8574 , &B10000001
     I2csend Pcf8574 , &B00000001
     Waitms 2
     I2csend Pcf8574 , &B10000100
     I2csend Pcf8574 , &B00000100
     Waitms 2
Next Lcd_h
End Sub


Sub Firstline
I2csend Pcf8574 , &B10000000
I2csend Pcf8574 , &B00000000
Waitms 2
I2csend Pcf8574 , &B10000010
I2csend Pcf8574 , &B00000010
Waitms 2
End Sub


' TCP
'
Sub Tcp
Local Work As Byte
Work = Tcp_flags
Tcp_fin = Work.0
Tcp_syn = Work.1
Tcp_rst = Work.2
Tcp_psh = Work.3
Tcp_ack = Work.4
Tcp_urg = Work.5

If Tcp_destporth = 0 Then
   Select Case Tcp_destportl
      Case 80 : Call Http
   End Select
End If

End Sub

Sub Http
#if Debug = 1
   Print "HTTP"
   Print
   Print "Destination port low  " ; Tcp_destportl
   Print "Destination port high " ; Tcp_destporth
   Print
   Print "TCPdatalen_in         " ; Tcpdatalen_in
   Print
   Print "Flags:"
   Print "FIN " ; Tcp_fin
   Print "SYN " ; Tcp_syn
   Print "RST " ; Tcp_rst
   Print "PSH " ; Tcp_psh
   Print "ACK " ; Tcp_ack
   Print "URG " ; Tcp_urg
   Print
   Print "Incoming:"
   Print "Tcp_seqnum3 " ; Hex(tcp_seqnum3)
   Print "Tcp_seqnum2 " ; Hex(tcp_seqnum2)
   Print "Tcp_seqnum1 " ; Hex(tcp_seqnum1)
   Print "Tcp_seqnum0 " ; Hex(tcp_seqnum0)
   Print
   Print "Tcp_acknum3 " ; Hex(tcp_acknum3)
   Print "Tcp_acknum2 " ; Hex(tcp_acknum2)
   Print "Tcp_acknum1 " ; Hex(tcp_acknum1)
   Print "Tcp_acknum0 " ; Hex(tcp_acknum0)
#endif
Local Msg_temp2 As String * 10
Local Tempword3 As Word
Local Z As Word
Local Ztemp As Word
Local Tempstring2 As String * 5
Local Templong1 As Long


Result16h = T_ip_pktlen0
Result16l = T_ip_pktlen1
'
' calculate IP header length
' MSN is version (IPv4)
' LSN is length
Hulp1 = T_ip_vers_len And &H0F
Hulp1 = Hulp1 * 4
' calculate TCP header length
' MSN is length / 4
Hulp2 = Tcp_hdr And &HF0
Shift Hulp2 , Right , 4
Hulp2 = Hulp2 * 4
Tcpdatalen_in = Result16 - Hulp1
Tcpdatalen_in = Tcpdatalen_in - Hulp2
   ' If an ACK is received and the destination port address is valid
   ' and no data is in the packet
If Tcp_ack = 1 Then
         If Tcpdatalen_in = 0 Then
            Incoming_ack0 = Tcp_acknum0
            Incoming_ack1 = Tcp_acknum1
            Incoming_ack2 = Tcp_acknum2
            Incoming_ack3 = Tcp_acknum3
            If Flags.synflag = 1 Then
               Reset Flags.synflag
               My_seqnum = Incoming_ack
                 Tempword3 = &H37
                 If Lcdpresent = 1 Then
                     Lcd_t = "*HTTP request"
                     Call Lcd_txt
                     Call Secondline
                     Lcd_t = "Sending: "
                     Call Lcd_txt
                     Tempstring = Bin(inputport1)
                     Lcd_t = "P" + Left(tempstring , 4)
                     Call Lcd_txt
                     Tempstring = Bin(relaystatus)
                     Lcd_t = "R" + Right(tempstring , 4)
                     Call Lcd_txt
                     Idletime = 0
                 End If
                 Restore Htmlcode
                 Do
                    Read Msg_temp
                    Msg_temp2 = Right(msg_temp , 8)
                    If Msg_temp2 = "endblock" Then
                       Exit Do
                    End If
                    If Msg_temp2 = "get-ipnr" Then
                       Readeeprom Hulp1 , 13
                       If Hulp1 = &HFF Then
                           Msg_temp = "http://" + Str(myip(1))
                           Msg_temp = Msg_temp + "." + Str(myip(2))
                           Msg_temp = Msg_temp + "." + Str(myip(3))
                           Msg_temp = Msg_temp + "." + Str(myip(4))
                           Else
                           Msg_temp = ""
                           For Y = 1 To Hulp1
                               Hulp3 = Y + 13
                               Readeeprom Hulp2 , Hulp3
                               Msg_temp = Msg_temp + Chr(hulp2)
                           Next Y
                       End If
                    End If
                   If Msg_temp2 = "get-info" Then
                              If Inputport1.4 = 0 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                              If Inputport1.5 = 0 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                              If Inputport1.6 = 0 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                              If Inputport1.7 = 0 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                              If Relaystatus.0 = 1 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                              If Relaystatus.1 = 1 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                              If Relaystatus.2 = 1 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                              If Relaystatus.3 = 1 Then
                                 Msg_temp = "<td bgcolor=green><b>on</td>"
                                 Else
                                 Msg_temp = "<td bgcolor=red><b>off</td>"
                              End If
                              For Y = 1 To Len(msg_temp)
                                  Tempstring1 = Mid(msg_temp , Y , 1)
                                  Packet(tempword3) = Asc(tempstring1)
                                  Incr Tempword3
                              Next Y
                    Else
                          For Y = 1 To Len(msg_temp)
                            Tempstring1 = Mid(msg_temp , Y , 1)
                            Packet(tempword3) = Asc(tempstring1)
                            Incr Tempword3
                          Next Y
                    End If
                Loop
                Tcpdatalen_out = Tempword3 - 55             'minus headerlength
               ' expect to get an acknowledgment of the message
               Expected_ack = My_seqnum + Tcpdatalen_out
               ' send the TCP/IP packet
               Call Send_tcp_packet
          End If
     End If
End If


' This code segment processes the incoming SYN from the Tenet client
' and sends back the initial sequence number (ISN) and acknowledges
' the incoming SYN packet
If Tcp_syn = 1 Then
   #if Debug = 1
      Print "Tcp_syn = 1"
   #endif
   Tcpdatalen_in = 1
   Set Flags.synflag
   Call Setup_packet
   Swap Tcp_srcportl , Tcp_destportl
   Swap Tcp_srcporth , Tcp_destporth
   Call Assemble_ack
   Call Tcpseqtomyseq
   Tcp_flags = 0
   Set Tcp_flags.1
   Set Tcp_flags.4
   Call Tcp_checksum
   Call Echopacket
End If

If Tcp_fin = 1 Then
      Set Flags.finflag
      Incr Tcpdatalen_in
      Incoming_ack0 = Tcp_acknum0
      Incoming_ack1 = Tcp_acknum1
      Incoming_ack2 = Tcp_acknum2
      Incoming_ack3 = Tcp_acknum3
      'Call Incomacqtotcpack
      If Incoming_ack <= Expected_ack Then
         Templong1 = Expected_ack - Incoming_ack
         My_seqnum = Expected_ack - Templong1
      End If
      Expected_ack = My_seqnum + Tcpdatalen_out
      Call Send_tcp_packet
End If


If Tcp_psh = 1 Then
   #if Debug = 1
      Print "Tcp_psh = 1"
   #endif
                    ' walk through the packet until GET / is found
                 For Z = 40 To 255
                     Ztemp = Z
                     Tempstring2 = Chr(packet(ztemp))
                     Incr Ztemp
                     Tempstring2 = Tempstring2 + Chr(packet(ztemp))
                     Incr Ztemp
                     Tempstring2 = Tempstring2 + Chr(packet(ztemp))
                     Incr Ztemp
                     Tempstring2 = Tempstring2 + Chr(packet(ztemp))
                     Incr Ztemp
                     Tempstring2 = Tempstring2 + Chr(packet(ztemp))

                      If Tempstring2 = "GET /" Then
                        Ztemp = Ztemp + 301
                        Exit For
                     End If
                 #if Debug = 1
                     Print "/GET gevonden"
                 #endif

                 Next Z

                 'ztemp > 300 when GET / is found
                 'ztemp <= 300 when GET / not found
                 'when found ztemp has the pointer to it (plus 300)

                 If Ztemp > 300 Then
                     Ztemp = Ztemp - 300
                     If Chr(packet(ztemp)) = "R" Then
                        Incr Ztemp
                        Hulp1 = Val(packet(ztemp))
                        Select Case Hulp1
                           Case 1 To 4 : Call Relayon(hulp1)
                           Case 5 To 8 : Call Relayoff(hulp1)
                        End Select
                     End If
                 End If
End If
End Sub


Sub Tcp_checksum
Local Whulp1 As Word
Local Whulp2 As Word
Local Whulp3 As Word
Local Tempword2 As Word
Tcp_cksum = 0
I_chksum32 = 0
Tempwordh = T_ip_srcaddr0
Tempwordl = T_ip_srcaddr1
I_chksum32 = Tempword
Tempwordh = T_ip_srcaddr2
Tempwordl = T_ip_srcaddr3
I_chksum32 = I_chksum32 + Tempword
Tempwordh = T_ip_destaddr0
Tempwordl = T_ip_destaddr1
I_chksum32 = I_chksum32 + Tempword
Tempwordh = T_ip_destaddr2
Tempwordl = T_ip_destaddr3
I_chksum32 = I_chksum32 + Tempword
I_chksum32 = I_chksum32 + T_ip_proto

Tempwordh = T_ip_pktlen0
Tempwordl = T_ip_pktlen1
Tempword2 = T_ip_vers_len And &H0F
Tempword2 = Tempword2 * 4
I_chksum32 = I_chksum32 + Tempword
I_chksum32 = I_chksum32 - Tempword2


Whulp2 = Tempword - 20
Whulp2 = Whulp2 + &H23
Whulp2 = Whulp2 - 2

Val1 = &H23
Val2 = Whulp2
I_odd = Val2 - Val1
I_odd = I_odd Mod 2

Call General_part_checksum(val1 , Val2)
Tcp_cksumh = Val3
Tcp_cksuml = Val4
End Sub


' Send the TCP-packet, a bit different then echopacket
'
Sub Send_tcp_packet
   Ip_packet_len = 40 + Tcpdatalen_out
   T_ip_pktlen1 = Low(ip_packet_len)
   T_ip_pktlen0 = High(ip_packet_len)
   Call Setup_packet
   Swap Tcp_srcporth , Tcp_destporth
   Swap Tcp_srcportl , Tcp_destportl
   Call Assemble_ack
   Call Tcpseqtomyseq
   Tcp_flags = 0
   'fin_out
   Set Tcp_flags.0                                          ' piggyback FIN onto the page date
   'ack_out
   Set Tcp_flags.4
   If Flags.finflag = 1 Then
      'fin_out
      Set Tcp_flags.0
      'clr_finflag
      Reset Flags.finflag
   End If
   Call Tcp_checksum

   Txlen = Ip_packet_len + 14
   If Txlen < 60 Then
      Txlen = 60
   End If

   Call Write_rtl8019as(cr , &H22)
   Call Write_rtl8019as(tpsr , Txstart)
   Call Write_rtl8019as(rsar0 , &H00)
   Call Write_rtl8019as(rsar1 , &H40)
   Call Write_rtl8019as(isr , &HFF)
   Hulp1 = Low(txlen)
   Call Write_rtl8019as(rbcr0 , Hulp1)
   Hulp1 = High(txlen)
   Call Write_rtl8019as(rbcr1 , Hulp1)
   Call Write_rtl8019as(cr , &H12)

   For I = 1 To Txlen
      Call Write_rtl8019as(rdmaport , Packet(i))
   Next

   'make sure the DMA operation has succesfully completed
   Byte_read = 0
   Do
      Hulp1 = Byte_read And Rdc
      Call Read_rtl8019as(isr)
   Loop Until Hulp1 = 0

   Hulp1 = Low(txlen)
   Call Write_rtl8019as(tbcr0 , Hulp1)
   Hulp1 = High(txlen)
   Call Write_rtl8019as(tbcr1 , Hulp1)
   Call Write_rtl8019as(cr , &H24)

End Sub


Sub Setup_packet
'Move IP source address to destination address
T_ip_destaddr = T_ip_srcaddr
'Make ethernet module IP address source address
T_ip_srcaddr = My_ip
'Move hardware source address to destinatin address
Call Packetshape
Call Ip_header_checksum
End Sub

Sub Assemble_ack
Client_seqnum0 = Tcp_seqnum0
Client_seqnum1 = Tcp_seqnum1
Client_seqnum2 = Tcp_seqnum2
Client_seqnum3 = Tcp_seqnum3
Client_seqnum = Client_seqnum + Tcpdatalen_in
Tcp_acknum0 = Client_seqnum0
Tcp_acknum1 = Client_seqnum1
Tcp_acknum2 = Client_seqnum2
Tcp_acknum3 = Client_seqnum3
End Sub

Sub Tcpseqtomyseq
Tcp_seqnum0 = My_seqnum0
Tcp_seqnum1 = My_seqnum1
Tcp_seqnum2 = My_seqnum2
Tcp_seqnum3 = My_seqnum3
End Sub


' Routine to switch on relay X and update status
'
Sub Relayon(x)
Decr X
Relaystatus.x = 1
Call Status
End Sub


' Routine to switch off relay X and update status
'
Sub Relayoff(x)
X = X - 5
Relaystatus.x = 0
Call Status
End Sub


' Routine to switch on/off relais and get the status
'
Sub Status
   Databus_ddr = &HFF
   Databus = Relaystatus
   Set Latch
   Reset Latch
End Sub



' htmlcode
'
Htmlcode:
Data "HTTP/1.0 200" , &H0D , &H0A , &H0D , &H0A
Data "<html><head><meta http-equiv=" , &H22 , "Refresh" , &H22 , " CONTENT=" , &H22 , "9;URL="

Data "get-ipnr"

Data &H22 , ">"
Data "<meta http-equiv=" , &H22 , "Pragma" , &H22 , " Content=" , &H22 , "no cache" , &H22 , ">"
Data "<title>Ethernet I/O board</title></head>"
Data "<body style=" , &H22 , "font-family: Verdana; font-size: 8pt; "
Data "font-weight: Bold" , &H22 , " link=" , &H22 , "#000000" , &H22 , " vlink=" , &H22
Data "#000000" , &H22 , " alink=" , &H22 , "#000000" , &H22 , ">"
Data "<table border=" , &H22 , "10" , &H22 , " width=" , &H22 , "600" , &H22
Data " bordercolor=" , &H22 , "green" , &H22 , " height=" , &H22 , "225" , &H22
Data " cellspacing=" , &H22 , "12" , &H22 , "><tr>"
Data "get-info"
Data "<tr><tr>"
Data "<td><b>Input 1</td>"
Data "<td><b>Input 2</td>"
Data "<td><b>Input 3</td>"
Data "<td><b>Input 4</td>"
Data "<td><b>Relay 1</td>"
Data "<td><b>Relay 2</td>"
Data "<td><b>Relay 3</td>"
Data "<td><b>Relay 4</td>"
Data "</tr><tr><td height=" , &H22 , "100" , &H22
Data " colspan=" , &H22 , "4" , &H22 , " rowspan=" , &H22 , "2" , &H22 , " bordercolor=" , &H22
Data "white" , &H22 , " valign=" , &H22 , "bottom" , &H22 , ">"
Data "<p><b><font size=" , &H22 , "4" , &H22
Data " color=" , &H22 , "green" , &H22 , ">Ethernet I/O board"
Data "</font></b></p>"
Data "</td>"
Data "<td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R1" , &H22 , "><b>on</a></td>"
Data "<td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R2" , &H22 , "><b>on</a></td>"
Data "<td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R3" , &H22 , "><b>on</a></td>"
Data "<td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R4" , &H22 , "><b>on</a></td>"
Data "</tr><tr><td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R5" , &H22 , "><b>off</a></td>"
Data "<td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R6" , &H22 , "><b>off</a></td>"
Data "<td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R7" , &H22 , "><b>off</a></td>"
Data "<td height=" , &H22 , "50"
Data &H22 , "><a href=" , &H22 , "/R8" , &H22 , "><b>off</a></td>"
Data "</tr></table></body></html>" , &H0D , &H0A
Data "endblock"