;;========================================================================
;;
;; 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 18:10, local time: 2025/10/24 18:40,
216.73.216.188,10-3-157-36:LOG IN
|
| ©2025 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? <A HREF="http://massmind.ecomorder.com/Techref/piclist/petrovwwwpic/pic2.htm"> Denis Petrovs home page</A> |
| Did you find what you needed? |
Welcome to ecomorder.com! |
Welcome to massmind.ecomorder.com! |
.