;------------------------------------------------------------------------------
; PICNIC Wake-On-LAN Plus
;------------------------------------------------------------------------------
; バージョン履歴
;
;	1-SEP-2002	Version 1.2.0.0 ベースバージョン
;	2009/10/03	Ver.1.2.0.1 削除されたソケット表示の残骸を削除、Web出力文字列の置き場所を最適化
;	2009/10/03	Ver.1.2.0.2 Wake On LAN用のMACアドレス入力と起動ボタンの作成、ゼロ判定をMOVFに置き換え、ゼロ代入をCLRFに置き換え
;	2009/10/03	Ver.1.2.0.4 マジックパケット分岐まで完成
;	2009/10/04	Ver.1.2.0.5 とりあえず完成。自分のMACアドレスにマジックパケットを送ると応答がなくなるが修正しない。
;	2009/10/07	Ver.1.3.0.0 MACアドレスを16進数で入力できるようにした。
;	2011/01/23	Ver.1.3.0.1 画面レイアウトの変更、Wake on LAN にいらない表示を削除
;	2011/05/29	Ver.1.4.0.0 URLのファイル名をpicnic.cgiに統一。デフォルト値のデータアドレスが正しく設定されていなかった。
;	2011/05/30	Ver.1.4.0.1 URLに@と?が含まれているかどうかで、表示させるページを切り替えるようにした。制限ページでは60秒ごとにリロードする。
;	2011/05/30	Ver.1.4.0.2 @のモードをファイル名の照合に変更した。
;	2011/05/31	Ver.1.4.0.3 ブラウザがキャッシュを行わないようにMETAタグを入れた。
;	2011/06/04	Ver.1.4.1.0 URLに特定のファイル名が含まれているかどうかで3つの画面を切り替えるようにした。@は廃止。1.4.0.0からの総括。
;	2011/06/17	Ver.1.4.1.1 URLチェックで、従来はpicnic.htmlをセットするとppiiccnniicc.htmlのように文字の出現だけ見ていたが、連続してpicnic.htmlで判定するようにした。
;				    ただし、picnic.htmlをセットした場合、ppicnic.htmlは反応しないが、pppicnic.htmlは反応する。
;				    GETコマンド以降のスペースを混ぜて「 /picnic.html」とすると事実上フルパスでチェックがかかる。
;	2011/06/17	Ver.1.4.1.2 htmlメッセージを変更、制限ステータスにシャットダウン信号を表示
;	2011/06/18	Ver.1.4.2.0 estab1で3つの表示モードの判定のみを行い、EEPROMの80h～8Bhで実際に表示する画面の定義を作った。これでプログラムを書き換えなくても画面の構成を変更できる。
;				    ただし、操作画面と設定画面の変更はform actionのURLをプログラム側で変えないといけない。
;				    EEPROMの変更はPICライタを使っても良いし、config.html?80h=aa.bb.cc.dd.ee.ffで6バイトづつ書き込むか、80w=aaで1バイトづつ書き込んでも良い。
;	2011/09/10	Ver.1.4.2.1 表示を消していたRB6,RB7ボタン、パラレルポートの設定を復活。画面構成を変更。
;	2011/09/10	Ver.1.4.3.0 プログラムの配置変更。1E00hエリアが空く。
;	2014/01/21	Ver.1.4.4.0 マジックパケットを送信する時、Ethernetフレームにカプセル化するのを忘れていた。
;
;
; テキストテーブルについて
;	プログラム中にテキストテーブルが埋め込んであり、プログラムEEPROM読み出しを使ってダイレクトにデータを取得している。
;	データ配置は100Hバイトの境界で0バイト目から始まらなければならない。
;	0800H		htmlブランクメッセージ
;	1300H		ブートストラップモード・メッセージ
;	1400H-14FFH	httpレスポンス・ヘッダ リロードあり 制限画面用
;	1500H-16FFH	制限画面本文・フッタ
;	1700H-17FFH	httpレスポンス・ヘッダ リロードなし 操作・設定画面用
;	1800H-19FFH	操作画面本文 Part1
;	1A00H-1AFFH	操作画面本文 Part2
;	1B00H-1CFFH	設定画面本文
;	1D00H-1DFFH	ステータス表示・フッタ
;	1E00H		未使用
;	1F00H		EEPROMデータ初期値
;
;------------------------------------------------------------------------------
; デバイス	PIC16F877
;------------------------------------------------------------------------------
	LIST		P=PIC16F877,R=HEX,N=0
	INCLUDE		"P16F877.INC"
	ERRORLEVEL	0,-302,-306,-307
	__CONFIG	_CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _LVP_OFF & _WRT_ENABLE_OFF

;-----------------------------------------------------------------------------------
HTTP_PORT		EQU	.80			; HTTPポート番号(80=デフォルト)
LCD_PORT		EQU	.0			; LCDコントロール用ポート番号(0=未使用)10000=デフォルト
PARALLEL_PORT		EQU	.10001			; パラレル用ポート番号(0=未使用)10001=デフォルト
SERIAL_PORT		EQU	.0			; シリアル用ポート番号(0=未使用)10002=デフォルト

BOOTPC_PORT		EQU	.68			; BOOTPポート番号(クライアント)
BOOTPS_PORT		EQU	.67			; BOOTPポート番号(サーバ)

BAUD_RATE		EQU	.129	;10		; リセット時のRS232Cボーレート
							; 129=9600bps
							; 10=115200bps

PARALLEL_PACKET_SIZE	EQU	.8			; パラレル転送パケットサイズ
SERIAL_PACKET_SIZE	EQU	(.2 + .6 + .4 + .2 + .1 + .1)		; シリアルステータスパケットのサイズ
							; type:mac:ip:port:baud:flow
CH_BACKSPACE		EQU	.8			; バックスペースの文字コード
SOCKETS			EQU	.4			; ソケット総数(変更不可)


;-----------------------------------------------------------------------------------

		ORG	0x2100
		
		DE	.192, .168, 0, .200					; IPアドレス (0.0.0.0=DHCP) 00h-03h
		DE	.255, .255, .255, 0					; ネットマスク 04h-07h
		DE	0,0,0,0							; ゲートウェイ 08h-0Bh
		DE	1,4,4,0							; FW Version   0Ch-0Fh
		
		DE	HTTP_PORT / .256,HTTP_PORT & .255			; HTTPポート番号 10h-11h
		DE	LCD_PORT / .256,LCD_PORT & .255				; LCDポート番号  12h-13h
		DE	PARALLEL_PORT / .256,PARALLEL_PORT & .255		; PARALLELポート番号 14h-15h
		DE	SERIAL_PORT / .256,SERIAL_PORT & .255			; SERIALポート番号   16h-17h
		DE	0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh			; 18h-1Fhは未使用

		DE	0,0,0,0,0,0,0FFh,0FFh					; Host A MAC Address 20h-25h
		DE	0,0,0,0,0,0,0FFh,0FFh					; Host B MAC Address 28h-2Dh
		DE	0,0,0,0,0,0,0FFh,0FFh					; Host C MAC Address 30h-35h
		DE	0,0,0,0,0,0,0FFh,0FFh					; Host D MAC Address 38h-3Dh

		ORG	0x2140							; 40h-5Fh
		DE	" /picnic/control.html",0				; ポート操作用ファイル名、00hでターミネート
		ORG	0x2160							; 60h-7Fh
		DE	" /picnic/config.html",0				; コンフィグ用ファイル名、00hでターミネート
		ORG	0x2180							; 80h-83h
		DE	14H,15H,08H,08H						; 制限モード用画面の定義
		ORG	0x2184							; 84h-87h
		DE	17H,18H,1AH,1DH						; CMDモード用画面の定義
		ORG	0x2188							; 88h-8Bh
		DE	17H,1BH,1DH,08H						; CFGモード用画面の定義
;
;-----------------------------------------------------------------------------------

;
;		プロトコル番号など
;
COM_PROTO	EQU	08H			; HIGH BYTE(共通)
IP_PROTO	EQU	00H			; LOW BYTE (0800h means IP packet)
ARP_PROTO	EQU	06H			; LOW BYTE (0806h means ARP packet)
WOL_PROTO	EQU	42H			; LOW BYTE (0842h means Wake-On-LAN)

TCP_PROTO	EQU	.6
UDP_PROTO	EQU	.17
ICMP_PROTO	EQU	.1

;
;		RTL8019AS関連設定項目
;
PAGE_BEGIN	EQU	40H			; メモリ先頭アドレス
PAGE_START	EQU	46H			; 受信バッファ先頭アドレス
PAGE_STOP	EQU	80H			; 受信バッファ終端アドレス

DATA_SIZE	EQU	.18

;
;		Ethernet関連設定項目
;
NE_SIZE		EQU	.4			; RTL8019ステータスエリアサイズ
PACKET_SIZE	EQU	.6 + .6 + .2			; Ethernetヘッダサイズ
ARP_SIZE	EQU	.28			; ARPパケットサイズ
IP_SIZE		EQU	.20			; IP(基本)ヘッダサイズ
UDP_SIZE	EQU	.8			; UDPヘッダサイズ
TCP_SIZE	EQU	.20			; TCP(基本)ヘッダサイズ
DHCP_SIZE	EQU	.308
;
;		TCP/IPステート
;
LISTEN		EQU	00			; ひま
SYN_RCVD	EQU	80H			; SYN,ACKを送ってACKを待っている
ESTAB		EQU	81H			; 通信確立
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
;
;		URLのパス名の格納されているEEPROMアドレス、パス名は31文字で32文字目を00Hでターミネートする
;
URL_CMD		EQU	40H
URL_CFG		EQU	60H
MSG_LIM		EQU	80H	; 制限メッセージの定義
MSG_CMD		EQU	84H	; CMD画面用メッセージの定義
MSG_CFG		EQU	88H	; CFG画面用メッセージの定義

;-----------------------------------------------------------------------------------
;		Ｉ／Ｏポート設定
;-----------------------------------------------------------------------------------
SA		EQU	PORTC			; NE2000 アドレスバス
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


;
;		ＬＣＤ用Ｉ／Ｏ設定（オプショナルＬＣＤ用)
;
D7		EQU	7			;rb.7			; 液晶用
D6		EQU	6
D5		EQU	5
D4		EQU	4
E		EQU	3			; 液晶イネーブル
RS		EQU	2			;rb.2 ; 液晶ＲＳピン



;-----------------------------------------------------------------------------------
;		グローバル変数
;-----------------------------------------------------------------------------------
;		PAGE 0 

;	ＬＣＤ用変数
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_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			; プロトコル番号
state		EQU	38H			; TCPフラグ

;-----------------------------------------------------------------------------------
;
;		ＩＰプロトコル
;
ip_header	EQU	39H
ip_ver_len	EQU	39H		; VERSION:4,DATA SIZE:5
ip_tos		EQU	3AH		; service type
ip_length	EQU	3BH		; データ長
ip_length1	EQU	3CH
ip_ident	EQU	3DH	
ip_ident1	EQU	3EH
ip_flagment	EQU	3FH		
ip_flagment1	EQU	40H
ip_ttl		EQU	41H		; 生存期間
ip_proto	EQU	42H		; プロトコル 1:ICMP,6:TCP,17:UDP
ip_sum		EQU	43H		; ヘッダチェックサム
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


;-----------------------------------------------------------------------------------
;		ＴＣＰプロトコル
;
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	

;-----------------------------------------------------------------------------------
;		マジックパケット用・GETコマンド解析用
;
magic_mac	EQU	61H		; EEPROMからロードしたマジックパケットのアドレスを入れる
magic_mac2	EQU	62H
magic_mac3	EQU	63H
magic_mac4	EQU	64H
magic_mac5	EQU	65H
magic_mac6	EQU	66H
magic_loop	EQU	67H
magic_flag	EQU	68H		; マジックパケット・CGIファイル名解析フラグ
MAGIC		EQU	0		; マジック用MACアドレス入力フラグ
DO_CMD		EQU	1		; コマンド用CGI有効
DO_CFG		EQU	2		; コンフィグ用CGI有効

;-----------------------------------------------------------------------------------
;		ＵＤＰプロトコル
;
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


;-----------------------------------------------------------------------------------
;		ＡＲＰプロトコル
;
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


;-----------------------------------------------------------------------------------
;		ＩＣＭＰプロトコル
;
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


;-----------------------------------------------------------------------------------
;		ＤＨＣＰプロトコル
;
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


;-----------------------------------------------------------------------------------
;		環境設定用変数
;
;		PAGE 1
this_ip		EQU	0A0H		; 自分のＩＰアドレス
this_ip1	EQU	0A1H		
this_ip2	EQU	0A2H		
this_ip3	EQU	0A3H		
mymac		EQU	0A4H		; 自分のＭＡＣアドレス
mymac1		EQU	0A5H
mymac2		EQU	0A6H
mymac3		EQU	0A7H
mymac4		EQU	0A8H
mymac5		EQU	0A9H
seq_no		EQU	0AAH			; 自分のシーケンス番号
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			; 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		; ルーチンで使用する(GET)ポインタ
fifo_buff	EQU	0BCH		; 割り込みで使用する(SET)ポインタ
fifo_cn		EQU	0BDH		; 受信バイト数
fifo_top	EQU	0BEH		; バッファ
fifo_bottom	EQU	0DCH

fifo_line	EQU	0DCH		
fifo_line_cn	EQU	0DDH	


;-----------------------------------------------------------------------------------
;		Ethernetヘッダ
;
ne_header	EQU	0DEH		; NE2000 Status
ne_stat		EQU	0DEH		; 受信ステータス(RSR)
ne_next		EQU	0DFH		; 次のバウンダリポインタ(Next Boundary)
ne_cn_l		EQU	0E0H		; データサイズ（Ｌ）
ne_cn_h		EQU	0E1H		; データサイズ（Ｈ）

eth_header	EQU	0E2H			; Ethernet Header
eth_dest	EQU	0E2H			; 送信先ＭＡＣアドレス
eth_dest1	EQU	0E3H
eth_dest2	EQU	0E4H
eth_dest3	EQU	0E5H
eth_dest4	EQU	0E6H
eth_dest5	EQU	0E7H
eth_src		EQU	0E8H		; 送信元ＭＡＣアドレス
eth_src1	EQU	0E9H
eth_src2	EQU	0EAH
eth_src3	EQU	0EBH
eth_src4	EQU	0ECH
eth_src5	EQU	0EDH
eth_type	EQU	0EEH		; パケットタイプ
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




;-----------------------------------------------------------------------------------
;		共通変数
;

; BEGIN -- 割り込み時レジスタ待避用
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

;-----------------------------------------------------------------------------------
;	１０進変換用エリア
;-----------------------------------------------------------------------------------
;		PAGE 2
;		
			; バイナリ→10進数変換用
decimal_top	EQU	120H	


;-----------------------------------------------------------------------------------
;	ＲＳ２３２Ｃ送信先データ
;-----------------------------------------------------------------------------------
;		PAGE 3
on_ether	EQU	190H			; 宛て先Ethernetアドレス
on_ether1	EQU	191H
on_ether2	EQU	192H
on_ether3	EQU	193H
on_ether4	EQU	194H
on_ether5	EQU	195H
on_ip		EQU	196H		; 宛て先IPアドレス
on_ip1		EQU	197H
on_ip2		EQU	198H
on_ip3		EQU	199H
on_port		EQU	19AH				; 宛て先ポート番号
on_port1	EQU	19AH
on_rate		EQU	19CH				; 設定されているボーレート
on_flow		EQU	19DH				; ＝０
transmitted	EQU	19EH
skb		EQU	1A0H
;-----------------------------------------------------------------------------------
;		プログラムエントリ
;-----------------------------------------------------------------------------------
		ORG	0			; リセットベクタ(=0000h)
		MOVLW	HIGH (start)		; スタートアップルーチンへ

		MOVWF	PCLATH
		GOTO	start

;-----------------------------------------------------------------------------------
;		割り込み処理
;
;		スタック消費を押さえるため、割り込み処理内ではCALLしてはいけない。
;-----------------------------------------------------------------------------------

		org	4		; 割り込みベクタ(=0004h)
interrupt
;-----------------------------------------------------------------------------------
;		コンテキスト待避処理
		MOVWF	w_save		; Ｗレジスタ保存
		swapf	STATUS, 0	; STATUSレジスタを保存
		CLRF	STATUS				; STATUSを０にする
		MOVWF	status_save
		MOVF	PCLATH,0		; PCLATHを保存
		MOVWF	pclath_save
		CLRF	PCLATH			; PCLATH=0にする
		BCF	STATUS,IRP	
		MOVF	FSR, 0		
		MOVWF	fsr_save	; FSRを保存する
;-------------------------------------------------------------------------------;		RB0割り込み
		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受信？
		GOTO	int2
;-----------------------------------------------------------------------------------
;		シリアル受信割り込み処理
		BSF	STATUS,RP0	
		
		MOVLW	fifo_bottom - fifo_top
		SUBWF	fifo_cn,0
		BTFSC	STATUS,C
		GOTO	rec_over

		MOVF	fifo_buff,0		; 現在のリング
		MOVWF	FSR		;バッファのポインタ取得→fsrへ
		BCF	STATUS,RP0	;
		MOVF	RCREG,0			; リングバッ
		MOVWF	INDF		;ファに受信データを保存
		BSF	STATUS,RP0	
		INCF	fifo_buff,1	; 次のアドレスに...
		
		MOVLW	fifo_bottom
		SUBWF	fifo_buff,0
		BTFSS	STATUS,C
		GOTO	int1_1

		MOVLW	fifo_top	
		MOVWF	fifo_buff
int1_1		INCF	fifo_cn,1		; リングバッファにあるデータバイト数＋＋
;-----------------------------------------------------------------------------------
		MOVLW	(fifo_bottom - fifo_top) / 2	; [2004/10/30]
		subwf	fifo_cn,0
		BTFSS	STATUS,C
		GOTO	int2
		BSF	STATUS,RP1
		BTFSS	on_flow,0
		GOTO	int2
		CLRF	STATUS
		BSF	PORTB,1
int2
		CLRF	STATUS
;-------------------------------------------------------------------------------;		コンテキスト復帰処理
		MOVF	fsr_save,0			; fsrを復帰
		MOVWF	FSR
		MOVF	pclath_save,0		; pclathを復帰
		MOVWF	PCLATH
		swapf	status_save,0
		MOVWF	STATUS					; statusを復帰
		swapf	w_save,1
		swapf	w_save,0		; Wを復帰
;	ISR終了
		retfie				; 割り込みルーチンからのリターン


;		RS232C受信バッファオーバーフロー
rec_over
		BCF	STATUS, RP0	
		MOVF	RCREG, 0				; データを読んで捨てる
		BCF	STATUS, RP0	
		GOTO	int2


;-----------------------------------------------------------------------------------
;		ソケットのタイムアウトチェック
;
dec_tm
		BSF	STATUS, IRP
		MOVLW	SOCKETS
		MOVWF	timer_cn
		MOVLW	(skb + 1) & 0FFH	
		MOVWF	FSR
dec_tm0
		MOVF	INDF,W		
		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



;-----------------------------------------------------------------------------------
;		16進文字の取得ルーチン
;
getascii
		ANDLW	0fh
		ADDWF	PCL, 1		
		DT	"0123456789ABCDEF"
;-----------------------------------------------------------------------------------
;		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


;-----------------------------------------------------------------------------------
;		TCPのseq_noをインクリメントする。
;
inc_seq_no
		BSF	STATUS,IRP	
		MOVLW	.3		
		ADDWF	FSR,1
		MOVLW	.1		
		ADDWF	INDF,F
		DECF	FSR,1		
		BTFSC	STATUS,C	
		addwf	INDF,F		
		DECF	FSR,1	 
		BTFSC	STATUS,C	
		addwf	INDF,F		
		DECF	FSR,1		
		BTFSC	STATUS,C	
		addwf	INDF,F		
		BCF	STATUS,IRP	
		RETURN

;-----------------------------------------------------------------------------------
;		TCPのseq_noにip_lengthを加算する。
;
add_seq_no
		BSF	STATUS,IRP	
		MOVLW	.3		
		ADDWF	FSR,1

		MOVF	ip_length1,0	
		addwf	INDF,F		
		DECF	FSR,1		
		MOVLW	1
		BTFSC	STATUS,C	
		addwf	INDF,F		
		DECF	FSR,1		
		BTFSC	STATUS,C	
		addwf	INDF,F		
		DECF	FSR,1		
		BTFSC	STATUS,C	
		addwf	INDF,F		
	
		MOVLW	.2		
		ADDWF	FSR,1
		MOVF	ip_length,0	
		addwf	INDF,F		
		DECF	FSR,1		
		MOVLW	1
		BTFSC	STATUS,C	
		addwf	INDF,F		
		DECF	FSR,1		
		BTFSC	STATUS,C	
		addwf	INDF,F		
		BCF	STATUS,IRP	
		RETURN

;-----------------------------------------------------------------------------------
;		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

;-----------------------------------------------------------------------------------
;		TCPのack_noにip_lengthを加算する。
;
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_sum
		CLRF	sum		
		CLRF	sum1		
		CLRF	bytes		; HI byte/LO byteの識別用
		RETURN


;-----------------------------------------------------------------------------------
;		エラーリカバリールーチン
;-----------------------------------------------------------------------------------
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		; RTL8019を初期化
		
		MOVLW	0CH
		MOVWF	PORTC					; RCR
		MOVLW	B'000100'			; MONITOR解除
		CALL	assert_wr0
		
		MOVLW	0DH		
		MOVWF	PORTC					; TCR
		DB	01,00		;clrw				; L/B解除
		CALL	assert_wr0
		
		GOTO	main0			; 通常処理に戻る

;===================================================================================
;		メインルーチン
;===================================================================================
main

		CLRF	PORTC					;rc
		MOVLW	22h
		CALL	assert_wr0		; PAGE0に戻す

		MOVLW	0CH		
		MOVWF	PORTC
		MOVLW	B'000100'
		CALL	assert_wr0
		MOVLW	0DH		
		MOVWF	PORTC
		DB	01,00						; L/B解除
		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,W		
		INCF	FSR,1		
		iorwf	INDF,W		
		INCF	FSR,1		
		iorwf	INDF,W		
		INCF	FSR,1		
		iorwf	INDF,W		
		BTFSS	STATUS,2	
		GOTO	main0			; 自分のIPアドレスが0.0.0.0？
do_dhcp
		CLRF	STATUS
		MOVLW	HIGH (dhcp)	
		MOVWF	PCLATH
		CALL	dhcp
		MOVLW	$ >> 8		
		MOVWF	PCLATH
;===================================================================================
;		メインループ
;===================================================================================
main0
		BSF	STATUS,RP0
	 					; RS232C受信？
		MOVF	fifo_cn,0
		BTFSS	STATUS,Z
		GOTO	receive232c
		MOVLW	80h
		SUBWF	dhcp_done,0
		BTFSC	STATUS,Z
		GOTO	do_dhcp
		BCF	STATUS,RP0

		CLRF	PCLATH
		MOVLW	.7
		MOVWF	PORTC
		CALL	assert_rd		; ＲＣＲリード
		
		BTFSC	data0,4	
		GOTO	overflow
		BTFSC	data0,3
		GOTO	overflow
		BTFSC	data0,2
		GOTO	overflow
		GOTO	get_packet		; パケット受信あり
main99		GOTO	main0

receive232c
		BCF	STATUS,RP0
		MOVLW	serial_tx >> 8
		MOVWF	PCLATH			; receive232c処理へ
		GOTO	serial_tx



;-----------------------------------------------------------------------------------
;	パケット受信処理
;-----------------------------------------------------------------------------------
get_packet
						;	PAGE 1
		CLRF	PORTC
		MOVLW	B'01100010'
		CALL	assert_wr0		; PAGE1にする
		
		MOVLW	.7
		MOVWF	PORTC
		CALL	assert_rd
		MOVF	data0,0			; カレントページを取得
		MOVWF	curr
						;	PAGE 0
		CLRF	PORTC
		MOVLW	B'00100010'
		CALL	assert_wr0		; PAGE0に戻す
		
		MOVLW	.3
		MOVWF	PORTC
		CALL	assert_rd		; BNDYをよむ
		
		INCF	data0,1			; BNDY++
		MOVLW	PAGE_STOP		; overlap計算
		SUBWF	data0,0
		BTFSS	STATUS,C
		GOTO	packet1

		MOVLW	PAGE_START
		MOVWF	data0
packet1
		MOVF	curr,0			; (BNDY+1)==CURRの場合は新規データなし
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	main0			; 中断


;-----------------------------------------------------------------------------------
; RTL8019ステータス＋Ethernetヘッダの読み出し
		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			; アドレス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 バッファへセット
		INCF	FSR,1		
		DECFSZ	gcn1,1		
		GOTO	get_packet0
;
;		Ethernetヘッダによって処理を分岐
		BSF	STATUS,RP0	
		BTFSS	ne_stat,0	
		GOTO	main9
		MOVLW	COM_PROTO		; typeの上位８ビットが８以外はスキップ
		SUBWF	eth_type,0
		BTFSS	STATUS,Z
		GOTO	main9
		MOVLW	IP_PROTO		; IPプロトコル処理へ分岐
		SUBWF	eth_type1,0
		BTFSC	STATUS,Z
		GOTO	do_ip
		MOVLW	ARP_PROTO		; ARPプロトコル処理へ分岐
		SUBWF	eth_type1,0
		BTFSC	STATUS,Z
		GOTO	do_arp			; ARPプロトコル処理へ分岐
;		GOTO	main9			; その他
;-----------------------------------------------------------------------------------
main9
		BCF	STATUS,IRP
		BCF	STATUS,RP1
		BSF	STATUS,RP0
		MOVLW	PAGE_START		; Error Check and Recovery
		SUBWF	ne_next,0
		BTFSS	STATUS,C
		GOTO	overflow2
		MOVLW	PAGE_STOP		; Error Check and Recovery
		SUBWF	ne_next,0
		BTFSC	STATUS,C
		GOTO	overflow2

		DECF	ne_next,1		; 次のバンダリを計算
		MOVLW	PAGE_START	
		SUBWF	ne_next,0
		BTFSC	STATUS,C
		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,W			; バンダリポインタセット
		CALL	assert_wr0
		GOTO	main99



;-----------------------------------------------------------------------------------
;		ＡＲＰプロトコル処理
;-----------------------------------------------------------------------------------
do_arp
		BCF	STATUS,RP0	
		MOVLW	NE_SIZE + PACKET_SIZE	
		MOVWF	remote_adr
		MOVLW	ne_cn_l			
		MOVWF	FSR
		MOVF	INDF,W			
		MOVWF	remote_len
		INCF	FSR,1			
		MOVF	INDF,W			
		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				; アドレスip_header以降にデータを読み出す
		MOVWF	FSR
get_packet10
		MOVF	remote_len,0		
		iorwf	remote_len1,0		
		BTFSC	STATUS,Z		
		GOTO	get_packet2		; 読み込み終了？
		
		BCF	PORTE,0			
		BTFSS	PORTC,5						; ~Wait
		GOTO	$-1
		MOVF	PORTD,0			
		BSF	PORTE,0			
		MOVWF	INDF			
		INCF	FSR,1			
		
		MOVLW	1			; レングスをデクリメント
		SUBWF	remote_len,1		
		BTFSS	STATUS,C		
		SUBWF	remote_len1,1		
		
		BTFSS	FSR,7						; over flow?
		GOTO	get_packet10
;	80h以降
get_packet20
		MOVF	remote_len,0		
		iorwf	remote_len1,0		
		BTFSC	STATUS,Z		
		GOTO	get_packet2		; 読み込み終了
		
		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ヘッダの解析
get_packet2
		MOVF	arp_ope,0				; arp_codeが0001以外なら捨てる
		BTFSS	STATUS,Z
		GOTO	main9

		MOVLW	1			
		SUBWF	arp_ope1,0
		BTFSC	STATUS,Z
		GOTO	arp_req

		MOVLW	2			
		SUBWF	arp_ope1,0
		BTFSC	STATUS,Z
		GOTO	arp_reply
		
		GOTO	main9
arp_reply
		MOVLW	HIGH (ser_arp)		
		MOVWF	PCLATH
		GOTO	ser_arp
arp_req
arp
		MOVLW	this_ip				; this_ipはBANK 1にある。
		MOVWF	FSR
		MOVF	arp_dest_ip,0			; ARPのIPアドレスが自分と同じか？
		SUBWF	INDF,W
		BTFSS	STATUS,Z
		GOTO	main9
		INCF	FSR,1			

		MOVF	arp_dest_ip1,0		
		SUBWF	INDF,W
		BTFSS	STATUS,Z
		GOTO	main9
		INCF	FSR,1			

		MOVF	arp_dest_ip2,0		
		SUBWF	INDF,W
		BTFSS	STATUS,Z
		GOTO	main9
		INCF	FSR,1			
		MOVF	arp_dest_ip3,0		
		SUBWF	INDF,W
		BTFSS	STATUS,Z
		GOTO	main9


;	自分へのARP要求である
		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			; ARP応答を送信する
		GOTO	main9


;-----------------------------------------------------------------------------------
;		ＩＰプロトコル受信処理
;-----------------------------------------------------------------------------------
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,W			
		MOVWF	remote_len
		INCF	FSR,1			
		MOVF	INDF,W			
		MOVWF	remote_len1

		MOVLW	NE_SIZE + PACKET_SIZE				; 受信バイト数からEtherヘッダ長を引く
		SUBWF	remote_len,1
		MOVLW	1
		BTFSS	STATUS,C		
		subwf	remote_len1,1		
		CALL	remote_read
;
;	ＩＰパケットの受信
		MOVLW	ip_header				; アドレスip_headerへデータを読み込む
		MOVWF	FSR

		BCF	PORTE,0			
		BTFSS	PORTC,5						; ~Wait
		GOTO	$-1
		MOVF	PORTD,0			
		BSF	PORTE,0			
		MOVWF	INDF					; １バイト読む！
		INCF	FSR,1			

		MOVLW	1			
		subwf	remote_len,1		
		BTFSS	STATUS,C		
		subwf	remote_len1,1		

		MOVF	ip_ver_len,0		; 残りバイト数算出
		MOVWF	gcn1
		MOVLW	0FH			
		ANDWF	gcn1,1

		BCF	3,0			
		RLF	gcn1,1			
		RLF	gcn1,1			
		DECF	gcn1,1				; IPヘッダからIPヘッダサイズを計算
		CALL	copy_toram		; RAMに転送

ip_get_packet2
		MOVLW	45H			; IP Version 4 ?
		SUBWF	ip_ver_len,0
		BTFSS	STATUS,Z
		GOTO	ip_get_packet9
		MOVLW	TCP_PROTO			; TCP受信処理へ
		SUBWF	ip_proto,0
		BTFSC	STATUS,Z
		GOTO	tcp
		MOVLW	UDP_PROTO			; UDP受信処理へ
		SUBWF	ip_proto,0
		BTFSC	STATUS,Z
		GOTO	udp
		MOVLW	ICMP_PROTO		; ICMP受信処理へ
		SUBWF	ip_proto,0
		BTFSC	STATUS,Z
		GOTO	icmp
ip_get_packet9
		CALL	abort				; リモートＤＭＡ中止
		GOTO	main9

;-----------------------------------------------------------------------------------
;		gcn1のバイト数分データを読み込む
;-----------------------------------------------------------------------------------
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



;-----------------------------------------------------------------------------------
;		パケットの残りをバッファＲＡＭへ
;-----------------------------------------------------------------------------------
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				; 表にセット
		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				; バンクを変えて更に読み込み
		MOVWF	FSR
		BSF	STATUS,IRP	
get_remain20
		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				; 裏にセット
		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		; 読み込み終了
;		
;		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




;-----------------------------------------------------------------------------------
;		ＩＣＭＰプロトコル処理
;-----------------------------------------------------------------------------------
icmp
		CALL	get_remain			; RTL8019からデータを転送
		MOVLW	.8			; typeが08h以外は捨てる
		SUBWF	icmp_type,0
		BTFSS	STATUS,Z
		GOTO	main9
		MOVF	icmp_code,0				; codeが08h以外は捨てる
		BTFSS	STATUS,Z
		GOTO	main9
ping
		MOVLW	ICMP_PROTO			; プロトコル＝ICMP
		MOVWF	proto
		CALL	prepare_ip			; IPパケットの準備
;
		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			; チェックサムの値をクリア
		
		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,W			
		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,W			
		CALL	assert_wr0
		
		MOVLW	.6			
		MOVWF	PORTC
		INCF	FSR,1			
		MOVF	INDF,W			
		CALL	assert_wr0
		
		CALL	transmit			; PINGの応答を送信
		GOTO	main9
icmp20
		MOVLW	20H			
		MOVWF	FSR
		BSF	STATUS,IRP		
		GOTO	icmp19



;-----------------------------------------------------------------------------------
;		ＵＤＰ
;-----------------------------------------------------------------------------------
udp
		MOVLW	.8			
		MOVWF	gcn1
		CALL	copy_toram
		
;	BOOTPポートのチェック
		MOVLW	BOOTPC_PORT / .256	
		SUBWF	udp_tar_port,0
		BTFSS	STATUS,Z
		GOTO	udp_1
		MOVLW	BOOTPC_PORT & 0FFH		; BOOTP処理へ
		SUBWF	udp_tar_port1,0
		BTFSC	STATUS,Z
		GOTO	bootp_res

		MOVLW	this_ip			
		MOVWF	FSR
		MOVF	INDF,W				; 自分への送信データか？
		SUBWF	ip_dest,0
		BTFSS	STATUS,Z
		GOTO	main9

		INCF	FSR,1			
		MOVF	INDF,W			
		SUBWF	ip_dest1,0
		BTFSS	STATUS,Z
		GOTO	main9

		INCF	FSR,1			
		MOVF	INDF,W			
		SUBWF	ip_dest2,0
		BTFSS	STATUS,Z
		GOTO	main9
		INCF	FSR,1			
		MOVF	INDF,W			
		SUBWF	ip_dest3,0
		BTFSS	STATUS,Z
		GOTO	main9

;	LCDポートのチェック
udp_1
		MOVLW	lcd_port & 0FFH		
		MOVWF	FSR
		MOVF	INDF,W			
		SUBWF	udp_tar_port,0
		BTFSS	STATUS,Z
		GOTO	udp_2
		INCF	FSR,1			
		MOVF	INDF,W			
		SUBWF	udp_tar_port1,0
		BTFSC	STATUS,Z
		GOTO	udp_lcd_tag
udp_2
		MOVLW	para_port & 0FFH	
		MOVWF	FSR
		MOVF	INDF,W			
		SUBWF	udp_tar_port,0
		BTFSS	STATUS,Z
		GOTO	udp_3

		INCF	FSR,1			
		MOVF	INDF,W			
		SUBWF	udp_tar_port1,0
		BTFSC	STATUS,Z
		GOTO	udp_parallel_tag
udp_3
		MOVLW	serial_port & 0FFH	
		MOVWF	FSR
		MOVF	INDF,W			
		SUBWF	udp_tar_port,0
		BTFSS	STATUS,Z
		GOTO	udp_4
		INCF	FSR,1			
		MOVF	INDF,W			
		SUBWF	udp_tar_port1,0
		BTFSC	STATUS,Z
		GOTO	udp_serial_tag
