📄 final_forw77e58.asm
字号:
;2006-6-12
;增加了UDP数据包的校验和功能
;增加数据包在片外RAM中处理的能力
;进一步优化数据打包功能:
;1.将UDP和IP分开,便于下一步实现TCP协议
;2.将数据区划分,分别存储不同的参数
;050H-07FH作为IP相关参数存储区,具体如下:
;050-055:des mac ; 056-05B:source mac ; 05C-05D ;ether frame type
;060-063:source ip ; 064-067:des ip ; 068-069 :source port ;06A-06B:des port ; 06C:protocal ;06F:UDP是否校验
;070-073:local ip ; 74-77: mask ;78-7B: gate way ;7C-7F: ARP的IP
;080-088
;090
;0A0-0B1
;0BC-0BF 收到的数据帧个数
;0C0-0C3 ;0C8-0C9 ;0CA ;0CC-0CFh
;0D0-0D3 ping_reply ip ;0D4-0D7h ping时暂存064-067h,以方便arp
;串口收到的数据缓存在片外RAM中
;发送缓冲区定义在0100-2FFFH中,偱环存放.(12K)
;接收缓冲区定义在3000-6FFFH中,偱环存放.(16K)
;预留ARP缓存区为 7000H-70FFh (256字节)
;其它空间留作它用.
;下一步打算优化算法,以进一步减少数据处理的时间,提高系统的运行速度
;(发送一个数据包的时间为1.2ms ~ 20ms,真正的物理网卡发送时间仅占到5%左右,所以主要的时间还是花在数据处理上了.).
;目前最耗时的是checksum和对8019的DMA操作
;主要原因是发生在频繁改变DPTR上
;增加ICMP协议,可以ping 通本机
;增加配置功能 config
;77E58有两个DPTR,利用这个特性,可以大大提高处理速度.
org 0000h
LJMP 0030H
org 0003h
LJMP net_INT ;外部中断0
org 000Bh ;存储时钟信息
LJMP T0_INT
org 0030H
main:
call clock_initial
call Serial_initial
call welcome
call int_initial
call default_info
call default_setting
call net_initial
call wait_for_change
call work_now
mov DPTR,#0000h
loop:
;参数 DPTR 返回值 DPTR,R6,R7
call com_buffer
;参数 DPTR, R6,R7 返回值 R6,R7
call pack
;参数 DPTR, R6,R7 无返回值,不改变原有参数
call pac_send
inc DPH
mov A,DPH
clr C
subb A,#30h
jc m5
mov DPH,#00h
m5:
sjmp loop
;end main
;**********************************************
int_initial:
;----------中断初始化设置
clr IT0 ;低电平触发
SETB EX0
ret
T0_INT:
;------将时钟存储在寄存器2D-2F中
inc 2Fh
mov A,2Fh
jnz con78
inc 2Eh
con74:
mov A,2Eh
jnz con78
inc 2DH
con78:
retI
clock_initial:
clr A
;时钟信号清零
mov 2DH,A
mov 2EH,A
mov 2FH,A
setb ET0
setb EA
ret
net_INT:
;网络口中断,收到新的数据包
nop
clr EX0
push DPh
push DPl
push ACC
push B
mov 40h,R0 ;暂存R0-R7
mov 41h,R1
mov 42h,R2
mov 43h,R3
mov 44h,R4
mov 45h,R5
mov 46h,R6
mov 47h,R7
mov 24H,#40H ;收到的数据存放位置
mov 25H,#00H
call pac_receive
mov DPTR,#8007h
mov A,#0FFh ;清中断
movx @DPTR,A
mov R0,40h
mov R1,41h
mov R2,42h
mov R3,43h
mov R4,44h
mov R5,45h
mov R6,46h
mov R7,47h
POP B
pop ACC
pop dpl
pop dph
setb EX0
RETI
;*************************************************
Serial_initial:
;---------------------------------
MOV TMOD,#21h ;T1工作在方2,自动重装
mov TL1,#0ffh ;波特率115200
mov TH1,#0ffh
setb TR1 ;T1开始工作
setb TR0
mov SCON,#40h ;工作在方式1 10位UART
mov PCON,#80h ;波特率加倍
setb Ren
ret
com_buffer:
;---------------------------------
mov 20h,DPH
mov 21h,DPl
call com_rec
mov A,dPL
mov DPL,23h
clr C
subb A,23h
mov R7,A
mov A,DPH
mov DPH,22h
subb A,22h
mov R6,A
mov DPH,20h
mov DPL,21h
call command
jnz com_buffer
mov DPH,20h
mov DPL,21h
ret
command:
;---------
mov A,DPL
add A,#2Ah
mov DPL,A
jnc L204
inc DPH
L204:
movx A,@DPTR
cjne A,#'c',L218
inc DPTR
movx A,@DPTR
cjne A,#'o',exit208
inc DPTR
movx A,@DPTR
cjne A,#'n',exit208
inc DPTR
movx A,@DPTR
cjne A,#'f',exit208
inc DPTR
movx A,@DPTR
cjne A,#'i',exit208
inc DPTR
movx A,@DPTR
cjne A,#'g',exit208
call change
mov A,#0FFh
ret
L218:
cjne A,#'p',exit208
inc DPTR
movx A,@DPTR
cjne A,#'i',exit208
inc DPTR
movx A,@DPTR
cjne A,#'n',exit208
inc DPTR
movx A,@DPTR
cjne A,#'g',exit208
inc DPTR
mov A,R7
clr C
subb A,#6
mov R7,A
L240:
movx A,@DPTR
cjne A,#' ',L242
dec R7
inc DPTR
sjmp L240
L242:
call s_to_i
mov A,B
jnz exit208
call ping
mov A,#0FFH
ret
exit208:
mov A,#0
ret
com_rec:
;接收数据放于 DPTR + 2AH 起始处
mov A,dpl
add A,#2Ah
mov DPL,A
mov A,DPH
addc A,#0
mov DPH,A
mov 22h,DPH
mov 23h,DPL
clr A
mov R6,A
mov R7,A
wait050:
call com_receive
mov B,A
CJNE A,#0Dh,n1012 ; A=0D ?
movx @DPTR,A
inc DPTR
mov A,#0Ah
movx @DPTR,A
inc DPTR
call com_send ;回应
sjmp ret1023
n1012:
mov A,B
CJNE A,#08h,cd1568 ;退格删除
call dec_dptr
mov A,#20h
call com_send
mov A,#08h
call com_send
sjmp wait050
cd1568:
mov A,B
movx @DPTR,A
inc DPTR
sjmp wait050
ret1023:
ret
dec_dptr:
mov A,DPL
clr C
subb A,#1
mov DPL,A
jnc L225
dec DPH
L225:
ret
com_receive:
;---------------------------------
JBC RI,next
SJMP com_receive
next:
mov A,SBUF
com_send:
;-----------------------------
mov SBUF,A
wait1:
JNB TI,wait1
clr TI
ret
welcome:
;--------------
mov DPTR,#s1
mov R0,#22
call cout
call delay
mov DPTR,#s2
Mov R0,#14
call cout
mov R0,#60h
mov DPTR,#002Dh
PUSH DPL
PUSH DPH
mov B,#0
loop275:
mov A,B
inc B
mov DPTR,#s6
movc A,@A+DPTR
POP DPH
POP DPL
movx @DPTR,A
inc DPTR
PUSH DPL
PUSH DPH
djnz R0,loop275
POP ACC
POP ACC
ret
;---------------
default_info:
;--------------
mov DPTR,#s3
mov R0,#213 ;s3长度
call cout
call delay
mov DPTR,#s4
mov R0,#37
call cout
ret
;--------
work_now:
;------------
mov dPTR,#s15
mov R0,#20
call cout
ret
cout:
;------DPTR :#data R0:length ---
loop_c:
clr A
movc A,@A+DPTR
mov SBUF,A
inc DPTR
wait_c:
JNB TI,wait_c
clr TI
djnz R0,loop_c
ret
wait_for_change:
;-----------------
mov A,2Fh
add A,#90
mov B,A
wait340:
jB RI,change
mov A,2FH
clr C
subb A,B
jnz wait340
ret
string:
mov DPTR,#7500h
call com_buffer
mov DPTR,#752Ah
dec R7
dec R7
mov A,R7
ret
change:
;-------
clr RI
mov DPTR,#s14
mov R0,#40
call cout
L3655:
mov DPTR,#s7 ;本机IP:
mov R0,#7
call cout
mov R0,#60h
mov R2,#4
call i_to_s
mov A,#':'
call com_send
call string
jz L372
call S_To_i
mov A,B
jz L366
mov DPTR,#s9
mov R0,#20
call cout
sjmp L3655
L366:
mov DPTR,#s8 ;OK!\n
mov R0,#5
call cout
mov R0,#0C0h
mov R1,#60h
mov R2,#4
Loop373:
mov A,@R0
mov @R1,A
inc R0
inc R1
djnz R2,Loop373
L372:
mov DPTR,#s10 ; 目的IP:
mov R0,#7
call cout
mov R0,#64h
mov R2,#4
call i_to_s
mov A,#':'
call com_send
call string
jz L404
call S_To_i
mov A,B
jz L3760
mov DPTR,#s9
mov R0,#20
call cout
sjmp L372
L3760:
mov R0,#0C0h
mov R1,#64h
mov R2,#4
Loop398:
mov A,@R0
mov @R1,A
inc R0
inc R1
djnz R2,Loop398
mov DPTR,#s8 ;OK!\n
mov R0,#5
call cout
L404:
mov DPTR,#s11 ; 子网掩码:
mov R0,#9
call cout
mov R0,#74h
mov R2,#4
call i_to_s
mov A,#':'
call com_send
call string
jz L420
call S_To_i
mov A,B
jz L412
mov DPTR,#s9
mov R0,#20
call cout
sjmp L404
L412:
mov R0,#0C0h
mov R1,#74h
mov R2,#4
Loop422:
mov A,@R0
mov @R1,A
inc R0
inc R1
djnz R2,Loop422
mov DPTR,#s8 ;OK!\n
mov R0,#5
call cout
L420:
mov DPTR,#s12 ; 网关:
mov R0,#5
call cout
mov R0,#78h
mov R2,#4
call i_to_s
mov A,#':'
call com_send
call string
jz L440
call S_To_i
mov A,B
jz L430
mov DPTR,#s9
mov R0,#20
call cout
sjmp L420
L430:
mov R0,#0C0h
mov R1,#78h
mov R2,#4
Loop451:
mov A,@R0
mov @R1,A
inc R0
inc R1
djnz R2,Loop451
mov DPTR,#s8 ;OK!\n
mov R0,#5
call cout
L440:
mov DPTR,#s13
mov R0,#11
call cout
ret
S_To_i:
;--------------
mov R1,#0C0h
mov R3,#0
loop377:
movx A,@DPTR
mov R0,A
clr C
subb A,#'.'
jz L376
mov A,R0
subb A,#'0'
jc ret375
mov A,R0
clr C
subb A,#3Ah ;'9'+1
jnc ret375
mov A,R0
clr C
subb A,#'0'
mov R2,A
mov A,R3 ;<--------s
mov B,#10
mul AB
xch A,B
cjne A,#0,ret375
xch A,B
add A,R2
jc ret375
mov R3,A
sjmp L403
L376:
mov A,R3
mov @R1,A
inc R1
mov R3,#0
L403:
inc DPTR
djnz R7,loop377
cjne R1,#0C3h,ret375
mov A,R3
mov @R1,A
mov B,#0
ret
ret375:
mov B,#1 ;错误
ret
i_To_S:
;------将RAM中存储的IP转换成ASCII码,并输出到串口
;------格式 [***.***.***.***]:
;参数:R0,R2
mov A,#'['
call com_send
loop2004:
mov A,@R0
mov R1,#0CCh
loop2005:
mov B,#10
DIV AB
mov @R1,B
jz L336
inc R1
sjmp loop2005
L336:
mov A,@R1
add A,#'0'
call com_send
dec R1
cjne R1,#0CBh,L336
dec R2
mov A,R2
jz L3960
mov A,#'.'
call com_send
inc R0
sjmp loop2004
L3960:
mov A,#']'
call com_send
ret
buffer_send:
;----------DPTR,R6,R7
mov A,#0Dh
call com_send
mov A,#0Ah
call com_send
mov A,#3Eh ;'>'
call com_send
inc R6
loop312:
movx A,@DPTR
mov SBUF,A
here313:
jnb TI,here313
clr TI
inc DPTR
djnz R7,loop312
djnz R6,loop312
mov A,#0Dh
call com_send
mov A,#0Ah
call com_send
ret
;*********************Data process***************
default_setting:
;----------默认设置
mov DPTR,#ether_data
mov R0,#50H
mov R1,#0
loop872:
mov A,R1
movc A,@A+DPTR
mov @R0,A
inc R0
inc R1
cjne R1,#14,loop872
mov DPTR,#ip_data
mov R0,#60H
mov R1,#0
loop823:
mov A,R1
movc A,@A+DPTR
mov @R0,A
inc R0
inc R1
cjne R1,#12,loop823
mov DPTR,#subnet_data
mov R0,#70H
mov R1,#0
loop888:
mov A,R1
movc A,@A+DPTR
mov @R0,A
inc R0
inc R1
cjne R1,#12,loop888
clr A
mov DPTR,#7000h
movx @DPTR,A ;ARP条数为0
inc DPL
movx @DPTR,A
mov 06CH,#11h ;协议类型:UDP
mov 6Fh,#0 ;发送数据不进行UDP校验
mov R0,#0BDh
mov R1,#3
clr A
loop503:
mov @R0,A
inc R0
djnz R1,loop503
ret
pack:
;----------------------将XRAM 中的数据 加上UDP报头和IP头部
;------------目的地址:0011D8A51E15 目的IP:222.205.9.240
;------------源端口: 3456 目的端口:7788
PUSH 20H
PUSH 21H
PUSH 22H
PUSH 23H
mov 20H,DPH
mov 21H,DPL
call arp
mov DPH,20h
mov DPL,21h
call ether_pack
mov A,R7
add A,#8 ;数据长度 + 8 = UDP长度
mov R7,A
mov A,R6
addc A,#0
mov R6,A
mov B,#16H ;此偏移量正好是UDP加上伪头部时的位置 22H-0C(12字节)
call add_dptr
call udp_pack
mov A,R7
add A, #20 ; UDP长度 + 20 = IP长度
mov R7,A
mov A,R6
addc A,#0
mov R6,A
mov B,#0EH
call add_dptr
call ip_pack
mov A,R7
add A, #14 ;IP长度 + 14 = 总长度
mov R7,A
mov A,R6
addc A,#0
mov R6,A
mov DPH,20h
mov DPL,21h
POP 23H
POP 22H
POP 21H
POP 20H
ret
;-------------------------
add_dptr:
;------------参数 B---
PUSH ACC
mov DPH,20h
mov A,21H
add A,B
mov dpl,A
mov A,20h
addc A,#0
mov DPH,A
POP ACC
ret
ether_pack:
;---------------
mov R0,#50h
mov R1,#14
wait9510:
mov A,@R0
movx @DPTR,A
inc R0
inc DPTR
djnz R1,wait9510
ret
udp_pack:
;-----------------------------------
;dptr为真正的UDP包位置-12 ,这样做是为了便于加入校验伪头部
;堆栈中的参数为是否进行UDP校验
;------伪头部
clr A
movx @DPTR,A
inc DPTR
mov A,#11h
movx @DPTR,A
inc DPTR
mov A,R6
movx @DPTR,A
inc DPTR
mov A,R7
movx @DPTR,A
inc DPTR
mov R0,#60H
mov R1,#8
wait098:
mov A,@R0
movx @DPTR,A
inc DPTR
inc R0
djnz R1,wait098
;-------- 真正的头部
mov R1,#4
wait056:
mov A,@R0
movx @DPTR,A
inc DPTR
inc R0
djnz R1,wait056
mov A,R6 ;UDP长度
movx @DPTR,A
inc DPTR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -