www.pudn.com > PICTCPIP.rar > ethmod1.asm


;********************************************************** 
;    Project    -----  split air conditioner 
;    Chip       -----  NEC uPD789166 
;    Frequency  -----  4MHz crystal 
;    Date       -----  2003/07/03 
;    Version    -----  1.0 
;    Author     -----  moxi 
;    Resource   -----  206 bytes RAM // 5296 bytes ROM // max 18 bytes stack occupy 
;********************************************************** 
 
$processor(9177) 
 
;/******************************************************************/ 
;/*	Receive Ring Buffer Header Layout 
;//*   This is the 4-byte header that resides infront of the 
;//*   data packet in the receive buffer. 
;/*****************************************************************/ 
 
	enetpacketstatus	equ	00h 
	nextblock_ptr		equ	01h 
	enetpacketLenL		equ	02h 
	enetpacketLenH		equ	03h 
;/****************************************************************** 
;/*	Ethernet Header Layout 
;******************************************************************/ 
	enetpacketDest0		equ	 00h ; /*//destination mac address*/ 
	enetpacketDest1		equ	 01h; 
	enetpacketDest2		equ	 02h; 
	enetpacketDest3		equ	 03h; 
	enetpacketDest4		equ	 04h; 
	enetpacketDest5		equ	 05h; 
	enetpacketSrc0		equ	 06h;  /*//source mac address*/ 
	enetpacketSrc1		equ	 07h; 
	enetpacketSrc2		equ	 08h; 
	enetpacketSrc3		equ	 09h; 
	enetpacketSrc4		equ	 0Ah; 
	enetpacketSrc5		equ	 0Bh; 
	enetpacketType0		equ	 0Ch;  /*type/length field*/ 
	enetpacketType1		equ	 0Dh; 
	enetpacketData		equ	 0Eh;  /*IP data area begins here*/ 
;/****************************************************************** 
;//*	ARP Layout 
;//******************************************************************/ 
	arp_hwtype		equ	 0Eh 
	arp_prtype		equ	 10h 
	arp_hwlen		equ	 12h 
	arp_prlen		equ	 13h 
	arp_op			equ	 14h 
	arp_shaddr		equ	 16h  ;/*arp source mac address*/ 
	arp_sipaddr		equ	 1Ch   ;/*arp source ip address*/ 
	arp_thaddr		equ	 20h   ;/*arp target mac address*/ 
	arp_tipaddr		equ	 26h   ;/*arp target ip address*/ 
;/****************************************************************** 
;//*	IP Header Layout 
;//******************************************************************/ 
	ip_vers_len		equ	 0Eh	;/*/IP version and header length*/ 
	ip_tos			equ	 0Fh	;/*/IP type of service*/ 
	ip_pktlen		equ	 10h	;/*/packet length*/ 
	ip_id			equ	 12h	;/*/datagram id*/ 
	ip_frag_offset		equ	 14h	;/*/fragment offset*/ 
	ip_ttl			equ	 16h	;/*/time to live*/ 
	ip_proto		equ	 17h	;/*/protocol (ICMP=1, TCP=6, UDP=11)*/ 
	ip_hdr_cksum		equ	 18h	;/*/header checksum*/ 
	ip_srcaddr		equ	 1Ah	;/*/IP address of source*/ 
	ip_destaddr		equ	 1Eh	;/*/IP addess of destination*/ 
	ip_data			equ	 22h	;/*/IP data area*/ 
;/****************************************************************** 
;//*	TCP Header Layout 
;//******************************************************************/ 
	TCP_srcport		equ	 22h	;/*/TCP source port*/ 
	TCP_destport		equ	 24h	;/*/TCP destination port*/ 
	TCP_seqnum		equ	 26h	;/*/sequence number*/ 
	TCP_acknum		equ	 2Ah	;/*/acknowledgement number*/ 
	TCP_hdrflags		equ	 2Eh	;/*/4-bit header len and flags*/ 
	TCP_window		equ	 30h	;/*/window size*/ 
	TCP_cksum		equ	 32h	;/*/TCP checksum*/ 
	TCP_urgentptr		equ	 34h	;/*/urgent pointer*/ 
	TCP_data		equ	 36h  ;/*option/data*/ 
;/****************************************************************** 
;//*	TCP Flags 
;//*   IN flags represent incoming bits 
;//*   OUT flags represent outgoing bits 
;//******************************************************************/ 
	FIN_IN		equ	 packet[TCP_hdrflags+1].0 
	SYN_IN		equ	 packet[TCP_hdrflags+1].1 
	RST_IN		equ	 packet[TCP_hdrflags+1].2 
	PSH_IN		equ	 packet[TCP_hdrflags+1].3 
	ACK_IN		equ	 packet[TCP_hdrflags+1].4 
	URG_IN 		equ	 packet[TCP_hdrflags+1].5 
	FIN_OUT		equ	 packet[TCP_hdrflags+1].0=1; 
	SYN_OUT		equ	 packet[TCP_hdrflags+1].1=1; 
	RST_OUT		equ	 packet[TCP_hdrflags+1].2=1; 
	PSH_OUT		equ	 packet[TCP_hdrflags+1].3=1; 
	ACK_OUT		equ	 packet[TCP_hdrflags+1].4=1; 
	URG_OUT		equ	 packet[TCP_hdrflags+1].5=1; 
;/****************************************************************** 
;//*	Port Definitions 
;//*   This address is used by TCP and the Telnet function. 
;//*   This can be changed to any valid port number as long as 
;//*   you modify your code to recognize the new port number. 
;//******************************************************************/ 
	MY_PORT_ADDRESSh	equ		1fh 
	MY_PORT_ADDRESSl   	equ		98h  /* 8088 DECIMAL*/ 
;/****************************************************************** 
;//*	IP Protocol Types 
;//******************************************************************/ 
	PROT_ICMP		equ	 01h 
	PROT_TCP		equ	 06h 
	PROT_UDP		equ	 11h 
;/****************************************************************** 
;//*	ICMP Header 
;//******************************************************************/ 
	ICMP_type		equ	 ip_data 
	ICMP_code		equ	 ICMP_type+1 
	ICMP_cksum		equ	 ICMP_code+1 
	ICMP_id			equ	 ICMP_cksum+2 
	ICMP_seqnum		equ	 ICMP_id+2 
	ICMP_data		equ	 ICMP_seqnum+2 
;/****************************************************************** 
;//*	UDP Header 
;//;******************************************************************/ 
	UDP_srcport		equ	 ip_data 
	UDP_destport		equ	 UDP_srcport+2 
	UDP_len			equ	 UDP_destport+2 
	UDP_cksum		equ	 UDP_len+2 
	UDP_data		equ	 UDP_cksum+2 
;/****************************************************************** 
;//*	REALTEK CONTROL REGISTER OFFSETS 
;//*   All offsets in Page 0 unless otherwise specified 
;//******************************************************************/ 
	CR		equ	 00h 
	PSTART		equ	 01h 
	PAR0		equ	 01h   ;/* Page 1*/ 
	CR9346		equ	 01h    ;/* Page 3*/ 
	PSTOP		equ	 02h 
	BNRY		equ	 03h 
	TSR		equ	 04h 
	TPSR		equ	 04h 
	TBCR0		equ	 05h 
	NCR		equ	 05h 
	TBCR1		equ	 06h 
	ISR		equ	 07h 
	CURR		equ	 07h  ; /* Page 1*/ 
	RSAR0		equ	 08h 
	CRDA0		equ	 08h 
	RSAR1		equ	 09h 
	CRDAL		equ	 09h 
	RBCR0		equ	 0Ah 
	RBCR1		equ	 0Bh 
	RSR		equ	 0Ch 
	RCR		equ	 0Ch 
	TCR		equ	 0Dh 
	CNTR0		equ	 0Dh 
	DCR		equ	 0Eh 
	CNTR1		equ	 0Eh 
	IMR		equ	 0Fh 
	CNTR2		equ	 0Fh 
	RDMAPORT	equ	 10h 
	RSTPORT		equ	 18h 