udp_4
;
;		add new funciton this
;
		GOTO	main9
udp_lcd_tag
		MOVLW	udp_lcd >> 8
		MOVWF	PCLATH
		GOTO	udp_lcd
;
;		パラレルＩ／Ｏの処理（ＵＤＰ）
;
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応答
;-----------------------------------------------------------------------------------
bootp_res
		CALL	get_remain

		MOVLW	this_ip		
		MOVWF	FSR
		MOVF	INDF,W		
		INCF	FSR,1
		iorwf	INDF,W
		INCF	FSR,1
		iorwf	INDF,W
		INCF	FSR,1
		iorwf	INDF,W
		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			; 自分のＭＡＣ
		
		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
;
;	ここでDHCPサーバからもらったＩＰｱﾄﾞﾚｽを自分のｱﾄﾞﾚｽとして登録
		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

;
;	もらったＩＰアドレスを液晶に表示
		BCF	PORTB,2
		MOVLW	0C0H		
		MOVWF	d4
		MOVLW	HIGH (write_lcd4)
		MOVWF	PCLATH
		CALL	write_lcd4			; 2行目に移動
		
		MOVLW	HIGH(print_ip)
		MOVWF	PCLATH
		CALL	print_ip			; 表示！
		CLRF	PORTB
		CLRF	PCLATH
		GOTO	main9




;-----------------------------------------------------------------------------------
;		ＴＣＰ
;-----------------------------------------------------------------------------------
tcp
		MOVLW	.20			; 20バイトを読み込む
		MOVWF	gcn1
		CALL	copy_toram
		
		MOVLW	http_port & 0ffh
		MOVWF	FSR
		MOVF	INDF,W			; EEPROMのhttpポートと一致するか？
		SUBWF	tcp_tar_port,0
		BTFSS	STATUS,Z
		GOTO	tcp9

		INCF	FSR,1
				
		MOVF	INDF,W
		SUBWF	tcp_tar_port1,0
		BTFSC	STATUS,Z
		GOTO	tcp_www

tcp9		GOTO	main9			; http以外でTCPに応答するものはない
;
;	http処理
tcp_www
		MOVLW	this_ip
		MOVWF	FSR
		MOVF	INDF,W
		INCF	FSR,1
		iorwf	INDF,W
		INCF	FSR,1
		iorwf	INDF,W
		INCF	FSR,1
		iorwf	INDF,W
		BTFSC	STATUS,Z
		GOTO	main9			; IPアドレスが0.0.0.0なら処理中止
		
		BTFSC	tcp_flags,5		; TCP_URG
		GOTO	main9			; 廃棄
		
		MOVLW	HIGH(search_socket)
		MOVWF	PCLATH
		CALL	search_socket		; ソケットを検索
		MOVLW	HIGH (tcp_www)
		MOVWF	PCLATH
		BTFSC	STATUS,C
		GOTO	state1			; ステート存在あり？
		
		CALL	no_socket		; ソケット作成
		GOTO	main9
;
;	socket state1
state1
		MOVLW	.12
		ADDWF	FSR,1
	;	mov	pclath,#print_hex>>8
	;	mov	pclath,#$>>8
;
		MOVF	INDF,W		
		SUBWF	tcp_seq_no,0
		BTFSS	STATUS,Z
		GOTO	state12
		INCF	FSR,1
		MOVF	INDF,W		
		SUBWF	tcp_seq_no1,0
		BTFSS	STATUS,Z
		GOTO	state12
		INCF	FSR,1
		MOVF	INDF,W		
		SUBWF	tcp_seq_no2,0
		BTFSS	STATUS,Z
		GOTO	state12
		INCF	FSR,1
		MOVF	INDF,W		
		SUBWF	tcp_seq_no3,0
		BTFSS	STATUS,Z
		GOTO	state12
		MOVLW	.15		
		SUBWF	FSR,1
		CALL	state2
state12		CLRF	PCLATH
		GOTO	main9
		
state2
		MOVLW	HIGH(state_table)
		MOVWF	PCLATH

		MOVF	INDF,W
		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





;-----------------------------------------------------------------------------------
;		SYNを受け取り,
;		SYN,ACKを送って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

;-----------------------------------------------------------------------------------
;
;
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,W
		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
		CLRF	INDF
		BCF	STATUS,IRP
		
		CALL	inc_ack_no
		CALL	send_ack
		RETURN

;-----------------------------------------------------------------------------------
;
;
job_CLOSE_WAIT
		CLRF	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			GETの解析
;-----------------------------------------------------------------------------------
ESTAB_00
		INCF	INDF,F
		BCF	STATUS,IRP
		CLRF	magic_flag		; ファイル名一致フラグをOFF、コマンドパース前なのでmagic_flag全体をクリアしても問題ない
		MOVLW	URL_CMD			; コマンド用ファイル名のアドレス
		MOVWF	wk1
		MOVLW	URL_CFG			; コンフィグ用ファイル名のアドレス
		MOVWF	wk2
estab0
		MOVLW	HIGH(get_nextbyte)
		MOVWF	PCLATH
		CALL	get_nextbyte		; バッファからデータを取得
		MOVLW	HIGH (estab0)		; 戻す
		MOVWF	PCLATH
		
		MOVF	data0,W			; 終了？
		BTFSC	STATUS,Z
		GOTO	estab1

		MOVLW	0AH			; 改行文字？
		SUBWF	data0,W
		BTFSC	STATUS,Z
		GOTO	estab1

		MOVLW	HIGH(url_check)		; URLチェック
		MOVWF	PCLATH
		CALL	url_check
		
		MOVLW	'?'			; '?'文字を発見？(=GETコマンドの処理)
		SUBWF	data0,W
		BTFSC	STATUS,Z
		GOTO	parse_cgi_tag
		GOTO	estab0
parse9

;-----------------------------------------------------------------------------------
estab1						; htmlメッセージの送信
		CALL	abort			; バッファ転送中止
		CALL	add_ack_no		; ACK NOを加算
;		CALL	send_ack		; ACKを送信

		MOVLW	MSG_LIM			; フラグなしのメッセージ
		BTFSC	magic_flag,DO_CMD
		MOVLW	MSG_CMD			; コマンドフラグのメッセージ
		BTFSC	magic_flag,DO_CFG
		MOVLW	MSG_CFG			; コンフィグフラグのメッセージ
		GOTO	send_mes		; メッセージ送信

ESTAB_01
		INCF	INDF,F
		BCF	STATUS,IRP
	;	CALL	send_ack

		MOVLW	MSG_LIM + 1		; フラグなしのメッセージ
		BTFSC	magic_flag,DO_CMD
		MOVLW	MSG_CMD + 1		; コマンドフラグのメッセージ
		BTFSC	magic_flag,DO_CFG
		MOVLW	MSG_CFG + 1		; コンフィグフラグのメッセージ
		GOTO	send_mes		; メッセージ送信

ESTAB_02
		INCF	INDF,F
		BCF	STATUS,IRP
	;	CALL	send_ack
		
		MOVLW	MSG_LIM + 2		; フラグなしのメッセージ
		BTFSC	magic_flag,DO_CMD
		MOVLW	MSG_CMD + 2		; コマンドフラグのメッセージ
		BTFSC	magic_flag,DO_CFG
		MOVLW	MSG_CFG + 2		; コンフィグフラグのメッセージ
		GOTO	send_mes		; メッセージ送信

ESTAB_03
		INCF	INDF,F
		BCF	STATUS,IRP
	;	CALL	send_ack
		
		MOVLW	MSG_LIM + 3		; フラグなしのメッセージ
		BTFSC	magic_flag,DO_CMD
		MOVLW	MSG_CMD + 3		; コマンドフラグのメッセージ
		BTFSC	magic_flag,DO_CFG
		MOVLW	MSG_CFG + 3		; コンフィグフラグのメッセージ
		GOTO	send_mes		; メッセージ送信
;
;		リモートＤＭＡ転送中止
abort
		CLRF	PORTC	 
		MOVLW	22h
		CALL	assert_wr0		; PAGE0に戻す
		
		MOVLW	0Ah
		MOVWF	PORTC
		DB	01,00		;clrw
		CALL	assert_wr0
		
		MOVLW	0Bh
		MOVWF	PORTC
		DB	01,00		;clrw
		CALL	assert_wr0
		RETURN

;
;		バンク間ジャンプ用
parse_cgi_tag
		MOVF	magic_flag,F		; ファイル名フラグがセットされていない場合は、CGIパースを行わない
		BTFSC	STATUS,Z
		GOTO	estab1			; セットされていない(Z=SET)なら画面表示へ
		MOVLW	HIGH(parse_cgi)
		MOVWF	PCLATH
		GOTO	parse_cgi





;-----------------------------------------------------------------------------------
;		ＲＳＴパケットの送信
;-----------------------------------------------------------------------------------
send_rst
		MOVLW	B'000100'		; RST
		MOVWF	state
		GOTO	send_common


;-----------------------------------------------------------------------------------
;		ＦＩＮパケットの送信
;-----------------------------------------------------------------------------------
send_fin
		MOVLW	B'010001'		; ACK+FIN
		MOVWF	state
		GOTO	send_common


;-----------------------------------------------------------------------------------
;		ＡＣＫパケットの送信
;-----------------------------------------------------------------------------------
send_ack
		MOVLW	B'010000'		; ACK
		MOVWF	state
;		GOTO	send_common
send_common
		CLRF	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バイト
		MOVLW	.20
		MOVWF	remote_len
		;mov	remote_len[1],#0
		CLRF	remote_len1
		CALL	remote_write
		
		CALL	clear_sum			; チェックサムの値をクリア
		
		MOVLW	http_port & 0ffh
		MOVWF	FSR
		MOVLW	2
		CALL	transmit_nbytes			; 自分のポート番号
		
		MOVLW	tcp_src_port
		MOVWF	FSR
		MOVLW	2
		CALL	transmit_nbytes			; 相手のポート番号

		MOVF	com_fsr,0
		MOVWF	FSR
		MOVLW	.8
		ADDWF	FSR,1
		BSF	STATUS,IRP
		MOVLW	4+4
		CALL	transmit_nbytes			; 自分のＳＥＱＮＯ
		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			; 緊急ポインタ
		
		CALL	calc_tcp_sum			; TCP SUMの計算
		
		MOVLW	4h
		MOVWF	PORTC
		MOVLW	PAGE_BEGIN			; transmit page is start page 
		CALL	assert_wr0
		
		MOVLW	5
		MOVWF	PORTC
		MOVLW	.60				; 60バイト送信
		CALL	assert_wr0
		
		MOVLW	6
		MOVWF	PORTC
		DB	01,00		;clrw					; 上位転送バイト＝０
		CALL	assert_wr0
		CALL	transmit			; 送信！！
		RETURN

;-----------------------------------------------------------------------------------
; Web用のメッセージを送信する WレジスタにメッセージIDが記録されたEEPROMのアドレスを代入してから呼び出すこと Ver.1.4.2.0
;-----------------------------------------------------------------------------------
send_mes
		BSF	STATUS,RP1		; ページ2
		MOVWF	EEADR			; WをEEPROMのアドレスに代入
		BSF	STATUS,RP0		; ページ3
		MOVLW	B'00000001'
		MOVWF	EECON1			; EEPROM読み出しコマンド,EEPGDも一緒にリセット
		BCF	STATUS,RP0		; データにアクセス(ページ2)
		MOVF	EEDATA,W
		BCF	STATUS,RP1		; ページ0
		MOVWF	wk			; wkにメッセージのアドレスを入れる

		MOVLW	assert_wr2x & 0ffh	; 送信ｊｏｂをRTL8019に
		MOVWF	dest
		MOVLW	HIGH (assert_wr2x)	
		MOVWF	dest1		
send_mes_head
				; 仮に65535バイト転送に設定
;-------
		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			; チェックサムの値をクリア
		
		MOVLW	http_port & 0ffh
		MOVWF	FSR
		MOVLW	2
		CALL	transmit_nbytes2		; 自分のポート番号
		
		MOVLW	tcp_src_port
		MOVWF	FSR
		MOVLW	2
		CALL	transmit_nbytes2		; 相手のポート番号

		BSF	STATUS,IRP
		MOVF	com_fsr,0
		MOVWF	FSR
		MOVLW	.8
		ADDWF	FSR,1
		MOVLW	4
		CALL	transmit_nbytes2		; 自分のＳＥＱＮＯ
		BCF	STATUS,IRP
	
		MOVLW	tcp_seq_no
		MOVWF	FSR
		MOVLW	4
		CALL	transmit_nbytes2		; 相手のＳＥＱＮＯ＋１
		
		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		; 緊急ポインタ
		DB	01,00		;clrw
		CALL	assert_wr2		; 緊急ポインタ
	
		CLRF	ind
		BSF	STATUS,RP1
		BCF	STATUS,RP0
		MOVF	wk,0		; 読み出すアドレス＝[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 ; コードエリアからデータを読み出す
		NOP				; ダミーサイクル
		NOP
		BCF	STATUS,RP0
		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		; 上位７ビットが０か？
		MOVWF	data0
		MOVLW	7FH		
		ANDWF	data0,1
		MOVF	data0,1		
		BTFSC	STATUS,Z
		GOTO	send_mes9		; 上位７ビットが０なら終了
;
;		上位７ビットがメタ文字なら処理を分岐
		MOVLW	'$'  
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	ctrl_code2
 		MOVLW	'@'
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	ctrl_code3
 		MOVLW	'%'
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	ctrl_code4

		MOVF	data0,0			;
		CALL	assert_wr2
		
		MOVF	getmes_wk1,0		; 下位７ビットをRTL8019バッファへ転送
		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			; リモートＤＭＡ転送の中止
		
	
		MOVF	remote_len,0
		MOVWF	ip_length1
	
		MOVF	remote_len1,0
		MOVWF	ip_length

		CALL	calc_tcp_sum		; TCP SUMを計算する
		
		MOVLW	.20		;add	ip_length[1],#20; 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		; IPプロトコルの準備
		
		MOVLW	4h
		MOVWF	PORTC
		MOVLW	PAGE_BEGIN			; transmit page is start page 
		CALL	assert_wr0
		
		MOVLW	PACKET_SIZE			; パケットサイズ6+6+2を送信バイト数に加算1
		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			; 送信！！
		
;
;	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			; seq noに加算
		RETURN

send_mes_foot1
 		MOVLW	.60
		SUBWF	ip_length1,0
		BTFSC	STATUS,C
		GOTO	send_mes_foot2
		MOVLW	5
		MOVWF	PORTC
		MOVLW	.60				; MINIMUM 60bytes
		CALL	assert_wr0
		CALL	transmit
		GOTO	send_mes_foot3

;-----------------------------------------------------------------------------------
;		ＡＤ変換
;-----------------------------------------------------------------------------------
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		; ADCON1に値を設定
		MOVWF	ADCON1
		MOVLW	1
		MOVWF	wait_cn
		MOVLW	HIGH (wait_ms)
		MOVWF	PCLATH

		CALL	wait_ms				; サンプリング時間20us待機
		MOVLW	HIGH (ad_in)
		MOVWF	PCLATH
		
		BSF	ADCON1,2		; ＡＤ変換開始
		BTFSC	ADCON1,2		; ＡＤ変換待ち
		GOTO	$-1
		
		MOVF	ADRESH,0			; 変換結果をval[1]:val[0]へ
		MOVWF	val1
		BSF	STATUS,RP0
		MOVF	ADRESL,0	
		BCF	STATUS,RP0
		MOVWF	val		
		
		BTFSS	getmes_wk1,5				; RA5かどうか？
		GOTO	ad_in1				; RA5以外
	;
	;ＡＤ変換結果を５倍する
	;
		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	; 格納場所初期値
		MOVWF	FSR
		BSF	STATUS,IRP			; ＩＲＰ＝１
		MOVLW	HIGH (divide16)
		MOVWF	PCLATH

		CALL	divide16
ad_in1
		MOVLW	HIGH (put_decimal16)
		MOVWF	PCLATH

		CALL	put_decimal16			; 10進数に変換
		MOVLW	HIGH (ad_in1)
		MOVWF	PCLATH
		GOTO	ctrl_next



;--------------------------------------------------------------------------
;	TRIS
;	入力・出力の表示
;-----------------------------------------------------------------------------------
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,W		
		ANDWF	data0,1
		BTFSC	STATUS,Z		
		GOTO	ctrl_out
		GOTO	ctrl_in
;
;		ビット位置返す
;
getbitpos
		MOVWF	wk
		MOVLW	1	
		MOVWF	data0
		MOVLW	07H		
		ANDWF	wk,1
		BTFSC	STATUS,Z		
		GOTO	getbitpos9
getbitpos0
		BCF	3,0	
		RLF	data0,1	
		DECFSZ	wk,1		
		GOTO	getbitpos0
getbitpos9	RETURN


;-----------------------------------------------------------------------------------
;	PARALLEL
;	現在の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	STATUS,Z
		GOTO	ctrl_code31

		MOVLW	80h | PORTA
		ADDWF	FSR,1
		MOVF	getmes_wk1,0
		CALL	getbitpos
		
		MOVF	INDF,W
		andwf	data0,0				; TRIS_RAのチェック
		BTFSC	STATUS,Z			; 出力ピン？
		GOTO	ctrl_code32

		MOVLW	HIGH(getadtable)
		MOVWF	PCLATH
		CALL	getadtable
		MOVWF	wk	
		MOVLW	HIGH (ctrl_code3)
		MOVWF	PCLATH
		
		MOVF	wk,0
		ANDWF	data0,1
		BTFSS	STATUS,Z		; 1ならアナログ入力
		GOTO	ad_in
;
;
ctrl_code32
		CLRF	FSR		
ctrl_code31	MOVLW	PORTA				; + 05h
		ADDWF	FSR,1

		MOVF	getmes_wk1,0
		CALL	getbitpos
		MOVF	INDF,W		
		ANDWF	data0,1
		BTFSC	STATUS,Z		
		GOTO	ctrl_low
		GOTO	ctrl_high

;-----------------------------------------------------------------------------------
;	ショートメッセージの取得
;-----------------------------------------------------------------------------------
get_short_mes
		MOVLW	HIGH(mes_low)		; バンク＝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		; PCLATHの修正
		
		MOVF	data0,0			; NULL?
		BTFSC	STATUS,Z
		GOTO	ctrl_next
		MOVF	data0,0
		CALL	assert_wr2		; 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'			;不明
		
		CALL	ctrl_code1			; コントロール文字出力ルーチンへ
		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

;-----------------------------------------------------------------------------------
;		ソケットの作成
;-----------------------------------------------------------------------------------
no_socket
		BTFSS	tcp_flags,TCP_SYN
		RETURN
;
;	SYNパケットの受信→SYN+ACKの送信
;
recv_syn
		MOVLW	HIGH (socket_entry)
		MOVWF	PCLATH

		CALL	socket_entry			; ソケットのエントリーを検索
		MOVLW	HIGH (recv_syn)
		MOVWF	PCLATH
		BTFSC	STATUS,C
		GOTO	send_rst			; ソケットの空きなし
		
				;
		CLRF	ip_length
				; IPヘッダ=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
		CLRF	remote_len1

;-------		
		
		CALL	remote_write
		
		CALL	clear_sum			; チェックサムの値をクリア
		
		MOVLW	http_port & 0ffh
		MOVWF	FSR
		MOVLW	2
		CALL	transmit_nbytes			; 自分のポート番号
		
		MOVLW	tcp_src_port
		MOVWF	FSR
		MOVLW	2
		CALL	transmit_nbytes			; 相手のポート番号

		MOVLW	seq_no
		MOVWF	FSR
		MOVLW	4
		CALL	transmit_nbytes			; 自分のＳＥＱＮＯ
		
		
		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	; 自分のSEQ NOを自分のソケット＋８に
		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		; 相手のＳＥＱＮＯ＋１
		
		MOVLW	60h			; オプション有り
		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		; 緊急ポインタ
		
		MOVLW	2h
		CALL	assert_wr		
		MOVLW	4h
		CALL	assert_wr		
		MOVLW	5h
		CALL	assert_wr		
		MOVLW	0b4h
		CALL	assert_wr		
		
		CALL	calc_tcp_sum		; TCP SUMの計算
		
		MOVLW	4h
		MOVWF	PORTC
		MOVLW	PAGE_BEGIN		; transmit page is start page 
		CALL	assert_wr0
		
		MOVLW	5
		MOVWF	PORTC
		MOVLW	.60			; 60バイト送信
		CALL	assert_wr0
		
		MOVLW	6
		MOVWF	PORTC
		DB	01,00		;clrw
		CALL	assert_wr0
		CALL	transmit		; 送信！

		CALL	next_seq_no		; seq_no++
		RETURN

;-----------------------------------------------------------------------------------
;		チェックサム計算
calc_tcp_sum
		CLRF	bytes		;clr	bytes	;２バイトアラインの調整
		
		MOVLW	this_ip		;mov	fsr,#this_ip; 自分のＩＰアドレスを加算
		
		MOVWF	FSR
		MOVF	INDF,W
		CALL	calc_sum
		INCF	FSR,1
		MOVF	INDF,W
		CALL	calc_sum
		INCF	FSR,1
		MOVF	INDF,W
		CALL	calc_sum
		INCF	FSR,1
		MOVF	INDF,W
		CALL	calc_sum
	
		MOVF	ip_src,0		; 相手のＩＰアドレスを加算
		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				; プロトコル番号を加算
		CALL	calc_sum
		MOVLW	TCP_PROTO
		CALL	calc_sum
		
		MOVF	remote_len1,0	; バイト数を加算
		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		; RTL8019バッファに設定
		RETURN



;===================================================================================
;		ＮＩＣの初期化ルーチン
;===================================================================================
initialize
		CALL	init_nic			; ＮＩＣリセット
		CALL	getmac				; ＭＡＣアドレス取得
		CALL	setmac				; ＭＡＣアドレスセット
				; リングバッファ初期化 [2004/10/30]
		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



;-----------------------------------------------------------------------------------
;		RTL8019のリセット
;-----------------------------------------------------------------------------------
reset_nic
		CLRF	PORTC
		MOVLW	21h
		CALL	assert_wr0		; STOP OPERATION
		
		MOVLW	1Fh
		MOVWF	PORTC
		CALL	assert_rd		; 1ehを読む
		
		MOVLW	1Fh
		MOVWF	PORTC
		MOVF	data0,0
		CALL	assert_wr0		; それを書き戻す（RESET)
