please dont rip this site

;;========================================================================
;;
;; Program:         TCP/IP stack and HTTP-server in a chip
;; Idea:            Shrikumar H. <shri@cs.umass.edu>
;; Author:          Denis Petrov <zhengxi@operamail.com>
;; Platform:        Microchip PIC16F84
;; Date:            17.09.99
;; LastDate:        25.09.99
;;
;;========================================================================

;; todo: watching tcp_online
;;       use WDT
;;       more than 1 socket

include masmpic.inc
.386

;;========================================================================
;; General settings
;;========================================================================
QUARTZ_FREQ             =  6000000
RS_BAUD                 =    19200
RS_DATA                 =        8
RS_TICKS                =  (QUARTZ_FREQ/4)/RS_BAUD   ; [non-volatile]


ADDR_MYSELF_0           =      219      ; 219.192.55.208 ( ~my phone# :)
ADDR_MYSELF_1           =      192
ADDR_MYSELF_2           =       55
ADDR_MYSELF_3           =      208

TCP_PORT_HTTP           =       80      ; 1..255

TCP_RCV_WINDOW          =      128;!sic!; [non-volatile]
TCP_SND_WINDOW          =      128      ; [non-volatile]

RS_MONITOR              =        1      ; monitor works over raw RS232

FS_UNIT_SIZE            =      128      ; [non-volatile]
FS_ROOT_DIR_ENTRIES     =        8      ; min 2: INDEX and ERROR.

FS_USE_INTERNAL_ROM     =        1
FS_INTERNAL_ROM_UNITS   =        4      ; number of 128-byte pages
FS_USE_INTERNAL_EEPROM  =        0      ;

FS_USE_EXTERNAL_ROM     =        0


;;========================================================================
;; DATA RAM mapping
;;========================================================================
TCPR_RPORT_H            =   SRAM0           ; remote TCP port
TCPR_RPORT_L            =   SRAM1
TCPR_LPORT_H            =   SRAM2           ; local TCP port, TCPR_LPORT_H==0
TCPR_LPORT_L            =   SRAM3
TCPR_SEQ_L3             =   SRAM4
TCPR_SEQ_L2             =   SRAM5
TCPR_SEQ_L1             =   SRAM6
TCPR_SEQ_L0             =   SRAM7
TCPR_ACK_L3             =   SRAM8
TCPR_ACK_L2             =   SRAM9
TCPR_ACK_L1             =   SRAM10
TCPR_ACK_L0             =   SRAM11
TCPR_HLEN               =   SRAM12          ; Is not used when sending не используется при посылке

TCPR_FLAG               =   SRAM13          ; ÎÅ ÉÓÐÏÌØÚÕÅÔÓÑ ÐÒÉ ÐÏÓÙÌËÅ

TEMP_0                  =   SRAM2
TEMP_1                  =   SRAM12
TEMP_2                  =   SRAM13

HTTP_UNITIDX            =   SRAM14 ;***
HTTP_FILESIZE_H         =   SRAM15 ;***
HTTP_FILESIZE_L         =   SRAM16 ;***
HTTP_NAME_0             =   SRAM14
HTTP_NAME_1             =   SRAM15
HTTP_NAME_2             =   SRAM16

if RS_MONITOR
MON_ADDR_H              =   SRAM14
MON_ADDR_L              =   SRAM15
MON_TAG                 =   SRAM16          ; like (as) 'R', 'W', 'A' ×ÒÏÄÅ 'R','W','A'
endif

; socket data, it's valid if tcp_online==1
TCPR_POS                =   SRAM17          ; iterator 0 -->] 80..FF
                                            ; bytes received from the time communication opened 
                                            ; ÐÒÉÎÑÔÏ ÂÁÊÔ Ó ÏÔËÒÙÔÉÑ ÓÏÅÄÉÎÅÎÉÑ
TCPS_ACK                =   SRAM18
TCPS_SEQ                =   SRAM19
TCPS_LEN                =   SRAM20          ; for retransmit
TCPS_FLAG               =   SRAM21          ; for retransmit

RX_BYTE                 =   SRAM22          ; [soft uart]
TX_BYTE                 =   RX_BYTE         ; [soft uart]

IP_POS                  =   SRAM23          ; iterator
IP_HLEN                 =   SRAM24          ; IP header len (incoming only)
IP_LEN                  =   SRAM25          ; IP packet len
IP_SUM_0                =   SRAM26          ; TCP/IP chksum
IP_SUM_1                =   SRAM27          ; --//-----//-- low octet
IP_ADR_0                =   SRAM28          ; remote IP address
IP_ADR_1                =   SRAM29          ; --//--
IP_ADR_2                =   SRAM30          ; --//--
IP_ADR_3                =   SRAM31          ; --//--

DefBit      B_HTTP_STATE_0, TCPS_FLAG, 5
DefBit      B_HTTP_STATE_1, TCPS_FLAG, 6
DefBit      B_TCP_ONLINE,   TCPS_FLAG, 7
;DefBit     B_LED_1,        PORTA,     3
;DefBit     B_LED_2,        PORTA,     2
DefBit      B_RS232_RxD,    PORTB,     0
DefBit      B_RS232_TxD,    PORTA,     3
DefBit      B_RS232_CTS,    PORTA,     2
DefBit      B_SLIP_OUTPKT,  IP_HLEN,   7
DefBit      B_SLIP_ESCAPE,  IP_HLEN,   6


;;========================================================================
;; Useful macros
;;========================================================================
TXLW macro k
  movlw       (k)
  call        _tx
endm

SLITXLW macro k
  movlw       (k)
  call        _slitx
endm

SUM0 MACRO x:req
__TMPSUM=(((x)+((x) shr 16)) shr 8)
    movlw __TMPSUM
ENDM

SUM1 MACRO x:req
__TMPSUM=(((x)+((x) shr 16)) shr 0)
    movlw __TMPSUM
ENDM


;;========================================================================
;; Code
;;========================================================================
_start:
        clrf        INTCON                  ; Disable Interrupts ÚÁÐÒÅÔÉÔØ ×ÓÅ ÐÒÅÒÙ×ÁÎÉÑ ?
        movlw       01001111b               ; "_-", WDT/128
        option
        jump        _init

_interrupt:
;
; Soft UART ( simplex :( )
;
;         S01234567T
;        ƒ‚ˆˆˆˆˆˆˆˆˆ
; 115.2  „‰‰‰‰‰‰‰‰…„
;        ƒ ‚€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ€ˆ
;  57.6  „€‰€‰€‰€‰€‰€‰€‰€‰€… „
;        ƒ  ‚€€ˆ€€ˆ€€ˆ€€ˆ€€ˆ€€ˆ€€ˆ€€ˆ€€ˆ
;  38.4  „€€‰€€‰€€‰€€‰€€‰€€‰€€‰€€‰€€…  „
;        ƒ     ‚€€€€€ˆ€€€€€ˆ€€€€€ˆ€€€€€ˆ€€€€€ˆ€€€€€ˆ€€€€€ˆ€€€€€ˆ€€€€€ˆ€€
;  19.2  „€€€€€‰€€€€€‰€€€€€‰€€€€€‰€€€€€‰€€€€€‰€€€€€‰€€€€€‰€€€€€…     „€€
;                                        _________
;
;       _^_"þ"
;
_interrupt_b0:                              ; 5 ; Interrupt ÏÂÒÁÂÏÔÞÉÔ ÐÒÅÒÙ×ÁÎÉÑ INT
        call        _delay4                 ; 4 ; Delay 4 (ÍÏÍÅÎÔ "þ")
        movlw       8                       ; 1 ; 8Nx
_rx_next:
        bcf         B_RS232_CTS             ; 1 ; fall CTS
        call        _delay_x_9              ; x-9 ;
        bcf         C                       ; 1 ;
        skip1       B_RS232_RxD             ; 1 ;
        bsf         C                       ; 1 ; C:=RS232_RxD
        rrf         RX_BYTE,F               ; 1 ;
        addlw       -1                      ; 1 ;
        jnz         _rx_next                ; 3 ;

        movf        RX_BYTE,w               ;
        xorlw       0C0h                    ;
        jnz         _no_C0                  ; Starting to recieve ÎÁÞÉÎÁÅÍ ÐÒÉÅÍ
        bcf         B_SLIP_OUTPKT           ; New package (SLIP END) ÎÏ×ÏÇÏ ÐÁËÅÔÁ (SLIP END)
        clrf        IP_POS                  ;
        clrf        IP_SUM_0                ;
        clrf        IP_SUM_1                ;
        jump        _rx                     ;
_no_C0:
        j0          B_SLIP_OUTPKT,_mode_slip; if the symbol being revieved is not in the package 
                                            ; ÅÓÌÉ ÐÒÉÎÉÍÁÅÍÙÊ ÓÉÍ×ÏÌ ×ÎÅ ÐÁËÅÔÁ
_mode_terminal:
        xorlw       <00Dh xor 0C0h>         ;
        jnz         _rx                     ; Modem emulation ÜÍÕÌÑÃÉÑ ÍÏÄÅÍÁ:
        TXLW        'O'                     ; Respond to AT command ÏÔ×ÅÔ ÎÁ AT-ËÏÍÁÎÄÙ
        TXLW        'K'                     ;
        TXLW        0Dh                     ;
        jump        _rx                     ;
_mode_slip:
        j0          B_SLIP_ESCAPE,_no_slip_escape
        xorlw       <0DCh xor 0C0h>         ; Treatment of the 2nd byte
                                            ; ÏÔÒÁÂÏÔËÁ ×ÔÏÒÏÇÏ ÂÁÊÔÁ
        movlw       0DBh                    ; Special order SLIP ÓÐÅÃ.ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔÅÊ SLIP:
        skipnz                              ; 0xDB,0xDC --> 0xC0
        movlw       0C0h                    ; 0xDB,0xDD --> 0xDB
        movwf       RX_BYTE                 ; RX_BYTE=(RX_BYTE==0xDC?0xC0:0xDB)
;       jump        _end_slip_escape        ;
_no_slip_escape:                            ;
        bsf         B_SLIP_ESCAPE           ; if OxDB is recieved, then ÅÓÌÉ ÐÒÉÎÑÔ 0xDB, ÚÎÁÞÉÔ
        xorlw       <0DBh xor 0C0h>         ; this is the first byte ÜÔÏ ÐÅÒ×ÙÊ ÂÁÊÔ
        jz          _rx                     ; special order SLIP ÓÐÅÃ.ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔÉ SLIP:

_end_slip_escape:
        bcf         B_SLIP_ESCAPE           ;

        movf        RX_BYTE,W
        call        _checksum_byte          ; control sum refreshement (renewal?) 
                                            ; ÏÂÎÏ×ÌÅÎÉÅ ËÏÎÔÒÏÌØÎÏÊ ÓÕÍÍÙ
                                            ; of the package being recieved 
                                            ; ÐÒÉÎÉÍÁÅÍÏÇÏ ÐÁËÅÔÁ

        movf        IP_POS,W                ; treatment of the first 0x13 bytes 
                                            ; ÏÂÒÁÂÏÔËÁ ÐÅÒ×ÙÈ 0x13 ÂÁÊÔ
        addlw       -20                     ; after SLIP END as a header
                                            ; ÐÏÓÌÅ SLIP.END ËÁË ÚÁÇÏÌÏ×ÏË
        jc          _xxxx                   ; of the IP package IP ÐÁËÅÔÁ
        rlf         IP_POS,W                ;
        clrf        PCLATH                  ; usefull but not required
                                            ; ÜÔÏ ÐÏÌÅÚÎÏ, ÎÏ ÎÅ ÎÅÏÂÈÏÄÉÍÏ
        addwf       PCL,F                   ;

        movf        RX_BYTE,W               ; IPhdr+ 0  Version & IHL
        movwf       IP_HLEN                 ;
        rlf         IP_HLEN,F               ; IPhdr+ 1  Type of Service
        jump        _01_                    ;
        movlw       0                       ; IPhdr+ 2  Total Length (hi)
        jump        _rx_byte_must_equal_w   ;
        movf        RX_BYTE,W               ; IPhdr+ 3  Total Length (lo)
        movwf       IP_LEN                  ;
        jump        _finish                 ; IPhdr+ 4  Identification (hi)
_01_:   bcf         IP_HLEN,7               ;
        jump        _finish                 ; IPhdr+ 5  Identification (lo)
        nop                                 ;
        jump        _finish                 ; IPhdr+ 6  Flags & Fragment Offset (hi)
        nop                                 ;
        movlw       0                       ; IPhdr+ 7  Fragment Offset (lo)
        jump        _rx_byte_must_equal_w   ;
        jump        _finish                 ; IPhdr+ 8  Time to Live
        nop                                 ;
        movlw       6                       ; IPhdr+ 9  Protocol
        jump        _rx_byte_must_equal_w   ;
        jump        _finish                 ; IPhdr+10  Header Checksum (hi)
        nop                                 ;
        jump        _finish                 ; IPhdr+11  Header Checksum (lo)
        nop                                 ;
        movlw       IP_ADR_0                ; IPhdr+12  Source Address
        jump        _save_rx_byte           ;
        movlw       IP_ADR_1                ; IPhdr+13
        jump        _save_rx_byte           ;
        movlw       IP_ADR_2                ; IPhdr+14
        jump        _save_rx_byte           ;
        movlw       IP_ADR_3                ; IPhdr+15
        jump        _save_rx_byte           ;
        movlw       ADDR_MYSELF_0           ; IPhdr+16  Destination Address
        jump        _rx_byte_must_equal_w   ;
        movlw       ADDR_MYSELF_1           ; IPhdr+17
        jump        _rx_byte_must_equal_w   ;
        movlw       ADDR_MYSELF_2           ; IPhdr+18
        jump        _rx_byte_must_equal_w   ;
        movlw       ADDR_MYSELF_3           ; IPhdr+19
_rx_byte_must_equal_w:
        xorwf       RX_BYTE,W               ;
        jnz         _error                  ;

_xxxx:
        movf        IP_HLEN,W               ; IP_POS-IP_HLEN - on which position ÎÁ ËÁËÏÍ ÍÅÓÔÅ
        subwf       IP_POS,W                ; after the IP header, the recieved byte can be found
                                            ; ÐÒÉÎÑÔÙÊ ÂÁÊÔ ÎÁÈÏÄÉÔÓÑ ÐÏÓÌÅ IP ÚÁÇÏÌÏ×ËÁ
        jc          _post_ip                ; ... or is this still an IP header? 
                                            ; ... ÉÌÉ ÜÔÏ ×ÓÅ ÅÝÅ IP ÚÁÇÏÌÏ×ÏË?

_no_post_ip:
        xorlw       0FFh                    ; and if this is the last byte of the IP header
                                            ; Á ÅÓÌÉ ÜÔÏ ÐÏÓÌÅÄÎÉÊ ÂÁÊÔ IP ÚÁÇÏÌÏ×ËÁ
        jnz         _finish                 ; IP_SUM should be 0 IP_SUM ÄÏÌÖÎÁ ÂÙÔØ ÒÁ×ÎÁ 0
        movf        IP_SUM_0,W              ;
        iorwf       IP_SUM_1,W              ;
        jnz         _error                  ; wrong sum for monitoring
                                            ; ÎÅÐÒÁ×ÉÌØÎÁÑ ËÏÎÔÒÏÌØÎÁÑ ÓÕÍÍÁ...
_finish:
        incf        IP_POS,F                ; Next! ÓÌÅÄÕÀÝÉÊ!
        jump        _rx                     ;

_post_ip:
        addlw       -14                     ; saving the first 14 bytes of the TCP header
                                            ; ÓÏÈÒÁÎÑÅÍ ÐÅÒ×ÙÅ 14 ÂÁÊÔ TCP ÚÁÇÏÌÏ×ËÁ
        jnc         _save_as_tcp_header     ;
        jnz         _no_correct_tcp_hlen    ;
        rrf         TCPR_HLEN,F             ; if(IP_POS-IP_HLEN==14)
        rrf         TCPR_HLEN,F             ; {
        bcf         TCPR_HLEN,7             ;    TCPR_HLEN=(TCPR_HLEN<<2)&0x3F;
        bcf         TCPR_HLEN,6             ; }
_no_correct_tcp_hlen:
        subwf       TCPR_HLEN,W             ; saving bytes 5, 6 and 7 of the TCP _connection_
                                            ; ÓÏÈÒÁÎÑÅÍ 5,6É7 ÂÁÊÔÙ TCP _ÓÏÅÄÉÎÅÎÉÑ_.
        addlw       -15                     ; if now (W<14) - than the name of the file
                                            ; ÅÓÌÉ ÓÅÊÞÁÓ (W<14) - ÚÎÁÞÉÔ ÉÍÑ ÆÁÊÌÁ
        jc          _no_save_rx_byte        ;  came in multiple packages, for example, 
                                            ; ÐÒÉÛÌÏ × ÎÅÓËÏÌØËÉÈ ÐÁËÅÔÁÈ, ÎÁÐÒÉÍÅÒ,
                                            ; GET /xxx was typed in the telnet-client
                                            ; GET /xxx ÂÙÌÏ ÎÁÂÒÁÎÏ × telnet-ËÌÉÅÎÔÅ
                                            ; so this check is not necessary
                                            ;  ÔÁË ÞÔÏ ÜÔÁ ÐÒÏ×ÅÒËÁ ÎÅ Ñ×Ì. ÎÅÏÂÈÏÄÉÍÏÊ,
                                            ;  if only www-browser will be used
                                            ; ÅÓÌÉ ÂÕÄÅÔ ÐÏÌØÚÏ×ÁÔØÓÑ ÔÏÌØËÏ www-browser.
        subwf       TCPR_POS,W              ; like first symbols of the file name in "GET /"
                                            ; ËÁË ÐÅÒ×ÙÅ ÓÉÍ×ÏÌÙ ÉÍÅÎÉ ÆÁÊÌÁ × "GET /.."
        addlw       (-1-(5+3))              ; W=TCPR_POS-(TCPR_HLEN-(IP_POS-IP_HLEN-14))
        addlw       3                       ; (5.7)->(FD.FF) (5.7)->(0.2)
        jnc         _no_save_rx_byte
if (HTTP_NAME_0-(TCPR_RPORT_H+14)) ne 0
        addlw       (HTTP_NAME_0-(TCPR_RPORT_H+14))
endif
_save_as_tcp_header:
        addlw       TCPR_RPORT_H+14
_save_rx_byte:
        movwf       FSR                     ; [W]:=RX_BYTE - is often used ÞÁÓÔÏ ÉÓÐÏÌØÚÕÅÔÓÑ
        movf        RX_BYTE,W               ;
        movwf       INDR                    ;

_no_save_rx_byte:
        incf        IP_POS,W                ; ÅÓÌÉ ÐÒÉÎÑÔ ÐÏÓÌÅÄÎÉÊ ÂÁÊÔ
        subwf       IP_LEN,W                ; if the last byte of the IP package is recieved... 
                                            ; IP ÐÁËÅÔÁ...
        jnz         _finish                 ;

        movf        IP_HLEN,W               ; IP_LEN-=IP_HLEN;
        subwf       IP_LEN,F                ;
        call        _chksum_pseudoheader    ; control check sum of the TCP package's header/body 
                                            ; ÐÒÏ×ÅÒËÁ ËÏÎÔÒÏÌØÎÏÊ ÓÕÍÍÙ TCP ÚÁÇÏÌÏ×ËÁ/ÔÅÌÁ ÐÁËÅÔÁ
        movf        IP_SUM_0,W              ; 
        iorwf       IP_SUM_1,W              ;
        skipnz                              ;
        call        _process_tcp            ;
        jump        _error                  ;



;===========================================================================
; TX routines
;===========================================================================
;_txhex: movwf       FSR
;        swapf       FSR,W
;        call        _txhex0
;        movf        FSR,W
;_txhex0:andlw       00001111b
;        addlw       -10
;        skipnc
;        addlw       7
;        addlw       58
;        jump        _tx
;;------------------------------------------------
_slitx_csum:
        movf        IP_SUM_0,W              ; pass (or deliver) the control sum 
                                            ; ÐÅÒÅÄÁÔØ ËÏÎÔÒÏÌØÎÕÀ ÓÕÍÍÕ
        call        _slitx                  ; (2 bytes) (Ä×Á ÂÁÊÔÁ)
        movf        IP_SUM_1,W              ;
        jump        _slitx
;;------------------------------------------------
_slitx4:
        movwf       FSR                     ; pass (or deliver) 4 bytes (W[0]...W[3])
                                            ; ÐÅÒÅÄÁÔØ 4 ÂÁÊÔÁ (W[0]..W[3])
        call        _slitx2                 ; with the control sum correction
                                            ; Ó ËÏÒÒÅËÃÉÅÊ ËÏÎÔÒÏÌØÎÏÊ ÓÕÍÍÙ
_slitx2:
        movf        INDR,W                  ; pass (or deliver) 2 bytes (FSR[0]...FSR[1]) 
                                            ; ÐÅÒÅÄÁÔØ 2 ÂÁÊÔÁ (FSR[0]..FSR[1])
        call        _checksum_hi
        call        _slitx1
        movf        INDR,W
        call        _checksum_lo
_slitx1:
        movf        INDR,W                  ; pass (or deliver) 1 byte (*FSR++) 
                                            ; ÐÅÒÅÄÁÔØ 1 ÂÁÊÔ (*FSR++)
        incf        FSR,F                   ;
        jump        _slitx
;;------------------------------------------------
_tx_0_0:
        call        _tx_0                   ; pass (or deliver) 2 zeros
                                            ; ÐÅÒÅÄÁÔØ Ä×Á ÎÕÌÑ
_tx_0:
        movlw       000h                    ; pass (or deliver) a zero
                                            ; ÐÅÒÅÄÁÔØ ÎÕÌØ
_slitx:
        xorlw       0C0h                    ; pass (deliver) a byte by (using) SLIP protocol
                                            ; ÐÅÒÅÄÁÔØ ÂÁÊÔ ÐÏ ÐÒÏÔÏËÏÌÕ SLIP
        jnz         _ne_C0                  ; i.e. ( = that is) with substitutions
                                            ; Ô.Å. Ó ÚÁÍÅÎÁÍÉ
        TXLW        0DBh                    ;   0xC0 --> 0xDB,0xDC
        movlw       0DCh                    ;   0xDB --> 0xDB,0xDD
        jump        _tx                     ;
_ne_C0:
        xorlw       <0DBh xor 0C0h>         ;
        jnz         _tx11                   ;
        call        _tx11                   ;
        movlw       <0DDh xor 0DBh>         ;
_tx11:                                      ;
        xorlw       0DBh                    ;
_tx:
        bsf         B_RS232_TxD             ; just pass (deliver) one byte
                                            ; ÐÒÏÓÔÏ ÐÅÒÅÄÁÔØ ÏÄÉÎ ÂÁÊÔ
        movwf       TX_BYTE                 ; IN:  W
        movlw       <(-(RS_DATA+1))shl 4>   ; OUT: TX_BYTE:=W
_tx_loop_c:
        bsf         C                       ; 1
_tx_loop:
        call        _delay_x_9
        rrf         TX_BYTE,F               ; 1 ; 1
        jnc         _c_is_clear             ; 2 ; 3
        addlw       10h                     ; 1
        bcf         B_RS232_TxD             ; 1
        jnz         _tx_loop_c              ; 3
_delay_x_9:
; upon technical-delay it is not allowed:   ; ÐÒÉ TX-ÚÁÄÅÒÖËÅ ÎÅÌØÚÑ:
; 1. to change flag STATUS.C                ; 1. ÉÚÍÅÎÑÔØ ÆÌÁÇ STATUS.C
; 2. to overload the stream of returns      ; 2. ÓÉÌØÎÏ ÐÅÒÅÇÒÕÖÁÔØ ÓÔÅË ×ÏÚ×ÒÁÔÏ×
if ((RS_TICKS)-11) eq 28                    ; 38400 and 6MHz
        call        _x2 ;28=2+2*13
_x2:    nop
        call        _x1 ;12=2+2*5
_x1:    nop
        brake
elseif ((RS_TICKS)-11) eq 67                ; 19200 and 6MHz
if 0
        nop
        call        _x1 ;66=2*3+4*15
        call        _x1 ;
        call        _x1 ;66=2*5+10+10+10+10+10+6
        call        _x1 ;
        call        _x2 ;
_x1:    brake
        brake
_x2:    brake
        brake
else
TEMP_DELAY = TEMP_0
        clrf        TEMP_DELAY
        bsf         TEMP_DELAY,4
_tx_delay:
        nop
        decfsz      TEMP_DELAY,F
        jump        _tx_delay
endif
else
error
endif
_delay4:
        return
_c_is_clear:
        bsf         B_RS232_TxD             ; 1
        addlw       10h                     ; 1
        bcf         C                       ; 1  =nop
        jump        _tx_loop                ; 2



;========================================================================
;
;========================================================================
_init:
        ;movlw       00000000b              ; RS232_TxD:=0, RS232_CTS:=0
        clrf        PORTB                   ;
        clrf        PORTA
        movlw       00000000b               ; porta, ___ooooo
        tris        5
        movlw       00000001b               ; portb, oooooooi
        tris        6

        bcf         B_TCP_ONLINE            ;     tcp_online=0
_error:
        clrf        IP_HLEN                 ;
        bsf         B_SLIP_OUTPKT           ; at first outside of the package
                                            ; ÓÎÁÞÁÌÁ ÓÎÁÒÕÖÉ ÐÁËÅÔÁ
_rx:
        bsf         B_RS232_CTS             ; raise CTS ÐÏÄÎÑÔØ CTS
        movlw       10010000b               ; GIE+INTE
        movwf       INTCON
_rxl:
;       clrwdt                              ;????
        jump        _rxl

;========================================================================
; Sending of the TCP/IP package ÐÅÒÅÄÁÞÁ TCP/IP ÐÁËÅÔÁ
;========================================================================
_just_ack:
_tcp_send_empty_10:
        bcf         TCPS_FLAG,0             ; TCPS_FLAG=xxxxxxx0
        bcf         TCPS_FLAG,1             ; TCPS_FLAG=xxxxxx0x
_tcp_send_empty:
        clrf        TCPS_LEN
_tcp_send:
        call        _tx_slip_end
        SUM0        <-(4500h+4000h+8000h)>  ; calculation of the IP header control sum
                                            ; ÒÁÓÞÅÔ ËÏÎÔÒÏÌØÎÏÊ ÓÕÍÍÙ IP ÚÁÇÏÌÏ×ËÁ
        movwf       IP_SUM_0
        SUM1        <-(4500h+4000h+8000h)>
        movwf       IP_SUM_1
        TXLW        045h
        call        _tx_0_0
        movf        TCPS_LEN,W
        addlw       14h+14h
        movwf       IP_LEN                  ; IP_LEN = TCPS_LEN+14h+14h
        call        _slitx
        call        _chksum_pseudoheader
        call        _tx_0_0
        TXLW        040h
        call        _tx_0
        TXLW        080h
        TXLW        006h
        call        _slitx_csum
        SLITXLW     ADDR_MYSELF_0
        SLITXLW     ADDR_MYSELF_1
        SLITXLW     ADDR_MYSELF_2
        SLITXLW     ADDR_MYSELF_3
        movlw       IP_ADR_0
        call        _slitx4

        movf        TCPR_SEQ_L0,W           ; SEQ formatting for the TCP package which is
                                            ;  being sent
                                            ; ÆÏÒÍÉÒÏ×ÁÎÉÅ SEQ ÄÌÑ
        subwf       TCPS_ACK,W              ; ÏÔÐÒÁ×ÌÑÅÍÏÇÏ TCP ÐÁËÅÔÁ
        jc          _no_correct_hi_seq      ;
        incf        TCPR_SEQ_L1,F           ;
        skipnz                              ;
        incf        TCPR_SEQ_L2,F
        skipnz
        incf        TCPR_SEQ_L3,F
_no_correct_hi_seq:
        addwf       TCPR_SEQ_L0,F           ; TCPR_SEQ_L0+=TCPS_ACK-TCPR_SEQ_L0
        SUM0        <-(5000h+TCP_RCV_WINDOW-0014h)>
        movwf       IP_SUM_0                ; calculation of the TCP headers control sum
                                            ; ÒÁÓÞÅÔ ËÏÎÔÒÏÌØÎÏÊ ÓÕÍÍÙ TCP ÚÁÇÏÌÏ×ËÁ
        SUM1        <-(5000h+TCP_RCV_WINDOW-0014h)>
        movwf       IP_SUM_1
        call        _chksum_pseudoheader
        movlw       TCPR_LPORT_H
        movwf       FSR
        call        _slitx2
        movlw       TCPR_RPORT_H
        movwf       FSR
        call        _slitx2
        movlw       TCPR_ACK_L3
        call        _slitx4
        movlw       TCPR_SEQ_L3
        call        _slitx4
        TXLW        050h
        movf        TCPS_FLAG,W
        andlw       00010011b               ; 0x10,0x11,0x12
        call        _tx
        movf        TX_BYTE,W
        call        _checksum_lo
        call        _tx_0
        TXLW        TCP_RCV_WINDOW

        clrf        IP_POS
_loop_top0:
        movf        TCPS_LEN,W              ; calculation of the TCP package's body
                                            ; ÒÁÓÞÅÔ ËÏÎÔÒÏÌØÎÏÊ ÓÕÍÍÙ
        xorwf       IP_POS,W                ; ÔÅÌÁ TCP ÐÁËÅÔÁ
        jz          _loop_break0
        call        _file_read
        call        _checksum_byte
        incf        IP_POS,F
        jump        _loop_top0
_loop_break0:
        call        _slitx_csum
        call        _tx_0_0

        clrf        IP_POS                  ; delivery of the TCP package's body
                                            ; ÐÅÒÅÄÁÞÁ ÔÅÌÁ TCP ÐÁËÅÔÁ
_loop_top1:
        movf        TCPS_LEN,W
        xorwf       IP_POS,W
        jz          _loop_break1
        call        _file_read
        call        _slitx
        incf        IP_POS,F
        jump        _loop_top1
_loop_break1:

_tx_slip_end:
        movlw       0C0h                    ; deliver SLIP.END ÐÅÒÅÄÁÔØ SLIP.END
        jump        _tx


;========================================================================
; calculation/check of control sums of TCP/IP headers/packages
; ÒÁÓÞÅÔ/ÐÒÏ×ÅÒËÁ ËÏÎÔÒÏÌØÎÙÈ ÓÕÍÍ TCP/IP ÚÁÇÏÌÏ×ËÏ×/ÐÁËÅÔÏ×
;========================================================================
_chksum_pseudoheader:
        movf        IP_LEN,W
        call        _checksum_lo
        movf        IP_ADR_0,W
        call        _checksum_hi
        movf        IP_ADR_1,W
        call        _checksum_lo
        movf        IP_ADR_2,W
        call        _checksum_hi
        movf        IP_ADR_3,W
        call        _checksum_lo
        SUM0        <6+((ADDR_MYSELF_0+ADDR_MYSELF_2)shl 8)+(ADDR_MYSELF_1+ADDR_MYSELF_3)>
        call        _checksum_hi
        SUM1        <6+((ADDR_MYSELF_0+ADDR_MYSELF_2)shl 8)+(ADDR_MYSELF_1+ADDR_MYSELF_3)>
        jump        _checksum_lo
;------------------------------------------
_checksum_byte:
        j1          <IP_POS,0>,_checksum_lo
_checksum_hi:
        subwf       IP_SUM_0,F              ; correct high byte of the control sum
                                            ; ËÏÒÒÅËÔÉÒÏ×ÁÔØ ÓÔ.ÂÁÊÔ ËÏÎÔÒ.ÓÕÍÍÙ
        movlw       1
        skipc
_checksum_lo:
        subwf       IP_SUM_1,F              ; correct low byte of the control sum
                                            ; ËÏÒÒÅËÔÉÒÏ×ÁÔØ ÍÌ.ÂÁÊÔ ËÏÎÔÒ.ÓÕÍÍÙ
        movlw       1
        skipc
        subwf       IP_SUM_0,F
        skipc
        subwf       IP_SUM_1,F
        return


;========================================================================
; UDP handler
;========================================================================
_process_udp:
       ; ... to do ...


;========================================================================
; TCP handler
;========================================================================
_process_tcp:
        movf        TCPR_LPORT_L,W          ; testing the number of the local port
                                            ; ÐÒÏ×ÅÒËÁ ÎÏÍÅÒÁ ÌÏËÁÌØÎÏÇÏ ÐÏÒÔÁ
        xorlw       TCP_PORT_HTTP
        iorwf       TCPR_LPORT_H,W
        skipz
        return

        skip0       <TCPR_FLAG,2>           ; RST
        bcf         B_TCP_ONLINE
        j1          <TCPR_FLAG,0>,_tcp_fin  ; FIN
        j1          <TCPR_FLAG,1>,_tcp_syn  ; SYN
        skip1       <TCPR_FLAG,4>           ; ACK ????
        return
;_tcp_ack:
        movf        TCPS_SEQ,W
        subwf       TCPR_ACK_L0,W
        subwf       TCPS_LEN,W              ; TCPS_LEN-TCPR_ACK_L0+TCPS_SEQ
        jz          _my_transmit_is_acked
        subwf       TCPS_LEN,W              ; -TCPR_ACK_L0+TCPS_SEQ
        jz          _tcp_send               ; if client did not confirm recieve... RETRANSMIT!!
                                            ; ÅÓÌÉ ËÌÉÅÎÔ ÎÅ ÐÏÄÔ×ÅÒÄÉÌ ÐÒÉÅÍ... RETRANSMIT !!!!
        return                              ; completely wrong TCPR_ACK_L0 = we're not responding
                                            ; ÓÏ×ÓÅÍ ÎÅÐÒÁ×ÉÌØÎÙÊ TCPR_ACK_L0 = ÎÅ ÏÔ×ÅÞÁÅÍ
_my_transmit_is_acked:
        movf        TCPR_ACK_L0,W           ; tcps_seq=LO(tcpr.ack);
        movwf       TCPS_SEQ                ;
        movf        TCPR_SEQ_L0,W           ; if(tcpr.seq==tcps_ack1)
        xorwf       TCPS_ACK,W              ;
        jnz         _tcp_send               ; if we havn't RX'd what we expected... RETRANSMIT!
                                            ; ÅÓÌÉ ÍÙ ÐÏÌÕÞÉÌÉ ÎÅ ÔÏ, ÞÔÏ ÖÄÁÌÉ... RETRANSMIT !!!!
;_new_data_was_rvcd:
        movf        TCPR_HLEN,W
        subwf       IP_LEN,W
        addwf       TCPS_ACK,F              ; tcps_ack1 += ip_len-tcpr.hlen;

        addwf       TCPR_POS,F
        skipnc
        bsf         TCPR_POS,7              ; 0-->](128..255)


        ;;****** HTTP server ËÁË ËÏÎÅÞÎÙÊ Á×ÔÏÍÁÔ *******************
        movlw       00010001b               ; http_state    = *
                                            ; b_tcp_online  = 0
                                            ; tcps_flag     = FIN+ACK
        j1          B_HTTP_STATE_1,_set_flag_and_send
        j1          B_HTTP_STATE_0,_http_state_1
_http_state_0:

        movf        TCPR_POS,W              ; if(tcpr_pos<*) goto _tcp_send_empty_10
        addlw       -8 ; ***                ; strlen("GET / HTTP/0.9\r\n\r\n")=18
        jnc         _tcp_send_empty_10

                                            ; ??? todo: file system functions
                                            ;=set http_unitidx
                                            ;=set http_filesize_h
                                            ;=set http_filesize_l
if FS_USE_INTERNAL_ROM
                                            ;------------------------
                                            ; CGI
                                            ;------------------------
        movf        HTTP_NAME_0,W
        sublw       'a'                     ;
        jz          _cgi_a                  ; HTTP_NAME_0 == 'a'
        sublw       <'a'-'0'>               ;
        addlw       -10                     ;
        jnc         _cgi_digit              ; HTTP_NAME_0 in ['0'..'9']
        movlw       3                       ;
        movwf       HTTP_UNITIDX            ; HTTP_UNITIDX = 3
        clrf        HTTP_FILESIZE_H         ;
        movlw       068h                    ; HTTP_FILESIZE = 0x6E
        jump        _cgi_done               ;
_cgi_digit:
        rlf         HTTP_NAME_1,F           ; status.c=0
        movf        HTTP_NAME_1,W           ;
        rlf         HTTP_NAME_1,F           ;
        rlf         HTTP_NAME_1,F           ;
        addwf       HTTP_NAME_1,W           ;
        addwf       HTTP_NAME_2,W           ; W := 10*HTTP_NAME_0+HTTP_NAME_1
        addlw       -16                     ; W := 10*(HTTP_NAME_0-'0')+(HTTP_NAME_1-'0')
        skip0       <HTTP_NAME_0,0>
        addlw       100
        skip0       <HTTP_NAME_0,1>
        addlw       200
        movwf       PORTB                   ;

;       andlw       11110b
;       movwf       PORTB                   ;
_cgi_a:
        clrf        HTTP_UNITIDX            ; HTTP_UNITIDX = 0
        movlw       1                       ;
        movwf       HTTP_FILESIZE_H         ; HTTP_FILESIZE = 0x180
        movlw       080h                    ;
_cgi_done:
        movwf       HTTP_FILESIZE_L         ;

endif
if FS_USE_EXTERNAL_ROM
        ...todo...
endif
        bsf         B_HTTP_STATE_0          ; http_state=1
        jump        _send_portion_of_file

_http_state_1:
        incf        HTTP_UNITIDX,F          ; http_unitidx++
        movf        TCPS_LEN,W              ; http_filesize -= tcps_len;
        subwf       HTTP_FILESIZE_L,F
        skipc
        decf        HTTP_FILESIZE_H,F
_send_portion_of_file:
        movf        HTTP_FILESIZE_H,F
        jnz         _transmit_80
        movf        HTTP_FILESIZE_L,W
        addlw       7Fh
        jc          _transmit_80
        bsf         B_HTTP_STATE_1          ; http_state=3
        movf        HTTP_FILESIZE_L,W       ; <== TRANSMIT less than TCP_SND_WINDOW bytes
        jump        _transmit_not_80