;/****************************************************************** 
;//*	RTL8019AS INITIAL REGISTER VALUES 
;//******************************************************************/ 
	rcrval		equ	 04h 
	tcrval		equ	 00h 
	dcrval		equ	 58h   ;/* was  48*/ 
	imrval		equ	 11h    ;/* PRX and OVW interrupt enabled*/ 
	txstart		equ	 40h 
	rxstart		equ	 46h 
	rxstop		equ	 60h 
;/****************************************************************** 
;//*	PIN DEFINITIONS 
;//******************************************************************/ 
	cregaddr	equ	 p0 
	cregdata	equ	 p2 
	tocreg		equ	 pm2 
	fromcreg	equ	 pm2 
;/****************************************************************** 
;//*	RTL8016AS PIN DEFINITIONS 
;//******************************************************************/ 
	INT0		equ	 p3.0 
	ior_pin		equ	 p1.0 
	iow_pin		equ	 p1.1 
	rst_pin		equ	 p2.4 
;/****************************************************************** 
;//*	RTL8016AS ISR REGISTER DEFINITIONS 
;//******************************************************************/ 
	RST		equ	 07h 
	RDC		equ	 06h 
	OVW		equ	 04h 
	PRX		equ	 00h	 
;*************************** 
; addr list 
;*************************** 
data0          dseg   at   0fd00h        
;------------------	 
	pageheader	:ds	4 
	packet		:ds	96         ;/*//50 bytes of UDP data available*/ 
	aux_data	:ds	16         ;/*//received data area*/ 
;------------------ 
data1          dseg   at   0fe20h         
 
	addr		:ds	1 
	byte_read	:ds	1 
	data_H		:ds	1 
	data_L		:ds	1 
	high_nibble	:ds	1 
	low_nibble	:ds	1 
	high_char	:ds	1 
	low_char	:ds	1 
	resend		;ds	1 
	i		:ds	2 
	txlen		:ds	2 
	rxlen		:ds	2 
	chksum16	:ds	2 
	hdrlen		:ds	2 
	tcplen		:ds	2 
	tcpdatalen_in	:ds	2 
	tcpdatalen_out	:ds	2 
	ISN		:ds	2 
	portaddr	:ds	2 
	ip_packet_len	:ds	2 
	hdr_chksum	:ds	4 
	my_seqnum	:ds	4 
	client_seqnum	:ds	4 
	incoming_ack	:ds	4 
	expected_ack	:ds	4 
	synflag		:ds	1 
	finflag		:ds	1 
	regaddr		:ds	1 
	regdata		:ds	1	 