reset_nic0
		MOVLW	07h
		MOVWF	PORTC
		CALL	assert_rd		; ステータスを読む
		
		BTFSS	data0,7			;data.7	; RESET 終了チェック
		GOTO	reset_nic0
		RETURN


;-----------------------------------------------------------------------------------
;		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

;-----------------------------------------------------------------------------------
;		ＭＡＣアドレス取得
;-----------------------------------------------------------------------------------
getmac
		CLRF	PORTC
		MOVLW	22h
		CALL	assert_wr0
		
		CLRF	remote_adr 
		CLRF	remote_adr1	 
		MOVLW	.12	 	;12bytes転送
		MOVWF	remote_len
		CLRF	remote_len1	 
		CALL	remote_read

		MOVLW	6			; MACアドレスは６バイト
		MOVWF	gcn1
		MOVLW	mymac		; アドレスにmymacに設定
		MOVWF	FSR
get_mac0
		MOVLW	10h
		MOVWF	PORTC
		CALL	assert_rd		; から読み
		CALL	assert_rd		; 
		
		MOVF	data0,0	;mov	INDF,data		; MACアドレスをPICに読み込む
		MOVWF	INDF
		INCF	FSR,1
		DECFSZ	gcn1,1	 
		GOTO	get_mac0
		RETURN



;-----------------------------------------------------------------------------------
;		ＭＡＣアドレス設定
;-----------------------------------------------------------------------------------
setmac
;	PAGE 1
		CLRF	PORTC
		MOVLW	B'01100010'
		CALL	assert_wr0
;
		MOVLW	01h
		MOVWF	PORTC
		MOVLW	mymac
		MOVWF	FSR
		MOVLW	6			; MACアドレスは６バイト
		MOVWF	gcn1
setmac0
		MOVF	INDF,W
		CALL	assert_wr0		; MACアドレスの設定
		INCF	FSR,1
		INCF	PORTC,1
		DECFSZ	gcn1,1	 
		GOTO	setmac0
		MOVLW	7
		MOVWF	PORTC
		MOVLW	PAGE_START + 1		; ついでに
		CALL	assert_wr0		; カレントページのセット
		
		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



;-----------------------------------------------------------------------------------
;		リモートＤＭＡ書き込み準備
;-----------------------------------------------------------------------------------
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


;-----------------------------------------------------------------------------------
;		リモートＤＭＡ読み込み準備
;-----------------------------------------------------------------------------------
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

;-----------------------------------------------------------------------------------
;		チェックサムの計算
;-----------------------------------------------------------------------------------
calc_sum
		BTFSS	bytes,0		;BTFSS	bytes.0	;アラインメントチェック
		GOTO	calc_sum_high
;	LOWバイト
		ADDWF	sum,1	 ;データを(sum[1],sum[0])に加算
		MOVLW	1
		BTFSC	STATUS,C
		addwf	sum1,1		 

		BTFSC	STATUS,C			; １の補数の計算
		addwf	sum,1	 
		BTFSC	STATUS,C
		addwf	sum1,1	 
		INCF	bytes,1	 	; アラインを次に
		RETURN
;	HIGHバイト
calc_sum_high
		ADDWF	sum1,1		  ; データを(sum[1],sum[0])に加算
		MOVLW	1
		
		BTFSC	STATUS,C			; １の補数の計算
		ADDWF	sum,1		 
		BTFSC	STATUS,C
		ADDWF	sum1,1		 
	
		INCF	bytes,1	 			; アラインを次に
		RETURN



assert_wr2times
		DB	01,00		;clrw
		CALL	assert_wr
		DB	01,00		;clrw
		GOTO	assert_wr
;-----------------------------------------------------------------------------------
;	送信データ=data
assert_wr2x
		MOVLW	1	 	; remote_len++
		ADDWF	remote_len,1
		BTFSC	STATUS,C
		INCF	remote_len1,1	 
		MOVF	data0,0			; data変数を媒介
		GOTO	assert_wr
;	送信データ=W
assert_wr2	MOVWF	data0		; 一度しまう
		MOVLW	1	 	; remote_len++
		ADDWF	remote_len,1
		BTFSC	STATUS,C
		INCF	remote_len1,1	 
		MOVF	data0,0
;-----------------------------------------------------------------------------------
;		RTL8019へ書き込み(チェックサム考慮)
;-----------------------------------------------------------------------------------
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


;-----------------------------------------------------------------------------------
;		RTL8019へ単純書き込み
;-----------------------------------------------------------------------------------
assert_wr0
		MOVWF	PORTD	 
assert_wr0_2	BSF	STATUS,RP0
		CLRF	PORTD	 			; ＲＤポート出力
		BCF	STATUS,RP0
		
		BCF	PORTE,1	 
		

		BTFSS	PORTC,5
		GOTO	$-1
		
		BSF	PORTE,1	 
		
		BSF	STATUS,RP0
		MOVLW	0FFH		 	;ＲＤポート入力
		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



;-----------------------------------------------------------------------------------
;		パケット送信関連処理
;-----------------------------------------------------------------------------------
transmit_this_ip
		MOVLW	this_ip	 
		MOVWF	FSR
		MOVLW	4

transmit_nbytes
		MOVWF	gcn1
		MOVLW	10h
		MOVWF	PORTC
transmit0	MOVF	INDF,W
		CALL	assert_wr
		INCF	FSR,1
		DECFSZ	gcn1,1	 
		GOTO	transmit0
		RETURN


transmit_nbytes2
		MOVWF	gcn1
		MOVLW	10h
		MOVWF	PORTC
transmit2_0	MOVF	INDF,W
		CALL	assert_wr2
		INCF	FSR,1
		DECFSZ	gcn1,1		 
		GOTO	transmit2_0
		RETURN

;-----------------------------------------------------------------------------------
;		パケット送信
;-----------------------------------------------------------------------------------
transmit
retry
		CLRF	PORTC
		CALL	assert_rd
		
		BTFSC	data0,2	 	; 送信ビットを見る
		GOTO	transmit			; 送信待ち
		
		CLRF	PORTC
		MOVLW	B'00100110'			; 送信ビットを立てる
		CALL	assert_wr0			; 送信！
trans100
		MOVLW	4
		MOVWF	PORTC
		CALL	assert_rd
		
		BTFSC	data0,0	 
		GOTO	transmit9			; 送信完了？
		BTFSC	data0,3	 
		GOTO	retry
		
		GOTO	trans100
transmit9	RETURN


 
;-----------------------------------------------------------------------------------
;		Ethernetヘッダを作成する。
;-----------------------------------------------------------------------------------
prepare_ether2
		MOVLW	PACKET_SIZE + ARP_SIZE
		MOVWF	remote_len
		GOTO	prepare_ether1
prepare_ether
	;	CALL	wait_transmit			; 送信中待ちを行う
		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			; このパケットを送ってくれた相手のＭＡＣ
		MOVWF	PORTC
		MOVLW	eth_src
		MOVWF	FSR
		MOVLW	6
		CALL	transmit_nbytes
		
		MOVLW	mymac		; 自分のＭＡＣアドレスを設定
		MOVWF	FSR
		MOVLW	6
		CALL	transmit_nbytes
		RETURN


;-----------------------------------------------------------------------------------
;		ＩＰヘッダ作成作業
;-----------------------------------------------------------------------------------
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	 	;チェックサムは２バイトである
		MOVWF	remote_len
		CLRF	remote_len1	 
		CALL	remote_write
		
		MOVLW	10h
		MOVWF	PORTC
		MOVF	sum1,0
		CALL	assert_wr0			; チェックサムの書き込み(assert_wr0をコールしなければならない)
		MOVF	sum,0
		CALL	assert_wr0
		RETURN



;-----------------------------------------------------------------------------------
;		ＩＰプロトコルヘッダ作成
;-----------------------------------------------------------------------------------
ip_common
		CALL	clear_sum			; チェックサムの値をクリア
		
		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,W			; Seq No High
		CALL	assert_wr
		INCF	FSR,1
		
		MOVF	INDF,W			; Seq No Low
		CALL	assert_wr
		MOVLW	1		 
		ADDWF	INDF,F
		DECF	FSR,1
		BTFSC	STATUS,C
		addwf	INDF,F

		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

;----------------------------------------------------------------------------------------------------------
		ORG	0800h			; htmlブランクメッセージ
		DB	06H,8AH			; CR,LF 
		DB	0,0
;----------------------------------------------------------------------------------------------------------

;-----------------------------------------------------------------------------------
;		パラレルＩ／Ｆの制御
;-----------------------------------------------------------------------------------
		org	81Bh
udp_parallel
		MOVLW	$ >> 8
		MOVWF	PCLATH
		MOVLW	udp_data
		MOVWF	FSR
		
		MOVLW	6	 
		SUBWF	INDF,W
		BTFSC	STATUS,C
		GOTO	main90
		MOVF	INDF,W
		INCF	FSR,1
		ADDWF	2,1	 
		GOTO	para_get_status			; ステータスの取得
		GOTO	para_set_high			; Ｈｉｇｈ設定
		GOTO	para_set_low			; Ｌｏｗ設定
		GOTO	para_set_whole			; 全設定
		GOTO	para_get_adc			; A/D変換
		GOTO	para_set_rbpu			; 内蔵プルアップOn/Off
;
;	HIGH/INPUTにセット
para_set_high
		CALL	para_set_common
		MOVF	wk1,0	 
		IORWF	INDF,F
		GOTO	para_get_status
;
;	LOW/OUTPUTにセット
para_set_low
		CALL	para_set_common
		COMF	wk1,1	 
		MOVF	wk1,0	 
		ANDWF	INDF,F
		GOTO	para_get_status
;
;	ビット位置の計算
para_set_common
		INCF	FSR,1
		MOVF	INDF,W	 	;ビット位置(0-7)
		MOVWF	wk
		MOVLW	1 
		MOVWF	wk1
para_set_common0
		MOVF	wk,0
		BTFSC	STATUS,Z
		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,W		; I/Oポート番号
		MOVWF	FSR
		RETURN
;
;	SET WHOLEモード
para_set_whole
		MOVF	INDF,W	 	; ポート
		MOVWF	ptr
		INCF	FSR,1
		MOVF	INDF,W 		; サイズ
		MOVWF	gcn1
		INCF	FSR,1
para_set_whole0
		MOVF	INDF,W	 		; Mask
		MOVWF	wk
		INCF	FSR,1
		MOVF	INDF,W 
		MOVWF	wk1
		INCF	FSR,1
		
		MOVF	FSR,0 		; save FSR
		MOVWF	wk2
		MOVF	ptr,0
		MOVWF	FSR
		MOVF	INDF,W
		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


;
; 内蔵プルアップOn/Off
para_set_rbpu
		BSF	STATUS,RP0
		MOVF	INDF,W
		BTFSS	STATUS,Z
		GOTO	para_set_rbpu1
		BSF	OPTION_REG,7     ;プルアップしない
		GOTO	para_set_rbpu9
para_set_rbpu1
		BCF	OPTION_REG,7   ; プルアップする
para_set_rbpu9	BCF	STATUS,RP0
		GOTO	para_get_status



;-----------------------------------------------------------------------------------
para_get_adc
		MOVF	INDF,W 		; ADCON1の設定
		MOVWF	ADCON1
		BSF	ADCON1,0 
		INCF	FSR,1
		
		MOVF	INDF,W 		;アクイジションタイム待機
		MOVWF	wait_cn
