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