_transmit_80:
        movlw       TCP_SND_WINDOW          ; <== TRANSMIT TCP_SND_WINDOW bytes
_transmit_not_80:
        movwf       TCPS_LEN
        jump        _tcp_send


_tcp_fin:
        incf        TCPR_SEQ_L0,W           ; tcps_ack1 = B3(tcpr.seq)+1;
        movwf       TCPS_ACK
        incf        TCPS_SEQ,F              ; tcps_seq1++;
        movlw       00010000b               ; tcps_flag = 0x11; // SYN+ACK
                                            ; tcp_online=0;
                                            ; http_state=*;
_set_flag_and_send:
        movwf       TCPS_FLAG
        jump        _tcp_send_empty         ; tcp_send_empty(); // 0 byte ÐÅÒÅÄÁÅÍ 0 ÂÁÊÔ


_tcp_syn:
    ;;  j1      B_TCP_ONLINE,_return        ; if( 0==tcp_online ) {
        incf        TCPR_SEQ_L0,W           ; tcps_ack1 = B3(tcpr.seq)+1;
        movwf       TCPS_ACK
        clrf        TCPR_POS                ; tcpr_pos=0;
        clrf        TCPS_SEQ                ; tcps_seq1=ISS=0;
        movlw       10010010b               ; http_state=0; // just connected
        movwf       TCPS_FLAG               ; tcps_flag = 0x12; // SYN+ACK
        call        _tcp_send_empty         ; tcp_send_empty(); // ÐÅÒÅÄÁÅÍ 0 ÂÁÊÔ
        incf        TCPS_SEQ,F              ; tcps_seq1++;
        return                              ; }

