⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 v12.asm

📁 日本秋月电子采用PIC16F877a单片机的PICNIC以太网适配器程序
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		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,1
		DECF	FSR,1		
		btfsc	STATUS,C	
		addwf	INDF,1		
		DECF	FSR,1	 
		btfsc	STATUS,C	
		addwf	INDF,1		
		DECF	FSR,1		
		btfsc	STATUS,C	
		addwf	INDF,1		
		bcf	STATUS,IRP	
		retURN

;-----------------------------------------------------------------------------------
;		TCPのseq_noにip_lengthを加算する。
;
add_seq_no
		bsf	STATUS,IRP	
		movLW	.3		
		ADDWF	FSR,1

		MOVF	ip_length1,0	
		addwf	INDF,1		
		DECF	FSR,1		
		movlw	1
		btfsc	STATUS,C	
		addwf	INDF,1		
		DECF	FSR,1		
		btfsc	STATUS,C	
		addwf	INDF,1		
		DECF	FSR,1		
		btfsc	STATUS,C	
		addwf	INDF,1		
	
		movLW	.2		
		ADDWF	FSR,1
		MOVF	ip_length,0	
		addwf	INDF,1		
		DECF	FSR,1		
		movlw	1
		btfsc	STATUS,C	
		addwf	INDF,1		
		DECF	FSR,1		
		btfsc	STATUS,C	
		addwf	INDF,1		
		bcf	STATUS,IRP	
		retURN

;-----------------------------------------------------------------------------------
;		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,0		
		INCF	FSR,1		
		iorwf	INDF,0		
		INCF	FSR,1		
		iorwf	INDF,0		
		INCF	FSR,1		
		iorwf	INDF,0		
		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受信?
		MOVLW	0
		SUBWF	fifo_cn,0
		BTFSS	3,2
		GOTO	receive232c
		MOVLW	80h
		SUBWF	dhcp_done,0
		BTFSC	3,2
		GOTO	do_dhcp
		bcf	STATUS,RP0	

		CLRF	PCLATH		
		MOVLW	.7		
		MOVWF	PORTC
		call	assert_rd		; RCRリード
		
		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	3,0
		GOTO	packet1

		MOVLW	PAGE_START	
		MOVWF	data0
packet1
		MOVF	curr,0				; (BNDY+1)==CURRの場合は新規データなし
		SUBWF	data0,0
		BTFSC	3,2
		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の上位8ビットが8以外はスキップ
		SUBWF	eth_type,0
		BTFSS	3,2
		GOTO	main9
		MOVLW	IP_PROTO		; IPプロトコル処理へ分岐
		SUBWF	eth_type1,0
		BTFSC	3,2
		GOTO	do_ip
		MOVLW	ARP_PROTO		; ARPプロトコル処理へ分岐
		SUBWF	eth_type1,0
		BTFSC	3,2
		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	3,0
		GOTO	overflow2
		MOVLW	PAGE_STOP		; Error Check and Recovery
		SUBWF	ne_next,0
		BTFSC	3,0
		GOTO	overflow2

		DECF	ne_next,1					; 次のバンダリを計算
		MOVLW	PAGE_START	
		SUBWF	ne_next,0
		BTFSC	3,0
		GOTO	packet11

		MOVLW	PAGE_STOP-1	
		MOVWF	ne_next
packet11
		bcf	STATUS,RP0	
		
		CLRF	PORTC		
		movlw	B'00100010'
		call	assert_wr0
		
		MOVLW	.3		
		MOVWF	PORTC
		MOVLW	ne_next		
		MOVWF	FSR
		MOVF	INDF,0			; バンダリポインタセット
		call	assert_wr0
		goto	main99



;-----------------------------------------------------------------------------------
;		ARPプロトコル処理
;-----------------------------------------------------------------------------------
do_arp
		bcf	STATUS,RP0	
		MOVLW	NE_SIZE + PACKET_SIZE	
		MOVWF	remote_adr
		MOVLW	ne_cn_l			
		MOVWF	FSR
		MOVF	INDF,0			
		MOVWF	remote_len
		INCF	FSR,1			
		MOVF	INDF,0			
		MOVWF	remote_len1

		MOVLW	NE_SIZE + PACKET_SIZE	
		SUBWF	remote_len,1
		movlw	1
		btfss	STATUS,C		
		subwf	remote_len1,1		
		call	remote_read

		MOVLW	ip_header				; アドレス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
		MOVLW	0					; arp_codeが0001以外なら捨てる
		SUBWF	arp_ope,0
		BTFSS	3,2
		GOTO	main9

		MOVLW	1			
		SUBWF	arp_ope1,0
		BTFSC	3,2
		GOTO	arp_req

		MOVLW	2			
		SUBWF	arp_ope1,0
		BTFSC	3,2
		GOTO	arp_reply
		
		goto	main9
arp_reply
		MOVLW	HIGH (ser_arp)		
		MOVWF	PCLATH
		goto	ser_arp
arp_req
arp
		MOVLW	this_ip				; this_ipはBANK 1にある。
		MOVWF	FSR
		MOVF	arp_dest_ip,0			; ARPのIPアドレスが自分と同じか?
		SUBWF	INDF,0
		BTFSS	3,2
		GOTO	main9
		INCF	FSR,1			

		MOVF	arp_dest_ip1,0		
		SUBWF	INDF,0
		BTFSS	3,2
		GOTO	main9
		INCF	FSR,1			

		MOVF	arp_dest_ip2,0		
		SUBWF	INDF,0
		BTFSS	3,2
		GOTO	main9
		INCF	FSR,1			
		MOVF	arp_dest_ip3,0		
		SUBWF	INDF,0
		BTFSS	3,2
		GOTO	main9


;	自分へのARP要求である
		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


;-----------------------------------------------------------------------------------
;		IPプロトコル受信処理
;-----------------------------------------------------------------------------------
do_ip
		bcf	STATUS,RP0	
		MOVLW	NE_SIZE + PACKET_SIZE	
		MOVWF	remote_adr
		MOVLW	ne_cn_l			
		MOVWF	FSR
	;	mov	fsr,#ip_length
		MOVF	INDF,0			
		MOVWF	remote_len
		INCF	FSR,1			
		MOVF	INDF,0			
		MOVWF	remote_len1

		MOVLW	NE_SIZE + PACKET_SIZE				; 受信バイト数からEtherヘッダ長を引く
		SUBWF	remote_len,1
		movlw	1
		btfss	STATUS,C		
		subwf	remote_len1,1		
		call	remote_read
;
;	IPパケットの受信
		MOVLW	ip_header				; アドレスip_headerへデータを読み込む
		MOVWF	FSR

		bcf	PORTE,0			
		btfss	PORTC,5						; ~Wait
		goto	$-1
		MOVF	PORTD,0			
		bsf	PORTE,0			
		movwf	INDF					; 1バイト読む!
		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	3,2
		GOTO	ip_get_packet9
		MOVLW	TCP_PROTO			; TCP受信処理へ
		SUBWF	ip_proto,0
		BTFSC	3,2
		GOTO	tcp
		MOVLW	UDP_PROTO			; UDP受信処理へ
		SUBWF	ip_proto,0
		BTFSC	3,2
		GOTO	udp
		MOVLW	ICMP_PROTO		; ICMP受信処理へ
		SUBWF	ip_proto,0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -