; ---------------------------------------------------------------------------
;		PIC18F452 + 3COM 3C509b ISA network card                    ;
; ---------------------------------------------------------------------------
;
; Written by :
;
;		Jan Wagemakers	 : Donated to the Public Domain
;                         
; ---------------------------------------------------------------------------
;
; STATUS : 
;		ARP              : OK
;		ICMP (ping)      : OK		(ping -s 1472 192.168.1.99)
;		HTTP (webserver) : OK
;
; ---------------------------------------------------------------------------
;
; Met dank aan Gerard voor zijn bijdrage aan de broncode van dit programma!
;
; ---------------------------------------------------------------------------

	LIST P=PIC18F452, F=INHX32
        #INCLUDE    <p18f452.inc>

        ; - remove ";" below for LCD-routines
        ; - Verwijder ";" hieronder voor de LCD-routines
        #define LCD     1

        ; - define the IP-address here
        ; - stel hier het IP adres in
        #define IP0     D'192'
        #define IP1     D'168'
        #define IP2     D'001'
        #define IP3     D'099'

        ; - define the MAC-address here
        ; - stel hier het MAC-adres in
        #define MAC0    H'3C'
        #define MAC1    H'50'
        #define MAC2    H'9B'
        #define MAC3    H'18'
        #define MAC4    H'F4'
        #define MAC5    H'52'

;-) --- Definieer de poorten.

        #DEFINE RS PORTE, 0    ; RE0 = RS LCD
        #DEFINE E  PORTE, 1    ; RE1 = E  LCD

        #define a0              PORTD,0                 ; adres-lijnen 3COM
        #define a1              PORTD,1
        #define a2              PORTD,2
        #define a3              PORTD,3
        #define a9              PORTD,4
        ;
        ; a19 a18 a17 a16 a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0
        ;  0   0   0   0   0   0   0   0   0   0  x  1  0  0  0  0  y  y  y  y
        ;
        ;  x = 1 --> 110000yyyy --> 0x300 - 0x30F
        ;  x = 0 --> 010000yyyy --> 0x100 - 0x10F

        #define ior             PORTD,5
        #define iow             PORTD,7
        #define reset           PORTD,6

;-) --- PIC configuratie

        __CONFIG    _CONFIG1H, _OSCS_OFF_1H & _XT_OSC_1H
        __CONFIG    _CONFIG2L, _BOR_OFF_2L & _BORV_20_2L & _PWRT_ON_2L
        __CONFIG    _CONFIG2H, _WDT_OFF_2H
        __CONFIG    _CONFIG4L, _STVR_OFF_4L & _LVP_OFF_4L & _DEBUG_OFF_4L

;        __CONFIG    _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L
;        __CONFIG    _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
;        __CONFIG    _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L
;        __CONFIG    _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
;        __CONFIG    _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L
;        __CONFIG    _CONFIG7H, _EBTRB_OFF_7H

;-) --- Variabelen

	cblock  0x00                    ; Start RAM
        ;
        delay                   ; gebruikt in vertragings-routine en ....
        delay2                  ; .... als hulpvariable
        Hchecksum               ; gebruikt in checksum-routine en ....
        Lchecksum               ; .... als hulpvariable
	;
	texthtml		; Geeft aan dat het huidige bestand een html-bestand is
	;
	getfileH
	getfileL		; GET /bestandnaam
	;                       ;      ^--------------getfileH:getfileL
	;
        Llow                    ; Lengte van het pakket + hulp-variabele
        Lhigh
        endc

	IFDEF LCD
	cblock  ;
        Temp                    ; Enkel gebruikt in LCD-routine
        hundreds                ; BCD hundreds result
        tens_and_ones           ; BCD tens and ones result
        bin                     ; binary number to be converted to BCD
        ;
        endc
	ENDIF

	cblock  ;
        RAM                     ; Start van het nog VRIJE RAM geheugen
        ; Hier niets plaatsen!
        endc

;-) --- Macro's

EStrobe MACRO                   ; Strobe the "E" Bit
        bsf    E
        bcf    E
        ENDM

INCa0123 MACRO
        incf PORTD,f
        ENDM

DECa0123 MACRO
        decf PORTD,f
        ENDM

a0123   MACRO a
        IF a==H'0'
        call CLEARa0123
        ENDIF
        IF a==H'1'
        ERROR "a0123 ERROR"
        ENDIF
        IF a==H'2'
        ERROR "a0123 ERROR"
        ENDIF
        IF a==H'3'
        ERROR "a0123 ERROR"
        ENDIF
        IF a==H'4'
        call CLEARa0123
        bsf a2
        ENDIF
        IF a==H'5'
        ERROR "a0123 ERROR"
        ENDIF
        IF a==H'6'
        ERROR "a0123 ERROR"
        ENDIF
        IF a==H'7'
        ERROR "a0123 ERROR"
        ENDIF
        IF a==H'8'
        call CLEARa0123
        bsf a3
        ENDIF
        IF a==H'9'
        ERROR "a0123 ERROR"
        ENDIF
        IF a==H'A'
        bcf a0
        bcf a2
        bsf a3
        bsf a1
        ENDIF
        IF a==H'B'
        bsf a0
	bcf a2
	bsf a3
	bsf a1
        ENDIF
        IF a==H'C'
        ERROR "a0123 ERROR"
        ENDIF
        IF a==H'D'
        ERROR "a0123 ERROR"
        ENDIF
        IF a==H'E'
        call MOVL_E_a0123
        ENDIF
        IF a==H'f'
        ERROR "a0123 ERROR"
        ENDIF
        ENDM

;-) --- Ok, laten we eindelijk eens serieus beginnen.

	org  0x0000             ; Reset vector
        goto start

        org  0x0008             ; Lhigh priority interrupt vector
        goto  $                 ; Trap

        org  0x0018             ; Llow priority interrupt vector
        goto  $                 ; Trap

;-) --- Init het LCD-scherm

	IFDEF LCD

initlcd:
        call wacht40ms
        bcf    RS              ; send an 8 bit instruction
        movlw  0x03            ; Reset Command
        call   NybbleOut       ; Send the Nybble
        call wacht5ms
        EStrobe
        call wacht160us
        EStrobe
        call wacht160us
        bcf    RS              ; send an 8 bit instruction
        movlw  0x02            ; Set 4 Bit Mode
        call   NybbleOut
        call wacht160us
        movlw  0x028           ; 4 bit, 2 Line, 5x7 font
        call   SendINS
        movlw  0x010           ; display shift off
        call   SendINS
        movlw  0x006           ; increment cursor
        call   SendINS
        movlw  0x00C           ; display on cursor off
        call   SendINS
cls:
        movlw  0x001           ; Clear the Display RAM
        call   SendINS
        call wacht5ms
        return

;-) --- LCD goto lijn

goto1:
        movlw H'80'             ; we gaan naar lijn 2
        call SendINS
        Return

goto2:
        movlw H'C0'             ; we gaan naar lijn 2
        call SendINS
        Return

goto3:
        movlw H'94'             ; we gaan naar lijn 3
        call SendINS
        Return

goto4:
        movlw H'D4'             ; we gaan naar lijn 4
        call SendINS
        Return

NybbleOut:                     ; Send a Nybble to the LCD
        movwf  PORTA
        EStrobe                ; Strobe out the LCD Data
        call wacht160us
        return

SendINS:                       ; Send the Instruction to the LCD
        movwf  Temp            ; Save the Temporary Value
        swapf  Temp, w         ; Send the Lhigh Nybble
        bcf    RS              ; RS = 0
        call   NybbleOut
        movf   Temp, w         ; Send the Llow Nybble
        bcf    RS
        call   NybbleOut
        return

SendASCII
         addlw '0'              ; Send nbr as ASCII character
SendCHAR                        ; Send the Character to the LCD
         movwf  Temp            ; Save the Temporary Value
         swapf  Temp, w         ; Send the Lhigh Nybble
         bsf    RS              ; RS = 1
         call   NybbleOut
         movf   Temp, w         ; Send the Llow Nybble
         bsf    RS
         call   NybbleOut
         return

DispDec:
         movwf bin
         call binary_to_bcd
         movf hundreds, W
         call SendASCII
         swapf tens_and_ones, W
         andlw H'F'
         call SendASCII
         movf tens_and_ones, W
         andlw H'F'
         call SendASCII
         return

binary_to_bcd:                  ; by Scott Dattalo
         clrf hundreds
         swapf bin, W
         addwf bin, W
         andlw B'00001111'
         BTFSC  STATUS,DC
         addlw 0x16
	 BTFSC  STATUS,DC
         addlw 0x06
         addlw 0x06
	 BTFSS  STATUS,DC
         addlw -0x06
         btfsc bin,4
         addlw 0x16 - 1 + 0x6
	 BTFSS  STATUS,DC
         addlw -0x06
         btfsc bin,5
         addlw 0x30
         btfsc bin, 6
         addlw 0x60
         btfsc bin,7
         addlw 0x20
         addlw 0x60
         rlcf hundreds, f
         btfss hundreds, 0
         addlw -0x60
         movwf tens_and_ones
         btfsc bin,7
         incf hundreds, f
         return

ENDIF

;-) --- Delay routines - klokfrekwentie = 4Mhz
        ; - de 160us routine is berekend via <http://www.piclist.com:81/cgi-bin/delay.exe>
        ; - de 250us is hetzelfde als 160us, maar gebruikt 250 klokpulsen
        ; - de xxx ms routines roepen 4 * de 250us routine aan om aan de ms timing te komen.

        ; Bij een andere klok dient dus de 160us en 250us aangepast te worden.

wacht250us:
        ;250 cycles
        movlw 0x53
        goto wachtxxxus
wacht160us:
; Delay = 160 instruction cycles
; Clock frequency = 4 MHz

; Actual delay = 0.00016 seconds = 160 cycles
; Error = 0 %

        ;160 cycles
        movlw   0x35    ; Merk op dat 0x20 ook nog werkt en snellere pings teruggeeft
wachtxxxus:
        movwf   delay
Delay_0
        decfsz  delay, f
        goto    Delay_0
        return

wacht250ms:
        movlw D'250'
        goto wachtxxxms
wacht5ms:
        movlw D'5'
        goto wachtxxxms
wacht40ms:
        movlw D'40'
wachtxxxms:
        movwf   delay2
w2:
        call    wacht1ms
        decfsz  delay2, F
        goto    w2
        return

wacht1ms:
        call wacht250us
        call wacht250us
        call wacht250us
        call wacht250us
        return

wacht1s:
        call wacht250ms
        call wacht250ms
        call wacht250ms
        call wacht250ms
        return

;-) --- Start ---------------------------------------------------------------

start:

        ; --- INIT pic ------------------------------------------------------
        ;                                                                   ;
        setf    ADCON1                                                      ;
        ;                                                                   ;
        clrf    INTCON                                                      ;
        ;                                                                   ;
        clrf    TRISA           ; Zet alles op OUTPUT                       ;
        clrf    TRISB                                                       ;
        clrf    TRISC                                                       ;
        clrf    TRISD                                                       ;
        clrf    TRISE                                                       ;
        ;                                                                   ;
        ; -------------------------------------------------------------------

        IFDEF LCD
        call    initlcd
        ENDIF


	bcf	reset
        bsf     reset           ; RESET 3COM
        call    wacht1s
        bcf     reset
        call    wacht250ms

        bsf     ior             ; Initialisatie
        bsf     iow

        bcf     a9              ; Zet 0x100 op adres-bus : A0, A1, A2, A3, A9 = 0
        a0123   0

        ; -------------------------------------------------------------------
        ;                                                                   ;
        ; We gaan nu de PDF volgen op blz 66/67/68                          ;
        ; Schrijf eerst 2 * 0 naar de ISA-kaart om de aandacht te trekken.  ;
        ;                                                                   ;
        call    ISAout0                                                     ;
        call    ISAout0                                                     ;
        ;                                                                   ;
        ; Schrijf dan een bepaalde 'code' naar de kaart om hem wakker te    ;
        ; maken.                                                            ;
        ;                                                                   ;
        setf    RAM                                                         ;
        setf    RAM+1                                                       ;
Seq1:                                                                       ;
        movf    RAM+1,w                                                     ;
        call    ISAout                                                      ;
        bcf     STATUS,C                                                    ;
        rlcf    RAM+1,f                                                     ;
        bnc     Seq2                                                        ;
        movlw   0xcf                                                        ;
        xorwf   RAM+1,f                                                     ;
Seq2:                                                                       ;
        decfsz  RAM,f                                                       ;
        goto    Seq1                                                        ;
        ;                                                                   ;
        ; -------------------------------------------------------------------

        IFDEF LCD
        call    goto1
        movlw   D'000'
        call    DispDec
        call    wacht1s
        ENDIF

        ; -------------------------------------------------------------------
        ;                                                                   ;
        ; Nu de kaart wakker is, lees voldoende gegevens om hem wakker te   ;
        ; houden. En nu we toch bezig zijn, kunnen we hier dus ineens       ;
        ; nuttige informatie opvragen.                                      ;
        ;                                                                   ;
        ; We lezen van 0x87 en 0x98 en gaan na of we 0x6D50 binnenkrijgen.  ;
        ; Indien niet dan is er iets mis. Kaart niet aanwezig, draadbreuk,  ;
        ; geen 3COM ISA-kaart, ...                                          ;
        ;                                                                   ;
        movlw   H'87'           ; Start met 0x87                            ;
ee1:                                                                        ;
        movwf   RAM+3           ; Om straks te weten of we H'87' ...        ;
        rcall   ISAout          ; ... of H'98' hebben gedaan.               ;
        clrf    Llow                                                        ;
        clrf    Lhigh                                                       ;
        movlw   D'16'           ; Lees gegevens uit de EEprom.              ;
        ;                       ; De gevens worden bit per bit doorgestuurd ;
        ;                       ; 16 keer lezen en tot een 'woord' ...      ;
        ;                       ; ... samenvoegen.                          ;
        movwf   RAM+1                                                       ;