;*************************** 
; vector table 
;*************************** 
vector       cseg   at   0h 
 
             dw     start                ;reset 
             dw     ignore               ;nothing 
             dw     ignore               ;int_wdt 
             dw     ignore               ;int_p0		;receiving remote signal 
             dw     ignore               ;int_p1               ;check cross-zero signal of power 
             dw     ignore               ;int_p2               ;fan speed dection 
             dw     ignore               ;int_p3                
             dw     ignore               ;int_sr/int_csi0 
             dw     ignore               ;int_st 
             dw     ignore               ;int_wt 
             dw     ignore               ;int_wti 
             dw     ignore 		 ;int_tm0 
             dw     ignore               ;int_tm1		;int_tm1yv}ó鎫}zëô-z(|:~9b 
             dw     ignore               ;int_tm2              ;int_tm2;4MSv-r2ޝz{ 
             dw     ignore               ;int_tm5 
             dw     ignore               ;int_kr 
             dw     ignore               ;int_ad 
             dw     ignore               ;int_cmp 
 
;*************************** 
; callt table 
;*************************** 
calltlist  cseg   at   40h 
		dw 	show_aux_packet	;[40h] 
		dw	dump_header	;[42h] 
		dw	readwrite 	;[44h] 
		dw	bin2hex 	;[46h] 
		dw	show_regs 	;[48h] 
		dw	show_packet 	;[4ah] 
		dw	cls 		;[4ch] 
		dw	application_code ;[4eh] 
		dw	tcp 		;[50h] 
		dw	assemble_ack 	;[52h] 
		dw	write_creg 	;[54h] 
		dw	read_creg 	;[56h] 
		dw	get_packet 	;[58h] 
		dw	setipaddrs 	;[5ah] 
		dw	cksum 		;[5ch] 
		dw	echo_packet 	;[5eh] 
		dw	send_tcp_packet	;[60h]  
		dw	arp 		;[62h] 
		dw	icmp 		;[64h] 
		dw	udp 		;[66h] 
    
  
;********************************************************** 
;                    routine start 
;********************************************************** 
routine    cseg   at   80h 
 
start:     di 
;--------------------------- 
           movw   ax,#0fd80h 
           movw   sp,ax 
           mov    pcc,#0                 ;main oscillation,no prescaler,CPU clock=0.25us 
           mov    sckm,#00000011b        ;disable feedback resistor and suboscillation 
           mov    css,#0                 ;select main system oscillation 
           mov    tcl2,#00000110b        ;watchdog reset interval=32.768ms 
           mov    wdtm,#10011000b        ;enable watchdog reset 
           mov    tmc90,#00110010b       ;tm90 count clock frequency is 125kHz 
	                                 ;overflow every 524.288ms,capture at both edge 
;--------------------------- 
           mov    a,#4 
rlab010:   mov    c,#250 
rlab01:    mov    b,#0 
rlab02:    nop 
           set1   wdtm.7                 ;update WDT 
           dbnz   b,$rlab02 
           dbnz   c,$rlab01              ;delay about 130ms 
           dec    a 
           bnz    $rlab010               ;delay about 0.5s 
;--------------------------- 
	   mov    p0,#0 
	   mov    pm0,#20h 
	   mov    p1,#01h 
	   mov    pm1,#00000001b	 
	   mov    p2,#00001111b 
	   mov    pm2,#0      
	   mov    p3,#0	   
	   mov    pm3,#00000111b    
	   mov    p5,#0ffh 
	   mov    pm5,#00000001b 
	    
;--------------------------- 
           movw   hl,#0fd00h 
clrram:    set1   wdtm.7                 ;update WDT 
           mov    a,#00 
           mov    [hl],a 
           incw   hl 
           movw   ax,hl 
           cmpw   ax,#0ff00h 
           bc     $clrram                ;clr RAM from fd00-feffh 
            
 
;--------------------------- 
	   mov    intm0,#01000000b 
	   mov    intm1,#00000010b 
	    
	   clr1   tce82			;timer interval=125*32us=4ms 
	   mov    cr82,#62 		;2003-9-15 9:17;timer interval=125*32us=4ms 
	   mov    tmc82,#10000010b       ;count clock fx/128,cycle=32us 
 
	   clr1   tce80 
	   mov    cr80,#122               ;timer interval=62*2us=124us,4.032kHz 
	   mov    tmc80,#00000010b 
	    
	   mov    if0,#0 
	   mov    if1,#0 
	   mov    mk0,#11110001b         ;enable intp0-2 interrupt 
	   mov    mk1,#11110011b         ;enable tm1 and tm2 interrupt 
	    
 
	   nop 
	   nop	    
	   ei 
 
	    
;************************************************ 
;              main loop routine 
;************************************************ 
mainloop:  nop 
           nop            
           set1   wdtm.7                 ;update WDT 
 
           br     mainloop 
            
;/****************************************************************** 
;//*	Application Code 
;//*   Your application code goes here. 
;//*   This particular code toggles the LED on PORT A bit 4 using 
;//*   Telnet. 
;//******************************************************************/ 
application_code: 
	movw   ax,#aux_data 
	movw	hl,ax 
	mov	a,[hl] 
	mov	x,a 
	cmp	a,#0ah 
	bnz	applab0 
      	mov	tcpdatalen_out,#0 
      	br	$applab1	 
applab0:	 
   	mov	a,tcpdatalen_in 
   	mov	tcpdatalen_out,a 
applab1:   	 
	cmp	a,#'0' 
	bnz	$applab2 
	set1	p3.1 
	 
applab2: 
	cmp	a,#'1' 
	bnz	$applab3	 
	clr1	p3.1 
applab3:			 
	cmp	a,#0dh 
	bnz	$applab4		 
        mov	tcpdatalen_out,#21 
         ;strcpy(packet[TCP_data],"EDTP[0]\r\nEDTP Telnet Server>") 
applab4:	 
	ret 
;/****************************************************************** 
;//*	Write to NIC Control Register 
;	void write_creg(int regaddr, int regdata) 
;//******************************************************************/ 
write_creg: 
	clr1	regaddr.5 
	bf	regdata.7,$writelab0 
	set1	regaddr.5	 
writelab0:	 
;	mov	a,regaddr 
	mov	cregaddr,a 
	mov	a,regdata 
	mov	cregdata,a     
    	mov	tocreg,#0	;out 
    	mov	pm0,#00h    	 
    	clr1	iow_pin 
    	nop 
    	nop 
	set1	iow_pin 
    	mov	fromcreg,#0ffh	;in 
    	mov	pm0,#20h 
    	ret 
;/****************************************************************** 
;//*	Read From NIC Control Register 
;	char read_creg(int regaddr) 
;//******************************************************************/ 
read_creg: 
    	mov	fromcreg,#0ffh	;in    	 
    	mov	pm0,#20h	 
;	mov	a,regaddr 
	and	a,#1fh 
	mov	cregaddr,a 
    	clr1	iow_pin 
    	mov	a,cregdata 
	clr1	a.7 
	bf	p0.5,$read_creg0 
	set1	a.7   
read_creg0:	  	 
   	mov	byte_read,a 
	set1	iow_pin	 
	ret 
;/****************************************************************** 
;//*	Perform ARP Response 
;//*   This routine supplies a requesting computer with the 
;//*   Ethernet modules's MAC (hardware) address. 
;//******************************************************************/ 
arp: 
;   /*start the NIC*/ 
	mov	a,#22 
	mov	regdata,a 
	mov	a,#CR	 
	tcall	[54h] 
;   /*load beginning page for transmit buffer*/ 
;   write_creg(TPSR,txstart); 
	mov	a,#txstart 
	mov	regdata,a 
	mov	a,#TPSR	 
	tcall	[54h] 
;   /*set start address for remote DMA operation*/ 
;   write_creg(RSAR0,0x00); 
;   write_creg(RSAR1,0x40); 
	mov	a,#00 
	mov	regdata,a 
	mov	a,#RSAR0 
	tcall	[54h] 
	mov	a,#40 
	mov	regdata,a 
	mov	a,#RSAR1 
	tcall	[54h]	 
;   /*clear the Interrupts*/ 
;   write_creg(ISR,0xFF); 
	mov	a,#0FFh 
	mov	regdata,a 
	mov	a,#ISR 
	tcall	[54h] 
;   /*load data byte count for remote DMA*/ 
;   write_creg(RBCR0,0x3C); 
;   write_creg(RBCR1,0x00); 
	mov	a,#3Ch 
	mov	regdata,a 
	mov	a,#RBCR1 
	tcall	[54h] 
	mov	a,#00h 
	mov	regdata,a 
	mov	a,#RBCR0 
	tcall	[54h]	 
;   /*do remote write operation*/ 
;   write_creg(CR,0x12); 
	mov	a,#12h 
	mov	regdata,a 
	mov	a,#CR 
	tcall	[54h] 
   /*write destination MAC address*/ 
   	mov	i,#0 
arplab0:   	 
	movw	ax,#packet 
	xch	a,x 
	add	a,i 
	add	a,enetpacketSrc0 
	xch	a,x	 
	movw	hl,ax 
	mov	a,[hl] 
	mov	regdata,a 
	mov	a,#RDMAPORT 
	tcall	[54h]	 
	inc	i 
	cmp	i,#6 
	bnz	$arplab0 
		    
;      	write_creg(RDMAPORT,packet[enetpacketSrc0+i]); 
 
;	/*write source MAC address*/ 
;   for(i=0;i<6;++i) 
;      write_creg(RDMAPORT,MYMAC[i]); 
   	mov	i,#0 
arplab1:   	 
	movw	ax,#MYMAC 
	xch	a,x 
	add	a,i 
	xch	a,x	 
	movw	hl,ax 
	mov	a,[hl] 
	mov	regdata,a 
	mov	a,#RDMAPORT 
	tcall	[54h]	 
	inc	i 
	cmp	i,#6 
	bnz	$arplab1 
;   /*write typelen hwtype prtype hwlen prlen op:*/ 
 
	mov	ax,#packet	;   packet[arp_op+1] = 0x02; 
	xch	a,x 
	add	a,#arp_op+1 
	movw	hl,ax 
	mov	[hl],#02h   
	  
   	mov	i,#0 
arplab2:   	 
	movw	ax,#packet	;   addr = &packet[enetpacketType0]; 
	xch	a,x 
	add	a,#enetpacketType0 
	add	a,i 
	xch	a,x	 
	movw	hl,ax 
	mov	a,[hl] 
	mov	regdata,a 
	mov	a,#RDMAPORT 
	tcall	[54h]	 
	inc	i 
	cmp	i,#10 
	bnz	$arplab2 
	 
;   for(i=0;i<10;++i) 
;      write_creg(RDMAPORT,*addr++); 
 
   /*write ethernet module MAC address*/ 
;   for(i=0;i<6;++i) 
;      write_creg(RDMAPORT,MYMAC[i]); 
   	mov	i,#0 
arplab3:   	 
	movw	ax,#MYMAC	 
	xch	a,x 
	add	a,i 
	xch	a,x	 
	movw	hl,ax 
	mov	a,[hl] 
	mov	regdata,a 
	mov	a,#RDMAPORT 
	tcall	[54h]	 
	inc	i 
	cmp	i,#6 
	bnz	$arplab3 
	 
   /*write ethernet module IP address*/ 
;      for(i=0;i<4;++i) 
;      write_creg(RDMAPORT,MYIP[i]); 
   	mov	i,#0 
arplab4:   	 
	movw	ax,#MYIP[4]	 
	xch	a,x 
	add	a,i 
	xch	a,x	 
	movw	hl,ax 
	mov	a,[hl] 
	mov	regdata,a 
	mov	a,#RDMAPORT 
	tcall	[54h]	 
	inc	i 
	cmp	i,#4 
	bnz	$arplab4 
 
   /*write remote MAC address*/ 
;   for(i=0;i<6;++i) 
;      write_creg(RDMAPORT,packet[enetpacketSrc0+i]); 
   	mov	i,#0 
arplab5:   	 
	movw	ax,#packet	 
	xch	a,x 
	add	a,enetpacketSrc0 
	add	a,i 
	xch	a,x	 
	movw	hl,ax 
	mov	a,[hl] 
	mov	regdata,a 
	mov	a,#RDMAPORT 
	tcall	[54h]	 
	inc	i 
	cmp	i,#6 
	bnz	$arplab5 
 
   /*write remote IP address*/ 
;   for(i=0;i<4;++i) 
;      write_creg(RDMAPORT,packet[arp_sipaddr+i]); 
   	mov	i,#0 
arplab6:   	 
	movw	ax,#packet	 
	xch	a,x 
	add	a,arp_sipaddr 
	add	a,i 
	xch	a,x	 
	movw	hl,ax 
	mov	a,[hl] 
	mov	regdata,a 
	mov	a,#RDMAPORT 
	tcall	[54h]	 
	inc	i 
	cmp	i,#6 
	bnz	$arplab6 
;   /*write some pad characters to fill out the packet to*/ 
;   /*the minimum length*/ 
;   for(i=0;i<0x12;++i) 
;      write_creg(RDMAPORT,0x00); 
   	mov	i,#0 
arplab7:   	 
	mov	regdata,#0 
	mov	a,#RDMAPORT 
	tcall	[54h]	 
	inc	i 
	cmp	i,#12h 
	bnz	$arplab7 
;   /*make sure the DMA operation has successfully completed*/ 
	mov	byte_read,#0		;byte_read = 0; 
;   while(!bit_test(byte_read,RDC)) 
;      read_creg(ISR); 
arplab8: 
	mov	a,#ISR 
	tcall	[54h] 
	bf	byte_read.6,$arplab8 
	 
   /*load number of bytes to be transmitted*/ 
;   write_creg(TBCR0,0x3C); 
;   write_creg(TBCR1,0x00); 
	mov	a,#3Ch 
	mov	regdata,a 
	mov	a,#TBCR0 
	tcall	[54h] 
	mov	a,#00h 
	mov	regdata,a 
	mov	a,#TBCR1 
	tcall	[54h]	 
;   /*send the contents of the transmit buffer onto the network*/ 
;   write_creg(CR,0x24); 
	mov	a,#24h 
	mov	regdata,a 
	mov	a,#CR 
	tcall	[54h]    
	ret 
/****************************************************************** 
//*	Perform ICMP Function 
//*   This routine responds to a ping. 
//******************************************************************/ 
icmp: 
 
;   /*set echo reply*/ 
;   packet[ICMP_type]=0x00; 
;   packet[ICMP_code]=0x00; 
 
	movw	ax,#packet 
	xch	a,x 
	add	a,#ICMP_type 
	xch	a,x 
	movw	hl,ax 
	mov	[hl],#0 
	movw	ax,#packet 
	xch	a,x 
	add	a,#ICMP_code 
	xch	a,x 
	movw	hl,ax 
	mov	[hl],#0 
				 
   /*clear the ICMP checksum*/ 
;   packet[ICMP_cksum ]=0x00; 
;   packet[ICMP_cksum+1]=0x00; 
	movw	ax,#packet 
	xch	a,x 
	add	a,#ICMP_cksum 
	xch	a,x 
	movw	hl,ax 
	mov	a,#0 
	mov	[hl],a 
	incw	hl 
	mov	[hl],a 
;   /*setup the IP header*/ 
;   setipaddrs(); 
	tcall	[5ah] 
;   /*calculate the ICMP checksum*/ 
;   hdr_chksum =0; 
	mov	hdr_chksum,#0 
	mov	hdr_chksum+1,#0 
	mov	hdr_chksum+2,#0 
	mov	hdr_chksum+3,#0 
	 
;   	hdrlen = (make16(packet[ip_pktlen],packet[ip_pktlen+1]))  
;	- ((packet[ip_vers_len] & 0x0F) * 4); 
	 
	movw	ax,#packet 
	xch	a,x 
	add	a,#ip_pktlen 
	xch	a,x 
	movw	hl,ax	 
	mov	a,[hl] 
	mov	hdrlen,a 
	incw	hl 
	mov	a,[hl] 
	mov	hdrlen+1,a			 
	movw	ax,#packet 
	xch	a,x 
	add	a,#ip_vers_len	 
	xch	a,x 
	movw	hl,ax	 
	mov	a,[hl] 
	add	a,#0fh 
	rol	a,1 
	rol	a,1 
	mov	i,a	;i|-r|-—ŽßêBy} 
	movw	ax,hdrlen 
	xch	a,x 
	sub	a,i 
	xch	a,x 
	subc	a,#0 
	movw	hdrlen,ax 
				 
;   addr = &packet[ICMP_type]; 
	mov	a,#ICMP_type 
	mov	addr,a 
;   cksum(); 
	tcall	[5ch] 
;   chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16)); 
	movw	ax,hdr_chksum 
	xch	a,x 
	add	a,hdr_chksum+2 
	xor	a,#0 
	mov	chksum16,a 
	xch	a,x 
	adc	a,hdr_chksum+3 
	xor	a,#0 
	mov	chksum16+1,a	 
;   packet[ICMP_cksum] = make8(chksum16,1); 
;   packet[ICMP_cksum+1] = make8(chksum16,0);				 
	movw	ax,#packet 
	xch	a,x 
	add	a,#ICMP_cksum 
	xch	a,x 
	movw	hl,ax	 
	movw	ax,chksum16	 
	mov	[hl],a 
	incw	hl 
	xch	a,x 
	mov	[hl],a	 
 
 
;   /*send the ICMP packet along on its way*/ 
;   echo_packet(); 
   	tcall	[5eh] 
	ret 
/****************************************************************** 
//*	CHECKSUM CALCULATION ROUTINE 
//******************************************************************/ 
cksum: 
 
cksum00: 
	movw	ax,hdrlen	 
	cmpw	ax,#1 
	bnc	$cksum02 
	movw	ax,#packet 
	xch	a,x 
	add	a,addr 
	xch	a,x 
	movw	hl,ax	 
	mov	a,[hl]	 
	mov	chksum16,a 
	incw	hl 
	mov	a,[hl]	 
	mov	chksum16+1,a 
	movw	ax,hdr_chksum	;hdr_chksum = hdr_chksum + chksum16;	 
	xch	a,x 
	add	a,chksum16 
	xch	a,x 
	addc	a,chksum16+1 
	movw	hdr_chksum,ax 
	mov	a,hdr_chksum+2 
	addc	a,#0 
	mov	hdr_chksum+2,a 
	mov	a,hdr_chksum+3 
	addc	a,#0 
	mov	hdr_chksum+3,a						 
         	 
	inc	addr 
	inc	addr 
	movw	ax,hdrlen 
	subw	ax,#2 
	movw	hdrlen,ax 
	br	$cksum00	 
cksum02: 
	movw	ax,hdrlen 
	cmpw	ax,#0 
	bz	$cksum03       
 
;         data_H=*addr; 
;         data_L=0x00; 
;         chksum16=make16(data_H,data_L); 
;         hdr_chksum = hdr_chksum + chksum16; 
 
	movw	ax,#packet 
	xch	a,x 
	add	a,addr 
	xch	a,x 
	movw	hl,ax	 
	mov	a,[hl]	 
	mov	chksum16,a	 
	movw	ax,#packet	 
	movw	hl,ax		 
	mov	a,[hl]	 
	mov	chksum16+1,a 
	movw	ax,hdr_chksum	;hdr_chksum = hdr_chksum + chksum16;	 
	xch	a,x 
	add	a,chksum16 
	xch	a,x 
	addc	a,chksum16+1 
	movw	hdr_chksum,ax 
	mov	a,hdr_chksum+2 
	addc	a,#0 
	mov	hdr_chksum+2,a 
	mov	a,hdr_chksum+3 
	addc	a,#0 
	mov	hdr_chksum+3,a	 
cksum03:       
	ret	 
;************************************************ 
;         ignore interrupt subroutine 
;************************************************ 
ignore:    nop 
           reti		 
;/****************************************************************** 
;//*	IP ADDRESS DEFINITION 
;//*   This is the Ethernet Module IP address. 
;//*   You may change this to any valid address. 
;/******************************************************************/ 
MYIP:  
	db	192 
	db	168 
	db	254 
	db	100  
 
;/******************************************************************/ 
;/*	HARDWARE (MAC) ADDRESS DEFINITION 
;//*   This is the Ethernet Module hardware address. 
;//*   You may change this to any valid address. 
;//******************************************************************/ 
MYMAC: 
	db	0 
	db	'V' 
	db	'O' 
	db	'L' 
	db	'T' 
	db	'S'  
		end