if FS_USE_INTERNAL_ROM
;========================================================================
; Internal ROM/EEPROM File (max 512/64 bytes)
;========================================================================
; UNIT0:        ROM             0x0200..0x027F
; UNIT1:        ROM             0x0280..0x02FF
; UNIT2:        ROM             0x0300..0x037F
; UNIT3:        ROM             0x0380..0x03FF
; UNIT4:        EEPROM          0x0000..0x003F
;========================================================================
_file_read:
if FS_USE_INTERNAL_EEPROM
        j0          <HTTP_UNITIDX,2>,_ir_read
_ie_read:
        movf        IP_POS,W
        movwf       EEADR                   ; Address to read
        bsf         RP0
        bsf         EECON1,0                ; EE Read
        bcf         RP0
        movf        EEDATA,W                ; W = EEDATA
        return
endif
_ir_read:
        clrf        PCLATH
        bsf         PCLATH,1
if FS_INTERNAL_ROM_UNITS ge 2
        skip0       <HTTP_UNITIDX,1>
        bsf         PCLATH,0
endif
        movf        IP_POS,W
if FS_INTERNAL_ROM_UNITS ge 1
        skip0       <HTTP_UNITIDX,0>
        iorlw       80h
endif
        movwf       PCL


;========================================================================
; Simple CGI support :)
;========================================================================
_cgi_portb_hi:
        swapf       PORTB,W
        jump        _lo4bit_as_hexdigit
;        skip0       <PORTA,4>
;        retlw       '1'
;        retlw       '0'
_cgi_portb_lo:
        movf        PORTB,W
_lo4bit_as_hexdigit:
        andlw       00001111b
        addlw       -10
        skipnc
        addlw       7
        addlw       58
        return

.org 800h
;========================================================================
; JavaScript program for PortB control
;========================================================================
        .db 'H','T','T','P','/','1','.','0',' ','2','0','0', 13, 10, 13, 10
        ; "Content-Type: %s", "blah-blah-blah"
        ; "Content-Length: %d", blah_blah_blah
        ; "Refresh: %d", blah_blah_blah
        .db '<','t','i','t','l','e','>','P','o','r','t',' ','B','<','/','t'
        .db 'i','t','l','e','>','<','b','o','d','y',' ','o','n','L','o','a'
        .db 'd','=','"','f','o','r','(','v','a','r',' ','i','=','0',';','i'
        .db '<','7',';','i','+','+',')','d','o','c','u','m','e','n','t','.'
        .db 'f','o','r','m','s','[','0',']','.','e','l','e','m','e','n','t'
        .db 's','[','i',']','.','c','h','e','c','k','e','d','=','0','x'
        jump        _cgi_portb_hi           ; SIC!
        jump        _cgi_portb_lo
        .db     '&','(','2','<','<','i',')','"','>','<','f','o','r','m',' '

        .db 'a','c','t','i','o','n','=','a','>','<','s','c','r','i','p','t'
        .db '>','f','o','r','(','v','a','r',' ','i','=','1',';','i','<','8'
        .db ';','i','+','+',')','d','o','c','u','m','e','n','t','.','w','r'
        .db 'i','t','e','(','"','B','.','"','+','i','+','"','<','I','N','P'
        .db 'U','T',' ','T','Y','P','E','=','c','h','e','c','k','b','o','x'
        .db '>','<','B','R','>','"',')','<','/','s','c','r','i','p','t','>'
        .db '<','i','n','p','u','t',' ','t','y','p','e','=','s','u','b','m'
        .db 'i','t',' ','v','a','l','u','e','=','R','e','a','d','>','<','i'

        .db 'n','p','u','t',' ','t','y','p','e','=','b','u','t','t','o','n'
        .db ' ','v','a','l','u','e','=','W','r','i','t','e',' ','o','n','C'
        .db 'l','i','c','k','=','"','f','o','r','(','v','a','r',' ','v','='
        .db '4','0','0',',','i','=','0',';','i','<','7',';','v','+','=','d'
        .db 'o','c','u','m','e','n','t','.','f','o','r','m','s','[','0',']'
        .db '.','e','l','e','m','e','n','t','s','[','i',']','.','c','h','e'
        .db 'c','k','e','d','<','<','+','+','i',')',';','t','o','p','.','l'
        .db 'o','c','a','t','i','o','n','.','h','r','e','f','=','v','"','>'

