	list      p=16f877            ; list directive to define processor

	#include <p16f877.inc>        ; processor specific variable definitions
	
;
;		PICNIC - PIC Network Interface Controller
;		Copyright (c) 2002 SHINSHU UNIVERSITY KISO LAB
;		 All Rights Reserved.
;
;		01-SEP-2002	Version 1.2.0.0		[original]
;		27-APR-2003	Version 1.2.0.1		[K.Wasaki]
;


;-----------------------------------------------------------------------------------
	
	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC


;-----------------------------------------------------------------------------------
HTTP_PORT		EQU	.80			; HTTP Port Number(80=Default)
LCD_PORT		EQU	.0			; LCD Control Port Number(0=unused)
PARALLEL_PORT		EQU	.10001			; Parallel Port Number(0=Unused)
SERIAL_PORT		EQU	.10002			; Serial Port Number(0=Unused)

BOOTPC_PORT		EQU	.68			; BOOTC Port Number(Client)
BOOTPS_PORT		EQU	.67			; BOOTP Port Number(Server)

BAUD_RATE		EQU	.129	;10		; RS232C Baud Rate upon Reset
							; 129=9600bps
							; 10=115200bps

PARALLEL_PACKET_SIZE	EQU	.8			; Parallel transmit packet size
SERIAL_PACKET_SIZE	EQU	(.2 + .6 + .4 + .2 + .1 + .1)		; Serial status packet size 
							; type:mac:ip:port:baud:flow
CH_BACKSPACE		EQU	.8			; Backspace character code 
SOCKETS			EQU	.4			; Total sockets (changes not feasible) 

;-----------------------------------------------------------------------------------

		ORG	0x2100
		
		DE	.192, .168, 0, .200	; IP address(0.0.0.0=DHCP)
		DE	.255 , .255 , .255 , 0	; Netmask 
		DE	0,0,0,0		; GateWay
		DE	1,2,0,1		; Farmware Version x,x,x,x
		
		
		DE	HTTP_PORT / .256 , HTTP_PORT & .255				; HTT Port Number
		DE	LCD_PORT / .256 , LCD_PORT & .255				; LCD Port Number
		DE	PARALLEL_PORT / .256 , PARALLEL_PORT & .255			; PARALLEL Port Number
		DE	SERIAL_PORT / .256 , SERIAL_PORT & .255			; SERIAL Port Number

;
;-----------------------------------------------------------------------------------

;
;		Protocol number, etc
;
COM_PROTO	EQU	08H			; HIGH BYTE(common)
IP_PROTO	EQU	00H			; LOW BYTE (0800h means IP packet)
ARP_PROTO	EQU	06H			; LOW BYTE (0806h means ARP packet)


TCP_PROTO	EQU	.6
UDP_PROTO	EQU	.17
ICMP_PROTO	EQU	.1

;
;		RTL8019AS Related Setting Items  
;
PAGE_BEGIN	EQU	40H			; Beginning memory ardes 
PAGE_START	EQU	46H			; Starting buffer address  
PAGE_STOP	EQU	80H			; Ending buffer address 

DATA_SIZE	EQU	.18

;
;		Ethernet Related Setting  Items
;
NE_SIZE		EQU	.4			; RTL8019 status area size
PACKET_SIZE	EQU	.6 + .6 + .2			; Ethernet header size
ARP_SIZE	EQU	.28			; ARP packet size
IP_SIZE		EQU	.20			; IP(basic)header size
UDP_SIZE	EQU	.8			; UDP header size 
TCP_SIZE	EQU	.20			; TCP(basic)header size 
DHCP_SIZE	EQU	.308
;
;		TCP/IP status 
;
LISTEN		EQU	00			; Idle
SYN_RCVD	EQU	80H			; Transmit SYN and ACK, waiting for ACK
ESTAB		EQU	81H			; Transmission established
CLOSE_WAIT	EQU	82H
LAST_ACK	EQU	83H
FIN_WAIT_1	EQU	84H
FIN_WAIT_2	EQU	85H
CLOSING		EQU	86H
TIME_WAIT	EQU	87H

;		Socket Structure Form
;------------------------------------------
;		org	0
;so_job		ds	2
;so_ip		ds	4
;so_port	ds	2
;so_seq_no	ds	4
;so_ack_no	ds	4
;------------------------------------------



;-----------------------------------------------------------------------------------
;		I/O port setting 
;-----------------------------------------------------------------------------------
SA		EQU	PORTC			; NE2000 Address pass
SA0		EQU	0			;rc.0
SA1		EQU	1
SA2		EQU	2
SA3		EQU	3
SA4		EQU	4			;rc.4

SD		EQU	PORTD
SD0		EQU	0			;rd.0
SD1		EQU	1
SD2		EQU	2
SD3		EQU	3
SD4		EQU	4
SD5		EQU	5
SD6		EQU	6
SD7		EQU	7			;rd.7

RDY		EQU	5			;rc.5		; ~IOCHRDY


CNT		EQU	PORTE
RD		EQU	0			;re.0	; RTL8019AS ~RD
WR		EQU	1			;re.1	; RTL8019AS ~WR


;
;		I/O setting for LCD(For Optional LCD)
;
D7		EQU	7			;rb.7			; For Liquid Crystal Display 
	EQU	6
D5		EQU	5
D4		EQU	4
E		EQU	3			; Liquid Crystal Display Inabl  
RS		EQU	2			;rb.2 ; Liquid Crystal RS pin 



;-----------------------------------------------------------------------------------
;		  Global variable
;-----------------------------------------------------------------------------------
;		PAGE 0 
;		org	20h

;	LCD Variable
wait_cn		EQU	20H	
wait_cn2	EQU	21H	
d4		EQU	22H	
d8		EQU	23H	

cd		EQU	24H
tmp		EQU	24H	
use		EQU	25H	
;-----------------------------------------------------------------------------------
gcn1		EQU	26H	
sum		EQU	27H		; check sum for TCP,...
sum1		EQU	28H
bytes		EQU	29H			; current ptr for calculate above
ptr		EQU	2AH	


cn_l		EQU	2BH		; fan free
cn_h		EQU	2CH	

remote_adr	EQU	2DH			; Remote
remote_adr1	EQU	2EH
remote_len	EQU	2FH	
remote_len1	EQU	30H
curr		EQU	31H			; Current page address


val		EQU	32H	
val1		EQU	33H	
val2		EQU	34H	
val3		EQU	35H	
val_m		EQU	36H			; for DECIMAL
val_cn		EQU	37H
proto		EQU	37H			; Protocol number
state		EQU	38H			; TCP flag

;-----------------------------------------------------------------------------------
;
;		IPProtocol
;
ip_header	EQU	39H
ip_ver_len	EQU	39H		; VERSION:4,DATA SIZE:5
ip_tos		EQU	3AH		; service type
ip_length	EQU	3BH		; data length
ip_length1	EQU	3CH
ip_ident	EQU	3DH	
ip_ident1	EQU	3EH
ip_flagment	EQU	3FH		
ip_flagment1	EQU	40H
ip_ttl		EQU	41H		; Existing Period  
ip_proto	EQU	42H		; Protocol 1:ICMP,6:TCP,17:UDP
ip_sum		EQU	43H		; Header checksum
ip_sum1		EQU	44H
ip_src		EQU	45H	
ip_src1		EQU	46H
ip_src2		EQU	47H
ip_src3		EQU	48H
ip_dest		EQU	49H	
ip_dest1	EQU	4AH
ip_dest2	EQU	4BH
ip_dest3	EQU	4CH


;-----------------------------------------------------------------------------------
;		TCPProtocol
;
tcp_header	EQU	4DH	
tcp_src_port	EQU	4DH	
tcp_src_port1	EQU	4EH
tcp_tar_port	EQU	4FH	
tcp_tar_port1	EQU	50H
tcp_seq_no	EQU	51H	
tcp_seq_no1	EQU	52H
tcp_seq_no2	EQU	53H
tcp_seq_no3	EQU	54H
tcp_ack_no	EQU	55H	
tcp_ack_no1	EQU	56H
tcp_ack_no2	EQU	57H
tcp_ack_no3	EQU	58H
tcp_header_size	EQU	59H	
tcp_flags	EQU	5AH	
TCP_URG		EQU	5	
TCP_ACK		EQU	4	
TCP_PSH		EQU	3	
TCP_RST		EQU	2
TCP_SYN		EQU	1	
TCP_FIN		EQU	0	

tcp_window	EQU	5BH	
tcp_window1	EQU	5CH
tcp_sum		EQU	5DH	
tcp_sum1	EQU	5DH
tcp_		EQU	5FH	
tcp_1		EQU	60H	

;-----------------------------------------------------------------------------------
;		UDPProtocol
;
udp_header	SET	tcp_header
udp_src_port	SET	tcp_header+0
udp_src_port1	SET	tcp_header+1
udp_tar_port	SET	tcp_header+2
udp_tar_port1	SET	tcp_header+3
udp_length	SET	tcp_header+4
udp_length1	SET	tcp_header+5
udp_sum		SET	tcp_header+6
udp_sum1	SET	tcp_header+7
udp_data	SET	tcp_header+8
udp_data1	SET	tcp_header+9
udp_data2	SET	tcp_header + .10
udp_data3	SET	tcp_header + .11
udp_data4	SET	tcp_header + .12
udp_data5	SET	tcp_header + .13
udp_data6	SET	tcp_header + .14
udp_data7	SET	tcp_header + .15


;-----------------------------------------------------------------------------------
;		ARPProtocol
;
arp_header	SET	ip_header
arp_hard_type	SET	ip_header+0
arp_prot_type	SET	ip_header+2
arp_hard_len	SET	ip_header+4
arp_prot_len	SET	ip_header+5
arp_ope		SET	ip_header+6
arp_ope1	SET	ip_header+7
arp_src_mac	SET	ip_header+8
arp_src_ip	SET	ip_header + .14
arp_dest_mac	SET	ip_header + .18
arp_dest_ip	SET	ip_header + .24
arp_dest_ip1	SET	ip_header + .25
arp_dest_ip2	SET	ip_header + .26
arp_dest_ip3	SET	ip_header + .27
;		=	ip_header + .28


;-----------------------------------------------------------------------------------
;		ICMPProtocol
;
icmp_header	SET	tcp_header
icmp_type	SET	tcp_header+0
icmp_code	SET	tcp_header+1
icmp_sum	SET	tcp_header+2
icmp_mes	SET	tcp_header+4


;-----------------------------------------------------------------------------------
;		DHCPProtocol
;
dhcp_header	SET	udp_data
dhcp_ope	SET	udp_data+0
dhcp_type	SET	udp_data+1
dhcp_phylen	SET	udp_data+2
dhcp_hop	SET	udp_data+3
dhcp_trans	SET	udp_data+4
dhcp_sec	SET	udp_data+8
dhcp_dummy	SET	udp_data + .10
dhcp_client_ip	SET	udp_data + .12
dhcp_user_ip	SET	udp_data + .16
dhcp_user_ip1	SET	udp_data + .17
dhcp_user_ip2	SET	udp_data + .18
dhcp_user_ip3	SET	udp_data + .19
dhcp_server_ip	SET	udp_data + .20
dhcp_server_ip1	SET	udp_data + .21
dhcp_server_ip2	SET	udp_data + .22
dhcp_server_ip3	SET	udp_data + .23
dhcp_router_ip	SET	udp_data + .24


;-----------------------------------------------------------------------------------
;		environment setting variable
;
;		PAGE 1
;		org	0a0h
this_ip		EQU	0A0H		; My IP Address  
this_ip1	EQU	0A1H		
this_ip2	EQU	0A2H		
this_ip3	EQU	0A3H		
mymac		EQU	0A4H		; My MAC address  
mymac1		EQU	0A5H
mymac2		EQU	0A6H
mymac3		EQU	0A7H
mymac4		EQU	0A8H
mymac5		EQU	0A9H
seq_no		EQU	0AAH			; My sequence number
seq_no1		EQU	0ABH		
seq_no2		EQU	0ACH		
seq_no3		EQU	0ADH
ident		EQU	0AEH		
ident1		EQU	0AFH
timer		EQU	0B0H		
timer_cn	EQU	0B1H		
dhcp_done	EQU	0B2H		
http_port	EQU	0B3H			; copy of port number from EEPROM 
http_port1	EQU	0B4H
lcd_port	EQU	0B5H		
lcd_port1	EQU	0B6H
para_port	EQU	0B7H		
para_port1	EQU	0B8H
serial_port	EQU	0B9H		
serial_port1	EQU	0BAH

fifo_poi	EQU	0BBH		; Used in Routine(GET)pointer
fifo_buff	EQU	0BCH		; Used to Interrupt(SET)Pointer
fifo_cn		EQU	0BDH		; Received bytes
fifo_top	EQU	0BEH		; Buffer
fifo_bottom	EQU	0DCH

fifo_line	EQU	0DCH		
fifo_line_cn	EQU	0DDH	


;-----------------------------------------------------------------------------------
;		Ethernet Header
;
ne_header	EQU	0DEH		; NE2000 Status
ne_stat		EQU	0DEH		; Received status(RSR)
ne_next		EQU	0DFH		; Next boundary pointer(Next Boundary)
ne_cn_l		EQU	0E0H		; Data size(L)
ne_cn_h		EQU	0E1H		; Data size(H)

eth_header	EQU	0E2H			; Ethernet Header
eth_dest	EQU	0E2H			; Destination MAC address 
eth_dest1	EQU	0E3H
eth_dest2	EQU	0E4H
eth_dest3	EQU	0E5H
eth_dest4	EQU	0E6H
eth_dest5	EQU	0E7H
eth_src		EQU	0E8H		; Destination MAC address  
eth_src1	EQU	0E9H
eth_src2	EQU	0EAH
eth_src3	EQU	0EBH
eth_src4	EQU	0ECH
eth_src5	EQU	0EDH
eth_type	EQU	0EEH		; Packet Type
eth_type1	EQU	0EFH
null		EQU	0F0H


bs_ptr		SET	ne_header
bs_ptr2		SET	ne_header+1
save_line	SET	ne_header+2
save_cn		SET	ne_header+3




;-----------------------------------------------------------------------------------
;		Common Variables
;

;		org	70h		; COMMON MEMORY PAGE
; BEGIN - To avoid registration while interrupted 
w_save		EQU	070H	
pclath_save	EQU	071H	
status_save	EQU	072H	
fsr_save	EQU	073H		
save_fsr	EQU	074H		
; END

mul10		EQU	075H
mul101		EQU	076H
getmes_wk	EQU	075H		
getmes_wk1	EQU	076H
com_cn		EQU	077H		
byte_cn		EQU	078H		
com_fsr		EQU	078H		
ind		EQU	079H		
dest		EQU	07AH		
dest1		EQU	07BH
data0		EQU	07CH		; a data for transmit to ethernet chip
wk		EQU	07DH	
wk1		EQU	07EH
wk2		EQU	07FH
common		EQU	07FH	

;-----------------------------------------------------------------------------------
;	Decimal Conversion Area
;-----------------------------------------------------------------------------------
;		PAGE 2
;		
			; To convert into decimals --> 
decimal_top	EQU	120H	


;-----------------------------------------------------------------------------------
;	RS232C Destination Data
;-----------------------------------------------------------------------------------
;		PAGE 3
;		org	190h
on_ether	EQU	190H			; Destination Ethernet Address
on_ether1	EQU	191H
on_ether2	EQU	192H
on_ether3	EQU	193H
on_ether4	EQU	194H
on_ether5	EQU	195H
on_ip		EQU	196H		; Destination IP Address
on_ip1		EQU	197H
on_ip2		EQU	198H
on_ip3		EQU	199H
on_port		EQU	19AH				; Destination Port Number
on_port1	EQU	19AH
on_rate		EQU	19CH				; Set Baud Rate
on_flow		EQU	19DH				; =0
transmitted	EQU	19EH
skb		EQU	1A0H
;-----------------------------------------------------------------------------------
;		Programming Entry
;-----------------------------------------------------------------------------------
		ORG	0			; Vector Reset (=0000h)
		MOVLW	HIGH (start)		; To Startup Routine

		MOVWF	PCLATH
		GOTO	start

;-----------------------------------------------------------------------------------
;		Process of Interruption
;
;		To keep away from stack consumption, call should be avoided during the process of interruption  
;-----------------------------------------------------------------------------------

		org	4		; Vector Interrupt (=0004h)
interrupt
;-----------------------------------------------------------------------------------
;		Context Shelter Processing
		movwf	w_save		; Save W Registration 
		swapf	STATUS, 0	; Save STATUS Registration
		clrf	STATUS				; Make STATUS 0
		movwf	status_save
		movf	PCLATH,0		; Save PCLATH 
		movwf	pclath_save
		clrf	PCLATH			; PCLATH=0 
		bcf	STATUS,IRP	
		movf	FSR, 0		
		movwf	fsr_save	; Save FSR 
;-------------------------------------------------------------------------------;		RB0 Interruption
		btfss	INTCON,INTE
		GOTO	int_next2
		BTFSS	INTCON,INTF
		GOTO	int_next2

		bcf	INTCON,INTF
		BSF	STATUS,RP0
		BSF	STATUS,RP1
		BSF	on_flow,7
		BCF	STATUS,RP1
		BCF	STATUS,RP0
;-------------------------------------------------------------------------------;
int_next2
		BTFSC	PIR1,TMR1IF
		goto	int_tmr1
		goto	int_next1
int_tmr1
		bcf	PIR1,TMR1IF
		BSF	STATUS,RP0
		MOVF	dhcp_done,0
		andlw	7FH
		btfss	STATUS,Z
		DECF	dhcp_done,1
		bcf	STATUS,RP0
int_tmr2
		bsf	STATUS,RP0
		MOVLW	1
		ADDWF	timer,1
		btfsc	STATUS,C
		GOTO	dec_tm
dec_tm9		CLRF	STATUS
;-------------------------------------------------------------------------------
int_next1
		btfss	INTCON, PEIE	
		goto	int2
		btfss	PIR1,RCIF			; RS232C Transmission?
		goto	int2
;-----------------------------------------------------------------------------------
;		Procedure for Interrupting Serial transmission 
		bsf	STATUS,RP0	
		
		MOVLW	fifo_bottom - fifo_top
		SUBWF	fifo_cn,0
		BTFSC	3,0
		GOTO	rec_over

		movf	fifo_buff,0		; Current Ring
		movwf	FSR		; Buffer Pointer Acquisition  -->To fsr
		bcf	STATUS,RP0	;
		MOVF	RCREG,0			; Ringbatsu
		MOVWF	INDF		;Save transmitted data in fa 
		bsf	STATUS,RP0	
		incF	fifo_buff,1	; To the next address....
		
		MOVLW	fifo_bottom
		SUBWF	fifo_buff,0
		BTFSS	3,0
		GOTO	int1_1

		MOVLW	fifo_top	
		movwf	fifo_buff
int1_1		incf	fifo_cn,1		; Number of data bytes in Ring buffer++
;-----------------------------------------------------------------------------------
		MOVLW	#(fifo_bottom - fifo_top) / 2
		subwf	fifo_cn,0
		btfss	3,0
		goto	int2
		bsf	STATUS,RP1
		BTFSS	on_flow,0
		GOTO	int2
		CLRF	STATUS
		BSF	PORTB,1
int2
		CLRF	STATUS
;-------------------------------------------------------------------------------;		Context Revival Procedure
		MOVF	fsr_save,0			; Revive fsr 
		MOVWF	FSR
		MOVF	pclath_save,0		; Revive pclath 
		MOVWF	PCLATH
		swapf	status_save,0
		movwf	STATUS					; Revive status 
		swapf	w_save,1
		swapf	w_save,0		; Revive W 
;	End ISR 
		retfie				; Return from Routine Interruption


;		RS232C Buffer Transmission Overflow  
rec_over
		bcf	STATUS, RP0	
		MOVF	RCREG, 0				; Read the data and discard 
		bcf	STATUS, RP0	
		goto	int2


;-----------------------------------------------------------------------------------
;		Socket Timeout Check 
;
dec_tm
		bsf	STATUS, IRP
		MOVLW	SOCKETS
		MOVWF	timer_cn
		MOVLW	(skb + 1) & 0FFH	
		MOVWF	FSR
dec_tm0
		MOVF	INDF,0		
		andlw	0f0h
		btfsc	STATUS, Z	
		goto	dec_tm1
		MOVLW	10H		
		SUBWF	INDF, 1
		movF	INDF, 0		
		andlw	0f0h
		btfss	STATUS, Z	
		goto	dec_tm1
		DECF	FSR, 1		
		CLRF	INDF		
		INCF	FSR,1		
dec_tm1
		MOVLW	10H		
		ADDWF	FSR, 1
		DECFSZ	timer_cn, 1
		GOTO	dec_tm0
		bcf	STATUS, IRP	
		goto	dec_tm9



;-----------------------------------------------------------------------------------
;		Routine of Acquiring a Hexadecimal Character  
;
getascii
		andlw	0fh
		ADDWF	PCL, 1		
		DT	"0123456789ABCDEF"
;-----------------------------------------------------------------------------------
;		Increment TCP seq_no  
;
next_seq_no
		bsf	STATUS,RP0	
		movLW	1				; +65536
		ADDWF	seq_no2,1
		btfsc	STATUS,	C	
		ADDWF	seq_no3,1	
		bcf	STATUS,RP0	
		RETURN


;-----------------------------------------------------------------------------------
;		Increment TCP seq_no  
;
inc_seq_no
		bsf	STATUS,IRP	
		movLW	.3		
		ADDWF	FSR,1
		movLW	.1		
		ADDWF	INDF,1
		DECF	FSR,1		
		btfsc	STATUS,C	
		addwf	INDF,1		
		DECF	FSR,1	 
		btfsc	STATUS,C	
		addwf	INDF,1		
		DECF	FSR,1		
		btfsc	STATUS,C	
		addwf	INDF,1		
		bcf	STATUS,IRP	
		retURN

;-----------------------------------------------------------------------------------
;		Add ip_length to TCP seq_no  
;
add_seq_no
		bsf	STATUS,IRP	
		movLW	.3		
		ADDWF	FSR,1

		MOVF	ip_length1,0	
		addwf	INDF,1		
		DECF	FSR,1		
		movlw	1
		btfsc	STATUS,C	
		addwf	INDF,1		
		DECF	FSR,1		
		btfsc	STATUS,C	
		addwf	INDF,1		
		DECF	FSR,1		
		btfsc	STATUS,C	
		addwf	INDF,1		
	
		movLW	.2		
		ADDWF	FSR,1
		MOVF	ip_length,0	
		addwf	INDF,1		
		DECF	FSR,1		
		movlw	1
		btfsc	STATUS,C	
		addwf	INDF,1		
		DECF	FSR,1		
		btfsc	STATUS,C	
		addwf	INDF,1		
		bcf	STATUS,IRP	
		retURN

;-----------------------------------------------------------------------------------
;		Increment TCP ack_no 
;
inc_ack_no
		movLW	1		
		ADDWF	tcp_seq_no3,1
		btfsc	STATUS,C	
		addwf	tcp_seq_no2,1	
		btfsc	STATUS,C	
		addwf	tcp_seq_no1,1	
		btfsc	STATUS,C	
		addwf	tcp_seq_no,1	

		goto	copy_ack_no
;		ret

;-----------------------------------------------------------------------------------
;		Add ip_length to TCP ack_no 
;
add_ack_no
		MOVLW	.20 + .20	
		SUBWF	ip_length1,1
		movlw	1
		btfss	STATUS,C	
		subwf	ip_length,1	

		MOVF	ip_length1,0	
		ADDWF	tcp_seq_no3,1
		movlw	1
		btfsc	STATUS,C	
		addwf	tcp_seq_no2,1	
		btfsc	STATUS,C	
		addwf	tcp_seq_no1,1	
		btfsc	STATUS,C	
		addwf	tcp_seq_no,1	

		MOVF	ip_length,0	
		ADDWF	tcp_seq_no2,1
		movlw	1
		btfsc	STATUS,C	
		addwf	tcp_seq_no1,1	
		btfsc	STATUS,C	
		addwf	tcp_seq_no,1	
copy_ack_no
		MOVF	com_fsr,0	
		MOVWF	FSR
		MOVLW	.12		
		ADDWF	FSR,1
		bsf	STATUS,IRP	
		MOVF	tcp_seq_no,0	
		MOVWF	INDF
		INCF	FSR,1		
		MOVF	tcp_seq_no1,0	
		MOVWF	INDF
		INCF	FSR,1		
		MOVF	tcp_seq_no2,0	
		MOVWF	INDF
		INCF	FSR,1		
		MOVF	tcp_seq_no3,0	
		MOVWF	INDF
		bcf	STATUS,IRP	
		retURN


;-----------------------------------------------------------------------------------
;		Clear Checksum Value  
;
clear_sum
		clrF	sum		
		clrF	sum1		
		clrF	bytes		; For identifying HI byte/LO byte 
		retURN


;-----------------------------------------------------------------------------------
;		Error Recovery Routine
;-----------------------------------------------------------------------------------
overflow2
overflow
		clrF	STATUS		
		
		clrF	PORTC		
		movlw	21h			; RTL8019AS STOP
		call	assert_wr0
		
		MOVLW	HIGH (wait_ms)	
		MOVWF	PCLATH
		MOVLW	.2		
		MOVWF	wait_cn
		call	wait_ms			; 10ms Wait
		clrF	PCLATH		
		
		MOVLW	0AH		
		MOVWF	PORTC		
		DB	01,00		
		call	assert_wr0
		
		MOVLW	0BH		
		MOVWF	PORTC		
		DB	01,00		
		call	assert_wr0
		
		call	initialize		; Initialize RTL8019 
		
		MOVLW	0CH
		MOVWF	PORTC					; RCR
		movlw	B'000100'			;  MONITOR Release
		call	assert_wr0
		
		MOVLW	0DH		
		MOVWF	PORTC					; TCR
		DB	01,00		;clrw				; L/B Release
		call	assert_wr0
		
		goto	main0			; Return to Routine Procedure  

;===================================================================================
;		Main Routine
;===================================================================================
main

		CLRF	PORTC					;rc
		movlw	22h
		call	assert_wr0		; Return to PAGE0 

		MOVLW	0CH		
		MOVWF	PORTC
		movlw	B'000100'
		call	assert_wr0
		MOVLW	0DH		
		MOVWF	PORTC
		DB	01,00						; L/B Release
		call	assert_wr0
		
		MOVLW	HIGH (wait_ms)	
		MOVWF	PCLATH
		MOVLW	.100		
		MOVWF	wait_cn
		call	wait_ms			; 100ms Wait
		clrF	PCLATH		
		
		MOVLW	this_ip		
		MOVWF	FSR
		MOVF	INDF,0		
		INCF	FSR,1		
		iorwf	INDF,0		
		INCF	FSR,1		
		iorwf	INDF,0		
		INCF	FSR,1		
		iorwf	INDF,0		
		btfss	STATUS,2	
		goto	main0			; My IP address is 0.0.0.0?
do_dhcp
		CLRF	STATUS
		MOVLW	HIGH (dhcp)	
		MOVWF	PCLATH
		call	dhcp
		MOVLW	$ >> 8		
		MOVWF	PCLATH
;===================================================================================
;		Main Loop
;===================================================================================
main0

		bsf	STATUS,RP0	
	 			; RS232C Transmission?
		MOVLW	0
		SUBWF	fifo_cn,0
		BTFSS	3,2
		GOTO	receive232c
		MOVLW	80h
		SUBWF	dhcp_done,0
		BTFSC	3,2
		GOTO	do_dhcp
		bcf	STATUS,RP0	

		CLRF	PCLATH		
		MOVLW	.7		
		MOVWF	PORTC
		call	assert_rd		; RCRLead
		
		btfsc	data0,4		
		goto	overflow
		btfsc	data0,3		
		goto	overflow
		btfsc	data0,2		
		goto	overflow
		goto	get_packet		; Receive packet  
main99		goto	main0

receive232c
		bcf	STATUS,RP0	
		MOVLW	serial_tx >> 8	
		MOVWF	PCLATH		; Process for receiving 232c 
		goto	serial_tx



;-----------------------------------------------------------------------------------
;	Packet Reception Process
;-----------------------------------------------------------------------------------
get_packet
;	PAGE 1
		CLRF	PORTC		
		movlw	B'01100010'
		call	assert_wr0		; PAGE 1 
		
		MOVLW	.7		
		MOVWF	PORTC
		call	assert_rd
		MOVF	data0,0				; Receive Current Page  
		MOVWF	curr
;	PAGE 0
		CLRF	PORTC		
		movlw	B'00100010'
		call	assert_wr0		; Return to PAGE0 
		
		MOVLW	.3		
		MOVWF	PORTC
		call	assert_rd		; Read BNDY 
		
		INCF	data0,1					; BNDY++
		MOVLW	PAGE_STOP		; Calculate overlap 
		SUBWF	data0,0
		BTFSS	3,0
		GOTO	packet1

		MOVLW	PAGE_START	
		MOVWF	data0
packet1
		MOVF	curr,0				; No new data for (BNDY+1)==CURR
		SUBWF	data0,0
		BTFSC	3,2
		goto	main0			; Interruption


;-----------------------------------------------------------------------------------
; Read RTL8019 Status +Ethernet Header  
		CLRF	remote_adr	
		MOVF	data0,0		
		MOVWF	remote_adr1
		MOVLW	NE_SIZE + PACKET_SIZE	
		MOVWF	remote_len
		CLRF	remote_len1		
		call	remote_read
		
		MOVLW	NE_SIZE + PACKET_SIZE		; Loop Counter
		MOVWF	gcn1
		bcf	STATUS,IRP		
		MOVLW	ne_header					; Read address ne_header 
		MOVWF	FSR
		MOVLW	10H			
		MOVWF	PORTC
get_packet0
		bcf	PORTE,0				;RD
		btfss	PORTC,RDY				; ~Wait
		goto	$-1
		MOVF	PORTD,0		
		
		bsf	PORTE,0		;RD
		movwf	INDF		;INDF			; *INDF = data set to buffer
		INCF	FSR,1		
		DECFSZ	gcn1,1		
		GOTO	get_packet0
;
;		Diverge procedures using Ethernet header 
		bsf	STATUS,RP0	
		btfss	ne_stat,0	
		goto	main9
		MOVLW	COM_PROTO		; For top 8 bits, skip all except for 8		SUBWF	eth_type,0
		BTFSS	3,2
		GOTO	main9
		MOVLW	IP_PROTO		; Diverge IP Protocol Procedure
		SUBWF	eth_type1,0
		BTFSC	3,2
		GOTO	do_ip
		MOVLW	ARP_PROTO		; Diverge ARP Protocol Procedure
		SUBWF	eth_type1,0
		BTFSC	3,2
		GOTO	do_arp			; Diverge ARP Protocol Procedure 
;		goto	main9				; Others
;-----------------------------------------------------------------------------------
main9
		bcf	STATUS,IRP	
		bcf	STATUS,RP1	
		bsf	STATUS,RP0	
		MOVLW	PAGE_START		; Error Check and Recovery
		SUBWF	ne_next,0
		BTFSS	3,0
		GOTO	overflow2
		MOVLW	PAGE_STOP		; Error Check and Recovery
		SUBWF	ne_next,0
		BTFSC	3,0
		GOTO	overflow2

		DECF	ne_next,1					; Calculate the following boundary
		MOVLW	PAGE_START	
		SUBWF	ne_next,0
		BTFSC	3,0
		GOTO	packet11

		MOVLW	PAGE_STOP-1	
		MOVWF	ne_next
packet11
		bcf	STATUS,RP0	
		
		CLRF	PORTC		
		movlw	B'00100010'
		call	assert_wr0
		
		MOVLW	.3		
		MOVWF	PORTC
		MOVLW	ne_next		
		MOVWF	FSR
		MOVF	INDF,0			; Set boundary for pointer 
		call	assert_wr0
		goto	main99



;-----------------------------------------------------------------------------------
;		Process of ARP Protocol 
;-----------------------------------------------------------------------------------
do_arp
		bcf	STATUS,RP0	
		MOVLW	NE_SIZE + PACKET_SIZE	
		MOVWF	remote_adr
		MOVLW	ne_cn_l			
		MOVWF	FSR
		MOVF	INDF,0			
		MOVWF	remote_len
		INCF	FSR,1			
		MOVF	INDF,0			
		MOVWF	remote_len1

		MOVLW	NE_SIZE + PACKET_SIZE	
		SUBWF	remote_len,1
		movlw	1
		btfss	STATUS,C		
		subwf	remote_len1,1		
		call	remote_read

		MOVLW	ip_header				; Receive Data following the ip_header Address
		MOVWF	FSR
get_packet10
		movf	remote_len,0		
		iorwf	remote_len1,0		
		btfsc	STATUS,Z		
		goto	get_packet2		; Finish receiving data?
		
		bcf	PORTE,0			
		btfss	PORTC,5						; ~Wait
		goto	$-1
		MOVF	PORTD,0			
		bsf	PORTE,0			
		movwf	INDF			
		INCF	FSR,1			
		
		movlw	1			; decrement length  
		SUBWF	remote_len,1		
		btfss	STATUS,C		
		SUBWF	remote_len1,1		
		
		btfss	FSR,7						; over flow?
		goto	get_packet10
;	following 80h 
get_packet20
		movf	remote_len,0		
		iorwf	remote_len1,0		
		btfsc	STATUS,Z		
		goto	get_packet2		; Finish receiving data 
		
		bcf	PORTE,0			
		btfss	PORTC,5						; ~Wait
		goto	$-1
	;	MOVF	PORTD,0			
		bsf	PORTE,0			
	;	movwf	INDF

		movlw	1
		subwf	remote_len,1		
		btfss	STATUS,C		
		subwf	remote_len1,1		
		goto	get_packet20
;
;		ARP Header Analysis 
get_packet2
		MOVLW	0					; Get rid of arp_code if it is anything other than 0001
		SUBWF	arp_ope,0
		BTFSS	3,2
		GOTO	main9

		MOVLW	1			
		SUBWF	arp_ope1,0
		BTFSC	3,2
		GOTO	arp_req

		MOVLW	2			
		SUBWF	arp_ope1,0
		BTFSC	3,2
		GOTO	arp_reply
		
		goto	main9
arp_reply
		MOVLW	HIGH (ser_arp)		
		MOVWF	PCLATH
		goto	ser_arp
arp_req
arp
		MOVLW	this_ip				; this_ip is placed in BANK 1
		MOVWF	FSR
		MOVF	arp_dest_ip,0			;IP address for ARP is the same address with mine?
		SUBWF	INDF,0
		BTFSS	3,2
		GOTO	main9
		INCF	FSR,1			

		MOVF	arp_dest_ip1,0		
		SUBWF	INDF,0
		BTFSS	3,2
		GOTO	main9
		INCF	FSR,1			

		MOVF	arp_dest_ip2,0		
		SUBWF	INDF,0
		BTFSS	3,2
		GOTO	main9
		INCF	FSR,1			
		MOVF	arp_dest_ip3,0		
		SUBWF	INDF,0
		BTFSS	3,2
		GOTO	main9


;	ARP demand for myself  
		call	prepare_ether2		

		movlw	COM_PROTO		
		call	assert_wr
		movlw	ARP_PROTO		
		call	assert_wr

		MOVLW	arp1 >> 8
		movwf	PCLATH
		call	arp1			
		CLRF	PCLATH
		CLRF	PORTC			
		movlw	B'00100010'
		call	assert_wr0
		
		MOVLW	.4			
		MOVWF	PORTC
		movlw	PAGE_BEGIN		 
		call	assert_wr0
		
		MOVLW	.5			
		MOVWF	PORTC
		movlw	.60			
		call	assert_wr0
		
		MOVLW	.6			
		MOVWF	PORTC
		DB	01,00		
		call	assert_wr0
		
		call	transmit			; Transmit ARP Response 
		goto	main9


;-----------------------------------------------------------------------------------
;		Reception Process of IPProtocol  
;-----------------------------------------------------------------------------------
do_ip
		bcf	STATUS,RP0	
		MOVLW	NE_SIZE + PACKET_SIZE	
		MOVWF	remote_adr
		MOVLW	ne_cn_l			
		MOVWF	FSR
	;	mov	fsr,#ip_length
		MOVF	INDF,0			
		MOVWF	remote_len
		INCF	FSR,1			
		MOVF	INDF,0			
		MOVWF	remote_len1

		MOVLW	NE_SIZE + PACKET_SIZE				; Pull Ether Header Length from the number of received bytes
		SUBWF	remote_len,1
		movlw	1
		btfss	STATUS,C		
		subwf	remote_len1,1		
		call	remote_read
;
;	Reception ofIP packet
		MOVLW	ip_header				; Read data into address ip_header
		MOVWF	FSR

		bcf	PORTE,0			
		btfss	PORTC,5						; ~Wait
		goto	$-1
		MOVF	PORTD,0			
		bsf	PORTE,0			
		movwf	INDF					; Read 1 byte!
		INCF	FSR,1			

		movlw	1			
		subwf	remote_len,1		
		btfss	STATUS,C		
		subwf	remote_len1,1		

		MOVF	ip_ver_len,0		; Calculate the remaining number of bytes  
		MOVWF	gcn1
		MOVLW	0FH			
		ANDWF	gcn1,1

		BCF	3,0			
		RLF	gcn1,1			
		RLF	gcn1,1			
		DECF	gcn1,1				; Calculate IP header size from IP header  
		call	copy_toram		; Forward to RAM 

ip_get_packet2
		MOVLW	45H			; IP Version 4 ?
		SUBWF	ip_ver_len,0
		BTFSS	3,2
		GOTO	ip_get_packet9
		MOVLW	TCP_PROTO			; To TCP Reception Process
		SUBWF	ip_proto,0
		BTFSC	3,2
		GOTO	tcp
		MOVLW	UDP_PROTO			; To UDP Reception Process 
		SUBWF	ip_proto,0
		BTFSC	3,2
		GOTO	udp
		MOVLW	ICMP_PROTO		; To ICMP Reception Process 
		SUBWF	ip_proto,0
		BTFSC	3,2
		GOTO	icmp
ip_get_packet9
		call	abort				; Discontinue Remote DMA 
		goto	main9

;-----------------------------------------------------------------------------------
;		Read Data Equivalent to the number of gcn1 bytes 
;-----------------------------------------------------------------------------------
copy_toram
		bcf	PORTE,0		
		btfss	PORTC,5					; ~Wait
		goto	$-1
		MOVF	PORTD,0		
		bsf	PORTE,0		
		movwf	INDF				; *INDF = data
		INCF	FSR,1					; fsr++
		
		movlw	1		
		subwf	remote_len,1	
		btfss	STATUS,C	
		subwf	remote_len1,1	
		
		DECFSZ	gcn1,1		
		GOTO	copy_toram
		retURN



;-----------------------------------------------------------------------------------
;		Transfer remaining packets to buffer RAM 
;-----------------------------------------------------------------------------------
get_remain
get_remain0
		movf	remote_len,0	
		iorwf	remote_len1,0	
		btfsc	STATUS,Z	
		goto	get_remain9	
		
		bcf	PORTE,0		
		btfss	PORTC,5					; ~Wait
		goto	$-1
		MOVF	PORTD,0		
		bsf	PORTE,0		
		movwf	INDF				; Set to the front 
		INCF	FSR,1		
		
		movlw	1		
		subwf	remote_len,1	
		btfss	STATUS,C	
		subwf	remote_len1,1	
		
		movlw	.16+.128
		addwf	FSR,0		
		btfss	STATUS,C	
		goto	get_remain0

		MOVLW	20H				; Switch banks and read further  
		MOVWF	FSR
		bsf	STATUS,IRP	
get_remain20
		movf	remote_len,0	
		iorwf	remote_len1,0	
		btfsc	STATUS,Z	
		goto	get_remain9		; Finish Reading  
		
		bcf	PORTE,0		
		btfss	PORTC,5					; ~Wait
		goto	$-1
		MOVF	PORTD,0		
		bsf	PORTE,0		
		movwf	INDF				; Set to the back  
		INCF	FSR,1		
		
		movlw	1
		subwf	remote_len,1	
		btfss	STATUS,C	
		subwf	remote_len1,1	
		
		movlw	.16+.128
		addwf	FSR,0		
		btfss	STATUS,C	
		goto	get_remain20

get_remain30
		call	abort
		
;		movf	remote_len,0	
;		iorwf	remote_len[1],0
;		btfsc	z
;		goto	get_remain9		; Finish Reading
;		
;		bcf	RD
;		btfss	RDY			; ~Wait
;		goto	$-1
;		bsf	RD
;
;		movlw	1
;		subwf	remote_len[0],1
;		btfss	STATUS,C
;		subwf	remote_len[1],1
;		goto	get_remain30
get_remain9
		bcf	STATUS,IRP	
		retURN




;-----------------------------------------------------------------------------------
;		Process of ICMP Protocol 
;-----------------------------------------------------------------------------------
icmp
		call	get_remain			; Forward data from RTL8019 
		MOVLW	.8			; Get rid of all types except for 08h
		SUBWF	icmp_type,0
		BTFSS	3,2
		GOTO	main9
		MOVLW	0				; Get rid of all codes except for 08h
 
		SUBWF	icmp_code,0
		BTFSS	3,2
		GOTO	main9
ping
		MOVLW	ICMP_PROTO			; Protocol=ICMP
		MOVWF	proto
		call	prepare_ip			; Get ready for IP Packet
;
		MOVLW	PACKET_SIZE + IP_SIZE	
		MOVWF	remote_adr
		MOVLW	PAGE_BEGIN		
		MOVWF	remote_adr1
		MOVF	ip_length1,0				;ne_cn_l
		MOVWF	remote_len
		MOVLW	IP_SIZE - 1		
		SUBWF	remote_len,1
		CLRF	remote_len1		
		call	remote_write
		
		call	clear_sum			; Clear the value of checksum  
		
		MOVLW	10H			
		MOVWF	PORTC
		call	assert_wr2times			; type : code
		call	assert_wr2times			; sum High : Low
		
		MOVF	ip_length1,0				;ne_cn_l
		MOVWF	gcn1
		MOVLW	IP_SIZE + 4		;sub	gcn1,#IP_SIZE + 4
		SUBWF	gcn1,1
		MOVLW	icmp_header + 4		
		MOVWF	FSR
icmp10
		MOVF	INDF,0			
		INCF	FSR,1			
		call	assert_wr
		
		movlw	.16 + .128
		addwf	FSR,0			
		btfsc	STATUS,C		
		goto	icmp20
icmp19		DECFSZ	gcn1,1			
		GOTO	icmp10
		bcf	STATUS,IRP		

		DB	01,00		;clrw
		call	assert_wr

		MOVLW	PACKET_SIZE + IP_SIZE + 2	
		MOVWF	remote_adr
		MOVLW	PAGE_BEGIN		
		MOVWF	remote_adr1
		call	set_checksum
		
		MOVLW	4H			
		MOVWF	PORTC
		movlw	PAGE_BEGIN			; transmit page is start page 
		call	assert_wr0
		
		MOVLW	.5			
		MOVWF	PORTC
		MOVLW	ne_cn_l			
		MOVWF	FSR
		MOVF	INDF,0			
		call	assert_wr0
		
		MOVLW	.6			
		MOVWF	PORTC
		INCF	FSR,1			
		MOVF	INDF,0			
		call	assert_wr0
		
		call	transmit			; Transmit PING Response  
		goto	main9
icmp20
		MOVLW	20H			
		MOVWF	FSR
		bsf	STATUS,IRP		
		goto	icmp19



;-----------------------------------------------------------------------------------
;		UDP
;-----------------------------------------------------------------------------------
udp
		MOVLW	.8			
		MOVWF	gcn1
		call	copy_toram
		
;	Check BOOTP Port
		MOVLW	BOOTPC_PORT / .256	
		SUBWF	udp_tar_port,0
		BTFSS	3,2
		GOTO	udp_1
		MOVLW	BOOTPC_PORT & 0FFH		; To BOOTP Process
		SUBWF	udp_tar_port1,0
		BTFSC	3,2
		GOTO	bootp_res

		MOVLW	this_ip			
		MOVWF	FSR
		MOVF	INDF,0				; Is this data sent to me ?
		SUBWF	ip_dest,0
		BTFSS	3,2
		GOTO	main9

		INCF	FSR,1			
		MOVF	INDF,0			
		SUBWF	ip_dest1,0
		BTFSS	3,2
		GOTO	main9

		INCF	FSR,1			
		MOVF	INDF,0			
		SUBWF	ip_dest2,0
		BTFSS	3,2
		GOTO	main9
		INCF	FSR,1			
		MOVF	INDF,0			
		SUBWF	ip_dest3,0
		BTFSS	3,2
		GOTO	main9

;	Check LCD Port
udp_1
		MOVLW	lcd_port & 0FFH		
		MOVWF	FSR
		MOVF	INDF,0			
		SUBWF	udp_tar_port,0
		BTFSS	3,2
		GOTO	udp_2
		INCF	FSR,1			
		MOVF	INDF,0			
		SUBWF	udp_tar_port1,0
		BTFSC	3,2
		GOTO	udp_lcd_tag
udp_2
		MOVLW	para_port & 0FFH	
		MOVWF	FSR
		MOVF	INDF,0			
		SUBWF	udp_tar_port,0
		BTFSS	3,2
		GOTO	udp_3

		INCF	FSR,1			
		MOVF	INDF,0			
		SUBWF	udp_tar_port1,0
		BTFSC	3,2
		GOTO	udp_parallel_tag
udp_3
		MOVLW	serial_port & 0FFH	
		MOVWF	FSR
		MOVF	INDF,0			
		SUBWF	udp_tar_port,0
		BTFSS	3,2
		GOTO	udp_4
		INCF	FSR,1			
		MOVF	INDF,0			
		SUBWF	udp_tar_port1,0
		BTFSC	3,2
		GOTO	udp_serial_tag
udp_4
;
;		add new funciton this
;
		goto	main9
udp_lcd_tag
		movlw	udp_lcd >> 8
		movwf	PCLATH
		GOTO	udp_lcd
;
;		Process of Prallel I/O(UDP)
;
udp_parallel_tag
		MOVLW	udp_data		
		MOVWF	FSR
		call	get_remain
		MOVLW	HIGH (udp_parallel)	
		MOVWF	PCLATH
		goto	udp_parallel
udp_serial_tag
		MOVLW	HIGH (udp_serial)	
		MOVWF	PCLATH
		goto	udp_serial

;-----------------------------------------------------------------------------------
get_dgram
		movf	remote_len,0		
		iorwf	remote_len1,0		
		btfsc	STATUS,Z		
		goto	get_dgram9
		
		bcf	PORTE,0			
		btfss	PORTC,5						; ~Wait
		goto	$-1
		MOVF	PORTD,0			
		bsf	PORTE,0			
		movwf	data0
		
		movlw	1
		subwf	remote_len,1		
		btfss	STATUS,C		
		subwf	remote_len1,1		
		
		BCF	3,0							; OK
		retURN
get_dgram9
		BSF	3,0							; EOT
		RETURN


;-----------------------------------------------------------------------------------
;		BOOTP Response
;-----------------------------------------------------------------------------------
bootp_res
		call	get_remain

		MOVLW	this_ip		
		MOVWF	FSR
		MOVF	INDF,0		
		INCF	FSR,1
		iorwf	INDF,0
		INCF	FSR,1
		iorwf	INDF,0
		INCF	FSR,1
		iorwf	INDF,0
		btfss	STATUS,Z
		goto	main9
		
		MOVLW	HIGH (bootp)	
		MOVWF	PCLATH
		call	bootp
		MOVLW	HIGH (bootp_res)
		MOVWF	PCLATH
		
		movlw	35h	; 
		call	assert_wr
		movlw	01h
		call	assert_wr
		movlw	3		; request
		call	assert_wr
		
		movlw	3dh	; 
		call	assert_wr
		movlw	07h
		call	assert_wr
		movlw	01h
		call	assert_wr
		MOVLW	mymac		
		MOVWF	FSR
		movlw	6
		call	transmit_nbytes			; My MAC
		
		movlw	.54	; 
		call	assert_wr
		movlw	04h
		call	assert_wr
		movlw	0c0h
		call	assert_wr
		movlw	0a8h
		call	assert_wr
		movlw	0h
		call	assert_wr
		movlw	3h
		call	assert_wr

		movlw	.50	; 
		call	assert_wr
		movlw	4
		call	assert_wr
		
		MOVLW	dhcp_user_ip		
		MOVWF	FSR
		movlw	4
		call	transmit_nbytes
		
		
		movlw	0ffh
		call	assert_wr
		
		MOVLW	.64 - .7 - .9 - .1 - .6 - .6
		MOVWF	gcn1
bootp_40
		DB	01,00		;clrw
		call	assert_wr
		DECFSZ	gcn1,1		
		GOTO	bootp_40
		MOVLW	HIGH (bootp_tx)
		MOVWF	PCLATH
		call	bootp_tx
		MOVLW	HIGH (bootp_40)
		MOVWF	PCLATH
;
;	Register IP address acquired from DHCP server as my address  
		MOVLW	this_ip		
		MOVWF	FSR
		MOVF	dhcp_user_ip,0	
		MOVWF	INDF
		INCF	FSR,1
		MOVF	dhcp_user_ip1,0	
		MOVWF	INDF
		INCF	FSR,1
		MOVF	dhcp_user_ip2,0	
		MOVWF	INDF
		INCF	FSR,1
		MOVF	dhcp_user_ip3,0	
		MOVWF	INDF
		bsf	STATUS,RP0
		CLRF	dhcp_done
		BCF	STATUS,RP0

;
;	Obtained IP address is shown on the Liquid Crystal Display 
		bcf	PORTB,2
		MOVLW	0C0H		
		MOVWF	d4
		MOVLW	HIGH (write_lcd4)
		MOVWF	PCLATH
		call	write_lcd4			; Move to the second line 
		
		MOVLW	HIGH(print_ip)
		MOVWF	PCLATH
		call	print_ip			; Display!
		CLRF	PORTB
		CLRF	PCLATH
		goto	main9




;-----------------------------------------------------------------------------------
;		TCP
;-----------------------------------------------------------------------------------
tcp
		MOVLW	.20			; Read 20 bytes
		MOVWF	gcn1
		call	copy_toram
		
		MOVLW	http_port & 0ffh		
		MOVWF	FSR
		MOVF	INDF,0		; Does it concur with EEPROM http port? 
		SUBWF	tcp_tar_port,0
		BTFSS	3,2
		GOTO	tcp9

		INCF	FSR,1
				
		MOVF	INDF,0
		SUBWF	tcp_tar_port1,0
		BTFSC	3,2
		GOTO	tcp_www

tcp9		goto	main9				; Nothing else responds to TCP except for http http 
;
;	http Process
tcp_www
		MOVLW	this_ip		
		MOVWF	FSR
		MOVF	INDF,0
		INCF	FSR,1
		iorwf	INDF,0
		INCF	FSR,1
		iorwf	INDF,0
		INCF	FSR,1
		iorwf	INDF,0
		btfsc	STATUS,Z
		goto	main9			; If the IP address is 0.0.0.0, stop the process
		
		btfsc	tcp_flags,5	;TCP_URG			; URG
		goto	main9			; abandon
		
		MOVLW	HIGH(search_socket)
		MOVWF	PCLATH
		call	search_socket		; Search for Socket  
		MOVLW	HIGH (tcp_www)
		MOVWF	PCLATH
		btfsc	STATUS,C
		goto	state1			; Presence of state?  
		
		call	no_socket		; Construct Socket 
		goto	main9
;
;	socket state1
state1
		MOVLW	.12		;add	FSR,#12
		ADDWF	FSR,1
	;	mov	pclath,#print_hex>>8
	;	mov	pclath,#$>>8
;
		MOVF	INDF,0		
		SUBWF	tcp_seq_no,0
		BTFSS	3,2
		GOTO	state12
		INCF	FSR,1
		MOVF	INDF,0		
		SUBWF	tcp_seq_no1,0
		BTFSS	3,2
		GOTO	state12
		INCF	FSR,1
		MOVF	INDF,0		
		SUBWF	tcp_seq_no2,0
		BTFSS	3,2
		GOTO	state12
		INCF	FSR,1
		MOVF	INDF,0		
		SUBWF	tcp_seq_no3,0
		BTFSS	3,2
		GOTO	state12
		MOVLW	.15		
		SUBWF	FSR,1
		call	state2
state12		CLRF	PCLATH
		goto	main9
		
state2
		MOVLW	HIGH(state_table)
		MOVWF	PCLATH

		MOVF	INDF,0
		andlw	7fh
		ADDWF	2,1		
state_table
		goto	job_SYN_RCVD		;
		goto	job_ESTAB		;
		goto	job_CLOSE_WAIT		;
	;	nop	;goto	job_LAST_ACK	;
		goto	main9
		goto	job_FIN_WAIT_1		;
		goto	job_FIN_WAIT_2		;
	;	nop	;goto	job_CLOSING	;
		goto	main9
	;	nop	;goto	job_TIME_WAIT	;
		goto	main9
		goto	main9		;ACK,PSH,RST,SYN,FIN





;-----------------------------------------------------------------------------------
;		Receive SYN,
;		Send SYN,ACK and wait for ACK
job_SYN_RCVD
		btfsc	tcp_flags,TCP_RST
		goto	recv_rst
		btfsc	tcp_flags,TCP_FIN
		goto	recv_fin
		btfss	tcp_flags,TCP_ACK
		RETURN

		MOVLW	ESTAB	;mov	INDF,#ESTAB
		MOVWF	INDF
		bcf	STATUS,IRP
		RETURN
recv_rst
		clrF	INDF
		bcf	STATUS,IRP
		RETURN

;-----------------------------------------------------------------------------------
;
;
job_FIN_WAIT_1
		btfsc	tcp_flags,TCP_RST
		goto	recv_rst
		btfss	tcp_flags,TCP_ACK
		RETURN
		
		MOVLW	FIN_WAIT_2
		MOVWF	INDF
		bcf	STATUS,IRP
		RETURN

;-----------------------------------------------------------------------------------
;
;
job_FIN_WAIT_2
		btfsc	tcp_flags,TCP_RST
		goto	recv_rst
		btfss	tcp_flags,TCP_FIN
		RETURN
		
		clrF	INDF
		bcf	STATUS,IRP

		call	inc_ack_no
		call	send_ack
		RETURN

;-----------------------------------------------------------------------------------
;
;
		nop
job_ESTAB
		btfsc	tcp_flags,TCP_RST
		goto	recv_rst
		btfsc	tcp_flags,TCP_FIN
		goto	recv_fin
		
		INCF	FSR,1
		MOVLW	HIGH (job_ESTAB)
		MOVWF	PCLATH
		MOVF	INDF,0
		andlw	0fh
		ADDWF	2,1		;jmp	pc+w
		goto	ESTAB_00
		goto	ESTAB_01
		goto	ESTAB_02
		goto	ESTAB_03
		goto	ESTAB_99


recv_fin
		MOVLW	0
		MOVWF	INDF
		bcf	STATUS,IRP
		
		call	inc_ack_no
		call	send_ack
		RETURN

;-----------------------------------------------------------------------------------
;
;
job_CLOSE_WAIT
		MOVLW	0
		MOVWF	INDF
		bcf	STATUS,IRP
		
		call	send_fin
		RETURN
ESTAB_99
		decF	FSR,1
		MOVLW	FIN_WAIT_1
		MOVWF	INDF
		bcf	STATUS,IRP
		
		call	send_fin
		
		MOVF	com_fsr,0
		MOVWF	FSR
		MOVLW	.8
		ADDWF	FSR,1
		call	inc_seq_no
		RETURN

;-----------------------------------------------------------------------------------
;		ESTABLISH
;
ESTAB_00
		incF	INDF,1
		bcf	STATUS,IRP
estab0
		MOVLW	HIGH(get_nextbyte)
		MOVWF	PCLATH

		call	get_nextbyte		; Receive data from buffer  
		MOVLW	HIGH (estab0)
		MOVWF	PCLATH
		
		MOVLW	0			; Finished?
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	estab1
			; Changed line character?
		MOVLW	0AH
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	estab1
			; '?'Discover character ?(Process of =GET command)
		MOVLW	'?'
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	parse_cgi_tag
		goto	estab0
parse9

;-----------------------------------------------------------------------------------
;
;
estab1
		call	abort			; Abort forwarding buffer  
		call	add_ack_no		; Add ACK NO
;		call	send_ack		; Send ACK
		
		MOVLW	014H			;Bank address=14h fan
		MOVWF	wk
		goto	send_mes		; Send message  
;
;		For jumping between banks
parse_cgi_tag
		MOVLW	HIGH(parse_cgi)
		MOVWF	PCLATH

		goto	parse_cgi




ESTAB_01
		incF	INDF,1
		bcf	STATUS,IRP
	;	call	send_ack
	;
		MOVLW	017H	
		MOVWF	wk
		goto	send_mes		; Send message
ESTAB_02
		incF	INDF,1
		bcf	STATUS,IRP
	;	call	send_ack
		
		;mov	wk,#01Ah		; Bank address=19h
		MOVLW	01AH
		MOVWF	wk
		goto	send_mes		; Send message
ESTAB_03
		incF	INDF,1
		bcf	STATUS,IRP
	;	call	send_ack
		
		;mov	wk,#01Dh		; Bank address=1bh
		MOVLW	01DH
		MOVWF	wk
		goto	send_mes		; Send message
;
;		abort DMA transfer
abort
		CLRF	PORTC	 
		movlw	22h
		call	assert_wr0		;Return to PAGE0 
		
		MOVLW	0ah
		MOVWF	PORTC
		DB	01,00		;clrw
		call	assert_wr0
		
		MOVLW	0bh
		MOVWF	PORTC
		DB	01,00		;clrw
		call	assert_wr0
		RETURN





;-----------------------------------------------------------------------------------
;		Send RST Packet
send_rst
		MOVLW	B'000100'		; RST
		MOVWF	state
		goto	send_common


;-----------------------------------------------------------------------------------
;		Send FIN Packet
send_fin
		MOVLW	B'010001'		; ACK+FIN
		MOVWF	state
		goto	send_common


;-----------------------------------------------------------------------------------
;		Send ACK Packet
send_ack
		MOVLW	B'010000'		; ACK
		MOVWF	state
;		goto	send_common
send_common
		MOVLW	0		
		MOVWF	ip_length
		;mov	ip_length[1],#IP_SIZE + TCP_SIZE
		MOVLW	IP_SIZE + TCP_SIZE
		MOVWF	ip_length1
		
		MOVLW	TCP_PROTO	
		MOVWF	proto
		call	prepare_ip
		
		MOVLW	PACKET_SIZE + IP_SIZE	
		MOVWF	remote_adr
		;mov	remote_adr[1],#PAGE_BEGIN
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1

		;mov	remote_len[0],#20		; 20 bytes
		MOVLW	.20
		MOVWF	remote_len
		;mov	remote_len[1],#0
		MOVLW	0
		MOVWF	remote_len1
		call	remote_write
		
		call	clear_sum			; Clear the value of checksum  
		
		MOVLW	http_port & 0ffh
		MOVWF	FSR
		movlw	2
		call	transmit_nbytes			; My port number 
		
		MOVLW	tcp_src_port
		MOVWF	FSR
		movlw	2
		call	transmit_nbytes			;  The other party's port number  

		MOVF	com_fsr,0
		MOVWF	FSR
		MOVLW	.8
		ADDWF	FSR,1
		bsf	STATUS,IRP
		movlw	4+4
		call	transmit_nbytes			; My SEQNO
		bcf	STATUS,IRP
		
		movlw	50h			; 20bytes
		call	assert_wr
		MOVF	state,0			;mov	w,state
		call	assert_wr
		
		movlw	08h			; window(high)
		call	assert_wr
		movlw	00h			; window(low)
		call	assert_wr
		
		call	assert_wr2times			; tcp sum
		call	assert_wr2times			; Emergency Pointer
		
		call	calc_tcp_sum			; Calculate TCP SUM 
		
		MOVLW	4h
		MOVWF	PORTC
		movlw	PAGE_BEGIN			; transmit page is start page 
		call	assert_wr0
		
		MOVLW	5
		MOVWF	PORTC
		movlw	.60				; Transmit 60 bytes 
		call	assert_wr0
		
		MOVLW	6
		MOVWF	PORTC
		DB	01,00		;clrw					; Top forwarding bytes=0
		call	assert_wr0
		call	transmit			; Transmit!!
		RETURN

;-----------------------------------------------------------------------------------
;
;
send_mes
		MOVLW	assert_wr2x & 0ffh	; move transmitting job to RTL8019
		MOVWF	dest
		MOVLW	HIGH (assert_wr2x)	
		MOVWF	dest1		
send_mes_head
				; Temporarily set to forwarding 65535  bytes 
;-------
		MOVLW	PACKET_SIZE + IP_SIZE
		MOVWF	remote_adr
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1

		MOVLW	0FFH
		MOVWF	remote_len
		MOVLW	0FFH
		MOVWF	remote_len1

;-------		

		;mov	remote_len[1],#0ffh		; 
		call	remote_write
		
		;clr	remote_len[0]
		;clr	remote_len[1]
		CLRF	remote_len
		CLRF	remote_len1
		
		call	clear_sum			; Clear checksum value  
		
		MOVLW	http_port & 0ffh
		MOVWF	FSR
		movlw	2
		call	transmit_nbytes2		; My port number
		
		MOVLW	tcp_src_port
		MOVWF	FSR
		movlw	2
		call	transmit_nbytes2		; the other party's port number

		bsf	STATUS,IRP
		MOVF	com_fsr,0
		MOVWF	FSR
		MOVLW	.8
		ADDWF	FSR,1
		movlw	4
		call	transmit_nbytes2		; My SEQNO
		bcf	STATUS,IRP
	
		MOVLW	tcp_seq_no
		MOVWF	FSR
		movlw	4
		call	transmit_nbytes2		; The other party's SEQNO+1
		
		movlw	50h		; 20bytes
		call	assert_wr2
		movlw	B'011000'
		call	assert_wr2
		
		movlw	08h		; window(high)
		call	assert_wr2
		movlw	00h		; window(low)
		call	assert_wr2
		
		DB	01,00		;clrw
		call	assert_wr2		; tcp sum
		DB	01,00		;clrw
		call	assert_wr2		; tcp sum
		DB	01,00		;clrw
		call	assert_wr2		; Emergency pointer
		DB	01,00		;clrw
		call	assert_wr2		; Emergency pointer
	
		CLRF	ind
		bsf	STATUS,RP1
		bcf	STATUS,RP0
		MOVF	wk,0		; Address read=[wk:ind]
		MOVWF	EEADRH
send_mes0
		bsf	STATUS,RP1
		bcf	STATUS,RP0
		MOVF	ind,0		
		MOVWF	EEADR
		bsf	STATUS,RP0
		bsf	EECON1,7		;eepgd
		bsf	EECON1,0	;eecon1.0 ; Read data from code area  
		nop				; Dummy cycle
		nop
		bcf	STATUS,RP0
		MOVF	EEDATH,0		; Move (read data) to the working area  
		MOVWF	getmes_wk
		MOVF	EEDATA,0	
		MOVWF	getmes_wk1

		bcf	STATUS,RP1
		
		RLF	getmes_wk1,0		
		RLF	getmes_wk,1		
		MOVF	getmes_wk,0		; Top 7 bytes are 0  ?
		MOVWF	data0
		MOVLW	7FH		
		ANDWF	data0,1
		MOVF	data0,1		
		btfsc	STATUS,Z
		goto	send_mes9		; If top 7 bytes ared 0, stop
;
;		If top 7 bytes are meta characters, then diverge the process   
		MOVLW	'$'  
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	ctrl_code2
 		MOVLW	'@'
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	ctrl_code3
 		MOVLW	'%'
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	ctrl_code4

		MOVLW	'~'
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	ctrl_code5
		
		MOVF	data0,0			;
		call	assert_wr2
		
		MOVF	getmes_wk1,0		; Forward lower 7 bytes to RTL8019 buffer
		andlw	7fh
		call	assert_wr2
		
		MOVLW	1					; ind++
		ADDWF	ind,1
		bsf	STATUS,RP1
		bcf	STATUS,RP0
		btfsc	STATUS,C
		INCF	EEADRH,1
		goto	send_mes0
send_mes9

send_mes_foot
		call	abort			; Abort forwarding remote DMA
		
	
		MOVF	remote_len,0
		MOVWF	ip_length1
	
		MOVF	remote_len1,0
		MOVWF	ip_length

		call	calc_tcp_sum		; Calculate TCP SUM 
		
		MOVLW	.20		;add	ip_length[1],#20; Add 20 
		ADDWF	ip_length1,1
		movlw	1
		btfsc	STATUS,C
		addwf	ip_length,1		;addwf	ip_length[0]
		
		MOVLW	TCP_PROTO	; TCP packet
		MOVWF	proto
		call	prepare_ip		; Prepare for IP Protocol
		
		MOVLW	4h
		MOVWF	PORTC
		movlw	PAGE_BEGIN			; transmit page is start page 
		call	assert_wr0
		
		MOVLW	PACKET_SIZE			; Add the packet size to the number of bytes transmitted
		addWF	ip_length1,1
		movlw	1
		btfsc	STATUS,C
		addwf	ip_length,1	
		
		MOVLW	6
		MOVWF	PORTC
		MOVF	ip_length,0		
		call	assert_wr0
		MOVF	ip_length,1		
		btfsc	STATUS,Z
		goto	send_mes_foot1
send_mes_foot2
		MOVLW	5
		MOVWF	PORTC
		MOVF	ip_length1,0	
		call	assert_wr0
		call	transmit			; Transmit!!
		
;
;	Additional Code
send_mes_foot3
		MOVLW	PACKET_SIZE+IP_SIZE+TCP_SIZE
		SUBWF	ip_length1,1	
	
		movlw	1
		btfss	STATUS,C
	
		SUBWF	ip_length,1	
		
		MOVF	com_fsr,0
		MOVWF	FSR
		MOVLW	.8
		ADDWF	FSR,1
		call	add_seq_no			; Add to seq no 
		RETURN

send_mes_foot1
 		MOVLW	.60
		SUBWF	ip_length1,0
		BTFSC	3,0
		GOTO	send_mes_foot2
		MOVLW	5
		MOVWF	PORTC
		movlw	.60				; MINIMUM 60bytes
		call	assert_wr0
		call	transmit
		goto	send_mes_foot3

;-----------------------------------------------------------------------------------
;		ADConversion
;
ad_in
		RLF	getmes_wk1,1	
		RLF	getmes_wk1,1		
		RLF	getmes_wk1,1		
		MOVLW	B'00111000'	 
		ANDWF	getmes_wk1,1
		MOVLW	B'10000001'	
		IORWF	getmes_wk1,1
		MOVF	getmes_wk1,0		; Set the value to ADCON1 
		MOVWF	ADCON1
		MOVLW	1	
		MOVWF	wait_cn
		MOVLW	HIGH (wait_ms)
		MOVWF	PCLATH

		call	wait_ms				; Sampling time waiting for  20us  
		MOVLW	HIGH (ad_in)
		MOVWF	PCLATH
		
		bsf	ADCON1,2		; Sart converting AD
		btfsc	ADCON1,2		; Waiting for AD conversion
		goto	$-1
		
		MOVF	ADRESH,0			; Conversion result is sent to val[1]:val[0]
		MOVWF	val1
		bsf	STATUS,RP0
		MOVF	ADRESL,0	
		bcf	STATUS,RP0
		movwf	val		
		
		btfss	getmes_wk1,5				; RA5 or not?
		goto	ad_in1				; Other than RA5 
	;
	;AD Coversion result is multiplied by 5 
	;
		BCF	3,0		
		RLF	val,1		
		RLF	val1,1		
		BCF	3,0	
		RLF	val,1		
		RLF	val1,1		
		
		MOVF	ADRESH,0	
		ADDWF	val1,1
		bsf	STATUS,RP0
		MOVF	ADRESL,0
		bcf	STATUS,RP0
		addwf	val,1
		btfsc	STATUS,C
		INCF	val1,1	

		MOVLW	decimal_top & 0ffh	; Initial storage value
		MOVWF	FSR
		bsf	STATUS,IRP			; IRP=1
		MOVLW	HIGH (divide16)
		MOVWF	PCLATH

		call	divide16
ad_in1
		MOVLW	HIGH (put_decimal16)
		MOVWF	PCLATH

		call	put_decimal16			; Change to decimals
		MOVLW	HIGH (ad_in1)
		MOVWF	PCLATH
		goto	ctrl_next



;-----------------------------------------------------------------------------------
;	SOCKET STATUS
ctrl_code5
		MOVLW	7FH		
		ANDWF	getmes_wk1,1
		swapf	getmes_wk1,1	
		movf	getmes_wk1,0	
		movwf	FSR
		bsf	STATUS,IRP
		
;		movlw	put_socket_stat >> 8	
;		MOVWF	PCLATH
;		call	put_socket_stat			; Project socket status 
		bcf	STATUS,IRP
		goto	ctrl_next
;--------------------------------------------------------------------------
;	TRIS
;	Show input/output  
ctrl_code4
		MOVLW	7FH		
		ANDWF	getmes_wk1,1
		MOVF	getmes_wk1,0
		MOVWF	FSR
		SWAPF	FSR,1		
		MOVLW	0FH		
		ANDWF	FSR,1
		MOVLW	PORTA | 80H	
		ADDWF	FSR,1
		
		MOVF	getmes_wk1,0
		call	getbitpos
		MOVF	INDF,0		
		ANDWF	data0,1
		BTFSC	3,2		
		GOTO	ctrl_out
		goto	ctrl_in
;
;		Return byte position 
;
getbitpos
		movwf	wk
		MOVLW	1	
		MOVWF	data0
		MOVLW	07H		
		ANDWF	wk,1
		BTFSC	3,2		
		GOTO	getbitpos9
getbitpos0
		BCF	3,0	
		RLF	data0,1	
		DECFSZ	wk,1		
		GOTO	getbitpos0
getbitpos9	RETURN


;-----------------------------------------------------------------------------------
;	PARALLEL
;	Show current High/Low 
ctrl_code3
		MOVLW	7FH		
		ANDWF	getmes_wk1,1
		MOVF	getmes_wk1,0
		MOVWF	FSR
		SWAPF	FSR,1		
		MOVLW	0FH		
		ANDWF	FSR,1
		BTFSS	3,2		
		GOTO	ctrl_code31

		MOVLW	80h | PORTA
		ADDWF	FSR,1
		MOVF	getmes_wk1,0
		call	getbitpos
		
		MOVF	INDF,0
		andwf	data0,0				; Check TRIS_RA 
		BTFSC	3,2			; Output pin?
		GOTO	ctrl_code32

		MOVLW	1FH		
		MOVWF	PCLATH
		call	getadtable
		MOVWF	wk	
		MOVLW	HIGH (ctrl_code3)
		MOVWF	PCLATH
		
		MOVF	wk,0		
		ANDWF	data0,1
		BTFSS	3,2		; If 1, perform analog input 
		GOTO	ad_in
;
;
ctrl_code32
		CLRF	FSR		
ctrl_code31	MOVLW	PORTA				; + 05h
		ADDWF	FSR,1

		MOVF	getmes_wk1,0
		call	getbitpos
		MOVF	INDF,0		
		ANDWF	data0,1
		BTFSC	3,2		
		GOTO	ctrl_low
		goto	ctrl_high

;-----------------------------------------------------------------------------------
;	Receive short message 
get_short_mes
		MOVLW	1FH		; Bank=1h
		MOVWF	PCLATH
		MOVF	wk,0			
		MOVWF	PCL
ctrl_out
		movlw	mes_out & .255	; 'OUT'
		goto	put_short_mes10
ctrl_in
		movlw	mes_in & .255	; 'IN'
		goto	put_short_mes10
ctrl_high
		movlw	mes_high & .255	; 'HIGH'
		goto	put_short_mes10
ctrl_low
		movlw	mes_low & .255	; 'LOW'
		goto	put_short_mes10
put_short_mes10
		MOVWF	wk		
put_short_mes0
		call	get_short_mes
		MOVWF	data0		
		MOVLW	HIGH (put_short_mes0)
		MOVWF	PCLATH		; Correct PCLATH
		
		MOVLW	0			; NULL?
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	ctrl_next
		MOVF	data0,0
		call	assert_wr2		; Forward to RTL8019 
		
		INCF	wk,1		;			; wk++
		goto	put_short_mes0
;
;		META CHARACTER
ctrl_code2
		MOVLW	HIGH (ctrl_code1)
		MOVWF	PCLATH

		MOVF	getmes_wk1,0
		andlw	7fh
		addlw	-'0'			;Unknown
		
		call	ctrl_code1			; Output routine of control characters  
		MOVLW	HIGH (ctrl_code2)
		MOVWF	PCLATH
ctrl_next
		MOVLW	1			; ind++
		ADDWF	ind,1
		bsf	STATUS,RP1
		bcf	STATUS,RP0
		btfsc	STATUS,C
		INCF	EEADRH,1
		goto	send_mes0

;-----------------------------------------------------------------------------------
;		Construction of sockets
;
no_socket
		btfss	tcp_flags,TCP_SYN
		RETURN
;
;	Receive SYN Packet -->Send SYN+ACK 
;
recv_syn
		MOVLW	HIGH (socket_entry)
		MOVWF	PCLATH

		call	socket_entry			; Search for socket entry 
		MOVLW	HIGH (recv_syn)
		MOVWF	PCLATH
		btfsc	STATUS,C
		goto	send_rst			; None of the sockets are empty
		
				;
		MOVLW	0
		MOVWF	ip_length
				; IP Header=20+24
		MOVLW	.20 + .24
		MOVWF	ip_length1
		
		MOVLW	TCP_PROTO		; TCP packet
		MOVWF	proto
		call	prepare_ip
;
	
;-------
		MOVLW	PACKET_SIZE + IP_SIZE	;mov	remote_adr[0],#PACKET_SIZE + IP_SIZE
		MOVWF	remote_adr
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1

		MOVLW	.20 + .4
		MOVWF	remote_len
		MOVLW	0
		MOVWF	remote_len1

;-------		
		
		call	remote_write
		
		call	clear_sum			; Clear checksum value
		
		MOVLW	http_port & 0ffh
		MOVWF	FSR
		movlw	2
		call	transmit_nbytes			; My port number
		
		MOVLW	tcp_src_port
		MOVWF	FSR
		movlw	2
		call	transmit_nbytes			; the other party's port number

		MOVLW	seq_no
		MOVWF	FSR
		movlw	4
		call	transmit_nbytes			; My SEQNO
		
		
		call	inc_ack_no		; tcp_seq_no++;
		
		MOVF	com_fsr,0
		MOVWF	FSR
		MOVLW	.8
		ADDWF	FSR,1

		bsf	STATUS,IRP
		bsf	STATUS,RP0
		MOVF	seq_no,0	; Send my SEQ NO to my socket +8
		MOVWF	INDF
		INCF	FSR,1
		MOVF	seq_no1,0
		MOVWF	INDF
		INCF	FSR,1
		MOVF	seq_no2,0
		MOVWF	INDF
		INCF	FSR,1
		MOVF	seq_no3,0	
		MOVWF	INDF
		INCF	FSR,1
		bcf	STATUS,RP0
		
		MOVF	tcp_seq_no,0	
		MOVWF	INDF
		INCF	FSR,1
		MOVF	tcp_seq_no1,0
		MOVWF	INDF
		INCF	FSR,1
		MOVF	tcp_seq_no2,0
		MOVWF	INDF
		INCF	FSR,1
		;mov	INDF,tcp_seq_no[3]
		MOVF	tcp_seq_no3,0
		MOVWF	INDF
		bcf	STATUS,IRP
	
		MOVF	com_fsr,0
		MOVWF	FSR
		MOVLW	.8
		ADDWF	FSR,1
		call	inc_seq_no
		
		MOVLW	tcp_seq_no
		MOVWF	FSR
		movlw	4
		call	transmit_nbytes		; The other party'sSEQNO+1
		
		movlw	60h			; Option available
		call	assert_wr
		movlw	B'010010'			; ACK+SYN
		call	assert_wr
		
		movlw	08h			; window(high)
		call	assert_wr
		movlw	00h			; window(low)
		call	assert_wr
		
		call	assert_wr2times		; tcp sum
		call	assert_wr2times		; Emergency pointer
		
		movlw	2h
		call	assert_wr		
		movlw	4h
		call	assert_wr		
		movlw	5h
		call	assert_wr		
		movlw	0b4h
		call	assert_wr		
		
		call	calc_tcp_sum		; Calculate TCP SUM 
		
		MOVLW	4h
		MOVWF	PORTC
		movlw	PAGE_BEGIN		; transmit page is start page 
		call	assert_wr0
		
		MOVLW	5
		MOVWF	PORTC
		movlw	.60			; Transmit 60 bytes 
		call	assert_wr0
		
		MOVLW	6
		MOVWF	PORTC
		DB	01,00		;clrw
		call	assert_wr0
		call	transmit		; Transmit!

		call	next_seq_no		; seq_no++
		RETURN

;-----------------------------------------------------------------------------------
;		Checksum calculation
calc_tcp_sum
		CLRF	bytes		;clr	bytes	;Adjust 2 byte alignment
		
		MOVLW	this_ip		;mov	fsr,#this_ip; Add my IP address 
		
		MOVWF	FSR
		MOVF	INDF,0
		call	calc_sum
		INCF	FSR,1
		MOVF	INDF,0
		call	calc_sum
		INCF	FSR,1
		MOVF	INDF,0
		call	calc_sum
		INCF	FSR,1
		MOVF	INDF,0
		call	calc_sum
	
		MOVF	ip_src,0		; Add the other party's IP address
		call	calc_sum
		MOVF	ip_src1,0
		call	calc_sum
		MOVF	ip_src2,0
		call	calc_sum
		MOVF	ip_src3,0
		call	calc_sum
		
		DB	01,00		;clrw				; Add protocol number
		call	calc_sum
		MOVLW	TCP_PROTO
		call	calc_sum
		
		MOVF	remote_len1,0	; Add the number of bytes
		call	calc_sum
		MOVF	remote_len,0
		call	calc_sum
		
	
;-------
		MOVLW	PACKET_SIZE + IP_SIZE + .16
		MOVWF	remote_adr
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1

;-------		
		
		call	set_checksum		; Set RTL8019 as buffer 
		RETURN



;===================================================================================
;		NIC Initiation Routine 
;===================================================================================
initialize
		call	init_nic			; Reset NIC
		call	getmac				; Receive MAC address 
		call	setmac				; Set MAC address
		Initiating ring buffer  
		bsf	STATUS,RP0
		MOVLW	fifo_top		
		MOVWF	fifo_buff
		MOVWF	fifo_poi			
		MOVWF	fifo_line		 
		
		clrF	fifo_cn
		clrF	fifo_line_cn
		bcf	STATUS,RP0
		
		RETURN



;-----------------------------------------------------------------------------------
;		Resetting RTL8019 
;-----------------------------------------------------------------------------------
reset_nic
		clrF	PORTC
		movlw	21h
		call	assert_wr0		; STOP OPERATION
		
		MOVLW	1Fh
		MOVWF	PORTC
		call	assert_rd		; Read 1eh 
		
		MOVLW	1Fh
		MOVWF	PORTC
		MOVF	data0,0
		call	assert_wr0		; write it out(RESET)
reset_nic0
		MOVLW	07h
		MOVWF	PORTC
		call	assert_rd		; Read status 
		
		btfss	data0,7			;data.7	; RESET End check
		goto	reset_nic0
		RETURN


;-----------------------------------------------------------------------------------
;		Initiating RTL8019 
;-----------------------------------------------------------------------------------
init_nic
		call	reset_nic
		
		MOVLW	0eh			; DCR(Data Conifguration Register)
		MOVWF	PORTC
		movlw	68h
		call	assert_wr0
		
		MOVLW	0ah
		MOVWF	PORTC
		DB	01,00		;clrw
		call	assert_wr0		; for over flow
		
		MOVLW	0bh
		MOVWF	PORTC
		DB	01,00		;clrw
		call	assert_wr0		; for over flow
		
		MOVLW	01h
		MOVWF	PORTC
		movlw	PAGE_START		; PAGE START
		call	assert_wr0
		
		MOVLW	02h
		MOVWF	PORTC
		movlw	PAGE_STOP		; PAGE STOP
		call	assert_wr0
		
		MOVLW	03h
		MOVWF	PORTC
		movlw	PAGE_START		; BDRY
		call	assert_wr0
		
		MOVLW	0ch			; RCR
		MOVWF	PORTC
		movlw	0h	;	20h
		call	assert_wr0
		
		MOVLW	0dh			; TCR
		MOVWF	PORTC
		movlw	2			; LOOPBACK
		call	assert_wr0

		MOVLW	0fh			; IMR
		MOVWF	PORTC
		movlw	B'11111'
		call	assert_wr0
		
		MOVLW	7			; ISR
		MOVWF	PORTC
		movlw	0ffh
		call	assert_wr0

		clrF	PORTC			; CR(Command Regster)
		movlw	22h			; START OPERATION with L/B
		call	assert_wr0
		RETURN

;-----------------------------------------------------------------------------------
;		Receive MAC address
;-----------------------------------------------------------------------------------
getmac
		clrF	PORTC
		movlw	22h
		call	assert_wr0
		
		CLRF	remote_adr 
		CLRF	remote_adr1	 
		MOVLW	.12	 	;Forward 12bytes 
		MOVWF	remote_len
		clrF	remote_len1	 
		call	remote_read

		MOVLW	6			; MAC address is 6 bytes
		MOVWF	gcn1
		MOVLW	mymac		; Set address to mymac
		MOVWF	FSR
get_mac0
		MOVLW	10h
		MOVWF	PORTC
		call	assert_rd		; Read from 
		call	assert_rd		; 
		
		MOVF	data0,0	;mov	INDF,data		; Read MAC address into PIC
		MOVWF	INDF
		INCF	FSR,1
		DECFSZ	gcn1,1	 
		GOTO	get_mac0
		RETURN



;-----------------------------------------------------------------------------------
;		Set MAC Address 
;-----------------------------------------------------------------------------------
setmac
;	PAGE 1
		clrF	PORTC
		movlw	B'01100010'
		call	assert_wr0
;
		MOVLW	01h
		MOVWF	PORTC
		MOVLW	mymac
		MOVWF	FSR
		MOVLW	6			; MAC address is 6 bytes
		MOVWF	gcn1
setmac0
		MOVF	INDF,0
		call	assert_wr0		; Set MAC Address 
		INCF	FSR,1
		INCF	PORTC,1
		DECFSZ	gcn1,1	 
		GOTO	setmac0
		MOVLW	7
		MOVWF	PORTC
		movlw	PAGE_START + 1		; Further,
		call	assert_wr0		; Set current page
		
		MOVLW	8
		MOVWF	PORTC
		DB	01,00		;clrw
		call	assert_wr0
		INCF	PORTC,1	 
		DB	01,00		;clrw
		call	assert_wr0
		INCF	PORTC,1	 
		DB	01,00		;clrw
		call	assert_wr0
		INCF	PORTC,1	 
		DB	01,00		;clrw
		call	assert_wr0
		INCF	PORTC,1	 
		DB	01,00		;clrw
		call	assert_wr0
		INCF	PORTC,1	 
		DB	01,00		;clrw
		call	assert_wr0
		INCF	PORTC,1	 
		DB	01,00		;clrw
		call	assert_wr0
		INCF	PORTC,1	 
		DB	01,00		;clrw
		call	assert_wr0
		
		clrF	PORTC
		movlw	22h
		call	assert_wr0
		RETURN



;-----------------------------------------------------------------------------------
;		Preparation for writing remote DMA 
;-----------------------------------------------------------------------------------
remote_write
		MOVLW	8
		MOVWF	PORTC
		MOVF	remote_adr,0
		call	assert_wr0
		
		MOVLW	9
		MOVWF	PORTC
		MOVF	remote_adr1,0
		call	assert_wr0
		
		MOVLW	0ah
		MOVWF	PORTC
		MOVF	remote_len,0
		call	assert_wr0
		
		MOVLW	0bh
		MOVWF	PORTC
		MOVF	remote_len1,0
		call	assert_wr0
		
		clrF	PORTC
		movlw	B'00010010'
		call	assert_wr0		; write now!
		MOVLW	10h
		MOVWF	PORTC
		RETURN


;-----------------------------------------------------------------------------------
;		Preparation for reading remote DMA 
;-----------------------------------------------------------------------------------
remote_read
		MOVLW	8
		MOVWF	PORTC
		MOVF	remote_adr,0
		call	assert_wr0
		
		MOVLW	9
		MOVWF	PORTC
		MOVF	remote_adr1,0
		call	assert_wr0
		
		MOVLW	0ah
		MOVWF	PORTC
		MOVF	remote_len,0
		call	assert_wr0
		
		MOVLW	0bh
		MOVWF	PORTC
		MOVF	remote_len1,0
		call	assert_wr0
		
		clrF	PORTC
		movlw	B'00001010'
		call	assert_wr0		; read now!
		MOVLW	10h
		MOVWF	PORTC
		RETURN

;-----------------------------------------------------------------------------------
;		Calculate checksum
;-----------------------------------------------------------------------------------
calc_sum
		BTFSS	bytes,0		;btfss	bytes.0	;Alignment check
		goto	calc_sum_high
;	LOW byte
		ADDWF	sum,1	 ;Add data to(sum[1],sum[0]) 
		movlw	1
		btfsc	STATUS,C
		addwf	sum1,1		 

		btfsc	STATUS,C			; Calculating complement of1  
		addwf	sum,1	 
		btfsc	STATUS,C
		addwf	sum1,1	 
		INCF	bytes,1	 	; Align next
		RETURN
;	HIGH bytes
calc_sum_high
		ADDWF	sum1,1		  ; Add data to(sum[1],sum[0]) 
		movlw	1
		
		btfsc	STATUS,C			; Calculating complement of1
		ADDWF	sum,1		 
		btfsc	STATUS,C
		ADDWF	sum1,1		 
	
		INCF	bytes,1	 			; Align next
		RETURN



assert_wr2times
		DB	01,00		;clrw
		call	assert_wr
		DB	01,00		;clrw
		goto	assert_wr
;-----------------------------------------------------------------------------------
;	Sent data=data
assert_wr2x
		MOVLW	1	 	; remote_len++
		ADDWF	remote_len,1
		btfsc	STATUS,C
		INCF	remote_len1,1	 
		MOVF	data0,0			; Mediate data variable
		goto	assert_wr
;	Sent data=W
assert_wr2	movwf	data0		; Put it away for now 
		MOVLW	1	 	; remote_len++
		ADDWF	remote_len,1
		btfsc	STATUS,C
		INCF	remote_len1,1	 
		MOVF	data0,0
;-----------------------------------------------------------------------------------
;		Writing RTL8019 (Checksum Consideration)
;-----------------------------------------------------------------------------------HAVE
assert_wr
		MOVWF	PORTD	 
assert_wr_2	btfss	bytes,0		 
		goto	asser_wr_high
		
		ADDWF	sum,1		 
		movlw	1
		btfsc	STATUS,C
		ADDWF	sum1,1		 

		btfsc	STATUS,C
		ADDWF	sum,1	 
		btfsc	STATUS,C
		ADDWF	sum1,1	 
		
		INCF	bytes,1		 
		goto	assert_wr0_2
asser_wr_high
		ADDWF	sum1,1	 
		movlw	1
		
		btfsc	STATUS,C
		ADDWF	sum,1	 
		btfsc	STATUS,C
		ADDWF	sum1,1	 
	
		INCF	bytes,1	 
		goto	assert_wr0_2


;-----------------------------------------------------------------------------------
;		Simplely Writing RTL8019 
;-----------------------------------------------------------------------------------
assert_wr0
		movwf	PORTD	 
assert_wr0_2	bsf	STATUS,RP0
		clrF	PORTD	 			; RDport output
		bcf	STATUS,RP0
		
		bcf	PORTE,1	 
		

		btfss	PORTC,5
		goto	$-1
		
		bsf	PORTE,1	 
		
		bsf	STATUS,RP0
		MOVLW	0FFH		 	;RDport input
		MOVWF	PORTD
		bcf	STATUS,RP0
		RETURN


assert_rd
		bcf	PORTE,0
		
		btfss	PORTC,5			; ~Wait
		goto	$-1
		
		MOVF	PORTD,0		 
		MOVWF	data0
		bsf	PORTE,0
		RETURN



;-----------------------------------------------------------------------------------
;		Processes relating to packet transmittion
;-----------------------------------------------------------------------------------
transmit_this_ip
		MOVLW	this_ip	 
		MOVWF	FSR
		movlw	4

transmit_nbytes
		movwf	gcn1
		MOVLW	10h
		MOVWF	PORTC
transmit0	MOVF	INDF,0
		call	assert_wr
		INCF	FSR,1
		DECFSZ	gcn1,1	 
		GOTO	transmit0
		RETURN


transmit_nbytes2
		movwf	gcn1
		MOVLW	10h
		MOVWF	PORTC
transmit2_0	MOVF	INDF,0
		call	assert_wr2
		INCF	FSR,1
		DECFSZ	gcn1,1		 
		GOTO	transmit2_0
		RETURN

;-----------------------------------------------------------------------------------
;		Packet transmission
;-----------------------------------------------------------------------------------
transmit
retry
		clrF	PORTC
		call	assert_rd
		
		BTFSC	data0,2	 	; view  transmitted data
		goto	transmit			; Wait for transmission
		
		clrF	PORTC
		movlw	B'00100110'			; Set up transmission bytes
		call	assert_wr0			; transmit!
trans100
		MOVLW	4
		MOVWF	PORTC
		call	assert_rd
		
		btfsc	data0,0	 
		goto	transmit9			; transmission completed?
		btfsc	data0,3	 
		goto	retry
		
		goto	trans100
transmit9	RETURN


 
;-----------------------------------------------------------------------------------
;		Construct Ethernet header
;-----------------------------------------------------------------------------------
prepare_ether2
		movlw	PACKET_SIZE + ARP_SIZE
		MOVWF	remote_len
		GOTO	prepare_ether1
prepare_ether
	;	call	wait_transmit			; wait for transmission
		movlw	PACKET_SIZE + IP_SIZE
		MOVWF	remote_len
prepare_ether1
		CLRF	remote_len1
		CLRF	remote_adr
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1


 
		call	remote_write
		
		MOVLW	10h			; The other party's MAC who sent this packet 
		MOVWF	PORTC
		MOVLW	eth_src
		MOVWF	FSR
		movlw	6
		call	transmit_nbytes
		
		MOVLW	mymac		; Set my MAC address 
		MOVWF	FSR
		movlw	6
		call	transmit_nbytes
		RETURN


;-----------------------------------------------------------------------------------
;		IP header construction job
;-----------------------------------------------------------------------------------
prepare_ip
		call	prepare_ether
		movlw	COM_PROTO
		call	assert_wr
		movlw	IP_PROTO
		call	assert_wr
		
		call	ip_common
		
 
		MOVLW	ip_sum - ip_header + PACKET_SIZE
		MOVWF	remote_adr
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1


 		
	;	goto	set_checksum
set_checksum
		COMF	sum,1	 
		COMF	sum1,1	 
		
		MOVLW	2	 	;Checksum is 2  
		MOVWF	remote_len
		CLRF	remote_len1	 
		call	remote_write
		
		MOVLW	10h
		MOVWF	PORTC
		MOVF	sum1,0
		call	assert_wr0			; Writing checksum(assert_wr0 has to be called)
		MOVF	sum,0
		call	assert_wr0
		RETURN



;-----------------------------------------------------------------------------------
;		Constructing IP protocol header 
;-----------------------------------------------------------------------------------
ip_common
		call	clear_sum			; Clear checksum value
		
		MOVLW	10h
		MOVWF	PORTC
		movlw	45h			; ID
		call	assert_wr
		movlw	00h			; TOS
		call	assert_wr
		
		MOVF	ip_length,0			; length high
		call	assert_wr
		MOVF	ip_length1,0			; length low
		call	assert_wr
		
		MOVLW	ident
		MOVWF	FSR
		MOVF	INDF,0			; Seq No High
		call	assert_wr
		INCF	FSR,1
		
		MOVF	INDF,0			; Seq No Low
		call	assert_wr
		MOVLW	1		 
		ADDWF	INDF,1
		decF	FSR,1
		btfsc	STATUS,C
		addwf	INDF,1

		movlw	00h			; flagment(2bytes)
		call	assert_wr
		movlw	00h			;
		call	assert_wr
		
		movlw	0ffh			; TTL
		call	assert_wr
		
		MOVF	proto,0			; PROTOCOL = anything
		call	assert_wr
		
		call	assert_wr2times			; sum is zero
		
		call	transmit_this_ip
		
		MOVLW	ip_src			; to IP
		MOVWF	FSR
		movlw	4
		call	transmit_nbytes
		RETURN




;-----------------------------------------------------------------------------------
;		Controlling parallel I/F 
;-----------------------------------------------------------------------------------
		org	820h
udp_parallel
		MOVLW	$ >> 8
		MOVWF	PCLATH
		MOVLW	udp_data
		MOVWF	FSR
		
		MOVLW	6	 
		SUBWF	INDF,0
		BTFSC	3,0
		GOTO	main90
		MOVF	INDF,0
		INCF	FSR,1
		ADDWF	2,1	 
		goto	para_get_status			; Receive status 
		goto	para_set_high			; Set to High 
		goto	para_set_low			; Set to Low 
		goto	para_set_whole			; Whole setting
		goto	para_get_adc			; A/D conversion
		goto	para_set_rbpu			; Built-in pull-up On/Off
;
;   HIGH/INPUT setting 
para_set_high
		call	para_set_common
		MOVF	wk1,0	 
		IORWF	INDF,1
		goto	para_get_status
;
;	 LOW/OUTPUT  setting
para_set_low
		call	para_set_common
		COMF	wk1,1	 
		MOVF	wk1,0	 
		ANDWF	INDF,1
		goto	para_get_status
;
;	Calculating bit posision
para_set_common
		INCF	FSR,1
		MOVF	INDF,0	 	;Bit posision(0-7)
		MOVWF	wk
		MOVLW	1 
		MOVWF	wk1
para_set_common0
		MOVLW	0 
		SUBWF	wk,0
		BTFSC	3,2
		GOTO	para_set_common9
		BCF	3,0	 
		RLF	wk1,1 
		DECF	wk,1 
		goto	para_set_common0
para_set_common9
		decF	FSR,1
		MOVF	INDF,0		; I/O port number
		MOVWF	FSR
		RETURN
;
;	SET WHOLE Mode
para_set_whole
		MOVF	INDF,0	 	; Port
		MOVWF	ptr
		INCF	FSR,1
		MOVF	INDF,0 		; Size 
		MOVWF	gcn1
		INCF	FSR,1
para_set_whole0
		MOVF	INDF,0	 		; Mask
		MOVWF	wk
		INCF	FSR,1
		MOVF	INDF,0 
		MOVWF	wk1
		INCF	FSR,1
		
		MOVF	FSR,0 		; save FSR
		MOVWF	wk2
		MOVF	ptr,0
		MOVWF	FSR
		MOVF	INDF,0
		ANDWF	wk,0 
		IORWF	wk1,0	 
		movwF	INDF		; *ptr = (*ptr & Mask) | Value
		MOVF	wk2,0		; restore FSR
		MOVWF	FSR
		
		INCF	ptr,1 
		DECFSZ	gcn1,1	 
		GOTO	para_set_whole0
		goto	para_get_status


;
; Buil-in Pull-up On/Off
para_set_rbpu
		bsf	STATUS,RP0
		MOVLW	0 
		SUBWF	INDF,0
		BTFSS	3,2
		GOTO	para_set_rbpu1
		BSF	OPTION_REG,7     ;Do no perform pull-up
		goto	para_set_rbpu9
para_set_rbpu1
		BCF	OPTION_REG,7   ; Perform pull-up
para_set_rbpu9	bcf	STATUS,RP0
		goto	para_get_status



;-----------------------------------------------------------------------------------
para_get_adc
		MOVF	INDF,0 		; ADCON1 Setting
		MOVWF	ADCON1
		BSF	ADCON1,0 
		INCF	FSR,1
		
		MOVF	INDF,0 		;Wait for Acquisition Time
		MOVWF	wait_cn
para_get_aqu0
		MOVLW	8	 
		MOVWF	wait_cn2
		DECFSZ	wait_cn2,1 
		GOTO	$-1
		DECFSZ	wait_cn,1 		; 25us * WaitTime
		GOTO	para_get_aqu0
		BSF	ADCON1,2 	 ; Start AD Conversion
		BTFSC	ADCON1,2 	; wait for AD conversion(Synchronous)
		goto	$-1 		; Would like it to be asynchronous (^_^;
		
		CLRF	PCLATH
para_get_status
		MOVLW	para_port	 ; Port Number of the transmitting Source 
		MOVWF	wk2
common_get_status                      
		CLRF	ip_length	 
	 
		MOVLW	IP_SIZE + UDP_SIZE + PARALLEL_PACKET_SIZE
		MOVWF	ip_length1
		
		CLRF	PCLATH
		
		MOVLW	UDP_PROTO		; UDP packet
		MOVWF	proto
		call	prepare_ip			;Prepare untilIP packet
		
		call	clear_sum			; Clear check sum value
		
 
		MOVLW	PACKET_SIZE+IP_SIZE
		MOVWF	remote_adr
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1

		MOVLW	(UDP_SIZE + PARALLEL_PACKET_SIZE) & 0ffh
		MOVWF	remote_len
		MOVLW	HIGH (UDP_SIZE + PARALLEL_PACKET_SIZE)
		MOVWF	remote_len1
 
		call	remote_write
		
		MOVLW	10h
		MOVWF	PORTC
		
		MOVF	wk2,0		;para_port
		MOVWF	FSR
		MOVF	INDF,0			; From PORT #(HIGH)
		call	assert_wr
		INCF	FSR,1
		MOVF	INDF,0			; From PORT #(LOW)
		call	assert_wr
		
		MOVF	udp_src_port,00		; To PORT #
		call	assert_wr
		MOVF	udp_src_port1,0
		call	assert_wr
		
 		MOVLW	HIGH (UDP_SIZE + PARALLEL_PACKET_SIZE)
		call	assert_wr
		movlw	(UDP_SIZE + PARALLEL_PACKET_SIZE) & 0ffh ; UDP DATAGRAM SIZE
		call	assert_wr
		
		call	assert_wr2times			; sum(not fixed)
 		
		MOVF	PORTA,0
		call	assert_wr			; 
		MOVF	PORTB,0
		call	assert_wr			; 
		
		MOVLW	80h + PORTA			;ra
		MOVWF	FSR
		MOVF	INDF,0
		call	assert_wr			; 
		INCF	FSR,1
		MOVF	INDF,0
		call	assert_wr			; 
		
		MOVF	ADRESH,0 
		MOVWF	val1			; Conversion result is sent to val[1]:val[0] 
		bsf	STATUS,RP0
		MOVF	ADRESL,0			;adres,0; page1 is the lowest byte
		bcf	STATUS,RP0
		MOVWF	val		 
		
		MOVF	val1,0
		call	assert_wr			; AD Conversion Result(H)
		MOVF	val,0
		call	assert_wr			; AD Conversion Result(L)
		
		bsf	STATUS,RP0
		MOVF	ADCON1,0
		bcf	STATUS,RP0
		call	assert_wr			;
		movlw	0				; Reserved
		call	assert_wr			;
		
		MOVLW	HIGH (calc_udp_sum)
		MOVWF	PCLATH

		call	calc_udp_sum
		MOVLW	HIGH (transmit_60bytes)
		MOVWF	PCLATH

		call	transmit_60bytes
main90		
		MOVLW	HIGH (main9)
		MOVWF	PCLATH

		goto	main9


;-----------------------------------------------------------------------------------
;		UDPCheck sum calculation+Transmission
;
calc_udp_sum
		CLRF	PCLATH
		CLRF	bytes		;clr	bytes ; Adjust 2 byte align 
		MOVLW	this_ip	 	; Add my IP address
		MOVWF	FSR
		
		MOVF	INDF,0
		call	calc_sum
		INCF	FSR,1
		MOVF	INDF,0
		call	calc_sum
		INCF	FSR,1
		MOVF	INDF,0
		call	calc_sum
		INCF	FSR,1
		MOVF	INDF,0
		call	calc_sum
	
		MOVF	ip_src,0		; Add the other party's IP address 
		call	calc_sum
		MOVF	ip_src1,0
		call	calc_sum
		MOVF	ip_src2,0
		call	calc_sum
		MOVF	ip_src3,0
		call	calc_sum
	
		DB	01,00		;clrw				; Add Protocol number 
		call	calc_sum
		MOVLW	UDP_PROTO
		call	calc_sum
		
		MOVF	remote_len1,0		;#PARALLEL_PACKET_SIZE>>8
		call	calc_sum
		MOVF	remote_len,0		;#PARALLEL_PACKET_SIZE & 0ffh
		call	calc_sum

	 	; set position for check sum
 
		MOVLW	PACKET_SIZE+IP_SIZE + 6
		MOVWF	remote_adr
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1

 		call	set_checksum
		RETURN

transmit_60bytes
		CLRF	PCLATH
		
		MOVLW	4h
		MOVWF	PORTC
		movlw	PAGE_BEGIN			; transmit page is start page 
		call	assert_wr0
		
		MOVLW	5
		MOVWF	PORTC
		movlw	.60		; Basically 60 bytes  (PARALLEL_PACKET_SIZE+IP_SIZE+PACKET_SIZE) & 0ffh
		call	assert_wr0
		
		MOVLW	6
		MOVWF	PORTC
		movlw	0		; (PARALLEL_PACKET_SIZE+IP_SIZE+PACKET_SIZE) >> 8
		call	assert_wr0
		
		call	transmit
		RETURN

;-----------------------------------------------------------------------------------
;		Serial Port Process  
;
udp_serial
		bsf	STATUS,RP0
		BSF	STATUS,RP1
		movlw	.16
		MOVwf	transmitted & 0ffh
		clrf	STATUS

		MOVF	udp_length,0 
		MOVWF	remote_len1
		MOVF	udp_length1,0 
		MOVWF	remote_len

		MOVLW	8	 
		SUBWF	remote_len,1
		btfss	STATUS,C
		DECF	remote_len1,1 
		
		MOVLW	HIGH (get_dgram)
		MOVWF	PCLATH

		call	get_dgram
		MOVLW	$>>8		;HIGH (udp_serial)
		MOVWF	PCLATH
		
		btfsc	STATUS,C
		goto	main90
		
		MOVF	data0,0	 
		MOVWF	udp_data
		MOVLW	4	 
		SUBWF	data0,0
		BTFSC	3,0
		GOTO	main90
		MOVF	data0,0
		ADDWF	2,1 
		goto	ser_get_status		; Show Status
		goto	ser_register_tag	; Register Address
		goto	ser_unregister_tag	; Delete Address
		goto	ser_transmit		; Transmit Data
;
;		Process of Receiving ARP Response
ser_arp
		bcf	STATUS,IRP
		MOVLW	arp_src_mac & 0ffh
		MOVWF	FSR

		bsf	STATUS,RP0
		bsf	STATUS,RP1
		MOVF	INDF,0	 
		MOVWF	on_ether & 0FFH	; Set Hardware Address 
		INCF	FSR,1
		MOVF	INDF,0	 
		MOVWF	on_ether1 & 0FFH
		INCF	FSR,1
		MOVF	INDF,0 
		MOVWF	on_ether2 & 0FFH
		INCF	FSR,1
		MOVF	INDF,0 
		MOVWF	on_ether3 & 0FFH
		INCF	FSR,1
		MOVF	INDF,0	 
		MOVWF	on_ether4 & 0FFH
		INCF	FSR,1
		MOVF	INDF,0	 
		MOVWF	on_ether5 & 0FFH
		CLRF	STATUS	 
 
		
		bsf	RCSTA,4		;cren
		bsf	INTCON,6	;peie			; User Authorization
		MOVLW	HIGH (main9)
		MOVWF	PCLATH

		goto	main9

;-----------------------------------------------------------------------------------
;		Transmit serial port status to the host 
;-----------------------------------------------------------------------------------
ser_get_status
		CLRF	ip_length 
 		MOVLW	IP_SIZE + UDP_SIZE + SERIAL_PACKET_SIZE
		MOVWF	ip_length1

		CLRF	PCLATH
		
		MOVLW	UDP_PROTO		; UDP packet
		MOVWF	proto
		call	prepare_ip			; Prepare until IP packet 
		
		call	clear_sum			; Clear check sum value
		
 
		MOVLW	PACKET_SIZE+IP_SIZE
		MOVWF	remote_adr
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1

		MOVLW	(UDP_SIZE + SERIAL_PACKET_SIZE) & 0ffh
		MOVWF	remote_len
		MOVLW	HIGH (UDP_SIZE + SERIAL_PACKET_SIZE)
		MOVWF	remote_len1

;-------		
		call	remote_write
		
		MOVLW	10h
		MOVWF	PORTC
		
		MOVLW	serial_port
		MOVWF	FSR
		MOVF	INDF,0			; From PORT #(HIGH)
		call	assert_wr
		INCF	FSR,1
		MOVF	INDF,0			; From PORT #(LOW)
		call	assert_wr
		
		MOVF	udp_src_port,0		; To PORT #
		call	assert_wr
		MOVF	udp_src_port1,0
		call	assert_wr
		
		movlw	HIGH (UDP_SIZE + SERIAL_PACKET_SIZE)
		call	assert_wr
		movlw	(UDP_SIZE + SERIAL_PACKET_SIZE) & 0ffh ; UDP DATAGRAM SIZE
		call	assert_wr
		
		call	assert_wr2times			; sum(not fixed)
;
;		DGRAM
;
		CLRF	PCLATH
		
		MOVF	udp_data,0
		call	assert_wr			; sum(not fixed)
		
		bsf	STATUS,IRP
		MOVLW	transmitted & 0ffh
		movwf	FSR
		movf	INDF,0
		call	assert_wr
		MOVLW	on_ether & 0ffh
		MOVWF	FSR
		movlw	SERIAL_PACKET_SIZE-2
		call	transmit_nbytes
		bcf	STATUS,IRP
		
		MOVLW	HIGH (calc_udp_sum)
		MOVWF	PCLATH

		call	calc_udp_sum
		MOVLW	HIGH (transmit_60bytes)
		MOVWF	PCLATH

		call	transmit_60bytes

		MOVLW	HIGH (main9)
		MOVWF	PCLATH

		goto	main9

;-----------------------------------------------------------------------------------
ser_transmit
		bsf	STATUS,RP0
		bsf	STATUS,RP1
		CLRF	transmitted & 0ffh
		clrf	STATUS
ser_transmit0
		MOVLW	get_dgram >> 8
		movwf	PCLATH
		CALL	get_dgram
		MOVLW	$ >> 8
		MOVWF	PCLATH
		BTFSC	STATUS,C
		GOTO	ser_transmit9
		
		BSF	STATUS,RP0
		BSF	STATUS,RP1
		BTFSS	on_flow,0
		GOTO	ser_transmit1

		CLRF	STATUS
		BTFSC	PORTB,0
		GOTO	ser_transmit9
ser_transmit1
		CLRF	STATUS
		CALL	async_transmit
		bsf	STATUS,RP0
		BSF	STATUS,RP1
		INCF	transmitted,1
		clrf	STATUS
		GOTO	ser_transmit0
ser_transmit9
		MOVLW	HIGH (ser_get_status)
		MOVWF	PCLATH

		goto	ser_get_status

;-----------------------------------------------------------------------------------
ser_register_tag
		MOVLW	4+2			; Read 6 bytes
		MOVWF	gcn1
		MOVLW	udp_data+1
		MOVWF	FSR
		MOVLW	HIGH (copy_toram)
		MOVWF	PCLATH

		call	copy_toram
		
		MOVLW	HIGH (ser_register)
		MOVWF	PCLATH

		goto	ser_register

;-----------------------------------------------------------------------------------
ser_unregister_tag
		MOVLW	HIGH (ser_unregister)
		MOVWF	PCLATH

		goto	ser_unregister


;-----------------------------------------------------------------------------------
;		Check if there are sockets from received packet 
;-----------------------------------------------------------------------------------
search_socket
		bsf	STATUS,IRP
		MOVLW	SOCKETS		;mov	com_cn,#SOCKETS
		MOVWF	com_cn
		MOVLW	skb & 0ffh		;mov	com_fsr,#0a0h
		MOVWF	com_fsr
search_socket0
		MOVF	com_fsr,0
		MOVWF	FSR
		BTFSS	INDF,7	 
		goto	search_socket9
		
		MOVLW	.2
		ADDWF	FSR,1
		MOVF	ip_src,0 
		SUBWF	INDF,0
		BTFSS	3,2
		GOTO	search_socket9
		INCF	FSR,1
		MOVF	ip_src1,0 
		SUBWF	INDF,0
		BTFSS	3,2
		GOTO	search_socket9
		INCF	FSR,1
		MOVF	ip_src2,0 
		SUBWF	INDF,0
		BTFSS	3,2
		GOTO	search_socket9
		INCF	FSR,1
		MOVF	ip_src3,0 
		SUBWF	INDF,0
		BTFSS	3,2
		GOTO	search_socket9
		INCF	FSR,1
		
 
		MOVF	tcp_src_port,0
		SUBWF	INDF,0
		BTFSS	3,2
		GOTO	search_socket9
		INCF	FSR,1
 
		MOVF	tcp_src_port1,0	
		SUBWF	INDF,0
		BTFSS	3,2
		GOTO	search_socket9
		INCF	FSR,1
		
		MOVLW	.7
		SUBWF	FSR,1
		MOVLW	0F0H 
		IORWF	INDF,1
		decF	FSR,1
		BSF	3,0	 
		RETURN
search_socket9
		MOVLW	10H	 
		ADDWF	com_fsr,1
		DECFSZ	com_cn,1 
		GOTO	search_socket0
		bcf	STATUS,IRP
		BCF	3,0	 
		RETURN


;-----------------------------------------------------------------------------------
;		Construct New Socket
;-----------------------------------------------------------------------------------
socket_entry
		bsf	STATUS,IRP
		MOVLW	skb & 0ffh
		MOVWF	FSR
		MOVF	FSR,0	 
		MOVWF	com_fsr
		MOVLW	SOCKETS	 
		MOVWF	com_cn
entry0
		BTFSC	INDF,7	 
		goto	entry9
		
		MOVLW	SYN_RCVD
		MOVWF	INDF
		INCF	FSR,1
		MOVLW	0f0h
		MOVWF	INDF
		INCF	FSR,1
		MOVF	ip_src,0 
		MOVWF	INDF
		INCF	FSR,1
		MOVF	ip_src1,0 
		MOVWF	INDF
		INCF	FSR,1
		MOVF	ip_src2,0 
		MOVWF	INDF
		INCF	FSR,1
		MOVF	ip_src3,0 
		MOVWF	INDF
		INCF	FSR,1
		
		MOVF	tcp_src_port,0 
		MOVWF	INDF
		INCF	FSR,1
		MOVF	tcp_src_port1,0 
		MOVWF	INDF
		INCF	FSR,1
		
		MOVF	tcp_seq_no,0 
		MOVWF	INDF
		INCF	FSR,1
		MOVF	tcp_seq_no1,0 
		MOVWF	INDF
		INCF	FSR,1
		MOVF	tcp_seq_no2,0 
		MOVWF	INDF
		INCF	FSR,1
		MOVF	tcp_seq_no3,0 
		MOVWF	INDF
		INCF	FSR,1

		MOVF	tcp_ack_no,0 
		MOVWF	INDF
		INCF	FSR,1
		MOVF	tcp_ack_no1,0 
		MOVWF	INDF
		INCF	FSR,1
		MOVF	tcp_ack_no2,0 
		MOVWF	INDF
		INCF	FSR,1
		MOVF	tcp_ack_no3,0 
		MOVWF	INDF
		INCF	FSR,1
		bcf	STATUS,IRP
		BCF	3,0	 
		RETURN
entry9
		MOVLW	10h
		ADDWF	FSR,1

		MOVLW	10H	 
		ADDWF	com_fsr,1
		DECFSZ	com_cn,1 
		GOTO	entry0
		
socket_entry_99	bcf	STATUS,IRP
		BSF	3,0 
		RETURN


;-----------------------------------------------------------------------------------
;		Transmission Process of Ethernet Packet Broadcasting  
;-----------------------------------------------------------------------------------
broad_cast
		CLRF	PCLATH
 
		MOVLW	0
		MOVWF	remote_adr
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1

		MOVLW	IP_SIZE + PACKET_SIZE
		MOVWF	remote_len
		MOVLW	0
		MOVWF	remote_len1
 
		call	remote_write
		
		MOVLW	10h			; Source of Transmission :Transmit to ff-ff-ff-ff-ff-ff 
		MOVWF	PORTC
		movlw	0ffh
		call	assert_wr
		movlw	0ffh
		call	assert_wr
		movlw	0ffh
		call	assert_wr
		movlw	0ffh
		call	assert_wr
		movlw	0ffh
		call	assert_wr
		movlw	0ffh
		call	assert_wr
		
		MOVLW	mymac		; Source of Transmission:Set my MAC  address
		MOVWF	FSR
		movlw	6
		call	transmit_nbytes
		RETURN

bootp2
		call	broad_cast
		CLRF	PCLATH
		
		movlw	COM_PROTO
		call	assert_wr
		movlw	IP_PROTO
		call	assert_wr

		movlw	.255
		movwf	ip_src 	; Transmit my IP as  255.255.255.255 
		movwf	ip_src1	 
		movwf	ip_src2	 
		movwf	ip_src3	 
		
  
		MOVLW	HIGH (DHCP_SIZE+20)
		MOVWF	ip_length
 
		MOVLW	(DHCP_SIZE + .20) & 0FFH
		MOVWF	ip_length1
		
		MOVLW	UDP_PROTO
		MOVWF	proto
		call	ip_common
 
		MOVLW	ip_sum - ip_header + PACKET_SIZE
		MOVWF	remote_adr
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1
 		
		goto	set_checksum

bootp
		call	bootp2
		CLRF	PCLATH
		
		call	clear_sum			; Clear check sum value
 
		MOVLW	PACKET_SIZE+IP_SIZE
		MOVWF	remote_adr
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1

		MOVLW	DHCP_SIZE & 0ffh
		MOVWF	remote_len
		MOVLW	HIGH (DHCP_SIZE)
		MOVWF	remote_len1

;-------		
		call	remote_write
		
		MOVLW	10h
		MOVWF	PORTC
		
		movlw	0				; Client BOOTP port
		call	assert_wr
		movlw	BOOTPC_PORT			; Client BOOTP Port
		call	assert_wr
		
		movlw	0				; Server BOOTP Port
		call	assert_wr
		movlw	BOOTPS_PORT			; Server BOOTP Port
		call	assert_wr
		
		movlw	HIGH (DHCP_SIZE)	;DHCP_SIZE>>8
		call	assert_wr
		movlw	DHCP_SIZE & 0ffh		; length
		call	assert_wr
		
		call	assert_wr2times			; sum
		
		movlw	1
		call	assert_wr			; Requare:1,Reply:2
		movlw	1
		call	assert_wr			; 10Mbps Ethernet:1
		movlw	6
		call	assert_wr			; EthernetLength:6
		DB	01,00		;clrw
		call	assert_wr			; Hop Count
		
		
		MOVLW	mymac + 2
		MOVWF	FSR
		MOVF	INDF,0
		call	assert_wr
		INCF	FSR,1
		MOVF	INDF,0
		call	assert_wr
		INCF	FSR,1
		MOVF	INDF,0
		call	assert_wr
		INCF	FSR,1
		MOVF	INDF,0
		call	assert_wr
		
		call	assert_wr2times
		call	assert_wr2times
		
		
		MOVLW	4*4
		MOVWF	gcn1
bootp_10	
		MOVLW	HIGH (assert_wr)
		MOVWF	PCLATH

		DB	01,00		;clrw
		call	assert_wr
		MOVLW	HIGH (bootp_10)
		MOVWF	PCLATH
		DECFSZ	gcn1,1		;djnz	gcn1,bootp_10
		GOTO	bootp_10
;
;	Client Hardware Address
;
		MOVLW	mymac
		MOVWF	FSR
		MOVLW	HIGH (transmit_nbytes)
		MOVWF	PCLATH

		movlw	6
		call	transmit_nbytes
		MOVLW	HIGH (bootp_10)
		MOVWF	PCLATH
		
		MOVLW	.16 - .6
		MOVWF	gcn1
bootp_10_0
		MOVLW	HIGH (assert_wr)
		MOVWF	PCLATH

		DB	01,00		;clrw
		call	assert_wr
		MOVLW	HIGH (bootp_10_0)
		MOVWF	PCLATH
		DECFSZ	gcn1,1	 
		GOTO	bootp_10_0
;
;		 Name of the boot file
;
		MOVLW	.128 + .64
		MOVWF	gcn1
bootp_20
		MOVLW	HIGH (assert_wr)
		MOVWF	PCLATH

		DB	01,00		;clrw
		call	assert_wr
		MOVLW	HIGH (bootp_20)
		MOVWF	PCLATH
		DECFSZ	gcn1,1	 
		GOTO	bootp_20
	;
	;	Magic
	;
		MOVLW	HIGH (assert_wr)
		MOVWF	PCLATH

		movlw	63h	; 99
		call	assert_wr
		movlw	82h	; 130
		call	assert_wr
		movlw	53h	; 83
		call	assert_wr
		movlw	63h	; 99
		call	assert_wr
		RETURN


bootp_tx
		CLRF	PCLATH
		DB	01,00		;clrw
		call	calc_sum
		DB	01,00		;clrw
		call	calc_sum
		DB	01,00		;clrw
		call	calc_sum
		DB	01,00		;clrw
		call	calc_sum
		
		MOVLW	0ffh
		call	calc_sum
		MOVLW	0ffh
		call	calc_sum
		MOVLW	0ffh
		call	calc_sum
		MOVLW	0ffh
		call	calc_sum
		
		DB	01,00	 
		call	calc_sum
		MOVLW	.17
		call	calc_sum
		
		MOVLW	HIGH (DHCP_SIZE)
		call	calc_sum
		MOVLW	DHCP_SIZE & 0ffh
		call	calc_sum

 
 		MOVLW	PACKET_SIZE+IP_SIZE + 6
		MOVWF	remote_adr
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1
 		call	set_checksum
		
		
		MOVLW	4h
		MOVWF	PORTC
		movlw	PAGE_BEGIN			; transmit page is start page 
		call	assert_wr0
		
		MOVLW	5
		MOVWF	PORTC
		movlw	(DHCP_SIZE+IP_SIZE+PACKET_SIZE) & 0ffh
		call	assert_wr0
		
		MOVLW	6
		MOVWF	PORTC
		movlw	HIGH (DHCP_SIZE+IP_SIZE+PACKET_SIZE)
		call	assert_wr0
		
		call	transmit
;		setb	rb.5
		RETURN
;-----------------------------------------------------------------------------------
;		Writing EEPROM Data
;		Automatically Increment the Address
;--------------------------------------------------------------------------------- 
;		org	0a00h

		goto	$		;Unknown
write_eeprom16
		MOVLW	'b'	 
		MOVWF	ind
		MOVF	wk2,0	 
		XORWF	wk1,1
		MOVF	wk1,0	 
		XORWF	wk2,1
		MOVF	wk2,0	 
		XORWF	wk1,1
		call	write_eeprom
		MOVF	wk2,0	 
		MOVWF	wk1
write_eeprom
		MOVLW	'w'	 
		SUBWF	ind,0
		BTFSC	3,2
		GOTO	write_eeprom16
write_eeprom0	bsf	STATUS,RP1
		bcf	STATUS,RP0
		MOVF	wk,0	 	;addr
		MOVWF	EEADR
		MOVF	wk1,0 
		MOVWF	EEDATA
		bsf	STATUS,RP0
		bcf	EECON1,7			;eepgd
		bsf	EECON1,2		;wren
		
		bcf	INTCON,7		;gie
		MOVLW	55H	 
		MOVWF	EECON2
		MOVLW	0AAH	 
		MOVWF	EECON2
		bsf	EECON1,1		;wr
		
		btfsc	EECON1,1		;wr
		goto	$-1
		
		bcf	EECON1,2		;wren
		bcf	STATUS,RP0
		bcf	STATUS,RP1
		INCF	wk,1 
		bsf	INTCON,7		;gie
		RETURN




get_nextbyte
		MOVF	remote_len,0 
		iorwf	remote_len1,0 
		btfsc	STATUS,Z
		goto	get_nextbyte9
		
		bcf	PORTE,0
		btfss	PORTC,5			; ~Wait
		goto	$-1
		MOVF	PORTD,0
		bsf	PORTE,0
		
		MOVWF	data0	 
		MOVLW	0AH	 
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	get_nextbyte9
		movlw	1			; LENGTH--
		subwf	remote_len,1 
		btfss	STATUS,C
		subwf	remote_len1,1	 
		RETURN
get_nextbyte9
		CLRF	data0		 
		RETURN





;-----------------------------------------------------------------------------------
;		Parse Have for cgi(GET method) 
;		00b=192.168.0.200
;-----------------------------------------------------------------------------------
parse_cgi
		call	get_nextbyte
		MOVLW	0	 
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	parse9_tag
 
		MOVLW	0AH
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	parse9_tag
 	; Initial value
		MOVLW	'I'
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	initial_values_tag
	 		; Change the pin
		MOVLW	'R'
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	modify_pin
		

		MOVLW	'0'	 
		SUBWF	data0,1
		MOVF	data0,0	 
		MOVWF	wk
		SWAPF	wk,1 
		
		call	get_nextbyte
	 
		MOVLW	0
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	parse9_tag
		
		MOVLW	'0'	 
		SUBWF	data0,1
		MOVF	data0,0	 
		IORWF	wk,1
		
		call	get_nextbyte
	 
		MOVLW	0
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	parse9_tag
		MOVF	data0,0	 
		MOVWF	ind
 	; byte Unit
		MOVLW	'b'
		SUBWF	ind,0
		BTFSC	3,2
		GOTO	parse4
 		; word Unit
		MOVLW	'w'
		SUBWF	ind,0
		BTFSC	3,2
		GOTO	parse4
		goto	parse9_tag				; End if other than b|w 
parse4
		CLRF	wk1  			; Initical value=0
		CLRF	wk2	 
		
		call	get_nextbyte			; skip '='
	 
		MOVLW	0
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	parse9_tag
 
		MOVLW	'&'
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	parse_cgi

parse_cgi0
		call	get_nextbyte
 
		MOVLW	0
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	parse9_tag
 
		MOVLW	' '
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	parse91_tag
	 		MOVLW	9
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	parse91_tag
	 
		MOVLW	'&'
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	parse_cgi2
		
 
		MOVLW	'.'
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	parse_cgi3
 
		MOVLW	','
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	parse_cgi3
 
		MOVLW	'0'
		SUBWF	data0,0
		BTFSS	3,0
		GOTO	parse_cgi3
 
		MOVLW	'9' ^ 0FFH
		ADDWF	data0,0
		BTFSC	3,0
		GOTO	parse_cgi3
		
		call	multiply_added
		goto	parse_cgi0
parse_cgi2
		call	write_eeprom
		goto	parse_cgi
parse_cgi3
		call	write_eeprom
		CLRF	wk1	 
		CLRF	wk2	 
		goto	parse_cgi0
parse91_tag
		call	write_eeprom
parse9_tag
		MOVLW	HIGH (parse9)
		MOVWF	PCLATH

		goto	parse9


;-----------------------------------------------------------------------------------
;		Multiply the data by 10 and add it on
;-----------------------------------------------------------------------------------
multiply_added
		MOVLW	'0'	 	
		SUBWF	data0,1		; Because the data is ASCII character 
		
		BCF	3,0 
		RLF	wk1,1	 
		RLF	wk2,1	 		;
		
		MOVF	wk1,0 	;
		MOVWF	mul10
		MOVF	wk2,0	 
		MOVWF	mul101
		BCF	3,0 
		RLF	wk1,1	 
		RLF	wk2,1	 
		BCF	3,0	 
		RLF	wk1,1	 
		RLF	wk2,1	 
		MOVF	mul10,0	  
		ADDWF	wk1,1
		btfsc	STATUS,C
		INCF	wk2,1	 
		MOVF	mul101,0  
		ADDWF	wk2,1
		MOVF	data0,0	 	; Add
		ADDWF	wk1,1
		btfsc	STATUS,C			; Check CARRY 
		INCF	wk2,1	 
		RETURN



;-----------------------------------------------------------------------------------
;		Return EEPROM data to the initial value  
;-----------------------------------------------------------------------------------
		goto	$	 
initial_values_tag
		call	initial_values
		goto	parse9_tag

initial_values
		MOVLW	default_values_end - default_values_begin
		MOVWF	gcn1
		CLRF	wk	 
initial_values0
		call	get_initial_value
		MOVWF	wk1 
		
		MOVLW	HIGH (write_eeprom0)
		MOVWF	PCLATH

		call	write_eeprom0
		MOVLW	HIGH (initial_values0)
		MOVWF	PCLATH
		
		DECFSZ	gcn1,1	 
		GOTO	initial_values0
		RETURN

;-----------------------------------------------------------------------------------
;		modify pin using cgi 
;		RA0=H
;-----------------------------------------------------------------------------------HAVE
modify_pin
		call	get_nextbyte			; Receive the selection of a port
		MOVLW	'A' ; Error if outside the range
		SUBWF	data0,0
		BTFSS	3,0
		GOTO	parse9_tag
		MOVLW	'B' ^ 0FFH	 
		ADDWF	data0,0
		BTFSC	3,0
		GOTO	parse9_tag
		MOVLW	'A'	 	; Subtract 'A'
		SUBWF	data0,1
		MOVLW	PORTA	 
		ADDWF	data0,1
		MOVF	data0,0
		MOVWF	FSR

		call	get_nextbyte			; Receive byte position
		MOVLW	'0'	 	; Error if outside the range
		SUBWF	data0,0
		BTFSS	3,0
		GOTO	parse9_tag
		MOVLW	'9' ^ 0FFH		 	; 
		ADDWF	data0,0
		BTFSC	3,0
		GOTO	parse9_tag
		MOVLW	'0'		 
		SUBWF	data0,1
		INCF	data0,1		 
		CLRF	wk		 
		BSF	3,0	 
modify_pin0
		RLF	wk,1	 
		DECFSZ	data0,1	 
		GOTO	modify_pin0
		call	get_nextbyte
		MOVLW	'='		 
		SUBWF	data0,0		;; Error if '=' symbol is not added 
		BTFSS	3,2
		GOTO	parse9_tag
		call	get_nextbyte
		MOVLW	'H'	 
		SUBWF	data0,0		; Which is outpoutted High or Low ?
		BTFSC	3,2
		GOTO	modify_pin_h
		COMF	wk,1		 
		MOVF	wk,0		 
		ANDWF	INDF,1		; Output'L' to I/O port
		goto	parse9_tag

modify_pin_h
		MOVF	wk,0	 
		IORWF	INDF,1		;; Output 'H' to I/O port
		goto	parse9_tag


get_initial_value
		MOVLW	1FH	 ; Receive Initial value
		MOVWF	PCLATH
		MOVF	wk,0	 
		MOVWF	PCL




;===================================================================================
;		Startup Routine
;===================================================================================
;		org	0c00h

start

		CLRF	PORTA			;  Initialize each port
		CLRF	PORTB
		clrF	PORTC			; RC =  RTL8019AS SA0-SA5
		clrF	PORTD			; RD = 00h
		MOVLW	B'111'		; Each control port=H
		MOVWF	PORTE
		bsf	STATUS,RP0
		MOVLW	B'10000110'	 
		DB	00,62	 		; Interruption setting
		MOVLW	B'10000010' 
		MOVWF	ADCON1		; RE0-2 are Digital Pin
		MOVLW	B'00111111' 
		MOVWF	TRISA		; RA0-4 is an ADInput pin 
		MOVLW	B'000'	 	; RE0-2 is an Output pin 
		MOVWF	TRISE
		bcf	STATUS,RP0

		CLRF	use	 
				; Clear valid flag for LCD port and serial port 

		call	get_ip_address		; Read IP address of EEPROM onto file register
		call	get_port_no		; Read EEPROM port number onto file register
;
;	Check LCD Port
;	If port is other than 0, rb7-2 is outputted
;
		bsf	STATUS,RP0
		MOVF	lcd_port,0	; Check if LCD port is 0
		iorwf	lcd_port1,0 
		movlw	B'00001111'		; When LCD port is 0,  output RB7-4 Output and input RB3-0
		btfss	STATUS,Z
		movlw	B'00000011'		; When LCD port is not 0, output RB7-2 and input RB1-0
		MOVWF	TRISB	 
		bcf	STATUS,RP0
		
		btfss	STATUS,Z
		bsf	use,0	 
			; If LCD port is not 0, enable use.LCD.


;	Check SERIAL Port

		call	clear_seq_no		; Make the TCP Sequence Number 0
		
		call	init_lcd		; Initiate Liquid Crystal Display Module
		
		MOVLW	B'11' 
		MOVWF	PORTE		; Each Control Port=H
		
		MOVLW	5	 	; Wait 5ms
		MOVWF	wait_cn
		call	wait_ms
		
		bsf	STATUS,RP0
		MOVLW	B'11100000'
		MOVWF	TRISC
		MOVLW	B'11111111' 
		MOVWF	TRISD
		MOVLW	B'000'	 
		MOVWF	TRISE
		bcf	STATUS,RP0
		
		call	init_socket		; Initiate Socket Buffer
		CLRF	PCLATH
		
		call	initialize		; Initiate RTL8019AS
		
		MOVLW	$>>8
		MOVWF	PCLATH
		
		MOVLW	this_ip	 
		MOVWF	FSR
		;mov	FSR,#this_ip		; Check if My IP is 0.0.0.0 
		MOVF	INDF,0
		INCF	FSR,1
		iorwf	INDF,0
		INCF	FSR,1
		iorwf	INDF,0
		INCF	FSR,1
		iorwf	INDF,0
		btfsc	STATUS,Z
		goto	start1			; If IP is 0.0.0.0, go to start1
		
		MOVLW	HIGH (print_ip)	; Show IP address on Liquid Crystal Display
		MOVWF	PCLATH
		call	print_ip
		goto	start2
start1
		MOVLW	HIGH (write_lcd4)
		MOVWF	PCLATH
		
		bsf	PORTB,2
		MOVLW	'D'			; Show 'DHCP'on liquid crystal display
		MOVWF	d4
		call	write_lcd4
		MOVLW	'H'
		MOVWF	d4
		call	write_lcd4
		MOVLW	'C'
		MOVWF	d4
		call	write_lcd4
		MOVLW	'P'
		MOVWF	d4
		call	write_lcd4
		
		MOVLW	$ >> 8
		MOVWF	PCLATH
start2
		bsf	STATUS,RP0
		MOVLW	B'11110000'		; Change rc.4 to Input Bin
		MOVWF	PORTC
		bcf	STATUS,RP0
		
		MOVLW	HIGH (wait_us)
		MOVWF	PCLATH

		MOVLW	.100 	; 100us wait
		MOVWF	wait_cn
		call	wait_us
		
		MOVLW	HIGH (start2)
		MOVWF	PCLATH
		btfss	PORTC,4		 	; Check rc.4 bin
		goto	bootstrap		; If 'L', transfer to bootstrap mode 
		
		bsf	STATUS,RP0
		MOVLW	B'10100000'		; Revert rc
		MOVWF	TRISC
		MOVLW	B'00100110' 
		MOVWF	TXSTA			; Initiate transmission source of ASYNC Module
		MOVLW	BAUD_RATE 
		MOVWF	SPBRG			; Set Baud Rate
		BSF	PIE1,5			; rcie; Allow Reception interruption
		bcf	STATUS,RP0
		MOVLW	B'10000000'	 
		MOVWF	RCSTA			; Initiate reception source of ASYNC module
		bcf	STATUS,RP0
		bcf	INTCON,6	;peie		; Allow peripheral device interruption
		
		CLRF	PCLATH
		
		;mov	dest[0],#assert_wr2x & 0ffh
		;mov	dest[1],#assert_wr2x >>8
		MOVLW	assert_wr2x & 0ffh 
		MOVWF	dest
		MOVLW	HIGH (assert_wr2x) 
		MOVWF	dest1		
		bsf	STATUS,RP0
		CLRF	dhcp_done
		bcf	STATUS,RP0
		CLRF	PORTB			; Initial condition RB=00h
		CLRF	TMR1L
		CLRF	TMR1H
		MOVLW	B'000101'
		MOVWF	T1CON
		BSF	STATUS,RP0

		BSF	PIE1,TMR1IE
		BCF	STATUS,RP0
		BSF	INTCON,PEIE	 
		BSF	INTCON,GIE	 
		BSF	INTCON,GIE		;gie; Allow global interruption
		goto	main
;-----------------------------------------------------------------------------------
;		Clear socket buffer
;-----------------------------------------------------------------------------------
init_socket
		bsf	STATUS,IRP
		MOVLW	skb & 0FFh
		MOVWF	FSR

		MOVLW	SOCKETS * .16	 
		MOVWF	com_cn
init_socket0	clrF	INDF
		INCF	FSR,1
		DECFSZ	com_cn,1	 
		GOTO	init_socket0
;
;		Clear serial address registration
;
;		bsf	STATUS,IRP	; already irp set
		MOVLW	on_ether & 0ffh
		MOVWF	FSR

		MOVLW	SERIAL_PACKET_SIZE - 2	 
		MOVWF	com_cn
init_on_ether0	clrF	INDF
		INCF	FSR,1
		DECFSZ	com_cn,1		 
		GOTO	init_on_ether0
		
		bcf	STATUS,IRP
		RETURN

;-----------------------------------------------------------------------------------
;		If PIC16F877 is EEPROM, get IP address
;-----------------------------------------------------------------------------------
get_ip_address
		bsf	STATUS,RP0
		
		MOVLW	this_ip	 
		MOVWF	FSR
		MOVLW	4		 
		MOVWF	common
		bsf	STATUS,RP1
		bcf	STATUS,RP0
		CLRF	EEADR	 
get_ip_address0
		bsf	STATUS,RP1
		bsf	STATUS,RP0
		bcf	EECON1,7			;eepgd
		BSF	EECON1,0 
		bcf	STATUS,RP0
		MOVF	EEDATA,0	 
		INCF	EEADR,1	 
		bcf	STATUS,RP1
		
		movwf	INDF
		INCF	FSR,1
		DECFSZ	common,1 
		GOTO	get_ip_address0
		
		MOVLW	ident
		MOVWF	FSR
		clrF	INDF
		INCF	FSR,1
		clrF	INDF
		RETURN
;-----------------------------------------------------------------------------------
;		Receive port number from EEPROM of PIC16F877
;-----------------------------------------------------------------------------------
get_port_no
		MOVLW	http_port & 0ffh
		MOVWF	FSR
		MOVLW	.4 * .2	 
		MOVWF	common
		bsf	STATUS,RP1
		bcf	STATUS,RP0
		MOVLW	.16	 
		MOVWF	EEADR
get_port_no0
		bsf	STATUS,RP0
		bcf	EECON1,7	;eepgd
		bsf	EECON1,0 
		bcf	STATUS,RP0
		MOVF	EEDATA,0 
		MOVWF	INDF
		INCF	FSR,1
		INCF	EEADR,1	 
		
		DECFSZ	common,1 
		GOTO	get_port_no0
		bcf	STATUS,RP1
		RETURN
;-----------------------------------------------------------------------------------
;		Initiate TCP Sequence Number
;-----------------------------------------------------------------------------------
clear_seq_no
		bsf	STATUS,RP0
		CLRF	seq_no	 
		CLRF	seq_no1	 
		CLRF	seq_no2	 
		CLRF	seq_no3	 
		bcf	STATUS,RP0
		RETURN


;-----------------------------------------------------------------------------------
;		Initiate Liquid Crystal Display
;-----------------------------------------------------------------------------------HAVE
init_lcd
		MOVLW	.15	 	; wait 15ms
		MOVWF	wait_cn
		call	wait_ms
		
		BCF	PORTB,2			; RS='L'
		MOVLW	B'00110000'
		MOVWF	d8
		call	write_lcd8
		MOVLW	.5		; wait 4.1ms
		MOVWF	wait_cn
		call	wait_ms
		
		MOVLW	B'00110000'
		MOVWF	d8
		call	write_lcd8
		MOVLW	.100		; wait 100us
		MOVWF	wait_cn
		call	wait_us
		
		MOVLW	B'00110000'
		MOVWF	d8
		call	write_lcd8		; 0 0 0011 (3)
		
		MOVLW	B'00100000'
		MOVWF	d8
		call	write_lcd8		; 0 0 0010 (4bit)
	;
		MOVLW	B'00101000'		; duty,font set9
		MOVWF	d4
		call	write_lcd4
		
		MOVLW	B'00000001'		; Clear Command
		MOVWF	d4
		call	write_lcd4
		MOVLW	.2		; Wait to Clear
		MOVWF	wait_cn
		call	wait_ms
		
		MOVLW	B'00000110'		; entry mode set
		MOVWF	d4
		call	write_lcd4
		
		MOVLW	B'00001110'		; display on,cursor on
		MOVWF	d4
		call	write_lcd4
		RETURN



;-----------------------------------------------------------------------------------
;		Writing Routine for 8 bit mode liquid crystal Display
;-----------------------------------------------------------------------------------
write_lcd8
		BTFSS	use,0		;btfss	use.0; If LCD is not on, RB port is not written
		goto	lcd_skip
		
		MOVF	PORTB,0	 
		MOVWF	tmp
		MOVLW	0FH	 
		ANDWF	tmp,1
		MOVLW	0F0H	 
		ANDWF	d8,1
		MOVF	d8,0	 
		IORWF	tmp,1
		MOVF	tmp,0	 	; Output to RB port 
		MOVWF	PORTB

		goto	$+1
		BSF	PORTB,3	 	; E pin becomes  'H'
		GOTO	$+1			;jmp	$+1
		BCF	PORTB,3	 
lcd_skip
		MOVLW	.40
		MOVWF	wait_cn
		call	wait_us
		RETURN




;-----------------------------------------------------------------------------------
;		Writing Routine for 4 bit mode liquid crystal display
;-----------------------------------------------------------------------------------
write_lcd4
		MOVF	d4,0	 
		MOVWF	d8
		call	write_lcd8
		
		MOVF	d4,0	 
		MOVWF	d8
		SWAPF	d8,1	 
		call	write_lcd8
		RETURN

;-----------------------------------------------------------------------------------
;		Output routine for hexadecimal liquid crystal
;-----------------------------------------------------------------------------------
print_hex
		bsf	PORTB,2
		swapf	cd,0
		CLRF	PCLATH
		call	getascii
		MOVWF	d4	 
		call	write_lcd4
	;
		MOVF	cd,0
		CLRF	PCLATH
		call	getascii
		MOVWF	d4	 
		call	write_lcd4
		RETURN


;-----------------------------------------------------------------------------------
;		Wait for ms order 
;-----------------------------------------------------------------------------------
wait_ms
wait_ms0
		MOVLW	0	 
		MOVWF	wait_cn2
wait_ms1	GOTO	$+1	 
		GOTO	$+1 
		GOTO	$+1	 
		GOTO	$+1	 
		GOTO	$+1	 
		GOTO	$+1	 
		GOTO	$+1	 
		DECFSZ	wait_cn2,1 
		GOTO	wait_ms1
		DECFSZ	wait_cn,1 
		GOTO	wait_ms0
		RETURN

;-----------------------------------------------------------------------------------
;		wait for μsorder
;-----------------------------------------------------------------------------------
wait_us
wait_us0
		GOTO	$+1 
	 
		DECFSZ	wait_cn,1
		GOTO	wait_us0
		RETURN


;-----------------------------------------------------------------------------------
;		Decimal conversion routine for 32 binary bits
;-----------------------------------------------------------------------------------
put_decimal32
		MOVF	FSR,0	 
		MOVWF	save_fsr
		MOVLW	decimal_top & 0ffh	;Initiate storage value 
		MOVWF	FSR
		bsf	STATUS,IRP			; IRP=1
		call	divide32		; Modify the lowest
		call	divide32
		call	divide32
		call	divide32
		call	divide32
		
		call	divide32
		call	divide32
		call	divide32
		call	divide32
		call	divide32		; Modify the highest
		
		MOVLW	.10 - .1		;mov	val_cn,#10-1
		MOVWF	val_cn
		goto	put_decimal_ent


;-----------------------------------------------------------------------------------
;		Decimal conversion routine for 16 binary bits
;-----------------------------------------------------------------------------------
put_decimal16
		MOVF	FSR,0 
		MOVWF	save_fsr
		MOVLW	decimal_top & 0ffh	; Initiate storage value
		MOVWF	FSR
		bsf	STATUS,IRP			; IRP=1
		call	divide16		; Modify the lowest
		call	divide16
		call	divide16
		call	divide16
		call	divide16		; Modify the highest
		
		MOVLW	.5 - .1	 
		MOVWF	val_cn
		goto	put_decimal_ent

;-----------------------------------------------------------------------------------
;		Decimal conversion routine in 8 binary bits
;-----------------------------------------------------------------------------------
put_decimal
		movwf	val
		
		MOVF	FSR,0	 
		MOVWF	save_fsr
		MOVLW	decimal_top & 0ffh	; Initiate storage value
		MOVWF	FSR
		bsf	STATUS,IRP			; IRP=1
		call	divide			; Modify the lowest
		call	divide
		call	divide			; Modify the highest
		
		MOVLW	.3 - .1	 
		MOVWF	val_cn
put_decimal_ent	CLRF	val_m	 
put_decimal0
		MOVLW	0	 
		SUBWF	val_m,0
		BTFSS	3,2
		GOTO	put_decimal1
		MOVLW	'0'	 
		SUBWF	INDF,0
		BTFSC	3,2
		GOTO	put_decimal2
put_decimal1	MOVF	INDF,0	 
		MOVWF	data0
		call	puttty
			; Output(Output destination changes with "dest")
		MOVLW	HIGH (put_decimal1)
		MOVWF	PCLATH
		
		INCF	val_m,1	 
put_decimal2	INCF	FSR,1
		DECFSZ	val_cn,1 
		GOTO	put_decimal0
		MOVF	INDF,0	 	; The lowest digit
		MOVWF	data0
		call	puttty			; Output(Output destination changes with "dest")
		MOVLW	HIGH (put_decimal2)
		MOVWF	PCLATH

		bcf	STATUS,IRP
		MOVF	save_fsr,0
		MOVWF	FSR
		RETURN


;-----------------------------------------------------------------------------------
;		8 binary bits are displayed by decimals on the liquid crystal 
;-----------------------------------------------------------------------------------
print_dec
		movwf	val
		
		MOVF	FSR,0	 	; Save fsr
		MOVWF	save_fsr
		MOVLW	decimal_top & 0ffh	; Initiate storage value
		MOVWF	FSR
		bsf	STATUS,IRP			; IRP=1
		call	divide			; Modify the lowest
		call	divide
		call	divide			; Modify the highest
		
		bsf	PORTB,2
		MOVF	INDF,0 
		MOVWF	d4
		call	write_lcd4
		INCF	FSR,1
		MOVF	INDF,0	 
		MOVWF	d4
		call	write_lcd4
		INCF	FSR,1
		MOVF	INDF,0 
		MOVWF	d4
		call	write_lcd4
		
		bcf	STATUS,IRP
		MOVF	save_fsr,0
		MOVWF	FSR
		RETURN






;-----------------------------------------------------------------------------------
;		Subroutine for 8 bit subtraction
;-----------------------------------------------------------------------------------
divide
		MOVLW	8
		MOVWF	gcn1
		CLRF	val_m 
divide0
		BCF	3,0 
		RLF	val,1	 
		RLF	val_m,1	 
		
		movlw	B'11110110'
		addwf	val_m,0
		btfsc	STATUS,C
		MOVWF	val_m	 
		btfsc	STATUS,C
		INCF	val,1 
		
		DECFSZ	gcn1,1
		GOTO	divide0
		decF	FSR,1
		MOVF	val_m,0	 	; Left over 
		MOVWF	INDF
		MOVLW	'0'	 
		ADDWF	INDF,1
		RETURN


;-----------------------------------------------------------------------------------
;		Subroutine for 16 bit subtraction
;-----------------------------------------------------------------------------------
divide16
		MOVLW	.16
		MOVWF	gcn1
		clrF	val_m
divide16_0
		BCF	3,0	 
		RLF	val,1	 
		RLF	val1,1	 
		RLF	val_m,1	 
		
		movlw	B'11110110'
		addwf	val_m,0
		btfsc	STATUS,C
		MOVWF	val_m	 
		btfsc	STATUS,C
		INCF	val,1	 
		
		DECFSZ	gcn1,1	 
		GOTO	divide16_0
		decF	FSR,1
		MOVF	val_m,0 	; Left over
		MOVWF	INDF
		MOVLW	'0'	 
		ADDWF	INDF,1
		RETURN


;-----------------------------------------------------------------------------------
;		Subroutine for 32 bit subtraction
;-----------------------------------------------------------------------------------
divide32
		MOVLW	.32
		MOVWF	gcn1
		CLRF	val_m	 
divide32_0
		BCF	3,0	 
		RLF	val,1	 
		RLF	val1,1	 
		RLF	val2,1	 
		RLF	val3,1		 
		RLF	val_m,1	 
		
		movlw	B'11110110'
		addwf	val_m,0
		btfsc	STATUS,C
		MOVWF	val_m	 
		btfsc	STATUS,C
		INCF	val,1	 
		
		DECFSZ	gcn1,1	 
		GOTO	divide32_0
		decF	FSR,1
		MOVF	val_m,0	 	; left over
		MOVWF	INDF
		MOVLW	'0'	 
		ADDWF	INDF,1
		RETURN

;===================================================================================
;		 Bootstrap main routine
;===================================================================================
get_lcdmes
		MOVLW	lcd_mes >> 8	 
		MOVWF	PCLATH
		MOVF	wk,0 
		MOVWF	PCL
;
;	BOOTSTRAP MODE Entry
;
bootstrap
		MOVLW	$ >> 8	 
		MOVWF	PCLATH
		MOVLW	B'11000000' 
		MOVWF	d4
		bcf	PORTB,2			;RS
		call	write_lcd4		; Move the cursor to the second line

		MOVLW	.16	 
		MOVWF	gcn1
		MOVLW	lcd_mes & 0ffh
		MOVWF	wk
bootstrap10
		call	get_lcdmes		; Show 'Bootstrap Mode'on liquid crystal display
		MOVWF	d4 
		
		MOVLW	$ >> 8	 
		MOVWF	PCLATH

		bsf	PORTB,2		;RS
		call	write_lcd4
		MOVLW	$ >> 8	 
		MOVWF	PCLATH

		
		INCF	wk,1	 
		DECFSZ	gcn1,1
		GOTO	bootstrap10	 
;
;		Initialization of ASYNC
;
		bsf	STATUS,RP0 
		MOVLW	B'10100000' 
		MOVWF	TRISC
		MOVLW	B'00100110'	 	; Set transmission source
		MOVWF	TXSTA
		MOVLW	BAUD_RATE 	; set baud rate
		MOVWF	SPBRG
		BSF	PIE1,RCIE 		; Valid for reception interrupt
		bcf	STATUS,RP0	 
		MOVLW	B'10010000' 
		MOVWF	RCSTA
		MOVLW	async_transmit & 0ffh ;  Set transmission routine
		MOVWF	dest
		MOVLW	async_transmit >> 8  
		MOVWF	dest1
		bsf	INTCON,PEIE	 			; Allow peripheral device interruption 
		bsf	INTCON,GIE 			; Allow (global) interruption

		MOVLW	bs_1 & 00ffh 		; Boot message
		MOVWF	com_cn
		call	put_bs_text
		
		MOVLW	bs_config & 00ffh 
		MOVWF	com_cn			; Show current setting
		call	put_bs_text
		
		MOVLW	bs_prompt & 00ffh 	; Show prompt
		MOVWF	com_cn
		call	put_bs_text
;-----------------------------------------------------------------------------------
;		Bootstrap Main Loop
;-----------------------------------------------------------------------------------
		bsf	STATUS,RP0	 
bootstrap0
 			; Reception standby(Becomes fifo_cn!=0 after reception)
		MOVLW	0
		SUBWF	fifo_cn,0                 
		BTFSC	3,2
		GOTO	bootstrap0		
		MOVF	fifo_poi,0	 
		MOVWF	FSR			; Get reception pointer
		MOVF	INDF,0		 
		MOVWF	data0			; Get received character
		
		incF	fifo_poi,1				;  Increment reception buffer
 
		MOVLW	fifo_bottom
		SUBWF	fifo_poi,0
		BTFSS	3,0
		GOTO	ring1_1
		MOVLW	fifo_top 
		MOVWF	fifo_poi
ring1_1		DECF	fifo_cn,1	 	; decrement the number of received bytes
		
 		; In case for backspace character...
		MOVLW	CH_BACKSPACE
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	boots_bs
		bcf	STATUS,RP0 
		call	async_transmit				; For echo back, transmit!!
		bsf	STATUS,RP0 
		
 			; In case of CR...
		MOVLW	.13
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	boots_cr			
		incF	fifo_line_cn,1
		goto	bootstrap0				; Return to main loop


;-----------------------------------------------------------------------------------
;		Backspace reception process 
;-----------------------------------------------------------------------------------
boots_bs
 				; If there is no character to be deleted, no action is required
		MOVLW	0
		SUBWF	fifo_line_cn,0
		BTFSC	3,2
		GOTO	bootstrap0
		MOVF	fifo_poi,0 
		MOVWF	FSR
		DECF	FSR,1	 
		
 		MOVLW	fifo_top
		SUBWF	FSR,0
		BTFSC	3,0
		GOTO	boots_bs1
		MOVLW	fifo_bottom - 1	 
		MOVWF	FSR
boots_bs1	clrF	INDF	 	;  Clear BS character that was just typed
		
		MOVF	fifo_line,0	 
		MOVWF	FSR
		MOVF	fifo_line_cn,0	 
		ADDWF	FSR,1
		DECF	FSR,1		 
		
	 
		MOVLW	fifo_bottom
		SUBWF	FSR,0
		BTFSS	3,0
		GOTO	boots_bs2
		MOVLW	fifo_top	 
		SUBWF	FSR,1
boots_bs2	clrF	INDF	 	; Clear typed character right before this one
		bcf	STATUS,IRP		 
		
		bcf	STATUS,RP0	 
		call	async_transmit				; For echo back, echo BS character
		MOVLW	' '	 
		MOVWF	data0
		call	async_transmit				; After outputting space
		MOVLW	CH_BACKSPACE 
		MOVWF	data0
		call	async_transmit				; Echo BS again
		bsf	STATUS,RP0 
		
		decF	fifo_line_cn,1
		goto	bootstrap0


;-----------------------------------------------------------------------------------
		 CR reception process
;-----------------------------------------------------------------------------------
boots_cr
		MOVLW	.10	 
		MOVWF	data0
		bcf	STATUS,RP0	 
		call	async_transmit				; Echo the next line
		bsf	STATUS,RP0	 
	 	; Nothing is inputted?
		MOVLW	0
		SUBWF	fifo_line_cn,0
		BTFSS	3,2
		goto	bs_job					; Assign Work
bootstrap9
		bcf	STATUS,RP0		;rp0
		MOVLW	bs_prompt & 00ffh	;mov	com_cn,#bs_prompt & 00ffh
		MOVWF	com_cn			; Show prompt
		call	put_bs_text
		
		bsf	STATUS,RP0	 
		MOVF	fifo_poi,0		 
		MOVWF	fifo_line
		clrF	fifo_line_cn
		goto	bootstrap0				; To main loop

;
;		When invalid command is inputted
;
bootstrap99
		bcf	STATUS,RP0		 
		MOVLW	bs_invalid & 00ffh 
		MOVWF	com_cn
		call	put_bs_text
		goto	bootstrap9



get_bs_str
		MOVLW	1FH		 
		MOVWF	PCLATH
		MOVF	bs_ptr,0	 
		goto	get_bs_job
get_bs_str2
		MOVLW	1FH		 
		MOVWF	PCLATH
		MOVF	bs_ptr2,0	 
		MOVWF	PCL


;-----------------------------------------------------------------------------------
;		Process of Command Analysis 
;-----------------------------------------------------------------------------------
bs_job
		movf	fifo_line,0 
		MOVWF	save_line
		MOVF	fifo_line_cn,0	 
		MOVWF	save_cn
		clrF	bs_ptr
bs_job10
		call	get_bs_str
		MOVWF	bs_ptr2	 
		MOVLW	$ >> 8	 
		MOVWF	PCLATH

		
 				; Not Applicable
		MOVLW	0
		SUBWF	bs_ptr2,0
		BTFSC	3,2
		GOTO	bootstrap99
bs_job0
		call	get_bs_str2
		MOVWF	wk	 
		MOVLW	$ >> 8	 
		MOVWF	PCLATH

	 	; It OKs to the last.
		MOVLW	0
		SUBWF	wk,0
		BTFSC	3,2
		GOTO	bs_job1			
		call	getterm				; Receive 1 character from Buffer
		bsf	STATUS,RP0	 
		
 		MOVLW	.13
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	bs_job2	
 		; Wrong character?
		MOVF	data0,0
		SUBWF	wk,0
		BTFSS	3,2
		GOTO	bs_job2			
		incF	bs_ptr2,1				; Forward 1 character
		goto	bs_job0

bs_job2
		MOVLW	2		 
		ADDWF	bs_ptr,1
		MOVF	save_line,0	 
		MOVWF	fifo_line
		MOVF	save_cn,0	 
		MOVWF	fifo_line_cn
		goto	bs_job10
bs_job1
		incF	bs_ptr,1
		call	get_bs_str
		MOVWF	wk	 
		
		bcf	STATUS,RP0	 
		MOVLW	0EH		 
		MOVWF	PCLATH
		MOVF	wk,0	 
		MOVWF	PCL


;		org	0e00h


;-----------------------------------------------------------------------------------
;		'initialize' Execution Routine
bsj_init
		call	initial_values
bsj_config	MOVLW	bs_config & 00ffh    
		MOVWF	com_cn			; Show current setting

		call	put_bs_text
		goto	bootstrap9
;-----------------------------------------------------------------------------------
;		'help'Execution Routine
bsj_help
		MOVLW	bs_help & 00ffh	 
		MOVWF	com_cn			; Help
		call	put_bs_text
		goto	bootstrap9
;-----------------------------------------------------------------------------------
;		Skip space character
skip_space
		call	getterm
 
		MOVLW	' '
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	skip_space
 
		MOVLW	9
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	skip_space	
		retURN
;-----------------------------------------------------------------------------------
;		'lcd=xxxxx' Execution routine
bsj_lcd
		MOVLW	.16 + .2 
		MOVWF	 wk
		goto	bs_set_word
;-----------------------------------------------------------------------------------
;		'para=xxxxx' Execution Routine
bsj_para
		MOVLW	.16 + .2 + .2
		MOVWF	 wk
;		mov	wk[0],#16+2+2
		goto	bs_set_word
;-----------------------------------------------------------------------------------
;		'serial=xxxxx' Execution Routine
bsj_serial
;		mov	wk[0],#16+2+2+2
		MOVLW	.16 + .2 +.2 + .2
		MOVWF	 wk
		goto	bs_set_word
;-----------------------------------------------------------------------------------
;		'http=xxxxx' Execution Routine
bsj_http
;		mov	wk[0],#16
		MOVLW	.16
		MOVWF	 wk
		
bs_set_word	MOVLW	'w'	 
		MOVWF	ind
		MOVLW	1	 
		MOVWF	byte_cn
		goto	bs_set_common
;-----------------------------------------------------------------------------------
;		'net=xxxxx' Execution Routine
bsj_net
		;mov	wk[0],#4
		MOVLW	4
		MOVWF	wk
		goto	bs_set_byte
;-----------------------------------------------------------------------------------
;		'gate=xxxxx' Execution Routine
bsj_gate
 
		MOVLW	8
		MOVWF	wk
		goto	bs_set_byte
;-----------------------------------------------------------------------------------
;		'ip=xxx.xxx.xxx.xxx' Execution Routine
bsj_ip
 		; EEPROM ADR=0
		MOVLW	0
		MOVWF	wk
		
bs_set_byte 
		MOVLW	'b'
		MOVWF	ind
	 
		MOVLW	4
		MOVWF	byte_cn
		
bs_set_common
		call	skip_space
	 
		MOVLW	.13
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	put_bs_err	
	 
		MOVLW	'='
		SUBWF	data0,0
		BTFSS	3,2
		GOTO	put_bs_err			
		
		call	skip_space
	 
		MOVLW	.13
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	put_bs_err			
		CLRF	wk1		 ; Initial value=0
		CLRF	wk2	 	; Initial value=0
		goto	bs_getnumber
bs_getnumber0
		call	getterm
bs_getnumber
	 				; Abort if CR
		MOVLW	.13
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	bs_write9			
 		MOVLW	'.'
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	bs_write
 		MOVLW	','
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	bs_write
 		MOVLW	'0'
		SUBWF	data0,0
		BTFSS	3,0
		GOTO	bs_write
 		MOVLW	'9' ^ 0FFH
		ADDWF	data0,0
		BTFSC	3,0
		GOTO	bs_write

		call	multiply_added
		goto	bs_getnumber0
bs_write
		call	write_eeprom
		decF	byte_cn,1
 				; Was standard number of bytes written?
		MOVLW	0
		SUBWF	byte_cn,0
		BTFSC	3,2
		GOTO	bootstrap9
		CLRF	wk1		;clr	wk[1]; Initial value=0
		CLRF	wk2		;clr	wk[2]	; Initial value=0

		goto	bs_getnumber0
bs_write9
		call	write_eeprom
		goto	bootstrap9

;-----------------------------------------------------------------------------------
;		1 character read from line buffer(the last character is CR)
;-----------------------------------------------------------------------------------
getterm
		bsf	STATUS,RP0		;rp0
getterm0	MOVF	fifo_line,0		;mov	fsr,fifo_line
		MOVWF	FSR
		MOVF	INDF,0			;mov	data,indirect	
		MOVWF	data0			; Comman analysis
		
		incF	fifo_line,1
 		MOVLW	fifo_bottom
		SUBWF	fifo_line,0
		BTFSS	3,0
		GOTO	getterm1
		MOVLW	fifo_top 
		MOVWF	fifo_line
getterm1	decF	fifo_line_cn,1				; Decrement the number of received bytes 
		
			; Skip the "NULL" character
		MOVLW	0
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	getterm0
		bcf	STATUS,RP0		;rp0
		retURN 

put_bs_err
		MOVLW	bs_err & 00ffh	 
		MOVWF	com_cn			; Show Syntax error 
		call	put_bs_text
		goto	bootstrap9




;-----------------------------------------------------------------------------------
;		Text output routine for the boot strap routine
;-----------------------------------------------------------------------------------
put_bs_text
		bsf	STATUS,RP1
		bcf	STATUS,RP0
		MOVLW	13H	 	; BANK 10h fan
		MOVWF	EEADRH
		MOVF	com_cn,0	 
		MOVWF	EEADR
		bsf	STATUS,RP0
		bsf	EECON1,7	;eepgd
		BSF	EECON1,0 
		nop
		nop
		bcf	STATUS,RP0
		;mov	getmes_wk[0],eedath
		;mov	getmes_wk[1],eedata
		MOVF	EEDATH,0
		MOVWF	getmes_wk
		MOVF	EEDATA,0 
		MOVWF	getmes_wk1
		bcf	STATUS,RP1
		
		RLF	getmes_wk1,0	 
		RLF	getmes_wk,1	 
		MOVF	getmes_wk,0
		andlw	7fh
		btfsc	STATUS,Z
		goto	put_bs_text9
		MOVWF	data0		 
		MOVLW	'$'		 
		SUBWF	data0,0
		BTFSC	3,2
		GOTO	ctrl_code
		call	async_transmit
		
		MOVF	getmes_wk1,0
		andlw	7fh
		btfsc	STATUS,Z
		goto	put_bs_text9
		MOVWF	data0		 
		call	async_transmit
		
		INCF	com_cn,1	 
		goto	put_bs_text
put_bs_text9	RETURN



;-----------------------------------------------------------------------------------
;		232COutput Routine
;-----------------------------------------------------------------------------------
async_transmit
		BTFSS	PIR1,4		;btfss	pir1.4
		goto	async_transmit
		MOVF	data0,0		 
		MOVWF	TXREG
		RETURN


;-----------------------------------------------------------------------------------
;		Control Code Output (step 1) 
;-----------------------------------------------------------------------------------
;		org	0f00h
ctrl_code
		MOVLW	HIGH (ctrl_code1)
		MOVWF	PCLATH
		MOVF	getmes_wk1,0
		andlw	7fh
		addlw	-'0'
		call	ctrl_code1
		INCF	com_cn,1		 
		goto	put_bs_text
		
;		nop	10
ctrl_code1
		ADDWF	2,1	 
		goto	put_mac_address		; 0:MAC Address
		goto	put_ip_address		; 1:IP Address
		goto	put_netmask		; 2:Netmask
		goto	put_gateway_address	; 3:Gateway
		goto	put_http_port		; 4:http Port
		goto	put_lcd_port		; 5:lcd Port
		goto	put_io_port		; 6:parallel Port
		goto	put_232_port		; 7:232c Port
		goto	put_version		; 8:Display the version
		
		goto	put_send_packet		; 9: Number of sent packet
		goto	put_this_ip		; A: Display my IP
		goto	put_ptop		; B:PtoP IP Address

put_send_packet
		MOVLW	ident
		MOVWF	FSR
		MOVF	INDF,0		 
		MOVWF	val1
		INCF	FSR,1
		MOVF	INDF,0		 
		MOVWF	val
		INCF	FSR,1	
		MOVLW	0		 
		MOVWF	val2
		INCF	FSR,1
		MOVLW	0	 
		MOVWF	val3
		goto	put_decimal32		; Display the number of sent packet 

put_http_port
		bsf	STATUS,RP1
		MOVLW	.16		 
		MOVWF	EEADR
		goto	putcom16
put_lcd_port
		bsf	STATUS,RP1
		MOVLW	.16 + .2	 
		MOVWF	EEADR
		goto	putcom16
put_io_port
		bsf	STATUS,RP1
		MOVLW	.16 + .4	 
		MOVWF	EEADR
		goto	putcom16
put_232_port
		bsf	STATUS,RP1
		MOVLW	.16 + .6	 
		MOVWF	EEADR
putcom16	goto	put_number16
	;	RETURN


put_this_ip
		MOVLW	this_ip	 
		MOVWF	FSR
		MOVLW	4
		MOVWF	common
		call	put_number_fr
		RETURN
put_ptop
		bsf	STATUS,RP1
		MOVLW	.24	 
		MOVWF	EEADR
		goto	putcom32
put_ip_address
		bsf	STATUS,RP1
		CLRF	EEADR		 
		goto	putcom32
put_netmask
		bsf	STATUS,RP1
		MOVLW	.4
		MOVWF	EEADR
		goto	putcom32
put_gateway_address
		bsf	STATUS,RP1
		MOVLW	.8
		MOVWF	EEADR
		goto	putcom32
put_version
		bsf	STATUS,RP1
		MOVLW	.12
		MOVWF	EEADR
putcom32	MOVLW	.4	 
		MOVWF	common
		goto	put_number
		RETURN

;-----------------------------------------------------------------------------------  Output to the external port
;		
;-----------------------------------------------------------------------------------
puttty
		MOVF	dest1,0	 
		MOVWF	PCLATH
		MOVF	dest,0	 
		MOVWF	PCL


;-------------------------------------------------------------------------------

;-----------------------------------------------------------------------------------
;		Send socket status to the web browser (Otherwise known as, netstat -n)
;-----------------------------------------------------------------------------------
;put_socket_stat
;		bsf	STATUS,IRP 
;		MOVF	INDF,0	 
;		MOVWF	cd
;		incF	FSR,1		;fsr
;		call	put_hexadecimal
;		MOVF	INDF,0	 
;		MOVWF	cd
;		incF	FSR,1		;fsr
;		call	put_hexadecimal
;		
;		MOVLW	' '	 
;		MOVWF	data0
;		call	puttty
;		MOVLW	$ >> 8	 
;		MOVWF	PCLATH
;		bsf	STATUS,IRP	;irp
;		MOVF	INDF,0	 
;		incF	FSR,1		;fsr
;		call	put_decimal
;		MOVLW	'.'	 
;		MOVWF	data0
;		call	puttty
;		MOVLW	 $ >> 8	 
;;		MOVWF	PCLATH
;		
;		bsf	STATUS,IRP		;irp
;		MOVF	INDF,0		 
;		INCF	FSR,1	 
;		call	put_decimal
;		MOVLW	'.'	 
;		MOVWF	data0
;		call	puttty
;		MOVLW	$ >> 8	 
;		MOVWF	PCLATH
;		
;		bsf	STATUS,IRP
;		MOVF	INDF,0	 
;		INCF	FSR,1		;inc	fsr
;		call	put_decimal
;		MOVLW	'.'	 
;		MOVWF	data0
;		call	puttty
;		MOVLW	$ >>8	 
;		MOVWF	PCLATH
;		bsf	STATUS,IRP	;irp
;		MOVF	INDF,0	 
;		incF	FSR,1
;		call	put_decimal
;		
;;		MOVLW	' '	 
;		MOVWF	data0
;		call	puttty
;		MOVLW	$ >>8	 
;		MOVWF	PCLATH		
;		
;		bsf	STATUS,IRP	;irp
;		MOVF	INDF,0	 
;		MOVWF	val1
;		incF	FSR,1		;fsr
;		MOVF	INDF,0	 
;		MOVWF	val
;		INCF	FSR,1	 
;		call	put_decimal16
;		
;		MOVLW	' ' 
;		MOVWF	data0
;		call	puttty
;		MOVLW	$ >> 8	 
;		MOVWF	PCLATH
;		
;		bsf	STATUS,IRP	;irp
;		MOVF	INDF,0	 
;		MOVWF	val3
;		INCF	FSR,1	 
;		MOVF	INDF,0 
;		MOVWF	val2
;		INCF	FSR,1	 
;		MOVF	INDF,0	 
;		MOVWF	val1
;		INCF	FSR,1	 
;		MOVF	INDF,0	 
;		MOVWF	val
;		INCF	FSR,1	 
;		call	put_decimal32
;		
;		MOVLW	' '	 
;		MOVWF	data0
;		call	puttty
;		MOVLW	$ >>8	 
;		MOVWF	PCLATH
;		
;		bsf	STATUS,IRP	;irp
;		MOVF	INDF,0	 
;		MOVWF	val3
;		INCF	FSR,1	 
 ;		MOVF	INDF,0
;		MOVWF	val2
;		INCF	FSR,1	 
 ;		MOVF	INDF,0
;		MOVWF	val1
;		INCF	FSR,1		 
 ;		MOVF	INDF,0	
;		MOVWF	val
;		goto	put_decimal32
 ;


;-----------------------------------------------------------------------------------
;		With '.' 8 bit decimal value is acquired and displayed from EEPROM
;-----------------------------------------------------------------------------------
put_number0
		MOVLW	'.'	 
		MOVWF	data0
		call	puttty
		MOVLW	$ >> 8
		MOVWF	PCLATH
put_number
		bsf	STATUS,RP1
		bsf	STATUS,RP0
		bcf	EECON1,7	;eepgd
		BSF	EECON1,0 
		bcf	STATUS,RP0
		MOVF	EEDATA,0 
		MOVWF	data0
		INCF	EEADR,1	 
		bcf	STATUS,RP1
		
		MOVF	data0,0
		call	put_decimal
		DECFSZ	common,1 
		GOTO	put_number0
		RETURN


;-----------------------------------------------------------------------------------
;		With '.', 8 bit decimal value is displayed 
;-----------------------------------------------------------------------------------
put_number_fr0
		MOVLW	'.' 
		MOVWF	data0
		call	puttty
		MOVLW	HIGH (put_number_fr0)
		MOVWF	PCLATH
put_number_fr
		MOVF	INDF,0
		INCF	FSR,1
		call	put_decimal
		DECFSZ	common,1 
		GOTO	put_number_fr0
		RETURN


;-----------------------------------------------------------------------------------
;	16 bit value is acquired from EEPROM  and displayed in decimals
;-----------------------------------------------------------------------------------
put_number16
		bsf	STATUS,RP1
		bsf	STATUS,RP0
		bcf	EECON1,7	;eepgd
		BSF	EECON1,0 
		bcf	STATUS,RP0
		MOVF	EEDATA,0 
		INCF	EEADR,1	 
		bcf	STATUS,RP1
		MOVWF	val1	 
		
		bsf	STATUS,RP1
		bsf	STATUS,RP0
		bcf	EECON1,7	;eepgd
		BSF	EECON1,0 
		bcf	STATUS,RP0
		MOVF	EEDATA,0		;mov	w,eedata
		INCF	EEADR,1	 
		bcf	STATUS,RP1
		MOVWF	val 
		
		call	put_decimal16
		RETURN





;-----------------------------------------------------------------------------------
;		Hexadecimal output routine
;-----------------------------------------------------------------------------------
put_hexadecimal
		CLRF	PCLATH
		swapf	cd,0
		call	getascii
		MOVWF	data0	 
		MOVLW	HIGH (puttty)
		MOVWF	PCLATH

		call	puttty
	;	mov	pclath,#$>>8
	;
		CLRF	PCLATH
		MOVF	cd,0
		call	getascii
		MOVWF	data0	 
		MOVLW	HIGH (puttty)
		MOVWF	PCLATH

		call	puttty
		MOVLW	HIGH (put_hexadecimal)
		MOVWF	PCLATH
		RETURN

;-----------------------------------------------------------------------------------
;		Output MAC Address 
;-----------------------------------------------------------------------------------
put_mac_address
		MOVLW	mymac
		MOVWF	FSR
		MOVF	INDF,0	 
		MOVWF	cd
		INCF	FSR,1
		call	put_hexadecimal
		
		MOVLW	'-'	 
		MOVWF	data0
		call	puttty
		MOVLW	HIGH (put_hexadecimal)
		MOVWF	PCLATH
		
		MOVF	INDF,0	 
		MOVWF	cd
		INCF	FSR,1
		call	put_hexadecimal
		
		MOVLW	'-'	 
		MOVWF	data0
		call	puttty
		MOVLW	HIGH (put_hexadecimal)
		MOVWF	PCLATH

		MOVF	INDF,0	 
		MOVWF	cd
		INCF	FSR,1
		call	put_hexadecimal
		
		MOVLW	'-'	 
		MOVWF	data0
		call	puttty
		MOVLW	HIGH (put_hexadecimal)
		MOVWF	PCLATH 
		MOVF	INDF,0	 
		MOVWF	cd
		INCF	FSR,1
		call	put_hexadecimal
		
		MOVLW	'-' 
		MOVWF	data0
		call	puttty
		MOVLW	HIGH (put_hexadecimal)
		MOVWF	PCLATH

		MOVF	INDF,0 
		MOVWF	cd
		INCF	FSR,1
		call	put_hexadecimal
		
		MOVLW	'-' 
		MOVWF	data0
		call	puttty
		MOVLW	HIGH (put_hexadecimal)
		MOVWF	PCLATH

		MOVF	INDF,0	 
		MOVWF	cd
		INCF	FSR,1
		call	put_hexadecimal
		RETURN


;-----------------------------------------------------------------------------------
;		Output IP address onto the liquid crystal display
;-----------------------------------------------------------------------------------
print_ip
		MOVLW	HIGH (print_dec)
		MOVWF	PCLATH

		MOVLW	this_ip	 
		MOVWF	FSR
		
		MOVF	INDF,0
		INCF	FSR,1
		call	print_dec
		
		MOVLW	'.'
		MOVWF	d4
		call	write_lcd4
		
		MOVF	INDF,0
		INCF	FSR,1
		call	print_dec
		
		MOVLW	'.'
		MOVWF	d4
		call	write_lcd4
		
		MOVF	INDF,0
		INCF	FSR,1
		call	print_dec
		
		MOVLW	'.'
		MOVWF	d4
		call	write_lcd4
		
		MOVF	INDF,0
		INCF	FSR,1
		call	print_dec
		RETURN



;-----------------------------------------------------------------------------------
;		Register serial reception data destination
;-----------------------------------------------------------------------------------
		org	1000h

ser_register
		;mov	wk,#SERIAL_PACKET_SIZE-2
		MOVLW	SERIAL_PACKET_SIZE - 2
		MOVWF	wk
		CLRF	wk1	 
		bsf	STATUS,IRP
		MOVLW	on_ether & 0ffh
		MOVWF	FSR
ser_register0
		MOVF	INDF,0	 
		IORWF	wk1,1
		INCF	FSR,1
		DECFSZ	wk,1	 
		GOTO	ser_register0
		bcf	STATUS,IRP

		MOVLW	0 
		SUBWF	wk1,0		; No other action is required if already set,  
		BTFSS	3,2		;Transmit status only
		GOTO	ser_register9
;	Register the destination
		bsf	STATUS,IRP
		MOVLW	on_ip & 0ffh
		MOVWF	FSR
 		
		MOVF	udp_data1,0 
		MOVWF	INDF
		INCF	FSR,1
		MOVF	udp_data2,0 
		MOVWF	INDF
		INCF	FSR,1
		MOVF	udp_data3,0 
		MOVWF	INDF
		INCF	FSR,1
		MOVF	udp_data4,0 
		MOVWF	INDF
		INCF	FSR,1
		
		MOVF	udp_src_port,0 
		MOVWF	INDF
		INCF	FSR,1
		MOVF	udp_src_port1,0 
		MOVWF	INDF
		INCF	FSR,1

		MOVF	udp_data5,0 
		MOVWF	INDF
		bsf	STATUS,RP0
		MOVF	INDF,0 ; Set baud rate
		MOVWF	SPBRG
		bcf	STATUS,RP0
		
		INCF	FSR,1
		MOVF	udp_data6,0 
		MOVWF	INDF
		MOVLW	0
		SUBWF	INDF,0
		BTFSS	3,2
		BSF	INTCON,INTE
		bcf	STATUS,IRP
;
;		Transmit ARP Demand
;
		CLRF	PCLATH				; Important!
		
 		CLRF	remote_adr
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1

		MOVLW	PACKET_SIZE + ARP_SIZE
		MOVWF	remote_len
		CLRF	remote_len1

 		call	remote_write
		
		MOVLW	10h		; Address:Send to "ff-ff-ff-ff-ff-ff"
		MOVWF	PORTC
		movlw	0ffh
		call	assert_wr
		movlw	0ffh
		call	assert_wr
		movlw	0ffh
		call	assert_wr
		movlw	0ffh
		call	assert_wr
		movlw	0ffh
		call	assert_wr
		movlw	0ffh
		call	assert_wr
		
		MOVLW	mymac		; Transmission Source:Set my MAC address 
		MOVWF	FSR
		movlw	6
		call	transmit_nbytes
		
		movlw	COM_PROTO			; 08 Etherframe type
		call	assert_wr
		movlw	ARP_PROTO			; ARP
		call	assert_wr
		
		MOVLW	$ >> 8	
		MOVWF	PCLATH
		call	arp2				; ARP header write
		CLRF	PCLATH				; Important!
		
		clrF	PORTC
		movlw	B'00100010'
		call	assert_wr0
		
		MOVLW	4h
		MOVWF	PORTC
		movlw	PAGE_BEGIN		; transmit page is start page 
		call	assert_wr0
		
		MOVLW	.5
		MOVWF	PORTC
		movlw	.60				; minimum packet = 60
		call	assert_wr0
		
		MOVLW	6
		MOVWF	PORTC
		DB	01,00		;clrw					; adr high
		call	assert_wr0
		call	transmit			; Transmit ARP Response  
ser_register9
		MOVLW	HIGH (ser_get_status)
		MOVWF	PCLATH
		goto	ser_get_status

;-----------------------------------------------------------------------------------
;		Delete registration for serial reception data destination
;-----------------------------------------------------------------------------------
ser_unregister
		bcf	RCSTA,4		;cren
		bcf	INTCON,6	;peie				; Prohibition of use
		
 		MOVLW	SERIAL_PACKET_SIZE - 2
		MOVWF	wk
		CLRF	wk1		;clr	wk[1]
		bsf	STATUS,IRP
		MOVLW	on_ether & 0ffh
		MOVWF	FSR
ser_unregister0
		clrF	INDF
		INCF	FSR,1
		DECFSZ	wk,1	 
		GOTO	ser_unregister0
		bcf	STATUS,IRP
		
		goto	ser_register9





;
;	 Process of DHCP Protocol 
;
dhcp
		BSF	STATUS,RP0
		MOVLW	0FFH
		MOVWF	dhcp_done
		BCF	STATUS,RP0

		MOVLW	HIGH (bootp)
		MOVWF	PCLATH

		call	bootp			; Receive address with DHCP 
		CLRF	PCLATH

		movlw	35h	; 
		call	assert_wr
		movlw	01h
		call	assert_wr
		movlw	1
		call	assert_wr
		
		movlw	3dh	; 
		call	assert_wr
		movlw	07h
		call	assert_wr
		movlw	01h
		call	assert_wr
		MOVLW	mymac
		MOVWF	FSR
		movlw	6
		call	transmit_nbytes			; My MAC
		
		movlw	0ffh
		call	assert_wr
		
		MOVLW	.64 - .7 - .9 - .1
		MOVWF	gcn1
bootp_30
		CLRF	PCLATH
		DB	01,00		;clrw
		call	assert_wr
		
		MOVLW	HIGH (bootp_30)
		MOVWF	PCLATH
		DECFSZ	gcn1,1		;djnz	gcn1,bootp_30
		GOTO	bootp_30
		MOVLW	HIGH (bootp_tx)
		MOVWF	PCLATH

		call	bootp_tx
		RETURN



;-----------------------------------------------------------------------------------
;	Construct ARPHeader
arp1
		CLRF	PCLATH
		
		DB	01,00		;clrw
		call	assert_wr
		movlw	01h			; Ethernet is fixed on 1
		call	assert_wr

		movlw	COM_PROTO
		call	assert_wr
		movlw	IP_PROTO		; Leave this as IP 
		call	assert_wr
		movlw	06h
		call	assert_wr
		movlw	04h
		call	assert_wr
		movlw	00h
		call	assert_wr
		movlw	02h
		call	assert_wr
		movlw	mymac
		movwf	FSR
		movlw	6
		call	transmit_nbytes
		call	transmit_this_ip
		movlw	arp_src_mac
		movwf	FSR
		movlw	.10
		call	transmit_nbytes
		return
arp2	
		clrf	PCLATH
		db	01,00
		call	assert_wr
		movlw	01h
		call	assert_wr
		movlw	COM_PROTO
		call	assert_wr
		movlw	IP_PROTO
		call	assert_wr
		
		movlw	06h			; Number of Ethernet Address=6
		call	assert_wr
		movlw	04h			; Number of IP Address=4
		call	assert_wr

		movlw	00h
		call	assert_wr
		movlw	01h			; ARP Demand(=1)
		call	assert_wr
		
		MOVLW	mymac
		MOVWF	FSR
		movlw	6
		call	transmit_nbytes		;   Transmit my MAC
		call	transmit_this_ip	; transmit my IP
		
		movlw	00h
		call	assert_wr
		movlw	00h
		call	assert_wr
		movlw	00h
		call	assert_wr
		movlw	00h
		call	assert_wr
		movlw	00h
		call	assert_wr
		movlw	00h
		call	assert_wr
		
		bsf	STATUS,IRP
		MOVLW	on_ip & 0ffh
		MOVWF	FSR
check_netid
		MOVLW	HIGH (check_netid)
		MOVWF	PCLATH
		bsf	STATUS,RP1
		bcf	STATUS,RP0
		MOVLW	.4		; address=16
		MOVWF	EEADR
		bcf	STATUS,RP1
		
		call	getnetmask
		bsf	STATUS,RP0
		MOVF	this_ip,0 
		MOVWF	wk1
		MOVF	wk,0	 	; [1] = this
		ANDWF	wk1,1
		MOVF	INDF,0	 	;on_ip[0]
		ANDWF	wk,1
	; [0] = host
		INCF	FSR,1
		MOVF	wk1,0
		SUBWF	wk,0 
		BTFSS	3,2
		GOTO	gateway

		call	getnetmask
		bsf	STATUS,RP0
		MOVF	this_ip1,0
		MOVWF	wk1
		MOVF	wk,0
		ANDWF	wk1,1
		MOVF	INDF,0	 	;on_ip[0]	
		ANDWF	wk,1

		INCF	FSR,1
		MOVF	wk1,0	 
		SUBWF	wk,0
		BTFSS	3,2
		GOTO	gateway
		call	getnetmask
		bsf	STATUS,RP0
		;mov	wk[1],this_ip[2]
		;and	wk[1],wk[0]		; [1] = this
		;and	wk[0],INDF		;on_ip[0]	; [0] = host
		MOVF	this_ip2,0
		MOVWF	wk1
		MOVF	wk,0
		ANDWF	wk1,1
		MOVF	INDF,0
		ANDWF	wk,1
		INCF	FSR,1
		MOVF	wk1,0	 
		SUBWF	wk,0
		BTFSS	3,2
		GOTO	gateway

		call	getnetmask
		bsf	STATUS,RP0
		;mov	wk[1],this_ip[3]
		;and	wk[1],wk[0]		; [1] = this
		;and	wk[0],INDF		;on_ip[0]	; [0] = host
		MOVF	this_ip3,0
		MOVWF	wk1
		MOVF	wk,0
		ANDWF	wk1,1
		MOVF	INDF,0
		ANDWF	wk,1

		MOVF	wk1,0	 
		SUBWF	wk,0
		BTFSS	3,2
		GOTO	gateway

direct
		bcf	STATUS,RP0
		bcf	STATUS,RP1
		CLRF	PCLATH
		MOVLW	on_ip & 0ffh
		MOVWF	FSR
		movlw	4			; Transmit the other party's IP
		call	transmit_nbytes
		
		bcf	STATUS,IRP
		MOVLW	$ >> 8
		MOVWF	PCLATH
		RETURN

gateway
		bsf	STATUS,RP1
		bcf	STATUS,RP0
		MOVLW	.8		; address=16
		MOVWF	EEADR
		bsf	STATUS,RP0
		bcf	STATUS,RP1

		MOVLW	$ >> 8
		MOVWF	PCLATH
		call	getnetmask
		CLRF	PCLATH
		MOVF	wk,0
		call	assert_wr

		MOVLW	$ >> 8
		MOVWF	PCLATH
		call	getnetmask
		CLRF	PCLATH
		MOVF	wk,0
		call	assert_wr

		MOVLW	$ >> 8
		MOVWF	PCLATH
		call	getnetmask
		CLRF	PCLATH
		MOVF	wk,0
		call	assert_wr

		MOVLW	$ >> 8
		MOVWF	PCLATH
		call	getnetmask
		CLRF	PCLATH
		MOVF	wk,0
		call	assert_wr
		
		bcf	STATUS,IRP
		MOVLW	$ >> 8
		MOVWF	PCLATH
		RETURN

getnetmask
		bsf	STATUS,RP1
		bsf	STATUS,RP0
		bcf	EECON1,7	;eepgd
		BSF	EECON1,0		;bsf	eecon1,0
		bcf	STATUS,RP0
		MOVF	EEDATA,0		;mov	wk[0],eedata
		MOVWF	wk
		INCF	EEADR,1		;inc	eeadr
		bcf	STATUS,RP1
		RETURN


;-----------------------------------------------------------------------------------
;		  Transmit 232C data to the host
;-----------------------------------------------------------------------------------
serial_tx
		bsf	STATUS,IRP		;irp
		MOVLW	on_ether & 0ffh	 
		MOVWF	FSR
		bsf	STATUS,RP0		;rp0
		MOVF	INDF,0	 
		MOVWF	eth_src
		INCF	FSR,1	 
		MOVF	INDF,0
		MOVWF	eth_src1
		INCF	FSR,1	 
		MOVF	INDF,0
		MOVWF	eth_src2
		;mov	eth_src[2],INDF
		INCF	FSR,1	 
		MOVF	INDF,0
		MOVWF	eth_src3
		INCF	FSR,1		 
		;mov	eth_src[4],INDF
		MOVF	INDF,0
		MOVWF	eth_src4

		INCF	FSR,1	 
	 
		MOVF	INDF,0
		MOVWF	eth_src5

		INCF	FSR,1	 
		bcf	STATUS,RP0		;rp0
		
		;mov	ip_src[0],INDF
		MOVF	INDF,0
		MOVWF	ip_src
		INCF	FSR,1	 
		;mov	ip_src[1],INDF
		MOVF	INDF,0
		MOVWF	ip_src1

		INCF	FSR,1 
		;mov	ip_src[2],INDF
		MOVF	INDF,0
		MOVWF	ip_src2

		INCF	FSR,1 
		MOVF	INDF,0
		MOVWF	ip_src3

		INCF	FSR,1	 
		bcf	STATUS,IRP		;irp
;
;	Do preparation    
;
		bsf	STATUS,RP0		;rp0
		MOVF	fifo_cn,0 
		movwf	wk
;skip1
		bcf	STATUS,RP0		;rp0
		
		MOVLW	0	 
		MOVWF	ip_length
		MOVLW	IP_SIZE + UDP_SIZE 
		MOVWF	ip_length1
		MOVF	wk,0	 
		ADDWF	ip_length1,1		; Byte size of transmission
		MOVLW	SERIAL_PACKET_SIZE    ; Common Header Size
		ADDWF	ip_length1,1
		CLRF	PCLATH	 
		
		MOVLW	UDP_PROTO	 
		MOVWF	proto			; UDP packet
		call	prepare_ip			; Prepare up until IP packet 
		
		call	clear_sum			; Clear checksum value
		
 		MOVLW	PACKET_SIZE+IP_SIZE
		MOVWF	remote_adr
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1
		
		;mov	remote_len[0],#UDP_SIZE
		MOVLW	UDP_SIZE
		MOVWF	remote_len

 		MOVLW	SERIAL_PACKET_SIZE
		ADDWF	remote_len,1
		MOVF	wk,0
		ADDWF	remote_len,1
		MOVLW	0	 
		MOVWF	remote_len1
		call	remote_write
		
		
		MOVLW	10H	 
		MOVWF	PORTC
	
		MOVLW	serial_port	 
		MOVWF	FSR
		MOVF	INDF,0	 		; From PORT #(HIGH)
		call	assert_wr
		INCF	FSR,1	 
		MOVF	INDF,0	 			; From PORT #(LOW)
		call	assert_wr
		
		bsf	STATUS,IRP	;irp
		MOVLW	on_port & 0ffh 
		MOVWF	FSR			; To Port#
		MOVF	INDF,0	 
		call	assert_wr
		INCF	FSR,1	 
		MOVF	INDF,0	 
		call	assert_wr
		bcf	STATUS,IRP	;irp
		
		movlw	0
		call	assert_wr
		movlw	UDP_SIZE+SERIAL_PACKET_SIZE
		ADDWF	wk,0 
		call	assert_wr
		
		call	assert_wr2times

		movlw	4
		call	assert_wr
		MOVF	wk,0 
		addlw	SERIAL_PACKET_SIZE
		call	assert_wr			; sum(not fixed)
;
;		Status part
		bsf	STATUS,IRP	;irp
		MOVLW	on_ether & 0ffh	 
		MOVWF	FSR
		movlw	SERIAL_PACKET_SIZE - 2
		call	transmit_nbytes
		bcf	STATUS,IRP	;irp
;
;		Transmission
serial_tx0
		MOVLW	$ >> 8	 
		MOVWF	PCLATH
		bsf	STATUS,RP0		;rp0
		MOVF	fifo_poi,0 
		MOVWF	FSR		;; Reception Pointer(GET)
		MOVF	INDF,0	 
		MOVWF	data0		;  Acquire received character
		
		incF	fifo_poi,1			; Increment Reception Buffer
 		MOVLW	fifo_bottom
		SUBWF	fifo_poi,0
		BTFSS	3,0
		GOTO	tx100
		MOVLW	fifo_top 
		MOVWF	fifo_poi
tx100		decF	fifo_cn,1				;   Decrement the number of bytes received
		bcf	STATUS,RP0		;rp0
		
		clrF	PCLATH
		MOVF	data0,0	 
		call	assert_wr
		
		MOVLW	$ >> 8	 
		MOVWF	PCLATH
 		DECFSZ	wk,1
		GOTO	serial_tx0
		bcf	PORTB,1

;
;	  UDP sum calculation and transmission
		MOVLW	calc_udp_sum >> 8 
		MOVWF	PCLATH
		call	calc_udp_sum
		
		clrF	PCLATH		;pclc,#4hath
		MOVLW	4		 
		MOVWF	PORTC
		movlw	PAGE_BEGIN 
		call	assert_wr0

		MOVLW	PACKET_SIZE 
		ADDWF	ip_length1,1	; Packet size 6+6+2 is added to the number of bytes transmitted 
		movlw	1
		btfsc	STATUS,C 
		ADDWF	ip_length,1 
		
		MOVLW	6	 
		MOVWF	PORTC
		MOVF	ip_length,0 	; HIGH
		call	assert_wr0
		
		MOVLW	$ >> 8	 
		MOVWF	PCLATH
		MOVF	ip_length,1 
		btfsc	STATUS,Z 
		goto	serial_tx1
serial_tx2
		clrF	PCLATH	 
		MOVLW	5	 
		MOVWF	PORTC
		MOVF	ip_length1,0 
		call	assert_wr0
		call	transmit			; Transmit!!
		
		clrF	PCLATH		;pclath
		goto	main0
serial_tx1
 		MOVLW	.60	
		SUBWF	ip_length1,0
		BTFSC	3,0
		GOTO	serial_tx2

		CLRF	PCLATH	 
		MOVLW	5	 
		MOVWF	PORTC
		movlw	.60				; MINIMUM 60bytes
		call	assert_wr0
		call	transmit
		
		CLRF	PCLATH	 
		goto	main0
udp_lcd9
		clrf	PCLATH
		GOTO	main9
;-------------------------------------------------------------------------------;  Output characters onto the liquid crystal display
;-------------------------------------------------------------------------------
udp_lcd
		MOVF	udp_length,0
		movwf	remote_len1
		movf	udp_length1,0
		movwf	remote_len
		movlw	8
		subwf	remote_len,1
		btfss	STATUS,C
		
		decF	remote_len1,1
		MOVLW	get_dgram >> 8
		movwf	PCLATH
		CALL	get_dgram
		MOVLW	$ >> 8
		MOVWF	PCLATH
		BTFSC	STATUS,C
		GOTO	udp_lcd9
		
		MOVLW	1
		SUBWF	data0,0
		BTFSS	3,2
		GOTO	udp_lcd_0
		MOVLW	get_dgram >>8
		MOVWF	PCLATH
		CALL	get_dgram
		MOVLW	$ >> 8
		MOVWF	PCLATH
		BTFSC	STATUS,C
		GOTO	udp_lcd9

		MOVF	PORTB,0
		MOVWF	wk
		BCF	PORTB,2
		MOVF	data0,0
		MOVWF	d4
		
		MOVLW	write_lcd4 >> 8
		MOVWF	PCLATH
		CALL	write_lcd4
		MOVLW	$ >> 8
		MOVWF	PCLATH
		
		MOVF	wk,0
		MOVWF	PORTB
		MOVLW	B'11111100'
		ANDWF	d4,1
		BTFSS	STATUS,Z
		GOTO	udp_lcd_0
		
		MOVLW	2
		MOVWF	wait_cn
		MOVLW	wait_ms >> 8
		MOVWF	PCLATH
		CALL	wait_ms
		MOVLW	$ >> 8
		MOVWF	PCLATH
udp_lcd_0
		MOVLW	get_dgram >> 8
		MOVWF	PCLATH
		CALL	get_dgram
		MOVLW	$ >> 8
		MOVWF	PCLATH
		BTFSC	STATUS,C
		GOTO	udp_lcd91
		MOVF	PORTB,0
		MOVWF	wk
		BSF	PORTB,2
		MOVF	data0,0
		MOVWF	d4
		MOVLW	write_lcd4 >> 8
		MOVWF	PCLATH
		CALL	write_lcd4
		MOVLW	$ >> 8
		MOVWF	PCLATH
		MOVF	wk,0
		MOVWF	PORTB

		GOTO	udp_lcd_0
udp_lcd91
		MOVLW	lcd_port
		MOVWF	wk2
		MOVLW	para_get_status >> 8
		MOVWF	PCLATH
		GOTO	common_get_status


;-----------------------------------------------------------------------------------
;		 Boot Strap Mode Message
;-----------------------------------------------------------------------------------
		org	1300h
lcd_mes		DT	"Bootstrap Mode  "
bs_1		DB	06,8A,06,8A		;.13,.10,.13,.10,
		DA	"PIC Network Interface Card - Bootstrap Mode Version $8"
		DB	06,8A		;,.13,.10
		DB	0,0
bs_prompt	DA	"PICNIC>"
bs_config	DA	"***** Configuration ***** "
		DB	06,8A		;,.13,.10
		DA	"MAC Addr.  :$0"
		DB	06,8A		;,.13,.10
		DA	"[I]P Addr. :$1"
		DB	06,8A		;,.13,.10
		DA	"[N]etMask  :$2"
		DB	06,8A		;.13,.10
		DA	"[G]ateWay  :$3"
		DB	06,8A		;,.13,.10
		DA	"[H]ttpPort     #$4"
		DB	06,8A		;,.13,.10
		DA	"[L]CD Port     #$5"
		DB	06,8A		;,.13,.10
		DA	"[P]arallelPort #$6"
		DB	06,8A		;,.13,.10
		DA	"[S]erialPort   #$7"
		DB	06,8A		;,.13,.10
		DB	0,0
bs_err		DA	"Syntax Error"
		DB	17,0D,05,00		;(,and 13),(10,0)
bs_invalid	DA	"Invalid Command."
		DB	06,8A,00,00		;,.13,.10,0,0
bs_help
		DA	"***** Bootstrap Mode Help ***** "
		DB	06,8A		;,.13,.10
		DA	"config         - Print Board Configuration and Status."
		DB	06,8A		;,.13,.10
		DA	"{str}={value}  - Update System Configuration. "
		DB	06,8A		;,.13,.10
		DA	"initialize     - All registers set Initial Values."
		DB	06,8A		;,.13,.10
		DB	0,0


;-----------------------------------------------------------------------------------
;		 Message for Web Browser 
;-----------------------------------------------------------------------------------

		org	1400h
		DA	"HTTP/1.0 200 O"
		DB	25,8D		;'K',13
		DB	05,43		;10,C 
		DA	"onnection: close"
		DB	06,8A		;, .13, .10, 
		DA	"Content-type: text/htm"
		DB	36,0D,05,0D,05,3C		;'l', .13, .10, .13, .10, '<'
		DA	"HTML><HEAD><TITLE>PIC Network Interface Card</TITLE></HEAD><BODY"
		DB	1F,0A			;'>',.10
		DA	"<FONT SIZE=+2>PIC Network Interface Card Version  $8 </FONT>"
		DA	"<HR>"

		DA	"<h3>I/O Ports</h3>"
		DA	"<DL><DD><FORM ACTION=\"modify.cgi\" METHOD=\"GET\""
		DB	1F,0A		;'>',10
		DA	"<TABLE BORDER>"
		DA	"<TR><TD>Port</TD><TD>Value</TD></TR>"
		
		DA	"<TR><TD>RA0 "
		DB	12,80		;"%",0000_0000b,
		DA	" </TD>"
		DA	"<TD ALIGN=\"right\">"
		DB	20,00		;'@",00000000b,
		DA	"</TD></TR>"
		
		DA	"<TR><TD>RA1 "
		DB	12,81		;"%",0000_0001b,
		DA	" </TD>"
		DA	"<TD ALIGN=\"right\">"
		DB	20,01		;@",00000001b,
		DA	"</TD></TR>"
		
		DA	"<TR><TD>RA2 "
		DB	12,82		;%",0000_0010b,
		DA	" </TD>"
		DA	"<TD ALIGN=\"right\">"
		DB	20,02		;@",00000010b,
		DA	"</TD></TR>"
		
		DA	"<TR><TD>RA3 "
		DB	12,83		;%",0000_0011b,
		DA	" </TD>"
		DA	"<TD ALIGN=\"right\">"
		DB	20,03		;"@",00000011b,
		DA	"</TD></TR>"
		
		DA	"<TR><TD>RA5 "
		DB	12,84		;%",0000_0100b,
		DA	" </TD>"
		DA	"<TD ALIGN=\"right\">"
		DB	20,04		;@",00000100b,
		DA	" Celsius</TD></TR>"
		DB	0,0


		org	01700h
		DA	"<TR><TD>RB0 "
		DB	12,90		;%",0001_0000b,
		DA	" </TD>"
		DA	"<TD><INPUT TYPE=\"submit\" NAME=\"RB0\" VALUE=\"H\">"
		DB	20,10		;'@',0001_0000b,
		DA	"<INPUT TYPE=\"submit\" NAME=\"RB0\" VALUE=\"L\"></TD></TR>"
		DA	"<TR><TD>RB1 "
		DB	12,91		;%",0001_0001b,
		DA	" </TD>"
		DA	"<TD><INPUT TYPE=\"submit\" NAME=\"RB1\" VALUE=\"H\">"
		DB	20,11		;'@',0001_0001b,
		DA	"<INPUT TYPE=\"submit\" NAME=\"RB1\" VALUE=\"L\"></TD></TR>"
		DA	"<TR><TD>RB2 "
		DB	12,92		;%",0001_0010b,
		DA	" </TD>"
		DA	"<TD><INPUT TYPE=\"submit\" NAME=\"RB2\" VALUE=\"H\">"
		DB	20,12		;'@',0001_0010b,
		DA	"<INPUT TYPE=\"submit\" NAME=\"RB2\" VALUE=\"L\"></TD></TR>"
		DA	"<TR><TD>RB3 "
		DB	12,93		;%",0001_0011b,
		DA	" </TD>"
		DA	"<TD><INPUT TYPE=\"submit\" NAME=\"RB3\" VALUE=\"H\">"
		DB	20,13		;'@',0001_0011b,
		DA	"<INPUT TYPE=\"submit\" NAME=\"RB3\" VALUE=\"L\"></TD></TR>"
		
		
		DA	"<TR><TD>RB4 "
		DB	12,94		;%",0001_0100b,
		DA	" </TD>"
		DA	"<TD><INPUT TYPE=\"submit\" NAME=\"RB4\" VALUE=\"H\">"
		DB	20,14		;'@',0001_0100b,
		DA	"<INPUT TYPE=\"submit\" NAME=\"RB4\" VALUE=\"L\"></TD></TR>"
		DA	"<TR><TD>RB5 "
		DB	12,95		;%",0001_0101b,
		DA	" </TD>"
		DA	"<TD><INPUT TYPE=\"submit\" NAME=\"RB5\" VALUE=\"H\">"
		DB	20,15		;'@',0001_0101b,
		DA	"<INPUT TYPE=\"submit\" NAME=\"RB5\" VALUE=\"L\"></TD></TR>"
		DA	"<TR><TD>RB6 "
		DB	12,96		;%",0001_0110b,
		DA	" </TD>"
		DA	"<TD><INPUT TYPE=\"submit\" NAME=\"RB6\" VALUE=\"H\">"
		DB	20,16		;'@',0001_0110b,
		DA	"<INPUT TYPE=\"submit\" NAME=\"RB6\" VALUE=\"L\"></TD></TR>"
		DA	"<TR><TD>RB7 "
		DB	12,97		;%",0001_0111b,
		DA	" </TD>"
		DA	"<TD><INPUT TYPE=\"submit\" NAME=\"RB7\" VALUE=\"H\">"
		DB	20,17		;'@',0001_0111b,
		DA	"<INPUT TYPE=\"submit\" NAME=\"RB7\" VALUE=\"L\"></TD></TR>"
		DA	"<TR><TD> </TD>"
		DA	"<TD><INPUT TYPE=\"submit\" VALUE=\"Reload\"></TD></TR>"
		DA	"</TABLE>"
		DA	"</FORM></DL>"
		db	0,0
		
		org	1A00h
		DA	"<FORM METHOD=\"GET\" ACTION=\"submit.cgi\""
		DB	1F,0A	;>",10
		DA	"<h3>Configuration</h3>"

		DA	"<DL><DD><TABLE BORDER>"
		
		DA	"<TR><TD>MAC Address</TD>"
		DA	"<TD>$0</TD></TR>"
		
		DA	"<TR><TD>IP Addr</TD>"
		DA	"<TD><INPUT TYPE=\"text\" NAME=\"00b\"  VALUE=\""
		DA	"$1\"></TD></TR>"
		
		DA	"<TR><TD>NetMask</TD>"
		DA	"<TD><INPUT TYPE=\"text\" NAME=\"04b\"  VALUE=\""
		DA	"$2\"></TD></TR>"
		
		DA	"<TR><TD>GateWay</TD>"
		DA	"<TD><INPUT TYPE=\"text\" NAME=\"08b\"  VALUE=\""
		DA	"$3\"></TD></TR>"
		
;		DA	"<TR><TD>RS232C Conv</TD>"
;		DA	"<TD><INPUT TYPE=\"text\" NAME=\"18b\"  VALUE=\""
;		DA	'$','9'+2,""></TD></TR>"
		
		DA	"<TR><TD>http Port TCP:#</TD>"
		DA	"<TD><INPUT TYPE=\"text\" NAME=\"10w\"  VALUE=\""
		DA	"$4\"></TD></TR>"
		
		DA	"<TR><TD>LCD  Port UDP:#</TD>"
		DA	"<TD><INPUT TYPE=\"text\" NAME=\"12w\"  VALUE=\""
		DA	"$5\"></TD></TR>"
		
		DA	"<TR><TD>Parallel Port UDP:#</TD>"
		DA	"<TD><INPUT TYPE=\"text\" NAME=\"14w\"  VALUE=\""
		DA	"$6\"></TD></TR>"
		
		DA	"<TR><TD>Serial Port UDP:#</TD>"
		DA	"<TD><INPUT TYPE=\"text\" NAME=\"16w\"  VALUE=\""
		DA	"$7\"></TD></TR>"
		DA	"<TR><TD> </TD>"
		DA	"<TD><INPUT TYPE=\"submit\" VALUE=\"Save\">"
		DA	"<INPUT TYPE=\"submit\" NAME=\"INIT\" VALUE=\"Default\" ></TD></TR>"
		DA	"</TABLE>"
		DA	"</FORM></DL>"
		db	0,0
		
		
		org	1D00h
		
		DA	"<h3>Status </h3>"
		DA	"<DL><DD><TABLE BORDER>"
		DA	"<TR><TD>Sent Packets </TD>"
		DA	"<TD>$9</TD></TR>"
		DA	"<TR><TD>This IP</TD>"
		DA	"<TD>"
		DB	12,3A		;$",'9'+1, 
		DA	"</TD></TR>"
;		DA	"<TR><TD>Socket #1</TD>"
;		DA	"<TD>"
;		DB	3F,0A		;~",0ah,
;		DA	"</TD></TR>"
;		DA	"<TR><TD>Socket #2</TD>"
;		DA	"<TD>"
;		DB	3F,0B		;~",0bh,
;		DA	"</TD></TR>"
;		DA	"<TR><TD>Socket #3</TD>"
;		DA	"<TD>"
;		DB	3F,0C	;~",0ch,
;		DA	"</TD></TR>"
;		DA	"<TR><TD>Socket #4</TD>"
;		DA	"<TD>"
;		DB	3F,0D		;~",0dh,
;		DA	"</TD></TR>"
;		DA	"<TR><TD>Socket #5</TD>"
;		DA	"<TD>"
;		DB	3F,0E		;~",0eh,
;		DA	"</TD></TR>"
		DA	"</TABLE></DL> "
		
		DA	"<P><HR>Copyright (c) 2000-2001 by <A HREF=\"http://www.tristate.ne.jp\">TriState Co.,Ltd.</A> "
		DA	"<BR>Firmware Modified by <A HREF=\"http://sugsi.jp/\">Nagano TARO (02TA699X)</A> "
		DB	06,8A		;,13,10
		DA	"</BODY></HTML>"
		db	0,0




;-----------------------------------------------------------------------------------
;		Initial value of EEPROM data 
;-----------------------------------------------------------------------------------
		org	1F00h
default_values_begin
		DT	.192,.168,0,.200
		DT	.255,.255,.255,0
		DT	0,0,0,0
		DT	1,2,0,1		; Farmware Version x,x,x,x
		
		DT	HTTP_PORT / .256,HTTP_PORT & .255				; HTTP port number
		DT	LCD_PORT / .256,LCD_PORT & .255				; LCD port number
		DT	PARALLEL_PORT / .256,PARALLEL_PORT & .255			; PARALLEL port number
		DT	SERIAL_PORT / .256,SERIAL_PORT & .255			; SERIAL Port Number
default_values_end

getadtable
		bsf	STATUS,RP0		;rp0
		MOVF	ADCON1,0		;adcon1,0
		bcf	STATUS,RP0
		andlw	0fh
		ADDWF	2,1		;jmp	pc+w
		retLw	B'11111111'
		retLw	B'11111111'
		retLw	B'00011111'
		retLw	B'00011111'
		retLw	B'00001011'
		retLw	B'00000011'
		retLw	B'00000000'
		retLw	B'00000000'
		retLw	B'11110011'
		retLw	B'00111111'
		retLw	B'00110111'
		retLw	B'00110011'
		retLw	B'00010011'
		retLw	B'00000011'
		retLw	B'00000001'
		retLw	B'00000001'


mes_low		DT	" Low  ",0
mes_high	DT	" High ",0
mes_in		DT	"In ",0
mes_out		DT	"Out",0

;-----------------------------------------------------------------------------------
;		For Command Parse of the boot strap mode
;-----------------------------------------------------------------------------------
get_bs_job
		ADDWF	2,1		;jmp	pc+w
		DT	str_init & 0ffh,	bsj_init & 0ffh
		DT	str_init2 & 0ffh,	bsj_init & 0ffh
		
		DT	str_config & 0ffh,	bsj_config & 0ffh
		DT	str_config2 & 0ffh,	bsj_config & 0ffh
		
		DT	str_help & 0ffh,	bsj_help & 0ffh
		DT	str_help2 & 0ffh,	bsj_help & 0ffh
		
		DT	str_ip & 0ffh,		bsj_ip & 0ffh
		DT	str_ip2 & 0ffh,		bsj_ip & 0ffh
		
		DT	str_net & 0ffh,		bsj_net & 0ffh
		DT	str_net2 & 0ffh,	bsj_net & 0ffh
		
		DT	str_gate & 0ffh,	bsj_gate & 0ffh
		DT	str_gate2 & 0ffh,	bsj_gate & 0ffh
		
		DT	str_http & 0ffh,	bsj_http & 0ffh
		DT	str_http2 & 0ffh,	bsj_http & 0ffh

		DT	str_lcd & 0ffh,		bsj_lcd & 0ffh
		DT	str_lcd2 & 0ffh,	bsj_lcd & 0ffh

		DT	str_para & 0ffh,	bsj_para & 0ffh
		DT	str_para2 & 0ffh,	bsj_para & 0ffh

		DT	str_serial & 0ffh,	bsj_serial & 0ffh
		DT	str_serial2 & 0ffh,	bsj_serial & 0ffh

		DT	0,0		; Terminator


str_config	DT	"config",0
str_config2	DT	"ls",0

str_init	DT	"initialize",0
str_init2	DT	"init",0

str_help	DT	"help",0
str_help2	DT	'?',0

str_ip		DT	"ip",0
str_ip2		DT	'i',0

str_net		DT	"net",0
str_net2	DT	"n",0

str_gate	DT	"gate",0
str_gate2	DT	'g',0

str_http	DT	"http",0
str_http2	DT	'h',0

str_lcd		DT	"lcd",0
str_lcd2	DT	'l',0

str_para	DT	"parallel",0
str_para2	DT	'p',0

str_serial	DT	"serial",0
str_serial2	DT	's',0



		end