ee2:                                                                        ;
        rcall   ISAin                                                       ;
        movwf   RAM+4           ; zet ingelezen waarde op RAM+4             ;
        rrcf    RAM+4,w         ; C = bit0 van RAM+4                        ;
        rlcf    Llow,f          ; schuif 1 plaatsje naar links op met C     ;
        rlcf    Lhigh,f                                                     ;
        decfsz  RAM+1,f         ; alle 16bits gedaan?                       ;
        bra     ee2             ; nee, doe dan voort                        ;
        ;                                                                   ;
        movlw   H'6D'           ; vergelijk met 6D50                        ;
        cpfseq  Lhigh                                                       ;
        bra     start                                                       ;
        movlw   H'50'                                                       ;
        cpfseq  Llow                                                        ;
        bra     start           ; geen 6D50, ga terug naar start...         ;
        ;                                                                   ;
        movlw   H'98'           ; Herhaal nogmaals met 0x98                 ;
        cpfseq  RAM+3                                                       ;
        bra ee1                                                             ;
        ;                                                                   ;
        ; -------------------------------------------------------------------

        IFDEF LCD
        call    goto1
        movlw   D'001'
        call    DispDec
        call    wacht1s
        ENDIF

        ; -------------------------------------------------------------------
        ;                                                                   ;
        ; Nu de kaart wakker is, moeten we hem nog aktief maken.            ;
        ;                                                                   ;
        movlw   0xf0            ; activate adapter IO = 0x300               ;
        call    ISAout                                                      ;
        ;                                                                   ;
        ; -------------------------------------------------------------------

        ; -------------------------------------------------------------------
        ;                                                                   ;
        ; Nu de kaart aktief is kunnen we adreslijn A9 hoog maken zodat we  ;
        ; via IO 0x300 kunnen kommuniceren.                                 ;
        ;                                                                   ;
        bsf     a9                                                          ;
        ;                                                                   ;
        ; -------------------------------------------------------------------



;-) --- ; OK, zover zijn we al. Voor het verdere verloop raadplegen we de
        ; PDF A-3 : Driver Routine Flowchart



        ; -------------------------------------------------------------------
        ;                                                                   ;
        ; We moeten de kaart nu eerst nog enablen voordat we hem echt       ;
        ; kunnen gaan gebruiken.                                            ;
        ;                                                                   ;
        a0123   4       ; Configuration Control Register ...                ;
        ;               ; ... (Read/Write - Offset 4)                       ;
        movlw   B'00000001'                                                 ;
        call    ISAout  ; Schrijf een 1 naar dit register ENA --> 1         ;
        ;               ; adapter is nu ge-enabled                          ;
        INCa0123        ; adres + 1 (WORD)                                  ;
        call    ISAout0                                                     ;
        ;                                                                   ;
        ; -------------------------------------------------------------------

TXreset:

        ; -------------------------------------------------------------------
        ;                                                                   ;
        ; Reset transmitter door naar het Command register (offset 0e)      ;
        ; het tx-reset commando te sturen (zie pdf blz 38)                  ;
        ;                                                                   ;
        a0123   H'E'                                                        ;
        call    ISAout0                                                     ;
        INCa0123                                                            ;
        movlw   B'01011000'                                                 ;
        call    ISAout                                                      ;
        ;                                                                   ;
        ; -------------------------------------------------------------------

        ; -------------------------------------------------------------------
        ;                                                                   ;
        ; Reset receiver door naar het Command register (offset 0e) het     ;
        ; rx-reset commando te sturen (zie pdf blz 37)                      ;
        ;                                                                   ;
        DECa0123                                                            ;
        call    ISAout0                                                     ;
        INCa0123                                                            ;
        movlw   B'00101000'                                                 ;
        call    ISAout                                                      ;
        ;                                                                   ;
        ; -------------------------------------------------------------------

        ; -------------------------------------------------------------------
        ;                                                                   ;
        ; rx-filter instellen : zie pdf blz 41                              ;
        ;                                                                   ;
        DECa0123                                                            ;
        movlw   B'00000101'     ; 0001 Individual address                   ;
        ;                       ; 0010 Group (multicast) addresses          ;
        ;                       ; 0100 Broadcast address                    ;
        ;                       ; 1000 All addresses (promiscuous mode)     ;
        call    ISAout                                                      ;
        INCa0123                                                            ;
        movlw   B'10000000'                                                 ;
        call    ISAout                                                      ;
        ;                                                                   ;
        ; -------------------------------------------------------------------

        ; -------------------------------------------------------------------
        ;                                                                   ;
        ; Nu moeten we het MAC-adres nog instellen.                         ;
        ; naar WINDOW 2 , zie blz 28 pdf                                    ;
        ;                                                                   ;
        ; Kies eerst WINDOW 2 (zie pdf blz 36)                              ;
        ;                                                                   ;
        DECa0123                                                            ;
        movlw   0x02                                                        ;
        call    ISAout                                                      ;
        INCa0123                                                            ;
        movlw   0x08                                                        ;
        call    ISAout                                                      ;
        ;                                                                   ;
        ; Nu we in WINDOW2 zitten kunnen we het MAC-adres schrijven.        ;
        ;                                                                   ;
        a0123   0                                                           ;
        movlw   MAC0                                                        ;
        call    ISAout                                                      ;
        INCa0123                                                            ;
        movlw   MAC1                                                        ;
        call    ISAout                                                      ;
        INCa0123                                                            ;
        movlw   MAC2                                                        ;
        call    ISAout                                                      ;
        INCa0123                                                            ;
        movlw   MAC3                                                        ;
        call    ISAout                                                      ;
        INCa0123                                                            ;
        movlw   MAC4                                                        ;
        call    ISAout                                                      ;
        INCa0123                                                            ;
        movlw   MAC5                                                        ;
        call    ISAout                                                      ;
        ;                                                                   ;
        ; -------------------------------------------------------------------

        ; -------------------------------------------------------------------
        ;                                                                   ;
        ; We gaan 10BASE-T gebruiken, dus moeten we nu :                    ;
        ;                                                                   ;
        ; Set Link Beat and Jabber enable bits                              ;
        ; in Media Type and Status register                                 ;
        ; Stop transceiver                                                  ;
        ;                                                                   ;
        ; Hiervoor zijn we in Window 4 nodig                                ;
        ;                                                                   ;
        ; Kies eerst WINDOW 4                                               ;
        ;                                                                   ;
        a0123   H'E'                                                        ;
        movlw   0x04                                                        ;
        call    ISAout                                                      ;
        INCa0123                                                            ;
        movlw   0x08                                                        ;
        call    ISAout                                                      ;
        ;                                                                   ;
        ; Set Link Beat and Jabber enable bits                              ;
        ; zie pdf blz 58                                                    ;
        ;   Bit 7 1 = Link beat enabled (writable). Defaults to 0           ;
        ;             (disabled). Must be set by software only if the       ;
        ;              internal TP transceiver is in use. Link beat must be ;
        ;              disabled in ENDEC loopback mode.                     ;
        ;   Bit 6 1 = Jabber enabled (writable). Defaults to 0 (disabled).  ;
        ;             Must be set by software only if the internal TP       ;
        ;             transceiver is in use. This also enables the Polarity ;
        ;             Reversal state machine.                               ;
        ;                                                                   ;
        a0123 H'A'                                                          ;
        movlw   B'11000000'                                                 ;
        call    ISAout                                                      ;
        INCa0123                                                            ;
        call    ISAout0                                                     ;
        ;                                                                   ;
        ; -------------------------------------------------------------------

        ; -------------------------------------------------------------------
        ;                                                                   ;
        ; Nu moeten we rx_enable en tx_enable uitvoeren.                    ;
        ; zie pdf blz. blz 36 en 38                                         ;
        ;                                                                   ;
        a0123   H'E'                                                        ;
        call    ISAout0                                                     ;
        INCa0123                                                            ;
        movlw   0x20                                                        ;
        call    ISAout                                                      ;
        DECa0123                                                            ;
        call    ISAout0                                                     ;
        INCa0123                                                            ;
        movlw   0x48                                                        ;
        call    ISAout                                                      ;
        ;                                                                   ;
        ; Kies Window 1                                                     ;
        ;                                                                   ;
        DECa0123                                                            ;
        movlw   0x01                                                        ;
        call    ISAout                                                      ;
        INCa0123                                                            ;
        movlw   0x08                                                        ;
        call    ISAout                                                      ;
        ;                                                                   ;
        ; -------------------------------------------------------------------





;-) --- ; OK, de kaart is nu ingesteld. Nu gaan we over naar de lus waarin
        ; we pakketjes gaan ontvangen, analyseren en versturen.




De_Lus:

	; Vraag de TX Status op (PDF blz 50)
	a0123 H'0b'
	rcall ISAin		; w = TXstatus
				; Bit 7 Complete (1 = TX is complete)
				; Bit 6 Interrupt on Successful Transmission Completion Requested
				; Bit 5 Jabber Error (TP only: TX Reset required)
				; Bit 4 Underrun --> Network TX Reset and FIFO TX Reset required
				; Bit 3 Maximum Collisions
				; Bit 2 TX Status Overflow
				; Bit 1 Undefined
				; Bit 0 Undefined

	andlw B'00111000'	; Hou enkel rekening met deze bits
	iorlw D'0'
        btfsc STATUS, Z
        bra  TXstatusOK         ; TXstatus = 0 --> OK, ga verder
	bra TXreset

TXstatusOK:

        ; -------------------------------------------------------------------
        ;                                                                   ;
        ; Vraag de RX Status op (PDF blz 48)                                ;
        a0123 8                                                             ;
        rcall   ISAin                                                       ;
        movwf   Llow                                                        ;
        INCa0123                                                            ;
        rcall   ISAin                                                       ;
        movwf   Lhigh                                                       ;
        ;                                                                   ;
        btfsc   Lhigh,7         ; Bit 15 hoog --> geen of onvolledig pakket ;
        bra     De_Lus          ;             --> geen pakket -> lus        ;
        btfsc   Lhigh,6         ; Bit 14 hoog --> fouten in pakket!         ;
        goto    weg_ermee                                                   ;
        movlw   B'00000111'                                                 ;
        andwf   Lhigh, f        ; Bit 10...0 = Lengte van pakket            ;
        ;                                                                   ;
        ; -------------------------------------------------------------------

        ; Er staat een geldig pakket klaar! Doe er nu iets mee.

        ; -------------------------------------------------------------------
        ;                                                                   ;
        ; We gaan nu het pakket inlezen en in het RAM-geheugen plaatsen.    ;
        ;                                                                   ;
        lfsr 1, RAM             ; Start RAM geheugen dat we gaan gebruiken  ;
        ;                                                                   ;
        movff   Lhigh, FSR2H                                                ;
        movff   Llow, FSR2L     ; gebruik FSR2L en FSR2H als teller         ;
        ;                                                                   ;
Lees:                                                                       ;
        a0123   0                                                           ;
        rcall   ISAin                                                       ;
        movwf   POSTINC1                                                    ;
        ;                                                                   ;
        movf    POSTDEC2, f     ; teller FSR2H:FSR2L -1                     ;
        tstfsz  FSR2L                                                       ;
        bra     Lees                                                        ;
        tstfsz  FSR2H                                                       ;
        bra     Lees            ; Blijf lezen tot teller = 0                ;
        ;                                                                   ;
        ; -------------------------------------------------------------------

        ; Het pakket zit nu in het RAM-geheugen.

        ; We onderzoeken nu de ethernet-header    |
        ; ----------------------------------------+
        ; Byte 0 ... 5  : Destination MAC Address |
        ; Byte 6 ... B  : Source MAC Address      |
        ; Byte C D      : Type                    |
        ; ----------------------------------------+
        #define ETH_MAC_to      RAM + H'0'
        #define ETH_MAC_from    RAM + H'6'
        #define ETH_type        RAM + H'C'

        ; -------------------------------------------------------------------
        ;                                                                   ;
        lfsr 1, ETH_type        ; C = Type                                  ;
        ;                                                                   ;
        IFDEF LCD                                                           ;
        call    cls                                                         ;
        call    goto1                                                       ;
        movf    INDF1, w                                                    ;
        call DispDec                                                        ;
        ENDIF                                                               ;
        ;                                                                   ;
        movlw   D'008'                                                      ;
        cpfseq  POSTINC1        ; Vergelijk met RAM (FSR1H FSR1L) ...       ;
        bra     weg_ermee       ; ... en verhoog adres met 1                ;
        ;                                                                   ;
        IFDEF LCD                                                           ;
        movf    INDF1, w                                                    ;
        call    DispDec                                                     ;
        ENDIF                                                               ;
        ;                                                                   ;
        ; Type moet met 008 beginnen, anders is het geen geldig pakket.     ;
        ;                                                                   ;
        ; Als Type = 008 006 dan wil dit zeggen dat na de ethernet-header   ;
        ; er een ARP-header volgt.                                          ;
        movlw   D'000'                                                      ;
        cpfsgt  INDF1                                                       ;
        bra     IP              ; Als Type = 008 000 dan gaat het om IP     ;
        ;                                                                   ;
        movlw   D'006'                                                      ;
        cpfseq  INDF1           ; Vergelijk met RAM (FSR1H FSR1L)           ;
        bra     weg_ermee       ; Als Type 008 006 is, dan gaat het om ARP  ;
        bra     ARP             ; Stuur een gepast ARP-reply terug          ;
        ;                                                                   ;
        ; -------------------------------------------------------------------



IP:
        ; IP-Header             | Voorbeeld               |   Bytes | Offset t.o.v. RAM |
        ; ----------------------+-------------------------+---------+-------------------+
        ; version/headerlength  | 0100(*) 0101            |     1   |        0E         |
        ; type of service       | 000                     |     1   |        0F         |
        ; Total length:         | 000 084                 |     2   |        10         |
        ; Indentification:      | 000 000                 |     2   |        12         |
        ; 3-bit flags +         |                         |         |                   |
        ;   13-bit fragm.offset |                         |     2   |        14         |
        ; time to live TTL      | 064                     |     1   |        16         |
        ; protocol              | 1 = ICMP                |     1   |        17         |
        ; checksum              |                         |     2   |        18         |
        ; Source IP address:    | 192.168.2.2             |     4   |        1a         |
        ; Destinati IP address: | 192.168.2.11            |     4   |        1e         |
        ; options/data          |                         |         |                   |
        ; ----------------------+-------------------------+---------+-------------------+
        ; (*) version = 4 = IP, Internet Protocol.

        #define IP_start        RAM + H'0E'
        #define IP_id           RAM + H'12'
        #define IP_protocol     RAM + H'17'
        #define IP_from         RAM + H'1A'
        #define IP_to           RAM + H'1E'
        #define IP_checksum     RAM + H'18'
        #define IP_length       RAM + H'10'

        IFDEF LCD
        call goto3
        lfsr 1, IP_from
        movf POSTINC1, w
        call DispDec
        movlw "."
        call SendCHAR
        movf POSTINC1, w
        call DispDec
        movlw "."
        call SendCHAR
        movf POSTINC1, w
        call DispDec
        movlw "."
        call SendCHAR
        movf POSTINC1, w
        call DispDec
        call goto2
        movf POSTINC1, w
        call DispDec
        movlw "."
        call SendCHAR
        movf POSTINC1, w
        call DispDec
        movlw "."
        call SendCHAR
        movf POSTINC1, w
        call DispDec
        movlw "."
        call SendCHAR
        movf POSTINC1, w
        call DispDec
        ENDIF

        lfsr 1, IP_protocol

        movlw   D'1'
        cpfseq  INDF1           ; Vergelijk met RAM (FSR1H FSR1L)
        bra     geenICMP
        bra     ICMP            ; Als protocol = 1, dan gaat het om ICMP