;       .db 'H','T','T','P','/','1','.','0',' ','4','0','4', 13, 10, 13, 10
;       .db 'N','o','t',' ','f','o','u','n','d','<','h','r','>','<','a',' '
;       .db 'h','r','e','f','=','i','>','M','a','i','n',' ','P','a','g','e'
;       .db   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
;       .db   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
;       .db   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
;       .db   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
;       .db   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
        .db 'H','T','T','P','/','1','.','0',' ','2','0','0', 13, 10, 13, 10
        .db '<','a',' ','h','r','e','f','=','a','>','P','o','r','t','B',' '
        .db 'c','o','n','t','r','o','l','<','/','a','>','<','h','r','>','<'
        .db 'a',' ','h','r','e','f','=','h','t','t','p',':','/','/','z','h'
        .db 'e','n','g','x','i','.','d','a','.','r','u','>','D','e','n','i'
        .db 's',' ','P','e','t','r','o','v',27h,'s',' ','h','o','m','e',' '
        .db 'p','a','g','e','<','/','a','>',  0,  0,  0,  0,  0,  0,  0,  0
        .db   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0

endif

if FS_USE_EXTERNAL_ROM

_file_read:
        retlw       0

endif

end

file: /Techref/piclist/petrovwwwpic/pic2.htm, 137KB, , updated: 2006/3/5 17:10, local time: 2024/11/22 06:12,
TOP NEW HELP FIND: 
18.117.166.193:LOG IN

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://massmind.org/Techref/piclist/petrovwwwpic/pic2.htm"> Denis Petrovs home page</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here: 
if you want a response, please enter your email address: 
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?

 

Welcome to massmind.org!

 

Welcome to massmind.org!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  .