para_get_aqu0
		MOVLW	8	 
		MOVWF	wait_cn2
		DECFSZ	wait_cn2,1 
		GOTO	$-1
		DECFSZ	wait_cn,1 		; 25μs×WaitTime
		GOTO	para_get_aqu0
		BSF	ADCON1,2 	 ; ＡＤ変換開始
		BTFSC	ADCON1,2 	; ＡＤ変換待ち(同期式）
		GOTO	$-1 		; 本当は非同期にしたいところ(^_^;
		
		CLRF	PCLATH
para_get_status
		MOVLW	para_port	 ; 送信元ポート番号
		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			; ＩＰパケットまで作成
		
		CALL	clear_sum			; チェックサムの値をクリア
		
 
		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,W			; From PORT #(HIGH)
		CALL	assert_wr
		INCF	FSR,1
		MOVF	INDF,W			; 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,W
		CALL	assert_wr			; 
		INCF	FSR,1
		MOVF	INDF,W
		CALL	assert_wr			; 
		
		MOVF	ADRESH,0 
		MOVWF	val1			; 変換結果をval[1]:val[0]へ
		BSF	STATUS,RP0
		MOVF	ADRESL,0			;adres,0; page1は下位バイト
		BCF	STATUS,RP0
		MOVWF	val		 
		
		MOVF	val1,0
		CALL	assert_wr			; AD 変換結果(H)
		MOVF	val,0
		CALL	assert_wr			; AD 変換結果(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


;-----------------------------------------------------------------------------------
;		ＵＤＰチェックサム計算＋送信
;
calc_udp_sum
		CLRF	PCLATH
		CLRF	bytes		;clr	bytes ; ２バイトアラインの調整
		MOVLW	this_ip	 	; 自分のＩＰアドレスを加算
		MOVWF	FSR
		
		MOVF	INDF,W
		CALL	calc_sum
		INCF	FSR,1
		MOVF	INDF,W
		CALL	calc_sum
		INCF	FSR,1
		MOVF	INDF,W
		CALL	calc_sum
		INCF	FSR,1
		MOVF	INDF,W
		CALL	calc_sum
	
		MOVF	ip_src,0		; 相手のＩＰアドレスを加算
		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				; プロトコル番号を加算
		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

	 	; チェックサムのセット位置
 
		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		; 基本的に６０バイトとする。(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

;-----------------------------------------------------------------------------------
;		シリアルポート処理
;
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	STATUS,C
		GOTO	main90
		MOVF	data0,0
		ADDWF	2,1 
		GOTO	ser_get_status		; ステータス表示
		GOTO	ser_register_tag	; アドレス登録
		GOTO	ser_unregister_tag	; アドレス削除
		GOTO	ser_transmit		; データ送信
;
;		ＡＲＰ応答受信処理
ser_arp
		BCF	STATUS,IRP
		MOVLW	arp_src_mac & 0ffh
		MOVWF	FSR

		BSF	STATUS,RP0
		BSF	STATUS,RP1
		MOVF	INDF,W	 
		MOVWF	on_ether & 0FFH	; ハードウェアアドレスをセット
		INCF	FSR,1
		MOVF	INDF,W	 
		MOVWF	on_ether1 & 0FFH
		INCF	FSR,1
		MOVF	INDF,W 
		MOVWF	on_ether2 & 0FFH
		INCF	FSR,1
		MOVF	INDF,W 
		MOVWF	on_ether3 & 0FFH
		INCF	FSR,1
		MOVF	INDF,W	 
		MOVWF	on_ether4 & 0FFH
		INCF	FSR,1
		MOVF	INDF,W	 
		MOVWF	on_ether5 & 0FFH
		CLRF	STATUS	 
 
		
		BSF	RCSTA,4		;cren
		BSF	INTCON,6	;peie			; 使用許可
		MOVLW	HIGH (main9)
		MOVWF	PCLATH

		GOTO	main9

;-----------------------------------------------------------------------------------
;		ホストへシリアルポートのステータスを送信する。
;-----------------------------------------------------------------------------------
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			; ＩＰパケットまで作成
		
		CALL	clear_sum			; チェックサムの値をクリア
		
 
		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,W			; From PORT #(HIGH)
		CALL	assert_wr
		INCF	FSR,1
		MOVF	INDF,W			; 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,W
		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			; 6バイトを読み込む
		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


;-----------------------------------------------------------------------------------
;		受信したパケットのソケットが有るかをチェック
;-----------------------------------------------------------------------------------
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,W
		BTFSS	STATUS,Z
		GOTO	search_socket9
		INCF	FSR,1
		MOVF	ip_src1,0 
		SUBWF	INDF,W
		BTFSS	STATUS,Z
		GOTO	search_socket9
		INCF	FSR,1
		MOVF	ip_src2,0 
		SUBWF	INDF,W
		BTFSS	STATUS,Z
		GOTO	search_socket9
		INCF	FSR,1
		MOVF	ip_src3,0 
		SUBWF	INDF,W
		BTFSS	STATUS,Z
		GOTO	search_socket9
		INCF	FSR,1
		
 
		MOVF	tcp_src_port,0
		SUBWF	INDF,W
		BTFSS	STATUS,Z
		GOTO	search_socket9
		INCF	FSR,1
 
		MOVF	tcp_src_port1,0	
		SUBWF	INDF,W
		BTFSS	STATUS,Z
		GOTO	search_socket9
		INCF	FSR,1
		
		MOVLW	.7
		SUBWF	FSR,1
		MOVLW	0F0H 
		IORWF	INDF,F
		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


;-----------------------------------------------------------------------------------
;		ソケットの新規作成
;-----------------------------------------------------------------------------------
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


;-----------------------------------------------------------------------------------
;		Ethernetパケットのブロードキャスト送信処理
;-----------------------------------------------------------------------------------
broad_cast
		CLRF	PCLATH
 
		CLRF	remote_adr
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1

		MOVLW	IP_SIZE + PACKET_SIZE
		MOVWF	remote_len
		CLRF	remote_len1
 
		CALL	remote_write
		
		MOVLW	10h			; 送信先：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		; 送信元：自分のＭＡＣアドレスを設定
		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 	; 自分のＩＰは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			; チェックサムの値をクリア
 
		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				; クライアントBOOTPポート
		CALL	assert_wr
		MOVLW	BOOTPC_PORT			; クライアントBOOTPポート
		CALL	assert_wr
		
		MOVLW	0				; サーバBOOTPポート
		CALL	assert_wr
		MOVLW	BOOTPS_PORT			; サーバBOOTPポート
		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,W
		CALL	assert_wr
		INCF	FSR,1
		MOVF	INDF,W
		CALL	assert_wr
		INCF	FSR,1
		MOVF	INDF,W
		CALL	assert_wr
		INCF	FSR,1
		MOVF	INDF,W
		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
;
;	クライアントハードウェアアドレス
;
		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
;
;		起動ファイル名
;
		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
;-----------------------------------------------------------------------------------
;		ＥＥＰＲＯＭデータの書き込み
;		アドレスは自動インクリメントする
;--------------------------------------------------------------------------------- 

		GOTO	$		;不明
write_eeprom16
		MOVLW	'b' 
		MOVWF	ind
		MOVF	wk2,W
		XORWF	wk1,F
		MOVF	wk1,W
		XORWF	wk2,F
		MOVF	wk2,W
		XORWF	wk1,F
		CALL	write_eeprom
		MOVF	wk2,W
		MOVWF	wk1
write_eeprom
		MOVLW	'w'
		SUBWF	ind,W
		BTFSC	STATUS,Z
		GOTO	write_eeprom16
write_eeprom0	BSF	STATUS,RP1
		BCF	STATUS,RP0
		MOVF	wk,W	 	;addr
		MOVWF	EEADR
		MOVF	wk1,W
		MOVWF	EEDATA
		BSF	STATUS,RP0
		BCF	EECON1,EEPGD			;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,F
		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	STATUS,Z
		GOTO	get_nextbyte9
		MOVLW	1			; LENGTH--
		subwf	remote_len,1 
		BTFSS	STATUS,C
		subwf	remote_len1,1	 
		RETURN
get_nextbyte9
		CLRF	data0		 
		RETURN



;-----------------------------------------------------------------------------------
;		ｃｇｉ(GETメソッド)のパース
;		00b=192.168.0.200
;-----------------------------------------------------------------------------------
parse_cgi
		BCF	magic_flag,MAGIC
		CALL	get_nextbyte

		MOVF	data0,0					; NULLの時
		BTFSC	STATUS,Z
		GOTO	parse9_tag

		MOVLW	0AH					; 改行文字の時
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	parse9_tag

parse_command							; コマンドパース
		MOVF	magic_flag,W				; 画面表示フラグがセットされているか？
		BTFSC	STATUS,Z				; されていない(Z=SET)ならばコマンドは処理しない
		GOTO	parse9_tag

		MOVLW	'R'					; ピンの変更
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	modify_pin

		MOVLW	'M'					; マジックパケット送信
		SUBWF	data0,0
		BTFSS	STATUS,Z
		GOTO	parse_config
		CALL	get_nextbyte				; ジャンプする前に次の文字を読み込んでおく->data0

		MOVLW	HIGH(send_magic)
		MOVWF	PCLATH
		GOTO	send_magic

parse_config							; コンフィグパース
		BTFSS	magic_flag,DO_CFG			; コンフィグフラグがセットされているか？
		GOTO	parse9_tag				; されていない(CLEAR)ならばコンフィグコマンドは処理しない

		MOVLW	'I'					; Initial value
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	initial_values_tag
	 		
		MOVLW	'0'	 
		SUBWF	data0,1
		MOVF	data0,0	 
		MOVWF	wk
		SWAPF	wk,1 
		
		CALL	get_nextbyte
	 
		MOVF	data0,0
		BTFSC	STATUS,Z
		GOTO	parse9_tag
		
		MOVLW	'0'	 
		SUBWF	data0,1
		MOVF	data0,0	 
		IORWF	wk,1
		
		CALL	get_nextbyte
	 
		MOVF	data0,0
		BTFSC	STATUS,Z
		GOTO	parse9_tag
		MOVF	data0,0	 
		MOVWF	ind
 								; byte単位
		MOVLW	'b'
		SUBWF	ind,0
		BTFSC	STATUS,Z
		GOTO	parse4
 								; word単位
		MOVLW	'w'
		SUBWF	ind,0
		BTFSC	STATUS,Z
		GOTO	parse4
 								; 6オクテット単位
		MOVLW	'h'
		SUBWF	ind,0
		BTFSS	STATUS,Z
		GOTO	parse9_tag				; b|w|h以外なら終了
		BSF	magic_flag,MAGIC
parse4								; 値の取得
		CLRF	wk1  					; 値の初期値＝０
		CLRF	wk2

		CALL	get_nextbyte				; skip '='

		MOVF	data0,0					; =(NULL)
		BTFSC	STATUS,Z
		GOTO	parse9_tag
 
		MOVLW	'&'					; & パラメータ取得に戻る
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	parse_cgi

parse_cgi0
		CALL	get_nextbyte

		MOVF	data0,0
		BTFSC	STATUS,Z
		GOTO	parse9_tag

		MOVLW	' '
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	parse91_tag

		MOVLW	9
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	parse91_tag

		MOVLW	'&'
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	parse_cgi2
 
		MOVLW	'.'
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	parse_cgi3
 
		MOVLW	'-'
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	parse_cgi3
 
		MOVLW	'0'				; '0'より小さい場合は書き込む
		SUBWF	data0,W
		BTFSS	STATUS,C
		GOTO	parse_cgi3
 
		MOVLW	'A'				; 'A'より大きい場合は次へ
		SUBWF	data0,W
		BTFSC	STATUS,C
		GOTO	parse_alpha1

		MOVLW	'9' ^ 0FFH			; 'A'より小さく、'9'より大きい場合は書き込む
		ADDWF	data0,W
		BTFSC	STATUS,C
		GOTO	parse_cgi3
parse_alpha1
		MOVLW	'a'				; 'a'より大きい場合は
		SUBWF	data0,W
		BTFSC	STATUS,C
		GOTO	parse_alpha2
 
		MOVLW	'F' ^ 0FFH			; 'a'より小さく、'F'より大きい場合は書き込む
		ADDWF	data0,W
		BTFSC	STATUS,C
		GOTO	parse_cgi3
parse_alpha2
		MOVLW	'f' ^ 0FFH			; 'f'より大きい場合は書き込む
		ADDWF	data0,W
		BTFSC	STATUS,C
		GOTO	parse_cgi3

		BTFSS	magic_flag,MAGIC
		GOTO	parse_multi
		CALL	multiply_hex
		GOTO	parse_cgi0
		
parse_multi
		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


;-----------------------------------------------------------------------------------
;		１０倍してdataを足し込む
;-----------------------------------------------------------------------------------
multiply_added
		MOVLW	'0'	 	
		SUBWF	data0,1		; dataはASCIIキャラクタになっているため
		
		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	 	;足し込み
		ADDWF	wk1,1
		BTFSC	STATUS,C			; CARRYのチェック
		INCF	wk2,1	 
		RETURN

;-----------------------------------------------------------------------------------
;		１６倍してdataを足し込む
;-----------------------------------------------------------------------------------
multiply_hex
		MOVLW	'a'                             ; 'a'以上？
		SUBWF	data0,W
		BTFSS	STATUS,C
		GOTO	multiply_hex_upper
		MOVLW	'a' - .10
		GOTO	multiply_hex_subwf

multiply_hex_upper
		MOVLW	'A'                             ; 'A'以上？
		SUBWF	data0,W
		BTFSS	STATUS,C
		GOTO	multiply_hex_numeric
		MOVLW	'A'-.10
		GOTO	multiply_hex_subwf

multiply_hex_numeric
		MOVLW	'0'
multiply_hex_subwf
		SUBWF	data0,F				; dataはASCIIキャラクタになっているため

		SWAPF	wk1,W				; 上下反転
		ANDLW	B'11110000'			; 上位をフィルタ
		ADDWF	data0,W				; 下位を加算
		MOVWF	wk1
		RETURN


;-----------------------------------------------------------------------------------
;		ＥＥＰＲＯＭデータを初期値に戻す
;-----------------------------------------------------------------------------------
		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

;-----------------------------------------------------------------------------------
;		ｃｇｉによるピンの変更
;		RA0=H
;-----------------------------------------------------------------------------------
modify_pin
		CALL	get_nextbyte			; どのポートかを取得
		MOVLW	'A' ; 範囲外はエラー
		SUBWF	data0,0
		BTFSS	STATUS,C
		GOTO	parse9_tag
		MOVLW	'B' ^ 0FFH	 
		ADDWF	data0,0
		BTFSC	STATUS,C
		GOTO	parse9_tag
		MOVLW	'A'	 	; 'A'を減算
		SUBWF	data0,1
		MOVLW	PORTA	 
		ADDWF	data0,1
		MOVF	data0,0
		MOVWF	FSR

		CALL	get_nextbyte			; ビット位置の取得
		MOVLW	'0'	 	;範囲外はエラー
		SUBWF	data0,0
		BTFSS	STATUS,C
		GOTO	parse9_tag
		MOVLW	'9' ^ 0FFH		 	; 
		ADDWF	data0,0
		BTFSC	STATUS,C
		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		;; '='がないとエラー
		BTFSS	STATUS,Z
		GOTO	parse9_tag
		CALL	get_nextbyte
		MOVLW	'H'	 
		SUBWF	data0,0		; High/Lowどちらを出力するか？
		BTFSC	STATUS,Z
		GOTO	modify_pin_h
		COMF	wk,1		 
		MOVF	wk,0		 
		ANDWF	INDF,F		; Ｉ／Ｏポートに'Ｌ'を出力する
		GOTO	parse9_tag

modify_pin_h
		MOVF	wk,0	 
		IORWF	INDF,F		;; Ｉ／Ｏポートに'Ｈ'を出力する
		GOTO	parse9_tag


get_initial_value
		MOVLW	HIGH(default_values_begin) ; 初期値の値を取得
		MOVWF	PCLATH
		MOVF	wk,0	 
		MOVWF	PCL




;===================================================================================
;		スタートアップルーチン
;===================================================================================

start

		CLRF	PORTA			; 各ポートの初期化
		CLRF	PORTB
		CLRF	PORTC			; RC =  RTL8019AS の SA0-SA5
		CLRF	PORTD			; RD = 00h
		MOVLW	B'111'		; 各コントロールポート＝Ｈ
		MOVWF	PORTE
		BSF	STATUS,RP0
		MOVLW	B'10000110'	 
		DB	00,62	 		; 割り込みの設定
		MOVLW	B'10000010' 
		MOVWF	ADCON1		; RE0-2 are Digital Pin
		MOVLW	B'00111111' 
		MOVWF	TRISA		; RA0-4はＡＤ入力ピンとする
		MOVLW	B'000'	 	; RE0-2は出力ピンとする
		MOVWF	TRISE
		BCF	STATUS,RP0

		CLRF	use	 
				; LCDポート/シリアルポート有効フラグをクリア

		CALL	get_ip_address		; EEPROMのIPアドレスをファイルレジスタに読み出す。
		CALL	get_port_no		; EEPROMのポート番号をファイルレジスタに読み出す。
;
;	LCDポートのチェック
;	ポートが０以外ならrb７－２は出力
;
		BSF	STATUS,RP0
		MOVF	lcd_port,0	; ＬＣＤポート番号が０かのチェック
		iorwf	lcd_port1,0 
		MOVLW	B'00001111'		; ＬＣＤポートが０の時,RB7-4出力,RB3-0入力
		BTFSS	STATUS,Z
		MOVLW	B'00000011'		; ＬＣＤポートが０以外の時,RB7-2出力,RB1-0入力
		MOVWF	TRISB	 
		BCF	STATUS,RP0
		
		BTFSS	STATUS,Z
		BSF	use,0	 
			; ＬＣＤポートが０以外ならuse.LCDをイネーブルにする。


;	SERIALポートのチェック

		CALL	clear_seq_no		; TCPシーケンス番号を０に
		
		CALL	init_lcd		; 液晶モジュールの初期化
		
		MOVLW	B'11' 
		MOVWF	PORTE		; 各コントロールポート＝Ｈ
		
		MOVLW	5	 	; ５ｍｓ待つ
		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		; ソケットバッファ初期化
		CLRF	PCLATH
		
		CALL	initialize		; RTL8019ASの初期化
		
		MOVLW	$>>8
		MOVWF	PCLATH
		
		MOVLW	this_ip	 
		MOVWF	FSR
		;mov	FSR,#this_ip		; 自分のIPが 0.0.0.0 かどうかのチェック
		MOVF	INDF,W
		INCF	FSR,1
		iorwf	INDF,W
		INCF	FSR,1
		iorwf	INDF,W
		INCF	FSR,1
		iorwf	INDF,W
		BTFSC	STATUS,Z
		GOTO	start1			; IPが0.0.0.0の時はstart1へ
		
		MOVLW	HIGH (print_ip)	; IPアドレスを液晶に表示
		MOVWF	PCLATH
		CALL	print_ip
		GOTO	start2
start1
		MOVLW	HIGH (write_lcd4)
		MOVWF	PCLATH
		
		BSF	PORTB,2
		MOVLW	'D'			; 'DHCP'を液晶に表示
		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'		; rc.4を入力ピンに変更
		MOVWF	PORTC
		BCF	STATUS,RP0
		
		MOVLW	HIGH (wait_us)
		MOVWF	PCLATH

		MOVLW	.100 	; 100us待つ
		MOVWF	wait_cn
		CALL	wait_us
		
		MOVLW	HIGH (start2)
		MOVWF	PCLATH
		BTFSS	PORTC,4		 	; rc.4ピンをチェック
		GOTO	bootstrap		; 'L'ならブートストラップモードへ移行
		
		BSF	STATUS,RP0
		MOVLW	B'10100000'		; rcを元に戻す
		MOVWF	TRISC
		MOVLW	B'00100110' 
		MOVWF	TXSTA			; ASYNCモジュール送信側を初期化
		MOVLW	BAUD_RATE 
		MOVWF	SPBRG			; ボーレート設定
		BSF	PIE1,5			; rcie; 受信割り込み許可
		BCF	STATUS,RP0
		MOVLW	B'10000000'	 
		MOVWF	RCSTA			; ASYNCモジュール受信側を初期化
		BCF	STATUS,RP0
		BCF	INTCON,6	;peie		; 周辺装置割り込み許可
		
		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			; 初期状態 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; グローバル割り込み許可
		GOTO	main
;-----------------------------------------------------------------------------------
;		ソケットバッファのクリア
;-----------------------------------------------------------------------------------
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
;
;		シリアル登録アドレスのクリア
;
;		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

;-----------------------------------------------------------------------------------
;		PIC16F877のEEPROMならIPアドレスを取得
;-----------------------------------------------------------------------------------
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
;-----------------------------------------------------------------------------------
;		PIC16F877のEEPROMからポート番号を取得
;-----------------------------------------------------------------------------------
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
;-----------------------------------------------------------------------------------
;		ＴＣＰシーケンス番号の初期化
;-----------------------------------------------------------------------------------
clear_seq_no
		BSF	STATUS,RP0
		CLRF	seq_no	 
		CLRF	seq_no1	 
		CLRF	seq_no2	 
		CLRF	seq_no3	 
		BCF	STATUS,RP0
		RETURN


;-----------------------------------------------------------------------------------
;		液晶初期化
;-----------------------------------------------------------------------------------
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'		; クリアコマンド
		MOVWF	d4
		CALL	write_lcd4
		MOVLW	.2		; クリアが終わるまで待つ
		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



;-----------------------------------------------------------------------------------
;		８ビットモード用液晶書き込みルーチン
;-----------------------------------------------------------------------------------
write_lcd8
		BTFSS	use,0		;BTFSS	use.0; LCDがオンでないとRBポートには書き込まない
		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	 	; ＲＢポートへ出力
		MOVWF	PORTB

		GOTO	$+1
		BSF	PORTB,3	 	; Ｅピンを'H'
		GOTO	$+1			;jmp	$+1
		BCF	PORTB,3	 
lcd_skip
		MOVLW	.40
		MOVWF	wait_cn
		CALL	wait_us
		RETURN




;-----------------------------------------------------------------------------------
;		４ビットモード用液晶書き込みルーチン
;-----------------------------------------------------------------------------------
write_lcd4
		MOVF	d4,0	 
		MOVWF	d8
		CALL	write_lcd8
		
		MOVF	d4,0	 
		MOVWF	d8
		SWAPF	d8,1	 
		CALL	write_lcd8
		RETURN

;-----------------------------------------------------------------------------------
;		１６進数液晶出力ルーチン
;-----------------------------------------------------------------------------------
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_ms
wait_ms0
		CLRF	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_us
wait_us0
		GOTO	$+1 
	 
		DECFSZ	wait_cn,1
		GOTO	wait_us0
		RETURN


;-----------------------------------------------------------------------------------
;		バイナリ３２ビットの１０進変換ルーチン
;-----------------------------------------------------------------------------------
put_decimal32
		MOVF	FSR,0	 
		MOVWF	save_fsr
		MOVLW	decimal_top & 0ffh	; 格納場所初期値
		MOVWF	FSR
		BSF	STATUS,IRP			; ＩＲＰ＝１
		CALL	divide32		; 最下位変換
		CALL	divide32
		CALL	divide32
		CALL	divide32
		CALL	divide32
		
		CALL	divide32
		CALL	divide32
		CALL	divide32
		CALL	divide32
		CALL	divide32		; 最上位変換
		
		MOVLW	.10 - .1		;mov	val_cn,#10-1
		MOVWF	val_cn
		GOTO	put_decimal_ent


;-----------------------------------------------------------------------------------
;		バイナリ１６ビットの１０進変換ルーチン
;-----------------------------------------------------------------------------------
put_decimal16
		MOVF	FSR,0 
		MOVWF	save_fsr
		MOVLW	decimal_top & 0ffh	; 格納場所初期値
		MOVWF	FSR
		BSF	STATUS,IRP			; ＩＲＰ＝１
		CALL	divide16		; 最下位変換
		CALL	divide16
		CALL	divide16
		CALL	divide16
		CALL	divide16		; 最上位変換
		
		MOVLW	.5 - .1	 
		MOVWF	val_cn
		GOTO	put_decimal_ent

;-----------------------------------------------------------------------------------
;		バイナリ８ビットの１０進変換ルーチン
;-----------------------------------------------------------------------------------
put_decimal
		MOVWF	val
		
		MOVF	FSR,0	 
		MOVWF	save_fsr
		MOVLW	decimal_top & 0ffh	; 格納場所初期値
		MOVWF	FSR
		BSF	STATUS,IRP			; ＩＲＰ＝１
		CALL	divide			; 最下位変換
		CALL	divide
		CALL	divide			; 最上位変換
		
		MOVLW	.3 - .1	 
		MOVWF	val_cn
put_decimal_ent	CLRF	val_m	 
put_decimal0
		MOVF	val_m,0
		BTFSS	STATUS,Z
		GOTO	put_decimal1
		MOVLW	'0'	 
		SUBWF	INDF,W
		BTFSC	STATUS,Z
		GOTO	put_decimal2
put_decimal1	MOVF	INDF,W	 
		MOVWF	data0
		CALL	puttty
			; 出力(出力先は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,W	 	; 最下位桁
		MOVWF	data0
		CALL	puttty			; 出力(出力先はdestで変わる)
		MOVLW	HIGH (put_decimal2)
		MOVWF	PCLATH

		BCF	STATUS,IRP
		MOVF	save_fsr,0
		MOVWF	FSR
		RETURN


;-----------------------------------------------------------------------------------
;		バイナリ８ビットを１０進で液晶に表示する
;-----------------------------------------------------------------------------------
print_dec
		MOVWF	val
		
		MOVF	FSR,0	 	; fsrをセーブ
		MOVWF	save_fsr
		MOVLW	decimal_top & 0ffh	; 格納場所初期値
		MOVWF	FSR
		BSF	STATUS,IRP			; ＩＲＰ＝１
		CALL	divide			; 最下位変換
		CALL	divide
		CALL	divide			; 最上位変換
		
		BSF	PORTB,2
		MOVF	INDF,W 
		MOVWF	d4
		CALL	write_lcd4
		INCF	FSR,1
		MOVF	INDF,W	 
		MOVWF	d4
		CALL	write_lcd4
		INCF	FSR,1
		MOVF	INDF,W 
		MOVWF	d4
		CALL	write_lcd4
		
		BCF	STATUS,IRP
		MOVF	save_fsr,0
		MOVWF	FSR
		RETURN






;-----------------------------------------------------------------------------------
;		８ビット除算サブルーチン
;-----------------------------------------------------------------------------------
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	 	; 余り
		MOVWF	INDF
		MOVLW	'0'	 
		ADDWF	INDF,F
		RETURN


;-----------------------------------------------------------------------------------
;		１６ビット除算サブルーチン
;-----------------------------------------------------------------------------------
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 	; 余り
		MOVWF	INDF
		MOVLW	'0'	 
		ADDWF	INDF,F
		RETURN


;-----------------------------------------------------------------------------------
;		３２ビット除算サブルーチン
;-----------------------------------------------------------------------------------
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	 	; 余り
		MOVWF	INDF
		MOVLW	'0'	 
		ADDWF	INDF,F
		RETURN

;===================================================================================
;		ブートストラップメインルーチン
;===================================================================================
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		; カーソルを２行目に移動

		MOVLW	.16	 
		MOVWF	gcn1
		MOVLW	lcd_mes & 0ffh
		MOVWF	wk
bootstrap10
		CALL	get_lcdmes		; 'Bootstrap Mode'を液晶に表示
		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	 
;
;		ASYNCの初期化
;
		BSF	STATUS,RP0 
		MOVLW	B'10100000' 
		MOVWF	TRISC
		MOVLW	B'00100110'	 	; 送信側設定
		MOVWF	TXSTA
		MOVLW	BAUD_RATE 	; ボーレート設定
		MOVWF	SPBRG
		BSF	PIE1,RCIE 		; 受信割り込み有効
		BCF	STATUS,RP0	 
		MOVLW	B'10010000' 
		MOVWF	RCSTA
		MOVLW	async_transmit & 0ffh ; 送信ルーチンの設定
		MOVWF	dest
		MOVLW	async_transmit >> 8  
		MOVWF	dest1
		BSF	INTCON,PEIE	 			; 周辺装置割り込み許可
		BSF	INTCON,GIE 			; (グローバルな)割り込み許可

		MOVLW	bs_1 & 00ffh 		; 起動メッセージ
		MOVWF	com_cn
		CALL	put_bs_text
		
		MOVLW	bs_config & 00ffh 
		MOVWF	com_cn			; 現在の設定表示
		CALL	put_bs_text
		
		MOVLW	bs_prompt & 00ffh 	; プロンプト表示
		MOVWF	com_cn
		CALL	put_bs_text
;-----------------------------------------------------------------------------------
;		Bootstrapのメインループ
;-----------------------------------------------------------------------------------
		BSF	STATUS,RP0	 
bootstrap0
 			; 受信待機(受信するとfifo_cn!=0になる)
		MOVF	fifo_cn,0
		BTFSC	STATUS,Z
		GOTO	bootstrap0		
		MOVF	fifo_poi,0	 
		MOVWF	FSR			; 受信ポインタを取得
		MOVF	INDF,W		 
		MOVWF	data0			; 受信した文字を取得
		
		INCF	fifo_poi,1				; 受信バッファをインクリメント
 
		MOVLW	fifo_bottom
		SUBWF	fifo_poi,0
		BTFSS	STATUS,C
		GOTO	ring1_1
		MOVLW	fifo_top 
		MOVWF	fifo_poi
ring1_1		DECF	fifo_cn,1	 	; 受信バイト数をデクリメント
		
 		; バックスペース文字の場合...
		MOVLW	CH_BACKSPACE
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	boots_bs
		BCF	STATUS,RP0 
		CALL	async_transmit				; エコーバックの為、送信！！
		BSF	STATUS,RP0 
		
 			; CRの場合...
		MOVLW	.13
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	boots_cr			
		INCF	fifo_line_cn,1
		GOTO	bootstrap0				; メインループへ戻る


;-----------------------------------------------------------------------------------
;		バックスペース受信処理
;-----------------------------------------------------------------------------------
boots_bs
 				; 削除する文字がない場合はなにもしない
		MOVF	fifo_line_cn,0
		BTFSC	STATUS,Z
		GOTO	bootstrap0
		MOVF	fifo_poi,0 
		MOVWF	FSR
		DECF	FSR,1	 
		
 		MOVLW	fifo_top
		SUBWF	FSR,0
		BTFSC	STATUS,C
		GOTO	boots_bs1
		MOVLW	fifo_bottom - 1	 
		MOVWF	FSR
boots_bs1	CLRF	INDF	 	; いまタイプされたBS文字をクリア
		
		MOVF	fifo_line,0	 
		MOVWF	FSR
		MOVF	fifo_line_cn,0	 
		ADDWF	FSR,1
		DECF	FSR,1		 
		
	 
		MOVLW	fifo_bottom
		SUBWF	FSR,0
		BTFSS	STATUS,C
		GOTO	boots_bs2
		MOVLW	fifo_top	 
		SUBWF	FSR,1
boots_bs2	CLRF	INDF	 	; 直前のタイプ文字をクリア
		BCF	STATUS,IRP		 
		
		BCF	STATUS,RP0	 
		CALL	async_transmit				; エコーバックの為、BS文字をエコー
		MOVLW	' '	 
		MOVWF	data0
		CALL	async_transmit				; スペースの出力してから
		MOVLW	CH_BACKSPACE 
		MOVWF	data0
		CALL	async_transmit				; もう一度ＢＳをエコー
		BSF	STATUS,RP0 
		
		DECF	fifo_line_cn,1
		GOTO	bootstrap0


;-----------------------------------------------------------------------------------
;		ＣＲ受信処理
;-----------------------------------------------------------------------------------
boots_cr
		MOVLW	.10	 
		MOVWF	data0
		BCF	STATUS,RP0	 
		CALL	async_transmit				; 改行をエコー
		BSF	STATUS,RP0	 
	 	; 何も入力されていない？
		MOVF	fifo_line_cn,0
		BTFSS	STATUS,Z
		GOTO	bs_job					; 仕事を分担
bootstrap9
		BCF	STATUS,RP0		;rp0
		MOVLW	bs_prompt & 00ffh	;mov	com_cn,#bs_prompt & 00ffh
		MOVWF	com_cn			; プロンプト表示
		CALL	put_bs_text
		
		BSF	STATUS,RP0	 
		MOVF	fifo_poi,0		 
		MOVWF	fifo_line
		CLRF	fifo_line_cn
		GOTO	bootstrap0				; メインループへ

;
;		無効なコマンドが入力されたとき
;
bootstrap99
		BCF	STATUS,RP0		 
		MOVLW	bs_invalid & 00ffh 
		MOVWF	com_cn
		CALL	put_bs_text
		GOTO	bootstrap9



get_bs_str
		MOVLW	HIGH(get_bs_job)
		MOVWF	PCLATH
		MOVF	bs_ptr,0
		GOTO	get_bs_job
get_bs_str2
		MOVLW	HIGH(get_bs_job)
		MOVWF	PCLATH
		MOVF	bs_ptr2,0
		MOVWF	PCL


;-----------------------------------------------------------------------------------
;		コマンド解析処理
;-----------------------------------------------------------------------------------
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

		
 				; 該当なし
		MOVF	bs_ptr2,0
		BTFSC	STATUS,Z
		GOTO	bootstrap99
bs_job0
		CALL	get_bs_str2
		MOVWF	wk	 
		MOVLW	$ >> 8	 
		MOVWF	PCLATH

	 	; 最後までＯＫ
		MOVF	wk,0
		BTFSC	STATUS,Z
		GOTO	bs_job1			
		CALL	getterm				; バッファから１文字取得
		BSF	STATUS,RP0	 
		
 		MOVLW	.13
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	bs_job2	
 		; 文字違い？
		MOVF	data0,0
		SUBWF	wk,0
		BTFSS	STATUS,Z
		GOTO	bs_job2			
		INCF	bs_ptr2,1				; 1文字進める
		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


;-----------------------------------------------------------------------------------
;		'initialize' 実行ルーチン
bsj_init
		CALL	initial_values
bsj_config	MOVLW	bs_config & 00ffh    
		MOVWF	com_cn			; 現在の設定表示

		CALL	put_bs_text
		GOTO	bootstrap9
;-----------------------------------------------------------------------------------
;		'help' 実行ルーチン
bsj_help
		MOVLW	bs_help & 00ffh	 
		MOVWF	com_cn			; ヘルプ
		CALL	put_bs_text
		GOTO	bootstrap9
;-----------------------------------------------------------------------------------
;		スペース文字の読み飛ばし
skip_space
		CALL	getterm
 
		MOVLW	' '
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	skip_space
 
		MOVLW	9
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	skip_space	
		RETURN
;-----------------------------------------------------------------------------------
;		'lcd=xxxxx' 実行ルーチン
bsj_lcd
		MOVLW	.16 + .2 
		MOVWF	 wk
		GOTO	bs_set_word
;-----------------------------------------------------------------------------------
;		'para=xxxxx' 実行ルーチン
bsj_para
		MOVLW	.16 + .2 + .2
		MOVWF	 wk
;		mov	wk[0],#16+2+2
		GOTO	bs_set_word
;-----------------------------------------------------------------------------------
;		'serial=xxxxx' 実行ルーチン
bsj_serial
;		mov	wk[0],#16+2+2+2
		MOVLW	.16 + .2 +.2 + .2
		MOVWF	 wk
		GOTO	bs_set_word
;-----------------------------------------------------------------------------------
;		'http=xxxxx' 実行ルーチン
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' 実行ルーチン
bsj_net
		;mov	wk[0],#4
		MOVLW	4
		MOVWF	wk
		GOTO	bs_set_byte
;-----------------------------------------------------------------------------------
;		'gate=xxxxx' 実行ルーチン
bsj_gate
 
		MOVLW	8
		MOVWF	wk
		GOTO	bs_set_byte
;-----------------------------------------------------------------------------------
;		'ip=xxx.xxx.xxx.xxx' 実行ルーチン
bsj_ip
 		; EEPROM ADR=0
		CLRF	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	STATUS,Z
		GOTO	put_bs_err	
	 
		MOVLW	'='
		SUBWF	data0,0
		BTFSS	STATUS,Z
		GOTO	put_bs_err			
		
		CALL	skip_space
	 
		MOVLW	.13
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	put_bs_err			
		CLRF	wk1		 ; 値の初期値＝０
		CLRF	wk2	 	; 値の初期値＝０
		GOTO	bs_getnumber
bs_getnumber0
		CALL	getterm
bs_getnumber
	 				; CRなら終了
		MOVLW	.13
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	bs_write9			
 		MOVLW	'.'
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	bs_write
 		MOVLW	','
		SUBWF	data0,0
		BTFSC	STATUS,Z
		GOTO	bs_write
 		MOVLW	'0'
		SUBWF	data0,0
		BTFSS	STATUS,C
		GOTO	bs_write
 		MOVLW	'9' ^ 0FFH
		ADDWF	data0,0
		BTFSC	STATUS,C
		GOTO	bs_write

		CALL	multiply_added
		GOTO	bs_getnumber0
bs_write
		CALL	write_eeprom
		DECF	byte_cn,1
 					; 規定バイト数を書き込んだ？
		MOVF	byte_cn,0
		BTFSC	STATUS,Z
		GOTO	bootstrap9
		CLRF	wk1		;clr	wk[1]; 値の初期値＝０
		CLRF	wk2		;clr	wk[2]	; 値の初期値＝０

		GOTO	bs_getnumber0
bs_write9
		CALL	write_eeprom
		GOTO	bootstrap9

;-----------------------------------------------------------------------------------
;		ラインバッファから１文字読み込み(終端文字はCR)
;-----------------------------------------------------------------------------------
getterm
		BSF	STATUS,RP0		;rp0
getterm0	MOVF	fifo_line,0		;mov	fsr,fifo_line
		MOVWF	FSR
		MOVF	INDF,W			;mov	data,indirect	
		MOVWF	data0			; コマンドの解析
		
		INCF	fifo_line,1
 		MOVLW	fifo_bottom
		SUBWF	fifo_line,0
		BTFSS	STATUS,C
		GOTO	getterm1
		MOVLW	fifo_top 
		MOVWF	fifo_line
getterm1	DECF	fifo_line_cn,1		; 受信バイト数をデクリメント
		
			; NULL文字はスキップする
		MOVF	data0,0
		BTFSC	STATUS,Z
		GOTO	getterm0
		BCF	STATUS,RP0		;rp0
		RETURN 

put_bs_err
		MOVLW	bs_err & 00ffh	 
		MOVWF	com_cn			; Syntax error表示
		CALL	put_bs_text
		GOTO	bootstrap9




;-----------------------------------------------------------------------------------
;		ブートストラップルーチン用テキスト出力ルーチン
;-----------------------------------------------------------------------------------
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	STATUS,Z
		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



;-----------------------------------------------------------------------------------
;		２３２Ｃ出力ルーチン
;-----------------------------------------------------------------------------------
async_transmit
		BTFSS	PIR1,4		;BTFSS	pir1.4
		GOTO	async_transmit
		MOVF	data0,0		 
		MOVWF	TXREG
		RETURN


;-----------------------------------------------------------------------------------
;		コントロールコード出力(その１)
;-----------------------------------------------------------------------------------
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_mymac_address	; 0:自分のMACアドレス
		GOTO	put_ip_address		; 1:IPアドレス
		GOTO	put_netmask		; 2:ネットマスク
		GOTO	put_gateway_address	; 3:ゲートウェイ
		GOTO	put_http_port		; 4:httpポート
		GOTO	put_lcd_port		; 5:lcdポート
		GOTO	put_io_port		; 6:parallelポート
		GOTO	put_232_port		; 7:232cポート
		GOTO	put_version		; 8:バージョン表示
		GOTO	put_send_packet		; 9:送信パケット数
		GOTO	put_this_ip		; A:自ＩＰの表示 (:)
		GOTO	put_ptop		; B:PtoP IPアドレス (;)
		GOTO	put_wola_address	; C:WOL アドレス A (<)
		GOTO	put_wolb_address	; D:WOL アドレス B (=)
		GOTO	put_wolc_address	; E:WOL アドレス C (>)
		GOTO	put_wold_address	; F:WOL アドレス D (?)

put_wola_address
		MOVLW	20			; 読み込むWOLアドレス
		GOTO	read_wol
put_wolb_address
		MOVLW	28
		GOTO	read_wol
put_wolc_address
		MOVLW	30
		GOTO	read_wol
put_wold_address
		MOVLW	38
read_wol
		BSF	STATUS,RP1
		MOVWF	EEADR			; 読み込みアドレスセット
		BCF	STATUS,RP1
		MOVLW	.6
		MOVWF	magic_loop		; 読み込みバイト数セット
		MOVLW	magic_mac
		MOVWF	FSR
read_wol_loop
		BSF	STATUS,RP1
		BSF	STATUS,RP0
		BCF	EECON1,7		;eepgd
		BSF	EECON1,0
		BCF	STATUS,RP0
		MOVF	EEDATA,W
		MOVWF	INDF
		INCF	EEADR,F
		INCF	FSR,F
		BCF	STATUS,RP1
		DECFSZ	magic_loop,F
		GOTO	read_wol_loop
		MOVLW	magic_mac
		GOTO	put_mac_address

put_send_packet
		MOVLW	ident
		MOVWF	FSR
		MOVF	INDF,W		 
		MOVWF	val1
		INCF	FSR,1
		MOVF	INDF,W		 
		MOVWF	val
		INCF	FSR,1	
		CLRF	val2
		INCF	FSR,1
		CLRF	val3
		GOTO	put_decimal32		; 送信パケット数を表示

put_http_port
		MOVLW	.16		 
		GOTO	putcom16
put_lcd_port
		MOVLW	.16 + .2	 
		GOTO	putcom16
put_io_port
		MOVLW	.16 + .4	 
		GOTO	putcom16
put_232_port
		MOVLW	.16 + .6	 
putcom16
		BSF	STATUS,RP1
		MOVWF	EEADR
		GOTO	put_number16
	;	RETURN


put_this_ip
		MOVLW	this_ip 
		MOVWF	FSR
		MOVLW	4
		MOVWF	common
		CALL	put_number_fr
		RETURN
put_ptop
		MOVLW	.24	 
		GOTO	putcom32
put_ip_address
		MOVLW	0
		GOTO	putcom32
put_netmask
		MOVLW	.4
		GOTO	putcom32
put_gateway_address
		MOVLW	.8
		GOTO	putcom32
put_version
		MOVLW	.12
putcom32	BSF	STATUS,RP1
		MOVWF	EEADR
		MOVLW	.4 
		MOVWF	common
		GOTO	put_number
		RETURN

;-----------------------------------------------------------------------------------
;		外部ポートに出力
;-----------------------------------------------------------------------------------
puttty
		MOVF	dest1,0	 
		MOVWF	PCLATH
		MOVF	dest,0	 
		MOVWF	PCL

;-----------------------------------------------------------------------------------
;		'.' 区切りで８ビット１０進数値を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


;-----------------------------------------------------------------------------------
;		'.' 区切りで８ビット１０進数値を表示する
;-----------------------------------------------------------------------------------
put_number_fr0
		MOVLW	'.' 
		MOVWF	data0
		CALL	puttty
		MOVLW	HIGH (put_number_fr0)
		MOVWF	PCLATH
put_number_fr
		MOVF	INDF,W
		INCF	FSR,1
		CALL	put_decimal
		DECFSZ	common,1 
		GOTO	put_number_fr0
		RETURN


;-----------------------------------------------------------------------------------
;		EEPROMから１６ビット値を取得＋１０進表示する
;-----------------------------------------------------------------------------------
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


;-----------------------------------------------------------------------------------
;		１６進出力ルーチン
;-----------------------------------------------------------------------------------
put_hexadecimal
		CLRF	PCLATH
		swapf	cd,0
		CALL	getascii
		MOVWF	data0	 
		MOVLW	HIGH (puttty)
		MOVWF	PCLATH

		CALL	puttty

		CLRF	PCLATH
		MOVF	cd,0
		CALL	getascii
		MOVWF	data0	 
		MOVLW	HIGH (puttty)
		MOVWF	PCLATH

		CALL	puttty
		MOVLW	HIGH (put_hexadecimal)
		MOVWF	PCLATH
		RETURN

;-----------------------------------------------------------------------------------
;		ＭＡＣアドレスを出力
;-----------------------------------------------------------------------------------
put_mymac_address
		MOVLW	mymac
put_mac_address
		MOVWF	FSR
		MOVLW	5				; 5回ループ
		MOVWF	magic_loop
put_mac_address_loop
		MOVF	INDF,W
		MOVWF	cd
		INCF	FSR,F
		CALL	put_hexadecimal
		
		MOVLW	':' 
		MOVWF	data0
		CALL	puttty
		MOVLW	HIGH (put_hexadecimal)
		MOVWF	PCLATH

		DECFSZ	magic_loop,F
		GOTO	put_mac_address_loop

		MOVF	INDF,W				; 最後の1回はコロンを出力しないため別に設ける
		MOVWF	cd
		INCF	FSR,1
		CALL	put_hexadecimal

		RETURN


;-----------------------------------------------------------------------------------
;		ＩＰアドレスを液晶に出力
;-----------------------------------------------------------------------------------
print_ip
		MOVLW	HIGH (print_dec)
		MOVWF	PCLATH

		MOVLW	this_ip	 
		MOVWF	FSR
		
		MOVF	INDF,W
		INCF	FSR,1
		CALL	print_dec
		
		MOVLW	'.'
		MOVWF	d4
		CALL	write_lcd4
		
		MOVF	INDF,W
		INCF	FSR,1
		CALL	print_dec
		
		MOVLW	'.'
		MOVWF	d4
		CALL	write_lcd4
		
		MOVF	INDF,W
		INCF	FSR,1
		CALL	print_dec
		
		MOVLW	'.'
		MOVWF	d4
		CALL	write_lcd4
		
		MOVF	INDF,W
		INCF	FSR,1
		CALL	print_dec
		RETURN



;-----------------------------------------------------------------------------------
;		シリアル受信データの送信先を登録
;-----------------------------------------------------------------------------------
		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,W	 
		IORWF	wk1,1
		INCF	FSR,1
		DECFSZ	wk,1	 
		GOTO	ser_register0
		BCF	STATUS,IRP

		MOVF	wk1,0		; 既に設定済みの場合は何もしないで、
		BTFSS	STATUS,Z		;ステータスのみ送信する。
		GOTO	ser_register9
;	送信先を登録
		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,W ; ボーレートを設定
		MOVWF	SPBRG
		BCF	STATUS,RP0
		
		INCF	FSR,1
		MOVF	udp_data6,0 
		MOVWF	INDF
		MOVF	INDF,W
		BTFSS	STATUS,Z
		BSF	INTCON,INTE
		BCF	STATUS,IRP
;
;		ＡＲＰ要求を送信
;
		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		; 宛て先："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		; 送信元：自分のＭＡＣアドレスを設定
		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			; ARP応答を送信する
ser_register9
		MOVLW	HIGH (ser_get_status)
		MOVWF	PCLATH
		GOTO	ser_get_status

;-----------------------------------------------------------------------------------
;		シリアル受信データの送信先を登録削除
;-----------------------------------------------------------------------------------
ser_unregister
		BCF	RCSTA,4		;cren
		BCF	INTCON,6	;peie				; 使用禁止
		
 		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





;
;	DHCPプロトコル処理
;
dhcp
		BSF	STATUS,RP0
		MOVLW	0FFH
		MOVWF	dhcp_done
		BCF	STATUS,RP0

		MOVLW	HIGH (bootp)
		MOVWF	PCLATH

		CALL	bootp			; 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			; 自分のＭＡＣ
		
		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



;-----------------------------------------------------------------------------------
;	ＡＲＰヘッダの作成
;-----------------------------------------------------------------------------------
arp1
		CLRF	PCLATH
		
		DB	01,00		;clrw
		CALL	assert_wr
		MOVLW	01h			; Ethernetは１固定
		CALL	assert_wr

		MOVLW	COM_PROTO
		CALL	assert_wr
		MOVLW	IP_PROTO		; 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			; Ethernetアドレスのバイト数＝６
		CALL	assert_wr
		MOVLW	04h			; IPアドレスのバイト数＝４
		CALL	assert_wr

		MOVLW	00h
		CALL	assert_wr
		MOVLW	01h			; ARP要求(＝１)
		CALL	assert_wr
		
		MOVLW	mymac
		MOVWF	FSR
		MOVLW	6
		CALL	transmit_nbytes		; 自分のＭＡＣを送信
		CALL	transmit_this_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,W	 	;on_ip[0]
		ANDWF	wk,1
	; [0] = host
		INCF	FSR,1
		MOVF	wk1,0
		SUBWF	wk,0 
		BTFSS	STATUS,Z
		GOTO	gateway

		CALL	getnetmask
		BSF	STATUS,RP0
		MOVF	this_ip1,0
		MOVWF	wk1
		MOVF	wk,0
		ANDWF	wk1,1
		MOVF	INDF,W	 	;on_ip[0]	
		ANDWF	wk,1

		INCF	FSR,1
		MOVF	wk1,0	 
		SUBWF	wk,0
		BTFSS	STATUS,Z
		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,W
		ANDWF	wk,1
		INCF	FSR,1
		MOVF	wk1,0	 
		SUBWF	wk,0
		BTFSS	STATUS,Z
		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,W
		ANDWF	wk,1

		MOVF	wk1,0	 
		SUBWF	wk,0
		BTFSS	STATUS,Z
		GOTO	gateway

direct
		BCF	STATUS,RP0
		BCF	STATUS,RP1
		CLRF	PCLATH
		MOVLW	on_ip & 0ffh
		MOVWF	FSR
		MOVLW	4			; 相手のＩＰを送信
		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


;-----------------------------------------------------------------------------------
;		２３２Ｃデータをホストに送信
;-----------------------------------------------------------------------------------
serial_tx
		BSF	STATUS,IRP		;irp
		MOVLW	on_ether & 0ffh	 
		MOVWF	FSR
		BSF	STATUS,RP0		;rp0
		MOVF	INDF,W	 
		MOVWF	eth_src
		INCF	FSR,1	 
		MOVF	INDF,W
		MOVWF	eth_src1
		INCF	FSR,1	 
		MOVF	INDF,W
		MOVWF	eth_src2
		;mov	eth_src[2],INDF
		INCF	FSR,1	 
		MOVF	INDF,W
		MOVWF	eth_src3
		INCF	FSR,1		 
		;mov	eth_src[4],INDF
		MOVF	INDF,W
		MOVWF	eth_src4

		INCF	FSR,1	 
	 
		MOVF	INDF,W
		MOVWF	eth_src5

		INCF	FSR,1	 
		BCF	STATUS,RP0		;rp0
		
		;mov	ip_src[0],INDF
		MOVF	INDF,W
		MOVWF	ip_src
		INCF	FSR,1	 
		;mov	ip_src[1],INDF
		MOVF	INDF,W
		MOVWF	ip_src1

		INCF	FSR,1 
		;mov	ip_src[2],INDF
		MOVF	INDF,W
		MOVWF	ip_src2

		INCF	FSR,1 
		MOVF	INDF,W
		MOVWF	ip_src3

		INCF	FSR,1	 
		BCF	STATUS,IRP		;irp
;
;	下準備をする
;
		BSF	STATUS,RP0		;rp0
		MOVF	fifo_cn,0 
		MOVWF	wk
;skip1
		BCF	STATUS,RP0		;rp0
		
		CLRF	ip_length
		MOVLW	IP_SIZE + UDP_SIZE 
		MOVWF	ip_length1
		MOVF	wk,0	 
		ADDWF	ip_length1,1		; 送信バイトサイズ
		MOVLW	SERIAL_PACKET_SIZE    ; 共通ヘッダサイズ
		ADDWF	ip_length1,1
		CLRF	PCLATH	 
		
		MOVLW	UDP_PROTO	 
		MOVWF	proto			; UDP packet
		CALL	prepare_ip			; ＩＰパケットまで作成
		
		CALL	clear_sum			; チェックサムの値をクリア
		
 		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
		CLRF	remote_len1
		CALL	remote_write
		
		
		MOVLW	10H	 
		MOVWF	PORTC
	
		MOVLW	serial_port	 
		MOVWF	FSR
		MOVF	INDF,W	 		; From PORT #(HIGH)
		CALL	assert_wr
		INCF	FSR,1	 
		MOVF	INDF,W	 			; From PORT #(LOW)
		CALL	assert_wr
		
		BSF	STATUS,IRP	;irp
		MOVLW	on_port & 0ffh 
		MOVWF	FSR			; To Port#
		MOVF	INDF,W	 
		CALL	assert_wr
		INCF	FSR,1	 
		MOVF	INDF,W	 
		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)
;
;		ステータス部
		BSF	STATUS,IRP	;irp
		MOVLW	on_ether & 0ffh	 
		MOVWF	FSR
		MOVLW	SERIAL_PACKET_SIZE - 2
		CALL	transmit_nbytes
		BCF	STATUS,IRP	;irp
;
;		送信
serial_tx0
		MOVLW	$ >> 8	 
		MOVWF	PCLATH
		BSF	STATUS,RP0		;rp0
		MOVF	fifo_poi,0 
		MOVWF	FSR		;; 受信ポインタ(GET)
		MOVF	INDF,W	 
		MOVWF	data0		; 受信した文字を取得
		
		INCF	fifo_poi,1			; 受信バッファをインクリメント
 		MOVLW	fifo_bottom
		SUBWF	fifo_poi,0
		BTFSS	STATUS,C
		GOTO	tx100
		MOVLW	fifo_top 
		MOVWF	fifo_poi
tx100		DECF	fifo_cn,1				; 受信バイト数をデクリメント
		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サム計算＋送信
		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	; パケットサイズ6+6+2を送信バイト数に加算1
		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			; 送信！！
		
		CLRF	PCLATH		;pclath
		GOTO	main0
serial_tx1
 		MOVLW	.60	
		SUBWF	ip_length1,0
		BTFSC	STATUS,C
		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
;-------------------------------------------------------------------------------
;　　液晶への文字出力
;-------------------------------------------------------------------------------
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	STATUS,Z
		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

;-----------------------------------------------------------------------------------
;		URLファイル名チェックルーチン 1.4.1.1
;-----------------------------------------------------------------------------------
url_check					; CALLする前にCLRF magic_flag、wk1=URL_CMD、wk2=URL_CFGを実行しておくこと
		MOVF	wk1,W			; CMD用比較ファイル名ポインタロード
		BSF	STATUS,RP1		; ページ2
		MOVWF	EEADR
		BSF	STATUS,RP0		; ページ3
		MOVLW	B'00000001'
		MOVWF	EECON1			; EEPROM読み出しコマンド,EEPGDも一緒にリセット
		BCF	STATUS,RP0		; データにアクセス(ページ2)
		MOVF	EEDATA,W
		BCF	STATUS,RP1		; ページ0
		BTFSC	STATUS,Z		; 読み出したデータが0(NULL)か？
		BSF	magic_flag,DO_CMD	; ファイル名の最後にはNULLが入っていることになっているので、NULLが出現したら照合完了と判定する

		SUBWF	data0,W			; 読み出したデータと受信した文字は同一か？
		BTFSS	STATUS,Z
		GOTO	URL_CHECK0
		INCF	wk1,F			; 同一の時は次の文字を比較するようにする
		GOTO	URL_CHECK1
URL_CHECK0
		MOVLW	URL_CMD
		MOVWF	wk1

URL_CHECK1	MOVF	wk2,W			; CFG用比較ファイル名ポインタロード
		BSF	STATUS,RP1		; ページ2
		MOVWF	EEADR
		BSF	STATUS,RP0		; ページ3
		BSF	EECON1,RD		; EEPROM読み出しコマンド
		BCF	STATUS,RP0		; データにアクセス(ページ2)
		MOVF	EEDATA,W
		BCF	STATUS,RP1		; ページ0
		BTFSC	STATUS,Z		; 読み出したデータが0(NULL)か？
		BSF	magic_flag,DO_CFG	; ファイル名の最後にはNULLが入っていることになっているので、NULLが出現したら照合完了と判定する

		SUBWF	data0,W			; 読み出したデータと受信した文字は同一か？
		BTFSS	STATUS,Z
		GOTO	URL_CHECK2
		INCF	wk2,F			; 同一の時は次の文字を比較するようにする
		GOTO	URL_CHECK3
URL_CHECK2
		MOVLW	URL_CFG
		MOVWF	wk2
URL_CHECK3
		MOVLW	HIGH(estab0)		; 戻しておく
		MOVWF	PCLATH
		RETURN


;-----------------------------------------------------------------------------------
;		ブートストラップモードのコマンドパース用
;-----------------------------------------------------------------------------------
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_init	DT	"initialize",0
str_init2	DT	"init",0

str_config	DT	"config",0
str_config2	DT	"ls",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

;-----------------------------------------------------------------------------------
;		ブートストラップモード・メッセージ
;-----------------------------------------------------------------------------------
		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

;-----------------------------------------------------------------------------------
;		Ｗｅｂブラウザ用・メッセージ
;		メッセージのDA,DBの項目は必ず偶数バイトになるようにしないといけない。奇数になると、2バイト目にヌル(00h)が送られる。
;-----------------------------------------------------------------------------------
		ORG	1400h ;～14FFh							httpレスポンス・ヘッダ リロードあり 制限画面用
		DA	"HTTP/1.0 200 OK "
		DB	06H,8AH			; CR,LF 
		DA	"Connection: close "
		DB	06H,8AH			; CR,LF 
		DA	"Content-type: text/html "
		DB	06H,8AH			; CR,LF 
		DB	06H,8AH			; CR,LF 
		DA	"<html><head><title>PIC Network Interface Card</title><meta http-equiv=\"pragma\" content=\"no-cache\">"
		DA	"<meta http-equiv=\"cache-control\" content=\"no-cache\"><meta equiv=\"expires\" content=\"-1\"><meta http-equiv=\"refresh\" content=\"30\"></head><body>"
		DA	"<font size=\"+2\">PIC Network Interface Card<br>&nbsp;&nbsp;&nbsp;&nbsp;Wake-On-LAN Plus</font> <hr>"
		DA	"* Automatic refresh every 30 seconds *<br><br>"
		DB	06H,8AH			; CR,LF 
		DB	0,0

;----------------------------------------------------------------------------------------------------------
		ORG	1500h ;～16FFh							制限画面本文・フッタ
		DA	"<dl> <dt><font size=\"+1\">Activity</font>"
		DA	"<dd><table border>"
		DA	"<tr align=\"center\"><td colspan=\"2\">Signal</td><td>Status</td></tr>"
		DA	"<tr><td rowspan=\"3\">Host A</td><td>Power Line</td> <td align=\"center\">", 0x2010 , "</td></tr>"
		DA	"<tr><td>UPS Service</td> <td align=\"center\">" , 0x2011 , "</td></tr>"
		DA	"<tr><td>Shutdown</td><td align=\"center\">" , 0x2014 , "</td></tr>"
		DA	"<tr><td rowspan=\"3\">Host B</td><td>Power Line</td> <td align=\"center\">" , 0x2012 , "</td></tr>"
		DA	"<tr><td>UPS Service</td> <td align=\"center\">" , 0x2013 , "</td></tr>"
		DA	"<tr><td>Shutdown</td><td align=\"center\">" , 0x2015 , "</td></tr>"
		DA	"<tr><td colspan=\"2\">RB6 ",0x1296,"</td><td align=\"center\">",0x2016,"</td></tr>"
		DA	"<tr><td colspan=\"2\">RB7 ",0x1297,"</td><td align=\"center\">",0x2017,"</td></tr>"
		DA	"<tr><td colspan=\"2\">Temperature</td><td>" , 0x2004 ," deg.C</td></tr>"
		DA	"</table></dl> <hr></body></html>"
		DB	06H,8AH			; CR,LF 
		DB	0,0

;----------------------------------------------------------------------------------------------------------
		ORG	1700h ;～17FFh							httpレスポンス・ヘッダ リロードなし 操作・設定画面用
		DA	"HTTP/1.0 200 OK "
		DB	06H,8AH			; CR,LF 
		DA	"Connection: close "
		DB	06H,8AH			; CR,LF 
		DA	"Content-type: text/html "
		DB	06H,8AH			; CR,LF 
		DB	06H,8AH			; CR,LF 
		DA	"<html><head><title>PIC Network Interface Card</title><meta http-equiv=\"pragma\" content=\"no-cache\">"
		DA	"<meta http-equiv=\"cache-control\" content=\"no-cache\"><meta equiv=\"expires\" content=\"-1\"></head><body>"
		DA	"<font size=\"+2\">PIC Network Interface Card<br>&nbsp;&nbsp;&nbsp;&nbsp;Wake-On-LAN Plus</font> <hr>"
		DB	06H,8AH			; CR,LF 
		DB	0,0

;----------------------------------------------------------------------------------------------------------
		ORG	1800h ;～19FFh							操作画面本文 Part1
		DA	"<form method=\"get\" action=\"control.html\" >"
		DA	"<dl><dt><font size=\"+1\">Wake On LAN</font>"
		DA	"<dd><table border>"
		DA	"<tr><td>Host A [$<]</td><td><input type=\"submit\" name=\"MA\" value=\"ON\"></td></tr>"
		DA	"<tr><td>Host B [$=]</td><td><input type=\"submit\" name=\"MB\" value=\"ON\"></td></tr>"
		DA	"<tr><td>Host C [$>]</td><td><input type=\"submit\" name=\"MC\" value=\"ON\"></td></tr>"
		DA	"<tr><td>Host D [$?]</td><td><input type=\"submit\" name=\"MD\" value=\"ON\"></td></tr>"
		DA	"</table></dl></form>"
		DA	"<form action=\"control.html\" method=\"get\" >"
		DA	"<dl><dt><font size=\"+1\">Activity and Shutdown</font>"
		DA	"<dd><table border>"
		DA	"<tr align=\"center\"><td colspan=\"2\">Signal</td><td>Status</td></tr>"
		DA	"<tr> <td rowspan=\"3\">Host A</td><td>Power Line</td><td align=\"center\">",0x2010,"</td></tr>"
		DA	"<tr> <td>UPS Service</td><td align=\"center\">",0x2011,"</td></tr>"
		DA	"<tr> <td>Shutdown</td><td><input type=\"submit\" name=\"RB4\" value=\"H\">",0x2014
		DA	"<input type=\"submit\" name=\"RB4\" value=\"L\"></td></tr>"
		DA	"<tr> <td rowspan=\"3\">Host B</td><td>Power Line</td><td align=\"center\">",0x2012,"</td></tr>"
		DA	"<tr> <td>UPS Service</td><td align=\"center\">",0x2013,"</td></tr>"
		DB	0,0

;----------------------------------------------------------------------------------------------------------
		ORG	1A00h ;～1AFFh							操作画面本文 Part2
		DA	"<tr> <td>Shutdown</td><td><input type=\"submit\" name=\"RB5\" value=\"H\">",0x2015
		DA	"<input type=\"submit\" name=\"RB5\" value=\"L\"></td></tr>"
		DA	"<tr><td colspan=\"2\">RB6 ",0x1296,"</td><td><input type=\"submit\" name=\"RB6\" value=\"H\" >",0x2016
		DA	"<input type=\"submit\" name=\"RB6\" value=\"L\"></td></tr>"
		DA	"<tr><td colspan=\"2\">RB7 ",0x1297,"</td><td><input type=\"submit\" name=\"RB7\" value=\"H\" >",0x2017
		DA	"<input type=\"submit\" name=\"RB7\" value=\"L\"></td></tr>"
		DA	"<tr><td colspan=\"2\"></td><td><input type=\"submit\" value=\"Reload\"></td></tr> "
		DA	"</table></dl></form>"
		DB	06H,8AH			; CR,LF 
		DB	0,0

;----------------------------------------------------------------------------------------------------------
		ORG	1B00h ;～1CFFh							設定画面本文
		DA	"<form method=\"get\" action=\"config.html\">"
		DA	"<dl><dt><font size=\"+1\">Configuration</font>"
		DA	"<dd><table border>"
		DA	"<tr><td>IP Address</td><td><input type=\"text\" name=\"00b\" value=\"$1\"></td></tr>"
		DA	"<tr><td>Netmask</td> <td><input type=\"text\" name=\"04b\" value=\"$2\"></td></tr>"
		DA	"<tr><td>Gateway</td> <td><input type=\"text\" name=\"08b\" value=\"$3\"></td></tr>"
		DA	"<tr><td>HTTP Port TCP:#</td> <td><input type=\"text\" name=\"10w\" value=\"$4\"></td></tr>"
		DA	"<tr><td>Parallel Port UDP:#</td> <td><input type=\"text\" name=\"14w\" value=\"$6\"></td></tr>"
		DA	"<tr><td>Host A MAC Address</td><td><input type=\"text\" name=\"20h\" value=\"$<\"></td></tr>"
		DA	"<tr><td>Host B MAC Address</td><td><input type=\"text\" name=\"28h\" value=\"$=\"></td></tr>"
		DA	"<tr><td>Host C MAC Address</td><td><input type=\"text\" name=\"30h\" value=\"$>\"></td></tr>"
		DA	"<tr><td>Host D MAC Address</td><td><input type=\"text\" name=\"38h\" value=\"$?\"></td></tr>"
		DA	"<tr><td></td> <td><input type=\"submit\" value=\"Save\">&nbsp;"
		DA	"<input type=\"submit\" name=\"INIT\" value=\"Default\" ></td></tr>"
		DA	"</table></dl></form>"
		DB	06H,8AH			; CR,LF 
		DB	0,0

;----------------------------------------------------------------------------------------------------------
		ORG	1D00h ;～1DFFh							ステータス表示・フッタ
		DA	"<dl><dt><font size=\"+1\">Status</font> "
		DA	"<dd><table border>"
		DA	"<tr><td>Firmware Version</td> <td>$8</td></tr>"
		DA	"<tr><td>MAC Address</td><td>$0</td></tr>"
		DA	"<tr><td>Current IP</td> <td>$:</td></tr>"
		DA	"<tr><td>Temperature</td><td>" , 0x2004 ," deg.C</td></tr>"
		DA	"<tr><td>Sent Packets</td> <td>$9</td></tr>"
		DA	"</table></dl> "
		DA	"<hr></body></html>"
		DB	06H,8AH			; CR,LF 
		DB	0,0

;-----------------------------------------------------------------------------------
;		EEPROMデータ初期値
;-----------------------------------------------------------------------------------
		ORG	1F00h
default_values_begin
		DT	.192, .168, 0, .200					; IPアドレス (0.0.0.0=DHCP) 00h-03h
		DT	.255, .255, .255, 0					; ネットマスク 04h-07h
		DT	0,0,0,0							; ゲートウェイ 08h-0Bh
		DT	1,4,4,0							; FW Version   0Ch-0Fh
		
		DT	HTTP_PORT / .256,HTTP_PORT & .255			; HTTPポート番号 10h-11h
		DT	LCD_PORT / .256,LCD_PORT & .255				; LCDポート番号  12h-13h
		DT	PARALLEL_PORT / .256,PARALLEL_PORT & .255		; PARALLELポート番号 14h-15h
		DT	SERIAL_PORT / .256,SERIAL_PORT & .255			; SERIALポート番号   16h-17h
		DT	0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh			; 18h-1Fhは未使用

		DT	0,0,0,0,0,0,0FFh,0FFh					; Host A MAC Address 20h-25h
		DT	0,0,0,0,0,0,0FFh,0FFh					; Host B MAC Address 28h-2Dh
		DT	0,0,0,0,0,0,0FFh,0FFh					; Host C MAC Address 30h-35h
		DT	0,0,0,0,0,0,0FFh,0FFh					; Host D MAC Address 38h-3Dh
default_values_end

;-----------------------------------------------------------------------------------
;		マジックパケット送信ルーチン
;-----------------------------------------------------------------------------------
send_magic
		MOVLW	.6	 			; 6バイト分ループ
		MOVWF	magic_loop
		MOVLW	magic_mac			; INDF経由でmagic_macへ書き込む
		MOVWF	FSR
		BCF	STATUS,IRP			; magic_macは0ページRAM

		MOVLW	'A'				
		SUBWF	data0,F				; 00000011
		RLF	data0,F				; 00000110
		RLF	data0,F				; 00001100
		RLF	data0,F				; 00011000
		MOVLW	B'00011000'			; URLに変な文字を入れてもとりあえずフィルタがかかって暴走しないはず
		ANDWF	data0,F
		MOVLW	20
		ADDWF	data0,W				; A,B,C,Dの文字からEEPROMの実アドレスを計算
		BSF	STATUS,RP1			;|
		BCF	STATUS,RP0			;|
		MOVWF	EEADR				;V
		BSF	PCLATH,3			; このページ内でループ
		BSF	PCLATH,4
magic_load						; EEPROMから対象のMACアドレスを読み出す
		BSF	STATUS,RP1
		BSF	STATUS,RP0
		MOVLW	B'00000001'
		MOVWF	EECON1				; READ
		BCF	STATUS,RP0
		MOVF	EEDATA,W
		MOVWF	INDF				; INDF経由でmagic_macに読み出し
		INCF	FSR,F
		INCF	EEADR,F
		BCF	STATUS,RP1
		DECFSZ	magic_loop,F			; 6バイト分ループしてMACアドレスを読み出す
		GOTO	magic_load

							; ここからフレーム生成
		CLRF	remote_adr			; 8019送信バッファのリモートアドレス代入
		MOVLW	PAGE_BEGIN
		MOVWF	remote_adr1

		MOVLW	PACKET_SIZE + .17 * .6		; フレームのオクテット数
		MOVWF	remote_len
		CLRF	remote_len1

		CLRF	PCLATH
		CALL	remote_write

		MOVLW	10h				; リモートDMAレジスタを経由して送信バッファに送信データを送る
		MOVWF	PORTC
		MOVLW	0ffh				; 送信先：ff-ff-ff-ff-ff-ff
		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				; 送信元：自分のＭＡＣアドレスを設定
		MOVWF	FSR
		MOVLW	6
		CALL	transmit_nbytes

		MOVLW	COM_PROTO			; フレームタイプ 0x0842
		CALL	assert_wr
		MOVLW	WOL_PROTO
		CALL	assert_wr

		MOVLW	0ffh				; ff-ff-ff-ff-ff-ff
		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	.16				; 対象のＭＡＣアドレスを16回
		MOVWF	magic_loop
magic_16times
		MOVLW	magic_mac
		MOVWF	FSR
		MOVLW	6
		CLRF	PCLATH
		CALL	transmit_nbytes
		BSF	PCLATH,3			; このページ内でループ
		BSF	PCLATH,4

		DECFSZ	magic_loop,F
		GOTO	magic_16times
							; データの用意完了
		CLRF	PCLATH
		MOVLW	4h				; TPSR 送信開始ページレジスタ
		MOVWF	PORTC
		MOVLW	PAGE_BEGIN
		CALL	assert_wr0
		
		MOVLW	.5				; TBCR0 送信バイト数レジスタL
		MOVWF	PORTC
		MOVLW	PACKET_SIZE + .17 * .6
		CALL	assert_wr0
		
		MOVLW	6				; TBCR1 送信バイト数レジスタH
		MOVWF	PORTC
		MOVLW	0
		CALL	assert_wr0

		CALL	transmit			; フレーム送信

		MOVLW	HIGH (parse9)			; htmlメッセージの送信
		MOVWF	PCLATH
		GOTO	parse9

;-----------------------------------------------------------------------------------
;		ADCONテーブル
;-----------------------------------------------------------------------------------
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&nbsp; ",0
mes_high	DT	" <font color=\"red\" >High</font> ",0
mes_in		DT	"In ",0
mes_out		DT	"Out",0

		END