geenICMP:
        movlw   D'6'
        cpfseq  INDF1
        bra     weg_ermee       ; Als protocol = 6, dan gaat het om TCP
TCP:                            ; TCP afhandelen
        ; TCP-Header            | Voorbeeld               |   Bytes | Offset t.o.v. RAM |
        ; ----------------------+-------------------------+---------+-------------------+
        ; Source Port           |                         |     2   |        22         |
        ; Destination Port      |                         |     2   |        24         |
        ; Sequence Number       |                         |     4   |        26         |
        ; Acknowledgment Number |                         |     4   |        2A         |
        ; Data Offset           |                         |     1   |        2E         |
        ; ECN + Control Bits    |                         |     1   |        2F         |
        ; Window                |                         |     2   |        30         |
        ; checksum              |                         |     2   |        32         |
        ; Urgent Pointer        |                         |     4   |        34         |
        ; Options and padding   |                         | 0...44  |        38         |
        ; Data                  |                         |         |                   |
        ; ----------------------+-------------------------+---------+-------------------+

        #define TCP_start       RAM + H'22'
        #define TCP_from        RAM + H'22'
        #define TCP_to          RAM + H'24'
        #define TCP_control     RAM + H'2F'
        #define TCP_checksum    RAM + H'32'
        #define TCP_seqnum      RAM + H'26'
        #define TCP_acknum      RAM + H'2A'
        #define TCP_data_offset RAM + H'2E'

        ; TODO
        ;
        ; Control bits testen :
        ;  - als enkel SYN = 1 dan reply op deze SYN versturen.
        ;                           |
        ;                           +--> = SYN + ACK versturen
        ;  - als enkel ACK = 1 dan .... ?

        movlw D'000'
        cpfseq TCP_to
        bra weg_ermee
        movlw D'080'            ; PORT 80 www?
        cpfseq TCP_to+1
        bra weg_ermee           ; alles wat niet PORT 80 is negeren.

	btfss TCP_control, D'0' ; Is FIN-bit = 1
	bra FIN0
FIN1:
        ; Wissel Source en Desti.ports om :

        lfsr 0, delay   ; delay + delay2 ff als hulpvar gebruiken.
        lfsr 1, TCP_to
        call MOVFF_POSTINC1_POSTINC0_2X

        ; delay, delay2 = to

        lfsr 1, TCP_from
        lfsr 0, TCP_to

        call MOVFF_POSTINC1_POSTINC0_2X

        ; TCP_to = from

        lfsr 1, delay
        lfsr 0, TCP_from

        call MOVFF_POSTINC1_POSTINC0_2X

        ; TCP_from = to

        ; OK, Source en Desti.ports zijn omgewisseld.

        ; normaal moeten we nu testen of dat de HTTP-port wordt aangesproken.
        ; voor lopig vergeten

        ; ZET ACK-Flag

        bsf TCP_control, D'4'

	; CLEAR de FIN-Flag

	bcf TCP_control, D'0'

	bra SYNFIN			; Spring naar SYN-gedeelte dat ook
					; bruikbaar is voor FIN-routine. Dit is slordig, later een mooiere oplossing
					; zoeken

FIN0:
        btfss TCP_control, D'1' ; Is SYN-bit = 1
        bra SYNis0
SYN1:
	; Wissel Source en Desti.ports om :

        lfsr 0, delay   ; delay + delay2 ff als hulpvar gebruiken.
        lfsr 1, TCP_to
        call MOVFF_POSTINC1_POSTINC0_2X

        ; delay, delay2 = to

        lfsr 1, TCP_from
        lfsr 0, TCP_to

        call MOVFF_POSTINC1_POSTINC0_2X

        ; TCP_to = from

        lfsr 1, delay
        lfsr 0, TCP_from

        call MOVFF_POSTINC1_POSTINC0_2X

        ; TCP_from = to

        ; OK, Source en Desti.ports zijn omgewisseld.

        ; normaal moeten we nu testen of dat de HTTP-port wordt aangesproken.
        ; voor lopig vergeten

        ; ZET ACK-Flag

        bsf TCP_control, D'4'
SYNFIN:
        ; We moeten het ack-nummer nog mee sturen.
        ; ack-nummer = seqnummer + 1

        lfsr 1, TCP_seqnum              ; TCP_seqnum --> TCP_acknum
        lfsr 0, TCP_acknum
        call MOVFF_POSTINC1_POSTINC0_4X

        incf TCP_acknum+3,f             ; TCP_acknum = TCP_acknum + 1
        movlw D'000'
        addwfc TCP_acknum+2,f
        addwfc TCP_acknum+1,f
        addwfc TCP_acknum,f

	; En gebruik een nieuw SEQ-nummer - pseudo random

	rlcf TCP_seqnum, f
	rrcf TCP_seqnum+1, f
	swapf TCP_seqnum+2, f
	rlcf TCP_seqnum, f

        ; En we moeten in de ip-header het id op nul zetten.

        clrf IP_id
        clrf IP_id+1

        call    ip_set_to_from          ; Zet From To in IP-header goed

	; Geen options versturen, timestamp e.d. gebruiken wij niet!
	movlw B'00001111'
	andwf TCP_data_offset, f	; 4 hoogste bits = TCP_data_offset : reset
	movlw B'01010000'
	iorwf TCP_data_offset, f	; TCP_data_offset = 5 (5 32bitswords = 20 bytes)
	; Lengte pakket naar 54 brengen (Ethernet-header 14 + tcp-header 40)
	clrf  Lhigh
	clrf  IP_length
	movlw D'54'
	movwf Llow
	movlw D'40'			; IP-lengte = 40 (lengte zonder Ethernet-header (14))
	movwf IP_length+1
	;

        call    TCPIP_checksum          ; checksums berekenen

        bra     verzenden               ; alles klaar, versturen...

SYNis0:
        btfss TCP_control, D'4'         ; Is ACK-bit = 1
        bra weg_ermee
ACK1:
        ; Zet de ACK en FIN bit         ; Door FIN te zetten zeggen we ineens
                                        ; dat de verbinding verbroken moet
                                        ; worden. Dit werkt dus enkel als de
                                        ; data die verstuurd moet worden niet
                                        ; al te groot is!

        bsf TCP_control, D'4'
        bsf TCP_control, D'0'
        bcf TCP_control, D'1'
        bcf TCP_control, D'2'
        bcf TCP_control, D'3'
;	bsf TCP_control, D'3'		; Zet PUSH flag
        bcf TCP_control, D'5'

        ; ACK en FIN vlag zijn gezet, al de rest is clear

        ; nu gaan we testen of dit packet wel data bevatte.

        movlw D'000'
        cpfseq IP_length
        bra With_Data
        movlw D'040'
        cpfseq IP_length+1
        bra With_Data
        bra weg_ermee
With_Data:

        ; Was het een GET aanvraag?

	; TCP_data_offset bevat de lengte van de TCP-Header.
	; Hiermee kunnen we dus ontdekken waar de DATA zich bevind.

	swapf TCP_data_offset, w	; de hoogste 4 bits zijn van tel
	andlw B'00001111'
	mullw 4				; PRODH:PRODL bevat nu de lengte in bytes

	lfsr 2, TCP_start

        movf PRODL, w
	addwf FSR2L, f
	movf PRODH, w
	addwfc FSR2H, f			; FSRH:FSRL = TCP_start + header-lengte

	; Vergelijk FSR2H:FSR2L met "GET /", smijt het pakket weg als het geen GET is.
        movlw LOW (GET)
        movwf TBLPTRL
        movlw HIGH (GET)
        movwf TBLPTRH
        movlw UPPER (GET)
        movwf TBLPTRU           ; TBLPTR --> "GET /"
g1:
        tblrd*+                 ; Lees van adres TBLPTR in TABLAT / TBLPTR++
        movf TABLAT, w          ; w = het ingelezen karakter
        iorlw D'0'              ; End Of Text? ASCII 0
        btfsc STATUS, Z         ; Als ASCII 0 dan ...
        bra  g2                 ;                 ... stop.
	cpfseq POSTINC2
	bra weg_ermee		; Geen "GET /" --> weg ermee
	bra g1
g2:
	movlw " "
	cpfseq INDF2		; Gaat het om "GET / "?
	bra g3
	; Als het gaat om "GET / " moeten we zorgen dat index.html getoond wordt
	movlw LOW (index)
        movwf TBLPTRL
        movlw HIGH (index)
        movwf TBLPTRH
        movlw UPPER (index)
        movwf TBLPTRU           ; TBLPTR --> "index.html"
index1:
	tblrd*+			; "GET / " --> "GET /index.html "
	movf TABLAT, w
	iorlw D'0'
	btfsc STATUS, Z
	bra With_Data
	movwf POSTINC2
	bra index1
g3:
	movff FSR2H, getfileH
	movff FSR2L, getfileL	; getfileH:getfileL --> filename

        ; Wissel Source en Desti.ports om :

        lfsr 0, delay   ; delay + delay2 ff als hulpvar gebruiken.
        lfsr 1, TCP_to
        call MOVFF_POSTINC1_POSTINC0_2X

        ; delay, delay2 = to

        lfsr 1, TCP_from
        lfsr 0, TCP_to

        call MOVFF_POSTINC1_POSTINC0_2X

        ; TCP_to = from

        lfsr 1, delay
        lfsr 0, TCP_from

        call MOVFF_POSTINC1_POSTINC0_2X

        ; TCP_from = to

        ; OK, Source en Desti.ports zijn omgewisseld.

        ; We moeten het ack-nummer nog mee sturen.
        ; ack-nummer = seqnummer + TCP-lengte van ontvangen pakket

        lfsr 1, TCP_seqnum              ; TCP_seqnum --> delay
        lfsr 0, delay
        call MOVFF_POSTINC1_POSTINC0_4X

	; O ja, het Seq-nummer van dit pakket is het oude ack-nummer.

        lfsr 0, TCP_seqnum              ; TCP_acknum --> TCP_seqnum
        lfsr 1, TCP_acknum
        call MOVFF_POSTINC1_POSTINC0_4X

	; ga verder met aanpassen acknum

	lfsr 1, delay			; delay (orig TCP_seqnum) --> TCP_acknum
	lfsr 0, TCP_acknum
	call MOVFF_POSTINC1_POSTINC0_4X

        movff IP_length, delay		; High
        movff IP_length+1, delay+1	; Low

        movlw D'40'
        subwf delay+1, f
        movlw D'0'
        subwfb delay, f                 ; IP-lengte - 40 = TCP-lengte (meestal toch ;-)

        movf delay+1,w
        addwf  TCP_acknum+3,f           ; TCP_acknum = TCP_acknum + TCP-lengte
        movf delay,w
        addwfc TCP_acknum+2,f
        movlw D'000'                    ; Carry's er bij-tellen
        addwfc TCP_acknum+1,f
        addwfc TCP_acknum,f

        IFDEF LCD
        call cls
        call goto1
        lfsr 1, delay
        movf POSTINC1, w
        call DispDec
        movf POSTINC1, w
        call DispDec
        ENDIF

        ; Dataveld aanpassen : Webpagina in dataveld plaatsen

        lfsr 1, TCP_start + D'20'	; TCP-header = 20

	movlw B'00001111'
	andwf TCP_data_offset, f	; 4 hoogste bits = TCP_data_offset : reset
	movlw B'01010000'
	iorwf TCP_data_offset, f	; TCP_data_offset = 5 (5 32bitswords = 20 bytes)

	; Pseudo file system routine
        movlw LOW (web)
        movwf TBLPTRL
        movlw HIGH (web)
        movwf TBLPTRH
        movlw UPPER (web)
        movwf TBLPTRU           ; TBLPTR --> web
searchfile:
	movff getfileH, FSR2H
	movff getfileL, FSR2L

	tblrd*+
	movff TABLAT, delay	; delay = lengte string
	tstfsz delay		; is delay = 0?
	bra search
e404:
	; Bestand niet gevonden, geef een 404 fout
	movlw LOW (htmlerr)
        movwf delay
        movlw HIGH (htmlerr)
        movwf delay2
        movlw UPPER (htmlerr)
        movwf Hchecksum		; HTML error 404

	movlw LOW (err)
        movwf TBLPTRL
        movlw HIGH (err)
        movwf TBLPTRH
        movlw UPPER (err)
        movwf TBLPTRU           ; TBLPTR --> error
	bra header_lus
search:
	tblrd*+
	movf TABLAT, w
	cpfseq POSTINC2
	bra next
	decfsz delay, f
	bra search
	movlw " "
	cpfseq POSTINC2		; test of er na de bestandsnaam een spatie komt,
				;      om te vermijden dat bv. index.htmlblabla
				;      index.html zou weergeven.
	bra incnext
	bra gevonden
incnext:
	incf delay, f		; Terug bijtellen wat er reeds afgetrokken was
next:
	decf delay, w
	addwf TBLPTRL, f
	movlw D'0'
	addwfc TBLPTRH, f	; Tel het aantal niet gelezen chars bij TBLPTR

	movff TBLPTRL, delay
	movff TBLPTRH, delay2

	tblrd*+
	movf TABLAT, w
	addwf delay, f
	tblrd*+
	movf TABLAT, w
	addwfc delay2, f
	movff delay, TBLPTRL
	movff delay2, TBLPTRH
	tblrd*+
	tblrd*+			; SKIP dit bestand en ga klaar staan op de volgende bestandsnaam

	bra searchfile
gevonden:
	movff TBLPTRL, delay	; TBLPTR wijst naar inhoud 'bestand' , onthouden
	movff TBLPTRH, delay2
	movff TBLPTRU, Hchecksum

	; Plaats eerst de HTML-header in het geheugen
        movlw LOW (header)
        movwf TBLPTRL
        movlw HIGH (header)
        movwf TBLPTRH
        movlw UPPER (header)
        movwf TBLPTRU           ; TBLPTR --> header
