汇编编写的最小TCP协议栈驱动89C51MCU物联网终端(128RAM,1K Flash,8019)
18年前还不懂得C语言,用汇编写的物联网终端,最早的物联网终端,卫星电视共享盒网络驱动。
;***************************************************
;ATMEL89C51&RTL8109 ISA 接口驱动 MCU 128字节RAM 1K FLASH
;实现ARP DNS UDP 云服务器通讯
;网卡地址300H-31FH,复位地址P3.4,ISA为地址,IOD为数据
;程序设计:戴晓斌 QQ:949000
;开始时间:2006-4-1 8:00AM
;预计结束:2006-4-30
;****************************************************
ISA EQU P0
IOD EQU P2
IOR EQU P0.6
IOW EQU P0.7
RST EQU P1.7
INT EQU P3.6
LED EQU P3.7
SEN EQU P1.2 ;SEND发送数据给智能卡
DEN EQU P1.3 ;智能卡使能端
DAT EQU P1.4 ;DAT接收从智能卡
CLK EQU P1.5 ;频率为BPS的一倍
SERVER EQU 3AH
MYSP EQU 32H
ROUMAC EQU 10H; 网关MAC
MYMAC EQU 16H; 本机MAC
MYIP EQU 28H ; 本机 IP 16
MYDNS EQU 2CH; DNS服务器 1A
IPHEAD EQU 20H;IP头
IPTYPE EQU 24H;IP类型
IPPACK EQU 40H
AUX EQU 8EH
CHPENR EQU 0F6H
CHPCON EQU 0BFH
ORG 0H
LJMP START
ORG 3H
RETI
ORG 0BH
RETI
ORG 13H
RETI
ORG 1BH
RETI
ORG 23H
RETI ;LJMP RS232
ORG 40H
START:
MOV A,#0
MOV R0,A
RAM:
MOV @R0,A
INC R0
CJNE R0,#0FFH,RAM ;清除RAM
MOV P1,#0B0H
MOV P0,#0FFH
MOV P2,#0FFH
MOV P3,#0FFH
MOV SP,#0E8H
MOV 28H,#0C0H ;MY IP ADDRESS
MOV 29H,#0A8H
MOV 2AH,#1H
MOV 2BH,#2H
MOV 2CH,#202 ;DNS SERVER
MOV 2DH,#101
MOV 2EH,#98
MOV 2FH,#55
MOV 3EH,#1FH ;端口
MOV 3FH,#9AH
MOV 1DH,#02H ;ID
MOV 1EH,#20H
MOV 1FH,#50H
MOV 16H,#0H ;MY MAC
MOV 17H,#0H
MOV 18H,#21H
MOV 19H,#0CDH
MOV 1AH,#0E7H
MOV 1BH,#029H
MOV 3AH,#0C0H ;SERVER1
MOV 3BH,#0A8H
MOV 3CH,#1H
MOV 3DH,#0C6H
; LCALL INT232
LCALL ISAINT ;8019初始化
; LCALL READMAC
LCALL WRITEMAC
LCALL SENDMAC
MOV A,#0
LCALL EPAGE
MOV A,#0CH
MOV R0,#0CCH;
LCALL ISAW
MOV A,#0DH
MOV R0,#0E0H;
LCALL ISAW
MOV A,#0H
MOV R0,#22H;
LCALL ISAW
;———————————-ARP————
NOARP:
SETB LED
CLR C
MOV A,15H ;是否有网关MAC 如果没有发送ARP请求
JNZ NODNS
MOV R6,#60 ;读取ARP QUEST包发送
MOV R7,#0
MOV DPH,#08H
MOV DPL,#00H
LCALL SPACK
LCALL WAITBUS ;等待。。。
RNEXT:
LCALL NETPACK ;读取一个有效IP数据包
JZ NOARP
READUDP:
MOV A,55H
CJNE A,#2,RNEXT ;读下一个
MOV R0,#56H
MOV R1,#10H ;0A
MOV R6,#6
ROUTE_MAC:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R6,ROUTE_MAC
LJMP RNEXT
;—————————————————————-
NODNS:
MOV 8H,#0
MOV A,3AH
JNZ LOGIN
LCALL MYDOMAIN ;读取域名 第一个字节为长度。结束为0
LCALL DNS
LCALL WAITBUS ;等待。。。
NONEXT:
LCALL NETPACK ;读取一个有效IP数据包
JZ NODNS
LOADIP:
MOV A,63H ;判断是否DNS返回
CJNE A,#35H,NONEXT
LCALL SEARCH
JZ NODNS ;DNS找不到IP
ADD A,#13 ;找到C00C偏移量
ADD A,#40H;IPPACK
MOV R1,#3AH
MOV R0,A
MOV R6,#4
MIP:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R6,MIP
LJMP NONEXT
;——————————————————–
LOGIN: ;登陆到服务器。。。。。。
MOV A,26H
CJNE A,#4FH,RELOGIN
MOV A,27H
CJNE A,#4BH,RELOGIN
SJMP EMLOOP ;已经登陆开始处理数据
RELOGIN:
MOV A,8H
INC A
MOV 8H,A
SUBB A,#10
JNZ LOGINS ;登陆10次没有反应重新查找DNS
LJMP START ;重新初始化。。
LOGINS:
MOV R6,#40H
MOV R7,#0
MOV DPH,#07H
MOV DPL,#00H
;发送LOGIN TO SERVER
LCALL MYUDP
LCALL MYSPACK
LCALL WAITBUS ;等待服务器。。。。
WAITLOGIN:
LCALL NETPACK ;读取一个有效IP数据包
JZ LOGIN
LCALL ARPANS ;ARP应答
LCALL LOGINOK ;处理登陆返回数据
MOV A,26H
CJNE A,#4FH,WAITLOGIN
MOV A,27H
CJNE A,#4BH,WAITLOGIN
CLR LED ;登陆完毕,开始接受数据!
;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EMLOOP:
LCALL INITS ;清除8019重新初始化
MOV R6,#107 ;全部数据到107, 到id开始接收
MOV R7,#0
MOV DPH,#07H
MOV DPL,#50H
LCALL MYUDP ;发送IP头数据等待发送
LP1:
LCALL INT232
LCALL MYPIC ;等待接收数据,从PIC接收数据
JZ LP1 ;如果是ID继续
CJNE A,#0FEH,LP1 ;不等于FE没有正常接收数据
;———————————————————-
MOV R2,#02BH ;写入加密卡号
MOV R3,#0H
LCALL MY8019
MOV R4,#08H
MOV A,#08
MOV DPL,#0F8H
MOV DPH,#0FH
DES:
CLR A
MOVC A,@A+DPTR
MOV R0,A ;写入数据到8019
MOV A,#10H
LCALL ISAW
INC DPL
DJNZ R4,DES
;———————————————————
MOV A,#08H
MOV R0,A ;写入数据到8019
MOV A,#10H
LCALL ISAW
SETB LED
LCALL SENDMYDUP ;发送出去
CWW:
LCALL CW
CLR LED
SJMP EMLOOP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV R0,#5EH
MOV R1,#28H
MOV R2,#4
COMPIPORT:
MOV A,@R0
MOV R3,A
MOV A,@R1
SUBB A,R3 ;比较
JNZ CWW
INC R0
INC R1
DJNZ R2,COMPIPORT ;比较IP是否一样。。。。。
MOV R1,3EH ;端口是否一样
MOV A,@R0
SUBB A,R1
JNZ CWW ;处理其他数据
; SETB DEN
; SETB SEN
; CLR DAT
; CLR DAT
; LCALL INITS ;清除8019重新初始化
PROCOK:
; JNB DEN,EMLOOP ;P1.7
; JNB SEN,MYREAD ;P1.6
; SJMP PROCOK
MYREAD:
; LCALL READES ;发送给接收机
; LCALL INITS ;清除8019重新初始化
LJMP EMLOOP
;———————————————————————————————————————–
RS232: ;JB RI, HAD_RCV
;CLR TI
;RETI
HAD_RCV: PUSH ACC
MOV A,SBUF
MOV @R0,A
INC R0
INC R1
POP ACC
RETI
SEARCH:;查找DNS地址
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;R0=起始地址 R1=长度 R2=0未找到 返回偏移量
MOV R0,#40H
MOV R1,22H
MOV R2,#0H
LOOP:
MOV A,@R0
XRL A,#0C0H;
JNZ SS1
INC R0
MOV A,@R0
XRL A,#0CH
JZ SSEND
SS1:INC R0
INC R2
DJNZ R1,LOOP
MOV R2,#0
SSEND:
MOV A,R2
RET
NETPACK:
MOV R0,#0H ;选第一页
LCALL EPAGE
MOV R0,#0FFH
MOV A,#7
LCALL ISAW
MOV A,#3 ;读当前页指针
LCALL ISAR
MOV R4,A ;读取BNRY=R4
MOV R2,A ;NEXT_PAGE
;MOV 26H,A
MOV R0,#40H
LCALL EPAGE
MOV A,#7H
LCALL ISAR
MOV R7,A ;读取CURR=R7
;MOV 27H,A
JNZ CURR0 ;CURR=0退出
MOV A,#0
RET ;返回0退出
CURR0:
INC R4 ;BNRY=BNRY+1
CLR C
MOV A,R4
SUBB A,#7FH
JC NDY7F
MOV R4,#4CH ;BNRY>7FH BNRY=4C
NDY7F:
CLR C
MOV A,R4
SUBB A,R7
JNZ CB ;CURR=BNRY 没有数据进入退出
MOV A,#0
RET
CB: ;不相等有数据进入
MOV R0,#0
LCALL EPAGE
MOV R1,#20H ;存取地址
MOV R2,#4 ;读取前4个8019前置
MOV R3,#0 ;高位0
MOV R5,#0 ;页面地址低位
MOV A,R4 ;R4页面高位(读取R2或者R4有待验证)
;R1存放地址 R2长度低位 R3长度高位 R4页面地址 R5起始地址
LCALL RPACK ;读取前4个字节到20-23
MOV R1,#24H ;存取地址
MOV R2,#2 ;读取协议
MOV R3,#0 ;高位0
MOV R5,#10H ;页面地址低位
MOV A,R4 ;R4页面高位(读取R2或者R4有待验证)
LCALL RPACK ;读取前协议地址到
MOV A,20H
ORL A,#20H
XRL A,#21H
JNZ ERRPACK ;状态不等于21(21是广播)
MOV A,21H
CLR C
SUBB A,#7FH
JNC ERRPACK ;页面大于7FH
MOV A,21H
CLR C
SUBB A,#4CH ;页面小于4CH
JC ERRPACK
MOV A,23H
CLR C
SUBB A,#06H
JNC ERRPACK ;长度大于1535最大IP包错误13922805190
SJMP NOERR ;没有错误
ERRPACK:
MOV R0,#40H
LCALL EPAGE
MOV A,#7H
LCALL ISAR
SUBB A,#1
MOV R1,A
CLR C
SUBB A,#4CH
JNC NOOO
MOV R1,#7FH
NOOO:
MOV R0,#0
LCALL EPAGE
MOV A,R1
MOV R0,A
MOV A,#3H
LCALL ISAW
MOV A,#0
RET
NOERR:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV A,24H
CJNE A,#8H,NOREAD ;如果不是0800 或者0806放弃
MOV A,25H
JZ OK ;0800
CJNE A,#6H,NOREAD ;是否=0806
OK:
MOV R1,#40H ;存取地址
MOV R2,22H
MOV A,23H
CJNE A,#0,HIGHS ;高位不为0则读取全部低位
MOV A,R2 ;防止内存溢出,不接受大于BF长度的数据
CLR C
SUBB A,#08FH
JC OFULL
HIGHS:
MOV R2,#08FH
OFULL:
;MOV R3,23H ;长度高位
MOV R3,#0 ;高位暂时不读,因为内存不够用
MOV R5,#4 ;页面地址低位 跳过8019前置
MOV A,R4
MOV R4,A ;页面地址高位
CLR C
SUBB A,#4CH
JC NOREAD ;<4CH就不读取
MOV A,R4
CLR C
SUBB A,#7FH
JNC NOREAD ;>7FH就不读
LCALL RPACK
NOREAD:
MOV R0,#0
LCALL EPAGE
MOV A,#0BH ;DMA 高位
MOV R0,#0
LCALL ISAW
MOV A,#0AH ;DMA 低位
MOV R0,#0
LCALL ISAW
MOV A,#0 ;关闭DMA
MOV R0,#22H
LCALL ISAW
MOV A,21H ;读取NEXT_PAGE
SUBB A,#1
MOV R0,A
CLR C
SUBB A,#4CH ;NEXT_PAGE<4C
JNC CC
MOV R0,#7FH ;NEXT_PAGE=7F
CC:
MOV A,#3
LCALL ISAW ;写入到BNRY
MOV A,#7H
MOV R0,#0FFH
LCALL ISAW ;清除中断
MOV A,21H ;返回下一页地址
ENDRP:
RET
READ8019:
MOV R0,#0H
LCALL EPAGE
MOV R0,#0H
MOV R1,#0F0H
RER:
MOV A,R0
LCALL ISAR
MOV @R1,A
INC R0
INC R1
CJNE R0,#0FH,RER
RET
SPACK: ;R6,R7为长度
MOV R0,#0
LCALL EPAGE
;;;;;;;;;;可能不要
MOV A,#0H
MOV R0,#22H
LCALL ISAW ;中止DMA 可以不要
MOV A,#9 ;DMA写入高位地址
MOV R0,#40H ;修改发送缓冲
LCALL ISAW
MOV A,#8 ;DMA写入低位地址
MOV R0,#0H
LCALL ISAW
MOV A,R7 ;长度高位
MOV R0,A
MOV A,#0BH
LCALL ISAW
MOV A,R6 ;长度低位
MOV R0,A
MOV A,#0AH
LCALL ISAW
MOV A,#0 ;写DMA
MOV R0,#12H
LCALL ISAW
MOV A,R6
MOV R1,A
MOV A,R7
ADD A,#1
MOV R2,A
S1:
MOV A,#0
MOVC A,@A+DPTR
INC DPTR
MOV R0,A
MOV A,#10H
LCALL ISAW
DJNZ R1,S1
DJNZ R2,S1
MYSPACK:
MOV A,#0AH
MOV R0,#0
LCALL ISAW ;中止DMA 可以不要
MOV A,#0BH
MOV R0,#0
LCALL ISAW ;中止DMA 可以不要
MOV A,#0H
MOV R0,#22H
LCALL ISAW ;中止DMA 可以不要
MOV R5,#10H;最多重发16次
RSEND:
MOV R3,#4H ;等待是否发送完毕4*255=1000次
LOOOP:
MOV R4,#0FAH
LOOP1:
MOV A,#0
LCALL ISAR
ANL A,#4H ;检查TXP是否为0 发送完毕
CJNE A,#0,RSEND1
LJMP SEND
RSEND1:
DJNZ R4,LOOP1
DJNZ R3,LOOOP
MOV A,#4
LCALL ISAR
ANL A,#1H
CJNE A,#0,SEND
MOV A,#0
MOV R0,#3EH
LCALL ISAW ;启动发送
DJNZ R5,RSEND
SEND:
MOV A,#4
MOV R0,#040H ;修改发送缓冲
LCALL ISAW ;起始地址
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV A,R7 ;是否少于64个字节
JNZ NNZZ
MOV A,R6
CLR C
SUBB A,#64
JNC NNZZ
MOV A,R6 ;补上0到64个字节
ADD A,#40H
MOV R0,A
CLLL:
MOV A,#0
MOV @R0,A
INC R0
CJNE R0,#80H,CLLL
MOV R6,#64
NNZZ:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV A,R6
MOV R0,A
MOV A,#5
LCALL ISAW ;发送计数器低位
MOV A,R7
MOV R0,A
MOV A,#6
LCALL ISAW ;发送计数器高位
MOV A,#7 ;清除中断
MOV R0,#0FFH
LCALL ISAW
MOV A,#0 ;开始发送
MOV R0,#3EH
LCALL ISAW
RET
RPACK: ;R1存放地址 R2长度低位 R3长度高位 R4页面地址 R5起始地址
MOV R0,#0H
LCALL EPAGE ;选择0页
MOV A,R4 ;R4为页面地址
MOV R0,A
MOV A,#9H
LCALL ISAW
MOV A,R5
MOV R0,A
MOV A,#8H
;MOV R0,#0H ;低位地址
LCALL ISAW
MOV A,R2 ;R2为长度
MOV R0,A
MOV A,#0AH ;长度地位
LCALL ISAW
MOV A,R3
MOV R0,A
MOV A,#0BH ;长度高位
LCALL ISAW
MOV A,#0 ;DMA读取
MOV R0,#0AH
LCALL ISAW
MOV A,R3
ADD A,#1
MOV R7,A
MOV A,R2
MOV R6,A
RDMA:
MOV A,#10H ;读取一个字节
LCALL ISAR
MOV @R1,A
; MOVX @R1,A ;XX用外部RAM
INC R1
DJNZ R6,RDMA
DJNZ R7,RDMA
MOV A,#0
MOV R0,#22H
LCALL ISAW ;DMA读取完成
RET
SENDMAC:
MOV R1,#11H
CSEND: MOV A,@R1
MOV A, #55H
CLR TI
MOV SBUF,A
JNB TI,$
CLR TI
INC R1
CJNE R1,#17H,CSEND
RET
WRITEMAC:
MOV R0,#40H ;选择第一页
LCALL EPAGE
MOV R1,#16H ;MAC地址开始
MOV R2,#1
WMAC:
MOV A,@R1
MOV R0,A
MOV A,R1
MOV A,R2
LCALL ISAW
INC R1
INC R2
CJNE R2,#7,WMAC
MOV R0,#0H ;选择第0页
LCALL EPAGE
RET
READMAC:
MOV R0,#0H
LCALL EPAGE ;选择0页
MOV A,#8
MOV R0,#0H
LCALL ISAW
MOV A,#9H
MOV R0,#0H
LCALL ISAW
MOV A,#0AH ;12个数据
MOV R0,#0CH
LCALL ISAW
MOV A,#0BH ;开始地址
MOV R0,#0H
LCALL ISAW
MOV A,#0 ;DMA读取
MOV R0,#0AH
LCALL ISAW
MOV R7,#06H
MOV R1,#16H ;MAC地址开始
RMAC:
MOV A,#10H ;读取一个字节
LCALL ISAR
MOV @R1,A
INC R1
MOV A,#10H ;放弃一个字节
LCALL ISAR
DJNZ R7,RMAC
MOV A,#0
MOV R0,#22H
LCALL ISAW ;DMA读取完成
RET
EPAGE: ;R0=0 PAGE0 R0=40 PAGE1 R0=80 PAGE2 R0=C0 PAGE3
MOV A,#0
LCALL ISAR
ANL A,#3BH ;读取页面
ORL A,R0
MOV R0,A
MOV A,#0
LCALL ISAW
RET
INT232:
CLR TR1
CLR ES
CLR ET1
MOV TMOD,#20H
MOV SCON,#0D0H
MOV TH1,#0FAH
; MOV TL1,#0FAH
MOV PCON,#00H
SETB P3.0
SETB P3.1
SETB TR1
;SETB ES
;SETB EA
RET
;————————————
; 7 6 5 4 3 2 1 0
; PS1 PS0 RD2 RD1 RD0 TXP STA STP
;————————————-
;初始化网卡
ISAINT:
SETB RST ;硬件复位ISA网卡
LCALL waitbus
CLR RST ;End of Reset ISA bus
LCALL waitbus
MOV A,#1FH ;软件复位8019地址 #31FH
LCALL ISAR
LCALL LONGPAUSE
MOV R0,A
MOV A,#1FH
LCALL ISAW
LCALL LONGPAUSE
;复位结束
INITS:
MOV R0,#0
LCALL EPAGE
MOV A,#0 ;停止运行8109
MOV R0,#21H
LCALL ISAW
LCALL waitbus
MOV A,#1
MOV R0,#4CH ;接收起始页
LCALL ISAW
MOV A,#2
MOV R0,#80H ;PSTOP=80
LCALL ISAW
MOV A,#3
MOV R0,#4CH ;BNRY=4C
LCALL ISAW
MOV A,#4 ;发送起始页
MOV R0,#40H
LCALL ISAW
MOV A,#0CH
MOV R0,#0CCH
LCALL ISAW
MOV A,#0DH
MOV R0,#0E0H
LCALL ISAW
MOV A,#0EH
MOV R0,#0C8H
LCALL ISAW
MOV A,#0FH
MOV R0,#0H
LCALL ISAW
;换页面————————–
MOV R0,#40H
LCALL EPAGE
;——————————–
MOV A,#7
MOV R0,#4DH
LCALL ISAW
MOV A,#8
MOV R0,#0H
LCALL ISAW
MOV A,#9
MOV R0,#41H
LCALL ISAW
MOV A,#0AH
MOV R0,#0H
LCALL ISAW
MOV A,#0BH
MOV R0,#80H
LCALL ISAW
MOV A,#0CH
MOV R0,#0H
LCALL ISAW
MOV A,#0DH
MOV R0,#0H
LCALL ISAW
MOV A,#0EH
MOV R0,#0H
LCALL ISAW
MOV A,#0FH
MOV R0,#0H
LCALL ISAW
;初始化结束,开始运行网卡
MOV A,#0 ;开始运行8109
MOV R0,#22H
LCALL ISAW
RET ;结束
waitbus:
MOV R0,#0
waitbus1:
MOV R1,#0
waitbus2:
DJNZ R1,waitbus2
DJNZ R0,waitbus1
RET
longpause:
MOV DPTR,#-326
longpause_l:
INC DPTR
MOV A,DPL
ORL A,DPH
JNZ LONGPAUSE_L
RET
;A=地址,读出数据返回到A
ISAR:
MOV IOD,#0FFH
ORL A,#0C0H
MOV ISA,A
CLR IOR ;读取
MOV A,IOD
SETB IOR
RET
;A=地址,R0=数据,写入到8019
ISAW:
MOV IOD,#0H
ORL A,#0C0H
MOV ISA,A
MOV A,R0
CLR IOW ;写入
MOV IOD,A
SETB IOW
RET
CHECKSUM:; R2,R3=LEN RETURN R5,R6 DPTR 为地址 R0位内存地址
MOV A,#0
MOV R5,A
MOV R6,A
MOV R7,A
CLR C ;长度除于2
MOV A,R3
RRC A
MOV R3,A
MOV A,R2
MOV R1,A ;保存低位,最后判断是否为奇数
RRC A
MOV R2,A
INC R3 ;加一防止0-1=255
SSS:
MOV A,@R0
SS3:
; CPL A
CLR C
ADD A,R5
MOV R5,A
JNC AA1
CLR C
;INC R6 ;不会产生进位标志,改用加法运算
MOV A,R6
ADD A,#1
MOV R6,A
JNC AA1
INC R7 ;进位
AA1:
INC R0
MOV A,@R0
NORAM:
CLR C
; CPL A
ADD A,R6
MOV R6,A
JNC AA2
INC R7
AA2:
INC R0
DJNZ R2,SSS
DJNZ R3,SSS
;;;;如果为奇数则多加一个数据
MOV A,R1
ANL A,#1
JZ JISHU
MOV A,@R0
CLR C
ADD A,R5
MOV R5,A
JNC JISHU
CLR C
MOV A,R6
ADD A,#1
MOV R6,A
JNC AA1
INC R7 ;进位
JISHU:
;;;;;;;;;;;;;;;;;;;奇数结束
MOV A,R7
CLR C
ADD A,R5
MOV R5,A
JNC AA3
INC R6
AA3:
MOV A,R5
CPL A
MOV R5,A
MOV A,R6
CPL A
MOV R6,A
RET
ENXRAM:
MOV CHPENR,#87H
MOV CHPENR,#59H
MOV CHPCON,#10H
MOV CHPENR,#0H
RET
ORG 05E0H
DB 10H,03H, 77H,77H,77H,07H, 79H,6FH,75H,62H,61H,6EH,67H, 03H, 6EH, 65H, 74H,0H
; DB 0FH,03H, 77H,77H,77H,06H, 43H,4EH,37H,30H,30H,30H, 03H, 43H, 4FH, 4DH,0H
DB ‘WWW.CN7000.COM’
ORG 0800H ; ARP QUEST
DB 0FFH,0FFH, 0FFH, 0FFH, 0FFH, 0FFH ;目标地址
DB 0H, 0H, 21H, 0CDH, 0E7H, 29H ;我的网卡
DB 08H, 06H, 0H, 1H ;ARP
DB 08H, 00H, 6H, 4H, 0H, 1H
DB 0H, 0H, 21H, 0CDH, 0E7H, 29H ;我的MAC
DB 0C0H, 0A8H, 01H, 02H ;我的IP
DB 0H, 0H, 0H, 0H, 0H, 0H ;目的MAC
DB 0C0H, 0A8H, 01H,0C6H ;网关IP
DB 0H, 0H, 0H, 0H, 0H, 0H, 0H, 0H, 0H, 0H, 0H, 0H, 0H, 0H, 0H, 0H, 0H, 0H ;数据
ORG 0600H ; DNS QUEST
DB 00H,14H, 78H, 0BFH, 0A9H, 0B0H ;网关MAC
DB 0H, 0H, 21H, 0CDH, 0E7H, 29H ;我的MAC
DB 08H, 0H ; 协议类型 ;IP
DB 45H, 0H, 0H, 3CH, 0H, 85H, 0H,0H
DB 80H, 11H ; 128TTL UDP
; DB 4BH,0E5H ;CHECK SUM
DB 0H,0H
DB 0C0H, 0A8H, 01H, 02H ;MYIP
DB 0CAH, 65H, 62H, 37H ;DNS SERVER
;UDP DATA
DB 0AH, 59H ;MY PORT
DB 0H, 35H ;REMOTE PORT
DB 0H, 28H
;DB 7CH, 0A6H ;CHECKSUM
DB 0H,0H
DB 068H, 0F3H, 01H, 00H, 0H, 1H
DB 0H,0H,0H,0H,0H,0H
DB 03H, 77H, 77H, 77H, 06H, 63H, 6EH, 37H, 30H, 30H, 30H
DB 03H, 63H, 6FH, 6DH;DOMAIN
DB 0H, 0H, 1H, 0H,01H,0H,0H,0H,0H
ORG 700H ;UDP LOGIN 数据
DB 00H,14H, 78H, 0BFH, 0A9H, 0B0H ;网关MAC
DB 0H, 0H, 21H, 0CDH, 0E7H, 29H ;我的MAC
DB 08H, 0H ; 协议类型 ;IP
DB 45H, 0H
DB 0H, 29H;IPHEAD长度
DB 55H,95H,0H,0H
DB 80H,11H
;DB 0H,0H
DB 0BFH,0A4H;CHECKSUM
;DB 0H,0H
DB 0C0H, 0A8H, 01H, 02H; 我的IP
DB 192, 168, 1,198
;DB 0H,0H,0H,0H
DB 1FH, 0A2H ;服务器端口
DB 1FH, 9AH ;我的端口
DB 0H,15H ;UDP_LENGTH
DB 0H,0H ;UDP_CHECKSUM
;DB 95H,75H
; DB 0CCH, 41H, 42H, 32H, 32H, 38H, 30H, 30H, 32H, 31H, 32H, 33H, 34H
DB 0D5H, 43H, 56H, 31H, 39H, 31H, 30H, 30H, 30H, 38H, 38H, 38H, 38H
DB 0H, 0H,0H,0H
ORG 750H ;UDP数据
DB 00H,14H, 78H, 0BFH, 0A9H, 0B0H ;网关MAC
DB 0H, 0H, 21H, 0CDH, 0E7H, 29H ;我的MAC
DB 08H, 0H ; 协议类型 ;IP
DB 45H, 0H
DB 0H, 59H;IPHEAD长度
DB 55H,95H,0H,0H
;DB 80H,11H
DB 0H,0H
;DB 0BFH,074H;CHECKSUM
DB 0H,0H
DB 0C0H, 0A8H, 01H, 02H; 我的IP
DB 192, 168, 1,198
;DB 0H,0H,0H,0H
DB 1FH, 0A2H ;服务器端口
DB 1FH, 9AH ;我的端口
DB 0H,45h ;UDP_LENGTH
;DB 0C6H, 0F8H ;CHECKSUM
DB 0H,0H
DB 0DDH,058H,050H,032H,032H,038H,030H,030H,032H,008H,002H,020H,030H
DB 0E2H,003H,034H,033H,008H,0E2H,003H,022H,021H,042H,0E2H,003H,034H
DB 033H,069H,0E2H,003H,034H,033H,06AH,0EAH,010H,0B4H,0EFH,0ACH,07CH
DB 05DH,066H,021H,0D9H,08CH,01AH,04FH,008H,0D7H,088H,03EH,074H,0F6H
DB 008H,0DDH,0CAH,0FFH,059H,033H,051H,0DFH,04EH,000H,000H,000H,000H
ORG 660H ;PING 数据
DB 00H,15H, 58H, 07H, 07H, 8EH ;网关MAC
DB 0H, 0H, 21H, 0CDH, 0E7H, 29H ;我的MAC
DB 08H, 0H ; 协议类型 ;IP
DB 45H, 0H
DB 0H, 3CH;IPHEAD长度
DB 1H,04DH,0H,0H,40H,01H
DB 0F5H,05BH;CHECKSUM
;DB 0H,0H
DB 0C0H, 0A8H, 01H, 02H; 我的IP
DB 0C0H, 0A8H, 01H, 0C6H; 目的IP
DB 0H,0H,95H,58H ;CHECKSUM
DB 0H, 2H, 0C0H, 1H
DB 61H, 62H, 63H, 64H, 65H, 66H, 67H, 68H, 69H, 6AH, 6BH, 6CH, 6DH, 6EH, 6FH
DB 70H, 71H, 72H, 73H, 74H, 75H, 76H, 77H, 61H, 62H, 63H, 64H, 65H, 66H, 67H, 68H, 69H
ORG 900H
WRITWRAM: ;R6,R7 长度,R1是RAM地址 (R2,R3是8019 RAM地址) 移动RAM数据到发送缓冲
MOV R0,#0
LCALL EPAGE
MOV A,#0H
MOV R0,#22H
LCALL ISAW ;中止DMA 可以不要
MOV A,#9 ;DMA写入高位地址
MOV R0,#40H ;修改发送缓冲
LCALL ISAW
MOV A,#8 ;DMA写入低位地址
MOV R0,#0H
LCALL ISAW
MOV A,R7 ;长度高位
MOV R0,A
MOV A,#0BH
LCALL ISAW
MOV A,R7 ;是否少于64个字节
JNZ NNZ
MOV A,R6
CLR C
SUBB A,#64
JNC NNZ
MOV A,R6 ;补上0到64个字节
ADD A,#40H
MOV R0,A
CLL:
MOV A,#0
MOV @R0,A
INC R0
CJNE R0,#80H,CLL
MOV R6,#64
NNZ:
MOV A,R6 ;长度低位
MOV R0,A
MOV A,#0AH
LCALL ISAW
MOV A,#0 ;写DMA
MOV R0,#12H
LCALL ISAW
W1:
MOV A,@R1
INC R1
MOV R0,A
MOV A,#10H
LCALL ISAW
DJNZ R6,W1
RET
REARP: ;应答ARP
MOV R7,#6 ;填入目标MAC
MOV R0,#46H
MOV R1,#90H
RL0:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,RL0
MOV R7,#6 ;填入我的MAC
MOV R0,#16H
MOV R1,#96H
RL1:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,RL1
MOV A,#08H
MOV @R1,A
INC R1
MOV A,#06H
MOV @R1,A
INC R1
MOV A,#0H
MOV @R1,A
INC R1
MOV A,#01H
MOV @R1,A
INC R1
MOV A,#08H
MOV @R1,A
INC R1
MOV A,#0H
MOV @R1,A
INC R1
MOV A,#06H
MOV @R1,A
INC R1
MOV A,#04H
MOV @R1,A
INC R1
MOV A,#0H
MOV @R1,A
INC R1
MOV A,#02H
MOV @R1,A
INC R1
MOV R7,#6 ;填入我的MAc
MOV R0,#16H
RL20:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,RL20
MOV R7,#6 ;填入我的IP
MOV R0,#28H
RL22:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,RL22
MOV R7,#10 ;填入目标MAC和IP
MOV R0,#56H
RL3:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,RL3
MOV R7,#18
MOV A,#0
MOV R0,#6AH
FULL:
MOV A,@R0
MOV @R1,A
INC R1
INC R0
DJNZ R7,FULL
MOV R6,#68
MOV R7,#0
MOV R1,#90H
LCALL WRITWRAM
MOV R6,#68
MOV R7,#0
LCALL MYSPACK
RET
PINGREP: ;PING 应答
MOV A,22H ;长度
SUBB A,#4
MOV R7,A ;复制ping数据包
MOV R0,#40H
MOV R1,#90H
CPING:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,CPING
MOV R7,#6h ;复制目的MAC
MOV R0,#46H
MOV R1,#90H
CMAC:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,CMAC
MOV R7,#6h ;复制我的MAC
MOV R0,#40H
MOV R1,#96H
CMYMAC:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,CMYMAC
MOV A,56H ;TTL=TTL-1
SUBB A,#1
MOV R0,#0A6H
MOV @R0,A
MOV R7,#4h ;复制IP
MOV R0,#5AH
MOV R1,#0AEH
CIP:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,CIP
MOV R7,#4h ;复制IP
MOV R0,#5EH
MOV R1,#0AAH
CMYIP:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,CMYIP
MOV A,#0
MOV R0,#0B2H
MOV @R0,A ;PING REQUEST
MOV A,#0
MOV R0,#0A8H
MOV @R0,A
MOV R0,#0A9H
MOV @R0,A ;CHECKSUM=0
MOV R0,#9EH ;计算IP头CHECKSUM(9E+20)
MOV R2,#20
MOV R3,#0
LCALL CHECKSUM
MOV A,R5
MOV R0,#0A8H
MOV @R0,A
MOV A,R6
MOV R0,#0A9H
MOV @R0,A ;写入到CHECKSUM
MOV A,#0 ;CHECKSUM=0
MOV R0,#0B4H
MOV @R0,A
MOV R0,#0B5H
MOV @R0,A
MOV R0,#0B2H ;计算ICMP数据CHECKSUM(B2+40)
MOV R2,#40
MOV R3,#0
LCALL CHECKSUM
MOV A,R5
MOV R0,#0B4H
MOV @R0,A
MOV A,R6
MOV R0,#0B5H
MOV @R0,A ;写入到CHECKSUM
MOV A,22H ;长度低位
SUBB A,#4
MOV R6,A
MOV R7,#0
MOV R1,#90H
LCALL WRITWRAM
MOV A,22H
SUBB A,#4
MOV R6,A
MOV R7,#0
LCALL MYSPACK
RET
BNRYCURR: ;读取BNRY,CURR到8H,9H, R6,R7
MOV R0,#0H ;选第一页
LCALL EPAGE
MOV A,#3 ;读当前页指针
LCALL ISAR
;MOV 8H,A
MOV R6,A
MOV R0,#40H
LCALL EPAGE
MOV A,#7H
LCALL ISAR
;MOV 9H,A
MOV R7,A
RET
DNS:
MOV DPL,#0
MOV DPH,#6H
MOV R1,#40H
MOV R7,#36H
LOADDNS:
MOV A,#0
MOVC A,@A+DPTR
MOV @R1,A
INC DPL
INC R1
DJNZ R7,LOADDNS
MOV R0,#10H ;0A
MOV R1,#40H
MOV R7,#12
MACLOAD:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,MACLOAD
MOV R0,#28H
MOV R1,#5AH
MOV R7,#8
IPLOAD:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,IPLOAD
MOV R1,#76H ;DOMAIN开始地址 XXX.DOMAIN.COM.CN
MOV R0,#0C0H
MOV A,@R0
MOV R7,A
ADD A,#25
MOV R0,#67H ;长度指针
MOV @R0,A
MOV R0,#0C1H
DOMAINLOAD:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,DOMAINLOAD
MOV A,#0 ; 0H,0H,1H,0H,1H
MOV @R1,A
INC R1
MOV @R1,A
MOV A,#1
INC R1
MOV @R1,A
INC R1
MOV A,#0
MOV @R1,A
INC R1
MOV A,#1
MOV @R1,A
MOV A,#0
INC R1
MOV @R1,A
INC R1
MOV @R1,A
INC R1
MOV @R1,A
INC R1
MOV @R1,A ;0000
MOV R0,#067H
MOV A,@R0
ADD A,#20
MOV R0,#51H
MOV @R0,A ;总长度
MOV R0,#4EH ;计算IP头CHECKSUM(9E+20)
MOV R2,#20
MOV R3,#0
LCALL CHECKSUM
MOV A,R5
MOV R0,#058H
MOV @R0,A
MOV A,R6
MOV R0,#059H
MOV @R0,A ;写入到CHECKSUM
MOV R0,#67H
MOV A,@R0
ADD A,#38
MOV R6,A
MOV R7,#0
MOV R1,#40H
LCALL WRITWRAM
MOV R0,#67H
MOV A,@R0
ADD A,#38
MOV R6,A
MOV R7,#0
LCALL MYSPACK
RET
MYDOMAIN: ;从5E0H读取域名(必须长度开头带域名,0结束)
MOV R0,#0C0H ;读取域名
MOV DPL,#0E0H
MOV DPH,#5H
LOADWWW:
MOV A,#0H
MOVC A,@A+DPTR
MOV @R0,A
INC R0
INC DPL
MOV R1,A
MOV A,R1
JNZ LOADWWW ;遇到0为结束
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;发送用户报文
MYUDP: ;DPTR数据,R6,R7长度
; MOV DPL,#50H ;UDP数据 750
; MOV DPH,#7H
MOV R1,#40H
; MOV R6,#107 ;107
INC R7
LOADUDP:
MOV A,#0
MOVC A,@A+DPTR
MOV @R1,A
INC DPL
INC R1
DJNZ R6,LOADUDP
DJNZ R7,LOADUDP
MOV R0,#10H ;MAC 填充
MOV R1,#40H
MOV R7,#12
UDPMACLOAD:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,UDPMACLOAD
MOV R0,#28H ;我的IP
MOV R1,#5AH
MOV R7,#4
MYIPLOAD:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,MYIPLOAD
MOV R0,#3AH ;服务器IP
MOV R1,#5EH
MOV R7,#4
SERIPLOAD:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R7,SERIPLOAD
MOV A,#0
MOV R0,#058H
MOV @R0,A
MOV R0,#059H
MOV @R0,A ;写0000到CHECKSUM
MOV R0,#4EH ;计算IP头CHECKSUM(4E+20)
MOV R2,#20
MOV R3,#0
LCALL CHECKSUM
;MYUDP:
MOV R0,#058H
MOV A,R5
MOV @R0,A ;写入CHECKSUM
INC R0
MOV A,R6
MOV @R0,A ;写入CHECKSUM
MOV A,#80H ;写入TTLL
MOV R0,#56H
MOV @R0,A
MOV A,#11H
INC R0
MOV @R0,A
MOV A,#1FH ;填写端口 8090
MOV R0,#62H
MOV @R0,A
MOV A,#0A2H
INC R0
MOV @R0,A
MOV A,#01FH
INC R0
MOV @R0,A
MOV A,#9AH
INC R0
MOV @R0,A ;填写端口 8089
MOV R0,#51H
MOV A,@R0
ADD A,#14 ;加上ip头20
MOV R6,A
MOV R7,#0 ;高位不送
MOV R1,#40H
LCALL WRITWRAM
RET
LOGINOK:
MOV A,57H ;是否返回OK写入到8H,9H
CJNE A,#11H,NOLOGIN
MOV A,6BH
CJNE A,#4FH,NOLOGIN
MOV 26H,A
MOV A,6CH
CJNE A,#4BH,NOLOGIN
MOV 27H,A
MOV A,#0FFH
RET
NOLOGIN:
MOV A,#0
RET
ARPANS:
MOV A,55H ;ARP ANS
CJNE A,#1,PING
MOV R0,#28H ;比较IP是否一样
MOV R1,#66H
COMPIP:
MOV A,@R0
MOV R2,A
MOV A,@R1
CLR C
SUBB A,R2
JNZ NOANS ;IP不一样退出…
INC R0
INC R1
CJNE R0,#2CH,COMPIP
LCALL REARP ;应答ARP
MOV A,#0FFH
RET
NOANS:
MOV A,#0
RET
PING:
MOV A,62H ;PING ANS
CJNE A,#8,ENDEM
MOV R0,#28H ;比较IP是否一样
MOV R1,#5EH
COMPIP1:
MOV A,@R0
MOV R2,A
MOV A,@R1
CLR C
SUBB A,R2
JNZ ENDEM ;IP不一样退出…
INC R0
INC R1
CJNE R0,#2CH,COMPIP1
LCALL PINGREP
MOV A,#0FFH
RET
ENDEM:
MOV A,#0
RET
MY8019: ;R6,R7 长度 (R2,R3是8019 RAM地址) 移动RAM数据到发送缓冲
MOV R0,#0
LCALL EPAGE
MOV A,#0H
MOV R0,#22H
LCALL ISAW ;中止DMA 可以不要
MOV A,#9 ;DMA写入高位地址
MOV R0,#40H ;修改发送缓冲
LCALL ISAW
MOV A,R2
MOV R0,A
MOV A,#8 ;DMA写入低位地址
LCALL ISAW
MOV A,R7 ;长度高位
MOV R0,A
MOV A,#0BH
LCALL ISAW
MOV A,R6 ;长度低位
MOV R0,A
MOV A,#0AH
LCALL ISAW
MOV A,#0 ;写DMA
MOV R0,#12H
LCALL ISAW
RET
SENDMYDUP:
MOV R2,#11H ;准备发送数据初始化开始地址
MOV R3,#0H
MOV R6,#1H ;长度
MOV R7,#0
LCALL MY8019
MOV A,1CH
ADD A,#41 ;总长度
MOV 51H,A
MOV R0,A ;写入长度
MOV A,#10H
LCALL ISAW
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV A,#0
MOV 58H,A
MOV 59H,A
MOV R0,#4EH ;计算IP头CHECKSUM(4E+20)
MOV R2,#20
MOV R3,#0
LCALL CHECKSUM
MOV A,R5
MOV 58H,A
MOV A,R6
MOV 59H,A
MOV R2,#18H ;写入8019数据RAM地址
MOV R3,#0H
MOV R6,#2H ;长度
MOV R7,#0
LCALL MY8019
MOV A,58H
MOV R0,A ;写入CHECKSUM
MOV A,#10H
LCALL ISAW
MOV A,59H
MOV R0,A ;写入CHECKSUM
MOV A,#10H
LCALL ISAW ;写入到CHECKSUM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV R2,#27H ;写入8019数据RAM地址
MOV R3,#0H
MOV R6,#1H ;长度
MOV R7,#0
LCALL MY8019
MOV A,1CH
ADD A,#16 ;UDP长度+21
MOV R0,A ;写入长度
MOV A,#10H
LCALL ISAW
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV R2,#33H ;写入8019数据RAM地址
MOV R3,#0H
MOV R6,#1H ;长度
MOV R7,#0
LCALL MY8019
MOV A,1CH
ADD A,#55 ;55修改
MOV R6,A ;长度
MOV R7,#0
LCALL MYSPACK ;发送。。。。。。。。。。。。
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;————————————————————————
MYPIC:
MOV R0,#1DH
MOV R1,#0
MOV R5,#0
MOV R6,#0
MOV R7,#0
MOV A,#0H
MR7:
MOV R4,A
;起始位为AA,结束位为BB
REC:
JBC RI,REC1
SJMP REC
REC1:
MOV A,SBUF
LCALL T00
CJNE R4,#0AAH,MR7 ;如果没有收到AA一直等到AA出现
CJNE R5,#0,SAVETO8019
MOV R6,A
MOV R5,A
INC R5
INC R6
SUBB A,#7
MOV 1CH,A ;数据长度 记住判断是否长度等于0
MOV R2,#02CH ;准备发送数据初始化开始地址
MOV R3,#0H
LCALL MY8019
SJMP S8019
;———————————————————–
SAVETO8019: ;开始保存数据到8019
CJNE R5,#1,TO8019 ;放弃最后一个字节校验
SJMP S8019
TO8019: ;写入8019
;数据第一个字节描述系统 00代表亿华 05代表法国电信保存在R1中
MOV R0,A ;写入数据到8019
MOV A,#10H
LCALL ISAW
S8019:
DJNZ R5,REC
; SUBB A,#0BBH ;最后一个字节如果不是BB就不发送
; JNZ IMID
;启动发送
MOV A,#0AH
MOV R0,#0
LCALL ISAW ;中止DMA 可以不要
MOV A,#0BH
MOV R0,#0
LCALL ISAW ;中止DMA 可以不要
MOV A,#0H
MOV R0,#22H
LCALL ISAW ;中止DMA 可以不要
MOV A,#0FEH ;表示发送成功
RET
NODAT:
MOV A,#0AH
MOV R0,#0
LCALL ISAW ;中止DMA 可以不要
MOV A,#0BH
MOV R0,#0
LCALL ISAW ;中止DMA 可以不要
MOV A,#0H
MOV R0,#22H
LCALL ISAW ;中止DMA 可以不要
NOREC:
MOV A,#0 ;返回0表示收到ID不用发送
RET
CW:
SETB P3.0
SETB P3.1
WAITCW:
JNB P3.0,ENDCW
;JNB P3.6,WAITCW
LCALL NETPACK ;读取一个有效IP数据包
JZ WAITCW
MOV A,6AH
CJNE A,#88H,WAITCW
MOV 6AH,#0
MOV A,#0BBH
LCALL T00
MOV SBUF,A
JNB TI,$
CLR TI
MOV A,#11H
LCALL T00
MOV SBUF,A
JNB TI,$
CLR TI
MOV R4,#0
MOV R0,#6BH ;开始CW
;————————
SENDCW:
MOV A,@R0
XRL A,#55H
LCALL T00
MOV C,P
MOV TB8,C
MOV SBUF,A
add A,R4
MOV R4,A
INC R0
JNB TI,$
CLR TI
CJNE R0,#7BH,SENDCW
;————————-
MOV A,R4
LCALL T00
MOV SBUF,A
JNB TI,$
CLR TI
ENDCW:
RET
;———————————————————————–
T00:
MOV R3,#8
MOV R2,A
NOTDAT:
MOV A,R2
RRC A
MOV R2,A
MOV A,R1
RLC A
MOV R1,A
DJNZ R3,NOTDAT
CPL A
RET
ORG 0FF8H
DB 24H,52H,0D2H,68H,0BFH,01FH,0ABH,0F8H
END
作者:youbang