header_lus
        tblrd*+                 ; Lees van adres TBLPTR in TABLAT / TBLPTR++
        movf TABLAT, w          ; w = het ingelezen karakter
        iorlw D'0'              ; End Of Text? ASCII 0
        btfsc STATUS, Z         ; Als ASCII 0 dan ...
        bra  header_OK          ;                 ... stop.
        movwf POSTINC1          ; kopieer karakter naar TCP_DATA / FSR1++
        bra header_lus
header_OK:

	movff delay, TBLPTRL	; Terughalen TBLPTR = inhoud 'bestand'
	movff delay2, TBLPTRH
	movff Hchecksum, TBLPTRU


	tblrd*+
	movff TABLAT, delay
	tblrd*+
	movff TABLAT, delay2	; delay2:delay = lengte van de inhoud 'bestand'

	tblrd*			; tblptr --> Content-Type
	movff TABLAT, texthtml	; texthtml = t (maybe rewrite this to check for text/html?)
t1:
        tblrd*+                 ; Lees van adres TBLPTR in TABLAT / TBLPTR++
	movlw "t"
	cpfseq texthtml		; Is dit bestand een HTML-bestand?
	bra notHTML	
	movlw  "<"		; JA! Check for instructions chars
	cpfseq TABLAT
        bra notHTML		
	tblrd*+
	movlw  "?"
	cpfseq TABLAT
	bra undo
	bra PICinstruction
undo:
	tblrd*-
	movlw "<"
	movwf TABLAT
	bra notHTML
PICinstruction:			; Special character combination "<?" (HTML instruction for PIC)
	tblrd*+
	movlw  B'111'
	andwf  TABLAT, w	; TABLAT and '111' ex. D = 0044 and 111 = 4
	lfsr 0,PORTA
	addwf FSR0L, f		; FSR1H:FSR1L = PORTx + 1
	decf  FSR0L, f          ; FSR1H:FSR1L = PORTx (x : A,B,C,D,E)

	tblrd*+
	movlw B'1111'		; TABLAT and '1111' --> ascii-->number conversion
	andwf TABLAT, w	
	movwf Lchecksum		; gebruik Lchecksum als teller
	incf  Lchecksum, f
	movff INDF0, TABLAT	; TABLAT = READ(PORTx)
getBIT:
	rrcf  TABLAT, f
	decfsz Lchecksum, f
	bra getBIT
	clrf TABLAT		; TABLAT = 0
	movlw "0"		; W = ASCII(0)
	addwfc TABLAT, f	; if c = 0 then TABLAT = ASCII(0) else TABLAT = ASCII(1)

        movlw D'3'
        subwf delay, f
        movlw D'0'
        subwfb delay2, f        ; Teller aanpassen, we hebben nl. extra chars gelezen.
	
notHTML:	
	movff TABLAT, POSTINC1
	decf delay, f
	movlw D'0'
	subwfb delay2 , f	; Teller = Teller - 1

	tstfsz delay
	bra t1
	tstfsz delay2
	bra t1			; If teller <> 0 then goto t1

	clrf INDF1		; Afsluiten met een 0, nodig indien het gaat om een
				; oneven aantal bytes die verstuurd worden.
				; zie : (*TCP_cheksum padding) in "call    TCPIP_checksum"
        ; FSR1H:FSR1L = einde data

        lfsr 2, TCP_start + D'20'	; Wij versturen altijd een TCP-header van 20 bytes.

        movf FSR2L, w
        subwf FSR1L, f
        movf FSR2H, w
        subwfb FSR1H, f

        ; FSR1H:FSR1L = Lengte van de data.

        movlw D'40'
        addwf FSR1L, f
        movlw D'00'
        addwfc FSR1H, f

        ; FSR1H:FSR1L = Lengte data + 40 (TCP/IP-Header)

        movff FSR1H, IP_length
        movff FSR1L, IP_length+1

        movlw D'14'
        addwf FSR1L, f
        movlw D'00'
        addwfc FSR1H, f

        ; FSR1H:FSR1L = Lengte data + 40 (TCP/IP-Header) + 14 (Ethernet-Header)

        movff FSR1H, Lhigh
        movff FSR1L, Llow

        call    ip_set_to_from          ; Zet From To in IP-header goed
        call    TCPIP_checksum          ; checksums berekenen
        bra     verzenden               ; alles klaar, versturen...



ICMP:                                   ; ICMP afhandelen
        ; ICMP-Header   Bytes   Offset RAM
        ;
        ; Type          1       22
        ; Code          1       23
        ; Checksum      2       24
        ;

        #define ICMP_type       RAM + H'22'
	#define ICMP_checksum	RAM + H'24'

        lfsr 1, ICMP_type

        movlw   D'8'
        cpfseq  INDF1           ; Vergelijk met RAM (FSR1H FSR1L)
        bra     weg_ermee       ; Als type = 8, dan gaat het om een ECHO-request
ECHO:                           ; ECHO afhandelen
	; bsf LED1  ; ICMP echo
        lfsr 1, ICMP_type
	clrf    POSTINC1        ; Type = 0 = Echo Reply

	call    ip_set_to_from  ; Zet From To in IP-header goed

	; checksum herberekenen, nou ja, doe er gewoon 8 bij op
	;
	; Dank aan Gerard voor dit stukje code! :-)
	;
	movlw 8
	addwf ICMP_checksum,F
	btfsc STATUS,C       
	incf ICMP_checksum + 1,F   ; checksum_hi
	btfsc STATUS,Z
	incf ICMP_checksum,F

	bra     verzenden       ; en ECHO terugsturen
ARP:
        ; We hebben dus een ARP-pakket ontvangen.
        ;
        ; Als uit het IP-adres blijkt dat dit pakket voor ons bedoeld
        ; was, dienen we dus een ARP-Reply te versturen om de PC die het
        ; ARP-pakketje verstuurde te vertellen welk HWadres we hebben.

        ; ARP-Header            | Voorbeeld               |   Bytes | Offset t.o.v. RAM |
        ; ----------------------+-------------------------+---------+-------------------+
        ; Hardware type:        | 0x1 (Ethernet)          |     2   |        0E         |
        ; Protocol type:        | 0x800 (IP)              |     2   |        10         |
        ; Hardware length:      | 6                       |     1   |        12         |
        ; Protocol length:      | 4                       |     1   |        13         |
        ; Opcode:               | 1 (request)   2 (reply) |     2   |        14         |
        ; Sender Ether address: | 07:00:00:00:00:00       |     6   |        16         |
        ; Sender IP address:    | 192.168.2.1             |     4   |        1C         |
        ; Target Ether address: | 00:00:00:00:00:00       |     6   |        20         |
        ; Target IP address:    | 192.168.2.2             |     4   |        26         |
        ; ----------------------+-------------------------+---------+-------------------+

        #define ARP_opcode      RAM + H'14'
        #define ARP_MAC_from    RAM + H'16'
        #define ARP_IP_from     RAM + H'1C'
        #define ARP_MAC_to      RAM + H'20'
        #define ARP_IP_to       RAM + H'26'

        IFDEF LCD
        call goto3
        lfsr 1, ARP_IP_from
        movf POSTINC1, w
        call DispDec
        movlw "."
        call SendCHAR
        movf POSTINC1, w
        call DispDec
        movlw "."
        call SendCHAR
        movf POSTINC1, w
        call DispDec
        movlw "."
        call SendCHAR
        movf POSTINC1, w
        call DispDec
        call goto2
        lfsr 1, ARP_IP_to
        movf POSTINC1, w
        call DispDec
        movlw "."
        call SendCHAR
        movf POSTINC1, w
        call DispDec
        movlw "."
        call SendCHAR
        movf POSTINC1, w
        call DispDec
        movlw "."
        call SendCHAR
        movf POSTINC1, w
        call DispDec
        ENDIF

        lfsr 1, ARP_opcode      ; Wat geeft Opcode ?

        movlw  D'0'
        cpfseq POSTINC1
        bra    weg_ermee
        movlw  D'1'
        cpfseq POSTINC1
        bra    weg_ermee        ; 00 01 = Request : Smijt pakket weg als het
                                ;   iets anders is.

        ; Komt het "Target IP address" overeen met het ingestelde adres?

        lfsr 1, ARP_IP_to
        movlw  IP0
        cpfseq POSTINC1
        bra    weg_ermee
        movlw  IP1
        cpfseq POSTINC1
        bra    weg_ermee
        movlw  IP2
        cpfseq POSTINC1         ; Smijt alles wat geen juist bestemmings-
        bra    weg_ermee        ; IP-adres heeft weg
        movlw  IP3
        cpfseq POSTINC1
        bra    weg_ermee

        ; Ok, nu we weten dat dit pakket voor ons was bestemd, kunnen we
        ;   een antwoord terugsturen. Dit terugsturen doen we door de
        ;   ontvangen header aan te passen en dan te verzenden.

        ; Pas Opcode ARP aan

        lfsr 1, ARP_opcode

        clrf  POSTINC1
        movlw D'2'
        movwf POSTINC1          ; 00 02 = Reply

        ; Sender Ether address --> Target Ether address
        ;       Opm FSR1H:FSR1L staat reeds goed voor Sender Ether address

        lfsr 0, ARP_MAC_to
        call    MOVFF_POSTINC1_POSTINC0_6X

        ; Sender IP address --> Target IP address
        call    MOVFF_POSTINC1_POSTINC0_4X

        ; Steek het MAC-adres in Sender Ether Address

        lfsr 0, ARP_MAC_from
        call    MOV_MAC_POSTINC0

        ; Steek het IP-adres in Sender IP Address
        ;       Opm FSR0H:FSR0L staat reeds goed voor Target IP address
        call    MOV_IP_POSTINC0

        ; Niet alleen de ARP-header moeten we aanpassen, maar ook de
        ; Ethernetheader

        lfsr 0, ETH_MAC_to
        lfsr 1, ETH_MAC_from
        call    MOVFF_POSTINC1_POSTINC0_6X
        call    MOV_MAC_POSTINC0

        ; Lengte van pakket instellen op 42.
        ; Waarom 42?
        ; Ethernet-header = 6 + 6 + 2 bytes (Source MAC + Destination MAC + type)
        ; ARP-header = 2 + 2 + 1 + 1 + 2 + 6 + 4 + 6 + 4 ( zie boven )
        ; +  --------------------------------------------------------------------
        ; =  42 bytes

        movlw D'42'
        movwf Llow
        clrf  Lhigh

verzenden:
        call    verzend
weg_ermee:                      ; Smijt een ontvangen pakket weg en keer terug naar begin van lus
        a0123   H'E'
        rcall   ISAout0
        INCa0123
        movlw   0x40
        rcall   ISAout
        goto    De_Lus


;-) --- ; De subroutines i.v.m. ethernet.

ISAout0:
        movlw 0         ; ISAout waarbij w = 0
ISAout:
        ; Schrijf een byte naar de ISA-kaart :
        ; PORT B staat standaard op OUTPUT
        movwf PORTB
        bcf iow
        rcall wacht160us
        bsf iow
        return

ISAin:
        ; Lees een byte van de ISA-kaart :
        ; Zet PORT B eerst op INPUT

        setf    TRISB

        bcf ior
        rcall wacht160us
        movf PORTB, w
        bsf ior

        ; Zet PORT B terug op OUTPUT
        clrf TRISB
        return


CLEARa0123:
        ; Zet a0,a1,a2,a3 naar 0
        ;
        ; a0 = PORTD,0
        ; a1 = PORTD,1
        ; a2 = PORTD,2
        ; a3 = PORTD,3
        ;
        movlw B'11110000'
        andwf PORTD, f
        return

MOVL_E_a0123:
        ; Zet a0,a1,a2,a3 naar 0x0E
        ;
        movlw B'00001111'
        iorwf PORTD, f
        bcf a0
        return

verzend:
        a0123 0
        movf    Llow, w         ; Pakket-lengte
        rcall   ISAout
        movf    Lhigh, w
        rcall   ISAout

        rcall   ISAout0
        rcall   ISAout0

        lfsr 1, RAM             ; Start RAM geheugen dat we gebruiken

        movff Lhigh, FSR2H
        movff Llow, FSR2L               ; gebruik FSR2L en FSR2H als teller

Schrijf:
        movf    POSTINC1, W
        rcall   ISAout

        movf POSTDEC2, f        ; teller FSR2H:FSR2L -1
        tstfsz FSR2L
        bra Schrijf
        tstfsz FSR2H
        bra Schrijf             ; Blijf schrijven tot teller = 0

        ; versturen van padding data
pad:
        movlw B'00000011'
        andwf Llow, w
        bnz Schrijf_pad
        return

Schrijf_pad:
        rcall   ISAout0
        incf  Llow, f
        bra pad

MOV_MAC_POSTINC0:
        movlw   MAC0
        movwf   POSTINC0
        movlw   MAC1
        movwf   POSTINC0
        movlw   MAC2
        movwf   POSTINC0
        movlw   MAC3
        movwf   POSTINC0
        movlw   MAC4
        movwf   POSTINC0
        movlw   MAC5
        movwf   POSTINC0
        return

MOV_IP_POSTINC0:
        movlw   IP0
        movwf   POSTINC0
        movlw   IP1
        movwf   POSTINC0
        movlw   IP2
        movwf   POSTINC0
        movlw   IP3
        movwf   POSTINC0
        return

MOVFF_POSTINC1_POSTINC0_6X:
        movff   POSTINC1, POSTINC0
        movff   POSTINC1, POSTINC0
MOVFF_POSTINC1_POSTINC0_4X:
        movff   POSTINC1, POSTINC0
        movff   POSTINC1, POSTINC0
MOVFF_POSTINC1_POSTINC0_2X:
        movff   POSTINC1, POSTINC0
        movff   POSTINC1, POSTINC0
        return

ip_set_to_from:
        lfsr 0, ETH_MAC_to
        lfsr 1, ETH_MAC_from
        rcall   MOVFF_POSTINC1_POSTINC0_6X
        rcall   MOV_MAC_POSTINC0

        lfsr 0, IP_to
        lfsr 1, IP_from
        rcall    MOVFF_POSTINC1_POSTINC0_4X

        ; Steek ons IP in Source IP
        lfsr 0, IP_from
        rcall   MOV_IP_POSTINC0
        return

Checksum:
        ; -------------------------------------------------------------------
        ; Berekenen van "16-bit one's complement of the one's complement sum"
        ; Voor het aanroep, zet :
        ; -----------------------
        ;       FSR2H:FSR2l = lengte in bytes
        ;       clear old checksum
        ;       lfsr 1 = START RAM
        ;       clrf Hchecksum, Lchecksum indien nodig
        ; Na de aanroep, bevat :
        ; ----------------------
        ;       Hchecksum,Lchecksum = checksum waarop comf nog moet worden
        ;                               uitgevoerd.
        ; -------------------------------------------------------------------

        bcf STATUS, C                   ; Lengte is uitgedrukt in bytes, maar...
        rrcf FSR2H, f                   ; ...het berekenen van de checksum gaat...
	rrcf FSR2L, f                   ; per 16Bits, dus lengte/2

        bcf STATUS, C                   ; reset C-flag
CLus:
        movf POSTINC1, w
        addwfc Hchecksum, f
        movf POSTINC1, w
        addwfc Lchecksum, f

        movf POSTDEC2, w                ; teller FSR2H:FSR2L -1
        tstfsz FSR2L
        bra CLus
        tstfsz FSR2H
        bra CLus                        ; Blijf rekenen tot teller = 0

        movlw D'000'
        addwfc Hchecksum, f             ; Tel evt. carry van laatste optelling hierbij

        return


TCPIP_checksum:
        ; -------------------------------------------------------------------
        ; Berekenen van checksum voor de IP-header en de TCP-header
        ; -------------------------------------------------------------------

        ; De TCP-checksum bestaat uit one compledingens van een pseudoheader en
        ; de one compledingens van de tcp-header + data. Voor de tcp-header
        ; + data kunnen we de normale Checksum routine gebruiken, omdat deze
        ; data mooi in het geheugen zit. De pseudo header is her en der
        ; verspreid, dus reken we eerst de pseudo-header uit en voegen er dan
        ; het deel van tcp-header+data aan toe.

        clrf Hchecksum                  ; checksum = 0
        clrf Lchecksum

        lfsr 1, IP_from
        clrf  FSR2H
        movlw D'8'
        movwf FSR2L                     ; FSR2H:FSR2L = 8 = lengte in bytes
        call Checksum                   ; calculate checksum for IP_from and IP_to

        ; movlw D'0'                    ; Normaal moeten we hier nul bijtellen,
        ; addwfc Hchecksum, f           ; maar dit heeft toch geen effekt.
        movf IP_protocol, w
        addwfc Lchecksum, f             ; add checksum IP_protocol
        movlw D'0'
        addwfc Hchecksum, f             ; carry van hierboven overdragen

        movff IP_length, delay
        movff IP_length+1, delay2       ; delay, delay2 gebruiken als hulpvar

        movlw D'20'
        subwf delay2, f
        movlw D'0'
        subwfb delay,f                  ; Wij hebben lengte - 20 nodig

        lfsr 1, delay
        clrf  FSR2H
        movlw D'2'
        movwf FSR2L                     ; FSR2H:FSR2L = 2 = lengte in bytes
        call Checksum                   ; calculate checksum for IP_length

        ; Hchecksum:Lchecksum bevat nu de checksum van de speudo-header.
        ; TCP-Header bijtellen.

        lfsr 1, TCP_start

        movff delay , FSR2H             ; Lengte van TCP-header + DATA
        movff delay2, FSR2L             ; gebruik FSR2L en FSR2H als teller
	; (*TCP_cheksum padding)
	incf FSR2L, f			; Verhoog de lengte met 1
					; In call Cheksum wordt FSR2L / 2
					; Dus als FSR2L even was doet dit niets ( even + 1 ) / 2 = even / 2
					;                                    bv (  2   + 1 ) / 2 =  2   / 2 = 1
					; Maar als FSR2L oneven was wordt er een extra padding byte bijgevoegd.

        clrf TCP_checksum
        clrf TCP_checksum+1             ; clear TCP_checksum
        call Checksum                   ; Voeg checksum TCP-header+data toe

        ; comf nog uitvoeren op deze checksum

        comf Lchecksum, f
        comf Hchecksum, f               ; one complemet

        ; en dan de checksum kopieren naar de gepaste lokatie

        movff Hchecksum, TCP_checksum
        movff Lchecksum, TCP_checksum+1

        ; Checksum IP berekenen, nodig, want we hebben aanpassingen aan de
        ;    ip-header gemaakt.

        clrf Hchecksum
        clrf Lchecksum

        clrf FSR2H                      ; Lengte van IP-header
        movlw D'20'
        movwf FSR2L                     ; gebruik FSR2L en FSR2H als teller

        clrf IP_checksum                ; Oude checksum wissen
        clrf IP_checksum+1

        lfsr 1, IP_start

        call Checksum

        ; comf nog uitvoeren op deze checksum

        comf  Lchecksum, f
        comf  Hchecksum, f

        ; en dan de checksum kopieren naar de gepaste lokatie

        movff Hchecksum, IP_checksum
        movff Lchecksum, IP_checksum+1
        return

;-) --- ; text --------------------------------------------------------------

; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;
; ! Lees Dit / Read This !
; ------------------------
;
; Wanneer db een oneven aantal karakters bevat wordt er automatisch een
; zero-padding byte toegevoegd. Zorg dat waar dit een rol speelt de regels
; uit een even aantal karakters bestaan.
;
; When db contains an odd number of expressions, a zero-padding byte will
; be added. So, where necessary, use a even number of characters to avoid
; problems.
;
; 5.13 DB � Declare Data of One Byte
;
;    5.13.1 Syntax
;
;           [<label>] db <expr>[,<expr>,...,<expr>]
;
;    5.13.2 Description
;
;           Reserve program memory words with packed 8-bit values. Multiple
;           expressions continue to fill bytes consecutively until the end
;           of expressions. Should there be an odd number of expressions,
;           the last byte will be zero. When generating an object file,
;           this directive can also be used to declare initialized data
;           values. Refer to the IDATA directive for more information.
;
; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


index   db "index.html ",0
err     db "HTTP/1.0 404 Not Found", H'0A' , "C"
	db "ontent-Type: text/html", H'0A' , H'0A' , 0
htmlerr db D'89', D'0', "<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD><BODY><H1>404 Not Found</H1></BODY></HTML>"
header  db "HTTP/1.0 200 OK", H'0A'
	db "Server: PIC18F452 + 3COM 3C509b", H'0A'
        db "Content-Type: " , 0
GET	db "GET /",0

; web   db 'file-system'-format :
;
;	length file-name ; 1 byte
;	file-name        ; |xxxxxxxxx.xxx|
;       length of file   ; 2 bytes : LOW,HIGH     (Where length = length of file incl. Content-Type)
;       file             ; |Content-Type|,0x0A,0x0A + |xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
;         .
;         .
;         .
;       the same for the next file
;         .
;         .
;         .
;       zero byte to close the 'file-system'


;      length                      length of
;     file-name , file-name      , file      ,content-type,  0A ,  0A, xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
web	db H'09',"menu.html",H'59',H'04',"text/html",H'0A'
	db H'0A',H'3c',H'21',H'44',H'4f',H'43',H'54',H'59',H'50',H'45',H'20',H'48',H'54',H'4d',H'4c',H'20',H'50',H'55',H'42',H'4c'
	db H'49',H'43',H'20',H'22',H'2d',H'2f',H'2f',H'57',H'33',H'43',H'2f',H'2f',H'44',H'54',H'44',H'20',H'48',H'54',H'4d',H'4c'
	db H'20',H'34',H'2e',H'30',H'31',H'20',H'54',H'72',H'61',H'6e',H'73',H'69',H'74',H'69',H'6f',H'6e',H'61',H'6c',H'2f',H'2f'
	db H'45',H'4e',H'22',H'3e',H'0a',H'3c',H'68',H'74',H'6d',H'6c',H'3e',H'3c',H'68',H'65',H'61',H'64',H'3e',H'0a',H'3c',H'6d'
	db H'65',H'74',H'61',H'20',H'68',H'74',H'74',H'70',H'2d',H'65',H'71',H'75',H'69',H'76',H'3d',H'22',H'43',H'6f',H'6e',H'74'
	db H'65',H'6e',H'74',H'2d',H'54',H'79',H'70',H'65',H'22',H'20',H'63',H'6f',H'6e',H'74',H'65',H'6e',H'74',H'3d',H'22',H'74'
	db H'65',H'78',H'74',H'2f',H'68',H'74',H'6d',H'6c',H'3b',H'63',H'68',H'61',H'72',H'73',H'65',H'74',H'3d',H'69',H'73',H'6f'
	db H'2d',H'38',H'38',H'35',H'39',H'2d',H'31',H'22',H'3e',H'0a',H'3c',H'74',H'69',H'74',H'6c',H'65',H'3e',H'50',H'49',H'43'
	db H'31',H'38',H'66',H'34',H'35',H'32',H'20',H'2b',H'20',H'33',H'43',H'4f',H'4d',H'20',H'33',H'43',H'35',H'30',H'39',H'42'
	db H'20',H'2d',H'20',H'57',H'65',H'62',H'73',H'65',H'72',H'76',H'65',H'72',H'20',H'2d',H'3c',H'2f',H'74',H'69',H'74',H'6c'
	db H'65',H'3e',H'0a',H'3c',H'6d',H'65',H'74',H'61',H'20',H'6e',H'61',H'6d',H'65',H'3d',H'22',H'4b',H'65',H'79',H'77',H'6f'
	db H'72',H'64',H'73',H'22',H'20',H'63',H'6f',H'6e',H'74',H'65',H'6e',H'74',H'3d',H'22',H'50',H'49',H'43',H'31',H'38',H'66'
	db H'34',H'35',H'32',H'2c',H'20',H'33',H'43',H'35',H'30',H'39',H'42',H'2c',H'20',H'77',H'65',H'62',H'73',H'65',H'72',H'76'
	db H'65',H'72',H'22',H'3e',H'0a',H'20',H'20',H'3c',H'73',H'74',H'79',H'6c',H'65',H'20',H'74',H'79',H'70',H'65',H'3d',H'22'
	db H'74',H'65',H'78',H'74',H'2f',H'63',H'73',H'73',H'22',H'3e',H'0a',H'09',H'61',H'3a',H'68',H'6f',H'76',H'65',H'72',H'7b'
	db H'63',H'6f',H'6c',H'6f',H'72',H'3a',H'72',H'65',H'64',H'3b',H'20',H'74',H'65',H'78',H'74',H'2d',H'64',H'65',H'63',H'6f'
	db H'72',H'61',H'74',H'69',H'6f',H'6e',H'3a',H'6e',H'6f',H'6e',H'65',H'3b',H'20',H'7d',H'0a',H'20',H'20',H'3c',H'2f',H'73'
	db H'74',H'79',H'6c',H'65',H'3e',H'0a',H'3c',H'2f',H'68',H'65',H'61',H'64',H'3e',H'0a',H'0a',H'3c',H'62',H'6f',H'64',H'79'
	db H'20',H'73',H'74',H'79',H'6c',H'65',H'3d',H'22',H'6d',H'61',H'72',H'67',H'69',H'6e',H'3a',H'30',H'70',H'78',H'3b',H'22'
	db H'20',H'74',H'65',H'78',H'74',H'3d',H'22',H'23',H'30',H'30',H'30',H'30',H'30',H'30',H'22',H'20',H'62',H'67',H'63',H'6f'
	db H'6c',H'6f',H'72',H'3d',H'22',H'23',H'45',H'30',H'45',H'30',H'45',H'30',H'22',H'20',H'6c',H'69',H'6e',H'6b',H'3d',H'22'
	db H'23',H'30',H'30',H'30',H'30',H'46',H'46',H'22',H'20',H'76',H'6c',H'69',H'6e',H'6b',H'3d',H'22',H'23',H'38',H'30',H'30'
	db H'30',H'38',H'30',H'22',H'20',H'61',H'6c',H'69',H'6e',H'6b',H'3d',H'22',H'23',H'46',H'46',H'30',H'30',H'30',H'30',H'22'
	db H'3e',H'0a',H'0a',H'3c',H'74',H'61',H'62',H'6c',H'65',H'20',H'73',H'74',H'79',H'6c',H'65',H'3d',H'22',H'62',H'6f',H'72'
	db H'64',H'65',H'72',H'3a',H'20',H'73',H'6f',H'6c',H'69',H'64',H'20',H'32',H'70',H'78',H'20',H'67',H'72',H'65',H'65',H'6e'
	db H'3b',H'22',H'20',H'62',H'6f',H'72',H'64',H'65',H'72',H'3d',H'22',H'30',H'22',H'20',H'63',H'65',H'6c',H'6c',H'73',H'70'
	db H'61',H'63',H'69',H'6e',H'67',H'3d',H'22',H'30',H'22',H'20',H'63',H'65',H'6c',H'6c',H'70',H'61',H'64',H'64',H'69',H'6e'
	db H'67',H'3d',H'22',H'35',H'22',H'20',H'62',H'67',H'63',H'6f',H'6c',H'6f',H'72',H'3d',H'22',H'23',H'42',H'42',H'44',H'44'
	db H'46',H'46',H'22',H'20',H'77',H'69',H'64',H'74',H'68',H'3d',H'22',H'31',H'30',H'30',H'25',H'22',H'20',H'73',H'75',H'6d'
	db H'6d',H'61',H'72',H'79',H'3d',H'22',H'22',H'3e',H'0a',H'3c',H'74',H'72',H'3e',H'0a',H'3c',H'74',H'64',H'20',H'6e',H'6f'
	db H'77',H'72',H'61',H'70',H'20',H'61',H'6c',H'69',H'67',H'6e',H'3d',H'72',H'69',H'67',H'68',H'74',H'3e',H'0a',H'4d',H'65'
	db H'6e',H'75',H'0a',H'3c',H'2f',H'74',H'64',H'3e',H'0a',H'3c',H'74',H'64',H'20',H'73',H'74',H'79',H'6c',H'65',H'3d',H'22'
	db H'63',H'6f',H'6c',H'6f',H'72',H'3a',H'20',H'67',H'72',H'65',H'65',H'6e',H'22',H'20',H'6e',H'6f',H'77',H'72',H'61',H'70'
	db H'3e',H'0a',H'7c',H'0a',H'3c',H'2f',H'74',H'64',H'3e',H'3c',H'74',H'64',H'20',H'6e',H'6f',H'77',H'72',H'61',H'70',H'3e'
	db H'0a',H'3c',H'61',H'20',H'68',H'72',H'65',H'66',H'3d',H'22',H'2e',H'2f',H'64',H'65',H'6d',H'6f',H'2e',H'68',H'74',H'6d'
	db H'6c',H'22',H'20',H'74',H'61',H'72',H'67',H'65',H'74',H'3d',H'22',H'64',H'79',H'6e',H'61',H'6d',H'69',H'63',H'22',H'3e'
	db H'44',H'65',H'6d',H'6f',H'3c',H'2f',H'61',H'3e',H'0a',H'3c',H'2f',H'74',H'64',H'3e',H'0a',H'3c',H'74',H'64',H'20',H'73'
	db H'74',H'79',H'6c',H'65',H'3d',H'22',H'63',H'6f',H'6c',H'6f',H'72',H'3a',H'20',H'67',H'72',H'65',H'65',H'6e',H'22',H'20'
	db H'6e',H'6f',H'77',H'72',H'61',H'70',H'20',H'3e',H'0a',H'7c',H'0a',H'3c',H'2f',H'74',H'64',H'3e',H'3c',H'74',H'64',H'20'
	db H'6e',H'6f',H'77',H'72',H'61',H'70',H'3e',H'0a',H'3c',H'61',H'20',H'68',H'72',H'65',H'66',H'3d',H'22',H'2e',H'2f',H'67'
	db H'64',H'65',H'6d',H'6f',H'2e',H'68',H'74',H'6d',H'6c',H'22',H'20',H'74',H'61',H'72',H'67',H'65',H'74',H'3d',H'22',H'64'
	db H'79',H'6e',H'61',H'6d',H'69',H'63',H'22',H'3e',H'44',H'65',H'6d',H'6f',H'32',H'20',H'28',H'77',H'69',H'74',H'68',H'20'
	db H'70',H'69',H'63',H'74',H'75',H'72',H'65',H'73',H'29',H'3c',H'2f',H'61',H'3e',H'0a',H'3c',H'2f',H'74',H'64',H'3e',H'0a'
	db H'3c',H'74',H'64',H'20',H'73',H'74',H'79',H'6c',H'65',H'3d',H'22',H'63',H'6f',H'6c',H'6f',H'72',H'3a',H'20',H'67',H'72'
	db H'65',H'65',H'6e',H'22',H'20',H'6e',H'6f',H'77',H'72',H'61',H'70',H'20',H'3e',H'0a',H'7c',H'0a',H'3c',H'2f',H'74',H'64'
	db H'3e',H'3c',H'74',H'64',H'20',H'6e',H'6f',H'77',H'72',H'61',H'70',H'3e',H'0a',H'3c',H'61',H'20',H'68',H'72',H'65',H'66'
	db H'3d',H'22',H'2e',H'2f',H'69',H'6e',H'66',H'6f',H'2e',H'68',H'74',H'6d',H'6c',H'22',H'20',H'74',H'61',H'72',H'67',H'65'
	db H'74',H'3d',H'22',H'64',H'79',H'6e',H'61',H'6d',H'69',H'63',H'22',H'3e',H'4d',H'6f',H'72',H'65',H'20',H'69',H'6e',H'66'
	db H'6f',H'3c',H'2f',H'61',H'3e',H'0a',H'3c',H'2f',H'74',H'64',H'3e',H'0a',H'3c',H'2f',H'74',H'72',H'3e',H'0a',H'3c',H'2f'
	db H'74',H'61',H'62',H'6c',H'65',H'3e',H'0a',H'3c',H'74',H'61',H'62',H'6c',H'65',H'20',H'61',H'6c',H'69',H'67',H'6e',H'3d'
	db H'22',H'63',H'65',H'6e',H'74',H'65',H'72',H'22',H'20',H'68',H'65',H'69',H'67',H'68',H'74',H'3d',H'22',H'38',H'30',H'25'
	db H'22',H'3e',H'0a',H'3c',H'74',H'72',H'3e',H'3c',H'74',H'64',H'3e',H'3c',H'68',H'31',H'3e',H'50',H'49',H'43',H'31',H'38'
	db H'66',H'34',H'35',H'32',H'20',H'2b',H'20',H'33',H'43',H'4f',H'4d',H'20',H'33',H'43',H'35',H'30',H'39',H'42',H'20',H'2d'
	db H'20',H'57',H'65',H'62',H'20',H'53',H'65',H'72',H'76',H'65',H'72',H'20',H'2d',H'3c',H'2f',H'68',H'31',H'3e',H'3c',H'2f'
	db H'74',H'64',H'3e',H'3c',H'2f',H'74',H'72',H'3e',H'3c',H'2f',H'62',H'6f',H'64',H'79',H'3e',H'3c',H'2f',H'68',H'74',H'6d'
	db H'6c',H'3e',H'0a',H'05',"0.gif",H'8f',H'01',"image/gif",H'0A',H'0A'
	db H'47',H'49',H'46',H'38',H'39',H'61',H'12',H'00',H'12',H'00',H'd5',H'30',H'00',H'f5',H'f5',H'f5',H'e8',H'e8',H'e8',H'f9'
	db H'f9',H'f9',H'd2',H'd2',H'd2',H'f6',H'60',H'88',H'c9',H'c9',H'c9',H'76',H'76',H'76',H'62',H'62',H'62',H'9e',H'9e',H'9e'
	db H'f3',H'5f',H'87',H'd6',H'd6',H'd6',H'5b',H'5b',H'5b',H'ca',H'ca',H'ca',H'fb',H'67',H'8f',H'f9',H'63',H'8b',H'ea',H'5e'
	db H'83',H'ee',H'5d',H'84',H'cb',H'54',H'74',H'fa',H'6a',H'8f',H'b6',H'75',H'87',H'de',H'75',H'91',H'fa',H'67',H'8d',H'84'
	db H'84',H'84',H'fa',H'65',H'8c',H'fa',H'96',H'b1',H'f9',H'6c',H'92',H'f9',H'6c',H'91',H'f8',H'62',H'8a',H'e8',H'5c',H'81'
	db H'85',H'45',H'56',H'f9',H'84',H'a3',H'b9',H'4f',H'6b',H'e6',H'a6',H'b7',H'd4',H'5d',H'7d',H'4c',H'4c',H'4c',H'd5',H'6d'
	db H'88',H'f0',H'60',H'86',H'f5',H'61',H'88',H'f4',H'64',H'8a',H'f1',H'7a',H'9a',H'f3',H'5f',H'86',H'41',H'41',H'41',H'fb'
	db H'c0',H'd0',H'fb',H'c7',H'd5',H'fb',H'67',H'8e',H'f7',H'62',H'89',H'cc',H'cc',H'cc',H'f5',H'60',H'87',H'ff',H'ff',H'ff'
	db H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00'
	db H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00'
	db H'00',H'00',H'00',H'00',H'00',H'21',H'f9',H'04',H'01',H'00',H'00',H'30',H'00',H'2c',H'00',H'00',H'00',H'00',H'12',H'00'
	db H'12',H'00',H'00',H'06',H'a1',H'40',H'98',H'70',H'48',H'2c',H'1a',H'61',H'2b',H'4f',H'a6',H'51',H'd1',H'9c',H'40',H'01'
	db H'c1',H'11',H'23',H'b9',H'6c',H'5a',H'd8',H'96',H'89',H'32',H'00',H'14',H'31',H'2c',H'47',H'8b',H'f0',H'2a',H'bf',H'08'
	db H'a5',H'11',H'c3',H'2b',H'54',H'49',H'1c',H'64',H'b3',H'9c',H'34',H'19',H'48',H'61',H'9e',H'4b',H'4b',H'ce',H'7f',H'85'
	db H'10',H'01',H'42',H'19',H'1b',H'71',H'7d',H'65',H'0f',H'06',H'0a',H'42',H'0d',H'7b',H'86',H'66',H'09',H'07',H'2e',H'42'
	db H'15',H'8d',H'8e',H'2f',H'09',H'0b',H'05',H'42',H'1a',H'95',H'8e',H'1c',H'99',H'42',H'27',H'9d',H'86',H'11',H'91',H'42'
	db H'20',H'26',H'85',H'7d',H'10',H'1d',H'89',H'42',H'01',H'14',H'25',H'8e',H'28',H'1f',H'22',H'80',H'42',H'02',H'03',H'23'
	db H'24',H'ab',H'1f',H'29',H'16',H'76',H'43',H'00',H'0c',H'13',H'21',H'0f',H'09',H'09',H'1c',H'11',H'1d',H'22',H'16',H'6b'
	db H'45',H'00',H'03',H'08',H'06',H'07',H'0b',H'0b',H'07',H'06',H'08',H'5d',H'47',H'02',H'01',H'0a',H'2e',H'05',H'05',H'2e'
	db H'0a',H'51',H'47',H'e6',H'47',H'41',H'00',H'3b',H'05',"1.gif",H'94',H'01',"image/gif",H'0A'
	db H'0A',H'47',H'49',H'46',H'38',H'39',H'61',H'12',H'00',H'12',H'00',H'd5',H'33',H'00',H'e8',H'e8',H'e8',H'f5',H'f5',H'f5'
	db H'54',H'f2',H'7d',H'53',H'ef',H'7c',H'5b',H'5b',H'5b',H'c9',H'c9',H'c9',H'62',H'62',H'62',H'f9',H'f9',H'f9',H'd2',H'd2'
	db H'd2',H'd6',H'd6',H'd6',H'61',H'f6',H'88',H'fa',H'fa',H'fa',H'60',H'f5',H'87',H'5d',H'f6',H'85',H'56',H'f4',H'7f',H'50'
	db H'e4',H'77',H'4a',H'c7',H'6a',H'5b',H'f7',H'84',H'b4',H'f9',H'c6',H'ca',H'ca',H'ca',H'51',H'ea',H'79',H'54',H'f1',H'7e'
	db H'85',H'85',H'85',H'64',H'd3',H'81',H'3f',H'7f',H'50',H'a0',H'a0',H'a0',H'5a',H'f6',H'83',H'58',H'f6',H'81',H'76',H'76'
	db H'76',H'9e',H'9e',H'9e',H'77',H'77',H'77',H'70',H'ee',H'91',H'89',H'f8',H'a6',H'54',H'ec',H'7b',H'4c',H'4c',H'4c',H'6d'
	db H'dc',H'89',H'57',H'f0',H'7f',H'57',H'f5',H'81',H'53',H'd1',H'75',H'a0',H'e4',H'b2',H'46',H'b3',H'62',H'71',H'b4',H'82'
	db H'52',H'e6',H'79',H'77',H'f6',H'99',H'd3',H'd3',H'd3',H'5a',H'f7',H'84',H'42',H'42',H'42',H'cb',H'cb',H'cb',H'55',H'f3'
	db H'7f',H'cc',H'cc',H'cc',H'53',H'f1',H'7d',H'ff',H'ff',H'ff',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00'
	db H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00',H'00'
	db H'00',H'00',H'00',H'00',H'00',H'00',H'21',H'f9',H'04',H'01',H'00',H'00',H'33',H'00',H'2c',H'00',H'00',H'00',H'00',H'12'
	db H'00',H'12',H'00',H'00',H'06',H'a6',H'c0',H'99',H'70',H'48',H'2c',H'1a',H'67',H'92',H'95',H'22',H'a2',H'61',H'7c',H'4e'
	db H'80',H'c3',H'11',H'd4',H'd8',H'38',H'60',H'58',H'18',H'69',H'84',H'08',H'14',H'41',H'ad',H'12',H'4c',H'20',H'2b',H'cb'
	db H'04',H'95',H'cb',H'c4',H'2b',H'94',H'34',H'4a',H'64',H'b3',H'3c',H'94',H'42',H'48',H'67',H'ab',H'0d',H'4c',H'ce',H'97'
	db H'99',H'3a',H'00',H'42',H'0a',H'0e',H'71',H'7d',H'65',H'2a',H'1c',H'09',H'42',H'11',H'7b',H'86',H'66',H'03',H'06',H'31'
	db H'42',H'1a',H'8d',H'8e',H'32',H'03',H'04',H'05',H'42',H'0c',H'95',H'8e',H'0f',H'99',H'42',H'1f',H'9d',H'86',H'10',H'91'
	db H'42',H'27',H'24',H'85',H'7d',H'14',H'18',H'1e',H'8a',H'33',H'00',H'23',H'15',H'8e',H'03',H'28',H'22',H'19',H'81',H'33'
	db H'07',H'08',H'17',H'21',H'ab',H'28',H'2e',H'16',H'2c',H'0b',H'43',H'01',H'13',H'29',H'26',H'2a',H'03',H'03',H'0f',H'10'
	db H'18',H'22',H'16',H'2f',H'6c',H'c5',H'08',H'1d',H'1c',H'06',H'04',H'04',H'06',H'1e',H'19',H'2c',H'd3',H'44',H'07',H'00'
	db H'09',H'31',H'05',H'05',H'31',H'09',H'00',H'c4',H'47',H'eb',H'46',H'41',H'00',H'3b',H'0a',"index.html",H'7f',H'01',"text/html",H'0A',H'0A'
	db H'3c',H'21',H'44',H'4f',H'43',H'54',H'59',H'50',H'45',H'20',H'48',H'54',H'4d',H'4c',H'20',H'50',H'55',H'42',H'4c',H'49'
	db H'43',H'20',H'22',H'2d',H'2f',H'2f',H'57',H'33',H'43',H'2f',H'2f',H'44',H'54',H'44',H'20',H'48',H'54',H'4d',H'4c',H'20'
	db H'34',H'2e',H'30',H'31',H'20',H'46',H'72',H'61',H'6d',H'65',H'73',H'65',H'74',H'2f',H'2f',H'45',H'4e',H'22',H'3e',H'0a'
	db H'3c',H'68',H'74',H'6d',H'6c',H'3e',H'0a',H'3c',H'68',H'65',H'61',H'64',H'3e',H'0a',H'3c',H'74',H'69',H'74',H'6c',H'65'
	db H'3e',H'50',H'49',H'43',H'31',H'38',H'66',H'34',H'35',H'32',H'20',H'2b',H'20',H'33',H'43',H'4f',H'4d',H'20',H'33',H'43'
	db H'35',H'30',H'39',H'42',H'20',H'2d',H'20',H'57',H'65',H'62',H'20',H'73',H'65',H'72',H'76',H'65',H'72',H'20',H'2d',H'3c'
	db H'2f',H'74',H'69',H'74',H'6c',H'65',H'3e',H'0a',H'3c',H'2f',H'68',H'65',H'61',H'64',H'3e',H'0a',H'3c',H'66',H'72',H'61'
	db H'6d',H'65',H'73',H'65',H'74',H'20',H'72',H'6f',H'77',H'73',H'3d',H'22',H'31',H'30',H'30',H'2c',H'2a',H'22',H'20',H'62'
	db H'6f',H'72',H'64',H'65',H'72',H'3d',H'22',H'30',H'22',H'20',H'66',H'72',H'61',H'6d',H'65',H'62',H'6f',H'72',H'64',H'65'
	db H'72',H'3d',H'22',H'30',H'22',H'3e',H'0a',H'3c',H'66',H'72',H'61',H'6d',H'65',H'20',H'6e',H'61',H'6d',H'65',H'3d',H'22'
	db H'66',H'69',H'78',H'65',H'64',H'22',H'20',H'66',H'72',H'61',H'6d',H'65',H'62',H'6f',H'72',H'64',H'65',H'72',H'3d',H'22'
	db H'30',H'22',H'20',H'73',H'63',H'72',H'6f',H'6c',H'6c',H'69',H'6e',H'67',H'3d',H'22',H'6e',H'6f',H'22',H'20',H'73',H'72'
	db H'63',H'3d',H'22',H'6d',H'65',H'6e',H'75',H'2e',H'68',H'74',H'6d',H'6c',H'22',H'20',H'69',H'64',H'3d',H'22',H'66',H'69'
	db H'78',H'65',H'64',H'22',H'20',H'6e',H'6f',H'72',H'65',H'73',H'69',H'7a',H'65',H'3e',H'0a',H'3c',H'66',H'72',H'61',H'6d'
	db H'65',H'20',H'6e',H'61',H'6d',H'65',H'3d',H'22',H'64',H'79',H'6e',H'61',H'6d',H'69',H'63',H'22',H'20',H'66',H'72',H'61'
	db H'6d',H'65',H'62',H'6f',H'72',H'64',H'65',H'72',H'3d',H'22',H'30',H'22',H'20',H'73',H'72',H'63',H'3d',H'22',H'64',H'65'
	db H'6d',H'6f',H'2e',H'68',H'74',H'6d',H'6c',H'22',H'20',H'69',H'64',H'3d',H'22',H'64',H'79',H'6e',H'61',H'6d',H'69',H'63'
	db H'22',H'20',H'6e',H'6f',H'72',H'65',H'73',H'69',H'7a',H'65',H'3e',H'0a',H'3c',H'2f',H'66',H'72',H'61',H'6d',H'65',H'73'
	db H'65',H'74',H'3e',H'0a',H'3c',H'2f',H'68',H'74',H'6d',H'6c',H'3e',H'0a',H'09',"demo.html",H'b4',H'02',"text/html",H'0A'
	db H'0A',H'3c',H'68',H'74',H'6d',H'6c',H'3e',H'3c',H'68',H'65',H'61',H'64',H'3e',H'3c',H'6d',H'65',H'74',H'61',H'20',H'68'
	db H'74',H'74',H'70',H'2d',H'65',H'71',H'75',H'69',H'76',H'3d',H'22',H'43',H'6f',H'6e',H'74',H'65',H'6e',H'74',H'2d',H'54'
	db H'79',H'70',H'65',H'22',H'20',H'63',H'6f',H'6e',H'74',H'65',H'6e',H'74',H'3d',H'22',H'74',H'65',H'78',H'74',H'2f',H'68'
	db H'74',H'6d',H'6c',H'3b',H'63',H'68',H'61',H'72',H'73',H'65',H'74',H'3d',H'69',H'73',H'6f',H'2d',H'38',H'38',H'35',H'39'
	db H'2d',H'31',H'22',H'3e',H'3c',H'6d',H'65',H'74',H'61',H'20',H'68',H'74',H'74',H'70',H'2d',H'65',H'71',H'75',H'69',H'76'
	db H'3d',H'22',H'52',H'65',H'66',H'72',H'65',H'73',H'68',H'22',H'20',H'63',H'6f',H'6e',H'74',H'65',H'6e',H'74',H'3d',H'22'
	db H'34',H'22',H'3e',H'3c',H'2f',H'68',H'65',H'61',H'64',H'3e',H'0a',H'3c',H'62',H'6f',H'64',H'79',H'20',H'74',H'65',H'78'
	db H'74',H'3d',H'23',H'30',H'30',H'30',H'30',H'30',H'30',H'20',H'62',H'67',H'63',H'6f',H'6c',H'6f',H'72',H'3d',H'23',H'45'
	db H'30',H'45',H'30',H'45',H'30',H'20',H'6c',H'69',H'6e',H'6b',H'3d',H'23',H'30',H'30',H'30',H'30',H'46',H'46',H'20',H'76'
	db H'6c',H'69',H'6e',H'6b',H'3d',H'23',H'38',H'30',H'30',H'30',H'38',H'30',H'20',H'61',H'6c',H'69',H'6e',H'6b',H'3d',H'23'
	db H'46',H'46',H'30',H'30',H'30',H'30',H'3e',H'0a',H'3c',H'68',H'72',H'3e',H'3c',H'70',H'3e',H'54',H'68',H'69',H'73',H'20'
	db H'77',H'65',H'62',H'73',H'69',H'74',H'65',H'20',H'69',H'73',H'20',H'62',H'72',H'6f',H'75',H'67',H'68',H'74',H'20',H'74'
	db H'6f',H'20',H'79',H'6f',H'75',H'20',H'62',H'79',H'20',H'61',H'20',H'77',H'65',H'62',H'73',H'65',H'72',H'76',H'65',H'72'
	db H'20',H'74',H'68',H'61',H'74',H'20',H'69',H'73',H'20',H'72',H'75',H'6e',H'6e',H'69',H'6e',H'67',H'20',H'6f',H'6e',H'20'
	db H'61',H'20',H'50',H'49',H'43',H'31',H'38',H'46',H'34',H'35',H'32',H'20',H'63',H'6f',H'6e',H'6e',H'65',H'63',H'74',H'65'
	db H'64',H'20',H'74',H'6f',H'20',H'61',H'20',H'33',H'43',H'4f',H'4d',H'20',H'33',H'43',H'35',H'30',H'39',H'42',H'20',H'65'
	db H'74',H'68',H'65',H'72',H'6e',H'65',H'74',H'20',H'63',H'61',H'72',H'64',H'2e',H'3c',H'2f',H'70',H'3e',H'0a',H'3c',H'70'
	db H'3e',H'42',H'65',H'6c',H'6f',H'77',H'20',H'79',H'6f',H'75',H'20',H'63',H'61',H'6e',H'20',H'73',H'65',H'65',H'20',H'77'
	db H'68',H'69',H'63',H'68',H'20',H'69',H'6e',H'70',H'75',H'74',H'20',H'6f',H'66',H'20',H'74',H'68',H'69',H'73',H'20',H'50'
	db H'49',H'43',H'31',H'38',H'66',H'34',H'35',H'32',H'20',H'69',H'73',H'20',H'68',H'69',H'67',H'68',H'20',H'28',H'31',H'29'
	db H'20',H'6f',H'72',H'20',H'6c',H'6f',H'77',H'20',H'28',H'30',H'29',H'2e',H'3c',H'2f',H'70',H'3e',H'3c',H'68',H'72',H'3e'
	db H'0a',H'3c',H'50',H'52',H'45',H'3e',H'0a',H'50',H'4f',H'52',H'54',H'41',H'20',H'3c',H'3f',H'41',H'37',H'20',H'3c',H'3f'
	db H'41',H'36',H'20',H'3c',H'3f',H'41',H'35',H'20',H'3c',H'3f',H'41',H'34',H'20',H'3c',H'3f',H'41',H'33',H'20',H'3c',H'3f'
	db H'41',H'32',H'20',H'3c',H'3f',H'41',H'31',H'20',H'3c',H'3f',H'41',H'30',H'0a',H'50',H'4f',H'52',H'54',H'42',H'20',H'3c'
	db H'3f',H'42',H'37',H'20',H'3c',H'3f',H'42',H'36',H'20',H'3c',H'3f',H'42',H'35',H'20',H'3c',H'3f',H'42',H'34',H'20',H'3c'
	db H'3f',H'42',H'33',H'20',H'3c',H'3f',H'42',H'32',H'20',H'3c',H'3f',H'42',H'31',H'20',H'3c',H'3f',H'42',H'30',H'0a',H'50'
	db H'4f',H'52',H'54',H'43',H'20',H'3c',H'3f',H'43',H'37',H'20',H'3c',H'3f',H'43',H'36',H'20',H'3c',H'3f',H'43',H'35',H'20'
	db H'3c',H'3f',H'43',H'34',H'20',H'3c',H'3f',H'43',H'33',H'20',H'3c',H'3f',H'43',H'32',H'20',H'3c',H'3f',H'43',H'31',H'20'
	db H'3c',H'3f',H'43',H'30',H'0a',H'50',H'4f',H'52',H'54',H'44',H'20',H'3c',H'3f',H'44',H'37',H'20',H'3c',H'3f',H'44',H'36'
	db H'20',H'3c',H'3f',H'44',H'35',H'20',H'3c',H'3f',H'44',H'34',H'20',H'3c',H'3f',H'44',H'33',H'20',H'3c',H'3f',H'44',H'32'
	db H'20',H'3c',H'3f',H'44',H'31',H'20',H'3c',H'3f',H'44',H'30',H'0a',H'50',H'4f',H'52',H'54',H'45',H'20',H'3c',H'3f',H'45'
	db H'37',H'20',H'3c',H'3f',H'45',H'36',H'20',H'3c',H'3f',H'45',H'35',H'20',H'3c',H'3f',H'45',H'34',H'20',H'3c',H'3f',H'45'
	db H'33',H'20',H'3c',H'3f',H'45',H'32',H'20',H'3c',H'3f',H'45',H'31',H'20',H'3c',H'3f',H'45',H'30',H'0a',H'3c',H'2f',H'50'
	db H'52',H'45',H'3e',H'3c',H'68',H'72',H'3e',H'3c',H'2f',H'62',H'6f',H'64',H'79',H'3e',H'3c',H'2f',H'68',H'74',H'6d',H'6c'
	db H'3e',H'0a',H'0a',"gdemo.html",H'00',H'05',"text/html",H'0A',H'0A'
	db H'3c',H'68',H'74',H'6d',H'6c',H'3e',H'3c',H'68',H'65',H'61',H'64',H'3e',H'3c',H'6d',H'65',H'74',H'61',H'20',H'68',H'74'
	db H'74',H'70',H'2d',H'65',H'71',H'75',H'69',H'76',H'3d',H'22',H'43',H'6f',H'6e',H'74',H'65',H'6e',H'74',H'2d',H'54',H'79'
	db H'70',H'65',H'22',H'20',H'63',H'6f',H'6e',H'74',H'65',H'6e',H'74',H'3d',H'22',H'74',H'65',H'78',H'74',H'2f',H'68',H'74'
	db H'6d',H'6c',H'3b',H'63',H'68',H'61',H'72',H'73',H'65',H'74',H'3d',H'69',H'73',H'6f',H'2d',H'38',H'38',H'35',H'39',H'2d'
	db H'31',H'22',H'3e',H'3c',H'6d',H'65',H'74',H'61',H'20',H'68',H'74',H'74',H'70',H'2d',H'65',H'71',H'75',H'69',H'76',H'3d'
	db H'22',H'52',H'65',H'66',H'72',H'65',H'73',H'68',H'22',H'20',H'63',H'6f',H'6e',H'74',H'65',H'6e',H'74',H'3d',H'22',H'34'
	db H'22',H'3e',H'3c',H'2f',H'68',H'65',H'61',H'64',H'3e',H'0a',H'3c',H'62',H'6f',H'64',H'79',H'20',H'74',H'65',H'78',H'74'
	db H'3d',H'23',H'30',H'30',H'30',H'30',H'30',H'30',H'20',H'62',H'67',H'63',H'6f',H'6c',H'6f',H'72',H'3d',H'23',H'45',H'30'
	db H'45',H'30',H'45',H'30',H'20',H'6c',H'69',H'6e',H'6b',H'3d',H'23',H'30',H'30',H'30',H'30',H'46',H'46',H'20',H'76',H'6c'
	db H'69',H'6e',H'6b',H'3d',H'23',H'38',H'30',H'30',H'30',H'38',H'30',H'20',H'61',H'6c',H'69',H'6e',H'6b',H'3d',H'23',H'46'
	db H'46',H'30',H'30',H'30',H'30',H'3e',H'0a',H'3c',H'68',H'72',H'3e',H'3c',H'70',H'3e',H'54',H'68',H'69',H'73',H'20',H'77'
	db H'65',H'62',H'73',H'69',H'74',H'65',H'20',H'69',H'73',H'20',H'62',H'72',H'6f',H'75',H'67',H'68',H'74',H'20',H'74',H'6f'
	db H'20',H'79',H'6f',H'75',H'20',H'62',H'79',H'20',H'61',H'20',H'77',H'65',H'62',H'73',H'65',H'72',H'76',H'65',H'72',H'20'
	db H'74',H'68',H'61',H'74',H'20',H'69',H'73',H'20',H'72',H'75',H'6e',H'6e',H'69',H'6e',H'67',H'20',H'6f',H'6e',H'20',H'61'
	db H'20',H'50',H'49',H'43',H'31',H'38',H'46',H'34',H'35',H'32',H'20',H'63',H'6f',H'6e',H'6e',H'65',H'63',H'74',H'65',H'64'
	db H'20',H'74',H'6f',H'20',H'61',H'20',H'33',H'43',H'4f',H'4d',H'20',H'33',H'43',H'35',H'30',H'39',H'42',H'20',H'65',H'74'
	db H'68',H'65',H'72',H'6e',H'65',H'74',H'20',H'63',H'61',H'72',H'64',H'2e',H'3c',H'2f',H'70',H'3e',H'0a',H'3c',H'70',H'3e'
	db H'42',H'65',H'6c',H'6f',H'77',H'20',H'79',H'6f',H'75',H'20',H'63',H'61',H'6e',H'20',H'73',H'65',H'65',H'20',H'77',H'68'
	db H'69',H'63',H'68',H'20',H'69',H'6e',H'70',H'75',H'74',H'20',H'6f',H'66',H'20',H'74',H'68',H'69',H'73',H'20',H'50',H'49'
	db H'43',H'31',H'38',H'66',H'34',H'35',H'32',H'20',H'69',H'73',H'20',H'68',H'69',H'67',H'68',H'20',H'3c',H'69',H'6d',H'67'
	db H'20',H'73',H'72',H'63',H'3d',H'22',H'31',H'2e',H'67',H'69',H'66',H'22',H'3e',H'20',H'6f',H'72',H'20',H'6c',H'6f',H'77'
	db H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'22',H'30',H'2e',H'67',H'69',H'66',H'22',H'3e',H'2e',H'3c'
	db H'2f',H'70',H'3e',H'3c',H'68',H'72',H'3e',H'0a',H'3c',H'50',H'52',H'45',H'3e',H'0a',H'50',H'4f',H'52',H'54',H'41',H'20'
	db H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f',H'41',H'37',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c'
	db H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f',H'41',H'36',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69'
	db H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f',H'41',H'35',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d'
	db H'67',H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f',H'41',H'34',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67'
	db H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f',H'41',H'33',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20'
	db H'73',H'72',H'63',H'3d',H'3c',H'3f',H'41',H'32',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73'
	db H'72',H'63',H'3d',H'3c',H'3f',H'41',H'31',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72'
	db H'63',H'3d',H'3c',H'3f',H'41',H'30',H'2e',H'67',H'69',H'66',H'3e',H'0a',H'50',H'4f',H'52',H'54',H'42',H'20',H'3c',H'69'
	db H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f',H'42',H'37',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d'
	db H'67',H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f',H'42',H'36',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67'
	db H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f',H'42',H'35',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20'
	db H'73',H'72',H'63',H'3d',H'3c',H'3f',H'42',H'34',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73'
	db H'72',H'63',H'3d',H'3c',H'3f',H'42',H'33',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72'
	db H'63',H'3d',H'3c',H'3f',H'42',H'32',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63'
	db H'3d',H'3c',H'3f',H'42',H'31',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d'
	db H'3c',H'3f',H'42',H'30',H'2e',H'67',H'69',H'66',H'3e',H'0a',H'50',H'4f',H'52',H'54',H'43',H'20',H'3c',H'69',H'6d',H'67'
	db H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f',H'43',H'37',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20'
	db H'73',H'72',H'63',H'3d',H'3c',H'3f',H'43',H'36',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73'
	db H'72',H'63',H'3d',H'3c',H'3f',H'43',H'35',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72'
	db H'63',H'3d',H'3c',H'3f',H'43',H'34',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63'
	db H'3d',H'3c',H'3f',H'43',H'33',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d'
	db H'3c',H'3f',H'43',H'32',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c'
	db H'3f',H'43',H'31',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f'
	db H'43',H'30',H'2e',H'67',H'69',H'66',H'3e',H'0a',H'50',H'4f',H'52',H'54',H'44',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73'
	db H'72',H'63',H'3d',H'3c',H'3f',H'44',H'37',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72'
	db H'63',H'3d',H'3c',H'3f',H'44',H'36',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63'
	db H'3d',H'3c',H'3f',H'44',H'35',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d'
	db H'3c',H'3f',H'44',H'34',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c'
	db H'3f',H'44',H'33',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f'
	db H'44',H'32',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f',H'44'
	db H'31',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f',H'44',H'30'
	db H'2e',H'67',H'69',H'66',H'3e',H'0a',H'50',H'4f',H'52',H'54',H'45',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63'
	db H'3d',H'3c',H'3f',H'45',H'37',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d'
	db H'3c',H'3f',H'45',H'36',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c'
	db H'3f',H'45',H'35',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f'
	db H'45',H'34',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f',H'45'
	db H'33',H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f',H'45',H'32'
	db H'2e',H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f',H'45',H'31',H'2e'
	db H'67',H'69',H'66',H'3e',H'20',H'3c',H'69',H'6d',H'67',H'20',H'73',H'72',H'63',H'3d',H'3c',H'3f',H'45',H'30',H'2e',H'67'
	db H'69',H'66',H'3e',H'0a',H'3c',H'2f',H'50',H'52',H'45',H'3e',H'3c',H'68',H'72',H'3e',H'3c',H'2f',H'62',H'6f',H'64',H'79'
	db H'3e',H'3c',H'2f',H'68',H'74',H'6d',H'6c',H'3e',H'0a',H'09',"info.html",H'c9',H'02',"text/html",H'0A',H'0A'
	db H'3c',H'21',H'44',H'4f',H'43',H'54',H'59',H'50',H'45',H'20',H'48',H'54',H'4d',H'4c',H'20',H'50',H'55',H'42',H'4c',H'49'
	db H'43',H'20',H'22',H'2d',H'2f',H'2f',H'57',H'33',H'43',H'2f',H'2f',H'44',H'54',H'44',H'20',H'48',H'54',H'4d',H'4c',H'20'
	db H'34',H'2e',H'30',H'31',H'20',H'54',H'72',H'61',H'6e',H'73',H'69',H'74',H'69',H'6f',H'6e',H'61',H'6c',H'2f',H'2f',H'45'
	db H'4e',H'22',H'3e',H'0a',H'3c',H'68',H'74',H'6d',H'6c',H'3e',H'0a',H'3c',H'68',H'65',H'61',H'64',H'3e',H'0a',H'3c',H'6d'
	db H'65',H'74',H'61',H'20',H'68',H'74',H'74',H'70',H'2d',H'65',H'71',H'75',H'69',H'76',H'3d',H'22',H'43',H'6f',H'6e',H'74'
	db H'65',H'6e',H'74',H'2d',H'54',H'79',H'70',H'65',H'22',H'20',H'63',H'6f',H'6e',H'74',H'65',H'6e',H'74',H'3d',H'22',H'74'
	db H'65',H'78',H'74',H'2f',H'68',H'74',H'6d',H'6c',H'3b',H'63',H'68',H'61',H'72',H'73',H'65',H'74',H'3d',H'69',H'73',H'6f'
	db H'2d',H'38',H'38',H'35',H'39',H'2d',H'31',H'22',H'3e',H'0a',H'3c',H'74',H'69',H'74',H'6c',H'65',H'3e',H'50',H'49',H'43'
	db H'31',H'38',H'66',H'34',H'35',H'32',H'20',H'2b',H'20',H'33',H'43',H'4f',H'4d',H'20',H'33',H'43',H'35',H'30',H'39',H'42'
	db H'20',H'2d',H'20',H'57',H'65',H'62',H'73',H'65',H'72',H'76',H'65',H'72',H'20',H'2d',H'3c',H'2f',H'74',H'69',H'74',H'6c'
	db H'65',H'3e',H'0a',H'3c',H'6d',H'65',H'74',H'61',H'20',H'6e',H'61',H'6d',H'65',H'3d',H'22',H'4b',H'65',H'79',H'77',H'6f'
	db H'72',H'64',H'73',H'22',H'20',H'63',H'6f',H'6e',H'74',H'65',H'6e',H'74',H'3d',H'22',H'50',H'49',H'43',H'31',H'38',H'66'
	db H'34',H'35',H'32',H'2c',H'20',H'33',H'43',H'35',H'30',H'39',H'42',H'2c',H'20',H'77',H'65',H'62',H'73',H'65',H'72',H'76'
	db H'65',H'72',H'22',H'3e',H'0a',H'20',H'20',H'3c',H'73',H'74',H'79',H'6c',H'65',H'20',H'74',H'79',H'70',H'65',H'3d',H'22'
	db H'74',H'65',H'78',H'74',H'2f',H'63',H'73',H'73',H'22',H'3e',H'0a',H'09',H'61',H'3a',H'68',H'6f',H'76',H'65',H'72',H'7b'
	db H'63',H'6f',H'6c',H'6f',H'72',H'3a',H'72',H'65',H'64',H'3b',H'20',H'74',H'65',H'78',H'74',H'2d',H'64',H'65',H'63',H'6f'
	db H'72',H'61',H'74',H'69',H'6f',H'6e',H'3a',H'6e',H'6f',H'6e',H'65',H'3b',H'20',H'7d',H'0a',H'20',H'20',H'3c',H'2f',H'73'
	db H'74',H'79',H'6c',H'65',H'3e',H'0a',H'3c',H'2f',H'68',H'65',H'61',H'64',H'3e',H'0a',H'0a',H'3c',H'62',H'6f',H'64',H'79'
	db H'20',H'74',H'65',H'78',H'74',H'3d',H'22',H'23',H'30',H'30',H'30',H'30',H'30',H'30',H'22',H'20',H'62',H'67',H'63',H'6f'
	db H'6c',H'6f',H'72',H'3d',H'22',H'23',H'45',H'30',H'45',H'30',H'45',H'30',H'22',H'20',H'6c',H'69',H'6e',H'6b',H'3d',H'22'
	db H'23',H'30',H'30',H'30',H'30',H'46',H'46',H'22',H'20',H'76',H'6c',H'69',H'6e',H'6b',H'3d',H'22',H'23',H'38',H'30',H'30'
	db H'30',H'38',H'30',H'22',H'20',H'61',H'6c',H'69',H'6e',H'6b',H'3d',H'22',H'23',H'46',H'46',H'30',H'30',H'30',H'30',H'22'
	db H'3e',H'0a',H'3c',H'68',H'72',H'3e',H'0a',H'3c',H'75',H'6c',H'3e',H'0a',H'3c',H'6c',H'69',H'3e',H'0a',H'59',H'6f',H'75'
	db H'20',H'63',H'61',H'6e',H'20',H'66',H'69',H'6e',H'64',H'20',H'6d',H'6f',H'72',H'65',H'20',H'69',H'6e',H'66',H'6f',H'0a'
	db H'3c',H'61',H'20',H'68',H'72',H'65',H'66',H'3d',H'22',H'68',H'74',H'74',H'70',H'3a',H'2f',H'2f',H'77',H'77',H'77',H'2e'
	db H'6a',H'61',H'6e',H'77',H'2e',H'65',H'61',H'73',H'79',H'6e',H'65',H'74',H'2e',H'62',H'65',H'2f',H'70',H'69',H'63',H'31'
	db H'38',H'66',H'34',H'35',H'32',H'2d',H'65',H'2e',H'68',H'74',H'6d',H'6c',H'22',H'20',H'74',H'61',H'72',H'67',H'65',H'74'
	db H'3d',H'22',H'5f',H'74',H'6f',H'70',H'22',H'3e',H'68',H'65',H'72',H'65',H'3c',H'2f',H'61',H'3e',H'2e',H'0a',H'3c',H'2f'
	db H'6c',H'69',H'3e',H'0a',H'3c',H'6c',H'69',H'3e',H'0a',H'4d',H'65',H'65',H'72',H'20',H'69',H'6e',H'66',H'6f',H'72',H'6d'
	db H'61',H'74',H'69',H'65',H'20',H'76',H'69',H'6e',H'64',H'20',H'6a',H'65',H'0a',H'3c',H'61',H'20',H'68',H'72',H'65',H'66'
	db H'3d',H'22',H'68',H'74',H'74',H'70',H'3a',H'2f',H'2f',H'77',H'77',H'77',H'2e',H'6a',H'61',H'6e',H'77',H'2e',H'65',H'61'
	db H'73',H'79',H'6e',H'65',H'74',H'2e',H'62',H'65',H'2f',H'70',H'69',H'63',H'31',H'38',H'66',H'34',H'35',H'32',H'2e',H'68'
	db H'74',H'6d',H'6c',H'22',H'20',H'74',H'61',H'72',H'67',H'65',H'74',H'3d',H'22',H'5f',H'74',H'6f',H'70',H'22',H'3e',H'68'
	db H'69',H'65',H'72',H'3c',H'2f',H'61',H'3e',H'2e',H'0a',H'3c',H'2f',H'6c',H'69',H'3e',H'0a',H'3c',H'2f',H'75',H'6c',H'3e'
	db H'0a',H'3c',H'68',H'72',H'3e',H'0a',H'3c',H'2f',H'62',H'6f',H'64',H'79',H'3e',H'0a',H'3c',H'2f',H'68',H'74',H'6d',H'6c'
	db H'3e',H'0a',H'00'

        end

; ---------------------------------------------------------------------------
; I have created the web-line above with the following C-program on my
; Debian GNU/Linux BOX. The C-program converts the files in the
; directory web to data for the db-line. Use > to write to a file.
; ---------------------------------------------------------------------------

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>

#define REQUEST_DIR "./web"
int
main (int argc, char *argv[])
{

  int c, teller, odd;
  FILE *f1;
  FILE *fp;
  DIR *dirp;
  char type[20];
  struct dirent *dp;
  struct stat buf;
  char *rightstr (char *string, int number);

  dirp = opendir (REQUEST_DIR);
  chdir (REQUEST_DIR);

  odd = 0;
  printf ("\tdb ");

  /* Look at each entry in turn */
  while ((dp = readdir (dirp)) != NULL)
    {

      /*Now stat the file to get more info */
      if (stat (dp->d_name, &buf) == -1)
	perror ("stat\n");

      /* if (S_ISDIR(buf.st_mode)) 
         printf("%s is a directory\n", dp->d_name);
         else 
       */

      if (S_ISREG (buf.st_mode))
	{
	  /* printf("%s is a file\n", dp->d_name); */

	  /* PRINT lengte bestandsnaam, bestandsnaam */
	  printf ("H\'%02x\',\"%s\",", strlen (dp->d_name), dp->d_name);

	  /* Bepaal content-type aan de hand van de extensie 
	     Uit te breiden indien nodig.
	   */
	  strcpy (type, "text/html");
	  if (strcmp (rightstr (dp->d_name, 4), ".jpg") == 0)
	    {
	      strcpy (type, "image/jpeg");
	    }
	  if (strcmp (rightstr (dp->d_name, 4), ".gif") == 0)
	    {
	      strcpy (type, "image/gif");
	    }

	  /* PRINT lengte van het bestand */
	  f1 = fopen (dp->d_name, "r");
	  teller = strlen (type) + 2;	/* Inhoud bestand + content-type + 0A + 0A */
	  c = getc (f1);
	  while (c != EOF)
	    {
	      teller = teller + 1;
	      c = getc (f1);
	    }
	  printf ("H\'%02x\',", teller & 255);
	  printf ("H\'%02x\',", teller >> 8);
	  fclose (f1);

	  /* PRINT lijst met bytes */
	  printf ("\"%s\",", type);
	  odd = (odd + strlen (dp->d_name) + strlen (type) + 1) & 1;
	  if (odd == 0)
	    {
	      printf ("H'0A',H'0A'\n\tdb ");
	    }
	  else
	    {
	      printf ("H'0A'\n\tdb H'0A',");
	    }

	  f1 = fopen (dp->d_name, "r");
	  c = getc (f1);

	  while (c != EOF)
	    {
	      odd = odd + 1;
	      if (odd <= 19)
		{
		  printf ("H\'%02x\',", c);
		}
	      if (odd == 20)
		{
		  printf ("H\'%02x\'\n\tdb ", c);
		  odd = 0;
		}
	      c = getc (f1);
	    }
	  fclose (f1);
	}

    }

  (void) closedir (dirp);
  printf ("H'00'\n");
}

char *
rightstr (char *string, int number)
{
  int x;

  x = strlen (string) - number;
  if (x > 0)
    return (string + x);
  return (string);
}

; ---------------------------------------------------------------------------
; References
; ---------------------------------------------------------------------------
; http://www.networksorcery.com/enp/default0602.htm
; http://www.networkuptime.com/tutorials/arp/ : uitleg ARP
