📄 cs8900a.asm
字号:
MOV R0,#PacketRAM+u_src
ADD A,R0
MOV R0,A
MOV @R0,0DH
INC R0
MOV @R0,0AH
INC R0
MOV @R0,48H
INC R0
MOV @R0,65H
INC R0
MOV @R0,6CH
INC R0
MOV @R0,6CH
INC R0
MOV @R0,6FH
INC R0
MOV @R0,20H
INC R0
MOV @R0,57H
INC R0
MOV @R0,6FH
INC R0
MOV @R0,72H
INC R0
MOV @R0,6CH
INC R0
MOV @R0,64H
INC R0
MOV @R0,21H
MOV R1,#PacketRAM+u_len
MOV A,@R1
MOV R0,#PacketRAM+u_cksum
MOV @R0,A
INC R0
INC R1
MOV A,@R1
MOV @R0,A
; 修改帧长度
MOV R0,#PacketRAM+u_pktLenL
MOV A,@R0
ADD A,#14
MOV @R0,A
MOV R0,#PacketRAM+ip_len+1
MOV A,@R0
ADD A,#14
MOV @R0,A
MOV R0,#PacketRAM+u_len+1
MOV A,@R0
ADD A,#14
MOV @R0,A
MOV R0,#PacketRAM+u_cksum
MOV @R0,#0
INC R0
MOV @R0,#0
; 然后计算IP头的校验和
LCALL IpResp
; 发送帧
LCALL TxPacket
RET
;************************************
; 发送帧
;************************************
TxPacket:
MOV CAB,#portTxCmd
MOV CDB,#TxCmd
CLR AEN
CLR IOW
MOV CAB,#portTxCmd+1
MOV CDB,#0
CLR AEN
CLR IOW
MOV CAB,#portTxLength
MOV R0,#PacketRAM+pktLenL
MOV CDB,@R0
CLR AEN
CLR IOW
MOV CAB,#portTxLength+1
MOV R0,#PacketRAM+pktLenH
MOV CDB,@R0
CLR AEN
CLR IOW
TxPktl:
LCALL RegRead
DW ppBusST
MOV A,TempH
ANL A,#00000001B
CJNE A,#1,TxPktl
MOV R0,#PacketRAM+pktDestH
MOV R1,#PacketRAM+pktLenL
MOV A,@R1
MOV R1,A
TxL:
MOV A,@R0
MOV CDB,A
MOV CAB,#portRxTxData+1
CLR AEN
CLR IOW
INC R0
DJNZ R1,TxL
QuitTxP:
RET
;************************************
; 延时模块
;************************************
VWAIT:
MOV R0,#5
VWL1:
MOV R1,#200
VWL2:
MOV R2,#200
VWL3:
NOP
NOP
DJNZ R2,VML3
DJNZ R1,VML2
DJNZ R0,VML1
RET
;************************************
; 芯片复位
;************************************
Resetchip:
ACALL Regwrite ; 将复位命令写入SelfCTL寄存器
DW ppSelfCTL
DW Slfctlrst
Resetwait: ; 等待复位完成
ACALL Regread
DW ppSelfCTL
MOV a, TempL
ANL a, #40H
JNZ Resetwait
RET ; 程序返回
;************************************
; 芯片初始化
;************************************
Initchip:
; 寄存器初始化
ACALL Regwrite ; 写LineCTL寄存器初值
DW ppLineCTL
DW LineCTL
ACALL Regwrite ; 写TestCTL寄存器初值
DW ppTestCTL
DW TestCTL
ACALL Regwrite ; 写RxCFG寄存器初值
DW ppRxCFG
DW RxCFG
ACALL Regwrite ; 写RxCTL寄存器初值
DW ppRxCTL
DW RxCTL
ACALL Regwrite ; 写TxCFG寄存器初值
DW ppTxCFG
DW TxCFG
; 写MAC地址
ACALL Regwrite
DW ppindaddr
DW MAC00
ACALL Regwrite
DW ppindadds
DW MAC01
ACALL Regwrite
DW ppindaddt
DW MAC02
ACALL Regwrite
DW ppintnum
DW 0000H
ACALL Regread
DW ppBusCTL
ORL TempH, #80H
; 设置IRQ
MOV CAB, #PortData
MOV CDB, TempL
CLR AEN
CLR IOW
MOV CAB, #PortData+1
MOV CDB, TempH
CLR AEN
CLR IOW
ACALL Regread
DW ppLineCTL
ORL TempL, #0C0H
MOV CAB, #PortData
MOV CDB, TempL
CLR AEN
CLR IOW
MOV CAB, #PortData+1
MOV CDB, TempH
CLR AEN
CLR IOW
RET
;************************************
; 写寄存器
;************************************
Regwrite:
POP dph
POP dpl
; 写地址
MOV a, #01H
MOVC a, @a+dptr
MOV CDB, a
MOV CAB, #PortPtr ; 写入地址的高8位
CLR AEN
CLR IOW
MOV a, #00H
MOVC a, @a+dptr
MOV CDB, a
MOV CAB, #PortPtr+1 ;写入地址的低8位
CLR AEN
CLR IOW
; 写参数
MOV a, #03H
MOVC a, @a+dptr
MOV CDB, a
MOV CAB, #PortData ; 写入数据的高8位
CLR AEN
CLR IOW
MOV a, #02H
MOVC a, @a+dptr
MOV CDB, a
MOV CAB, #PortData+1 ;写入数据的低8位
CLR AEN
CLR IOW
; 程序返回
MOV a, #04H
JMP @a+dptr
;************************************
; 读寄存器
;************************************
Regread:
POP dph
POP dpl
; 写地址
MOV a, #01H
MOVC a, @a+dptr
MOV CDB, a
MOV CAB, #PortPtr ; 写入地址的高8位
CLR AEN
CLR IOW
MOV a, #00H
MOVC a, @a+dptr
MOV CDB, a
MOV CAB, #PortPtr+1 ; 写入地址的低8位
CLR AEN
CLR IOW
; 读出数据
MOV CAB, #PortData
MOV 90H, #0FFH
CLR AEN
CLR IOR
NOP ; 延时以保证读写时序正确
MOV TempL, CDB ; 读数据低8位
SETB AEN
MOV CAB, #PortData+1
MOV 90H, #0FFH
CLR AEN
CLR IOR
NOP ; 延时以保证读写时序正确
MOV TempH, CDB ; 读数据高8位
SETB AEN
; 程序返回
MOV a, #02H
JMP @a+dptr
;************************************
; 接收数据模块
; 仅接收帧长度、源MAC、目的MAC、以太网帧头
;************************************
Receiver:
; 首先读取的是RxStatus和RxLength
MOV CAB,#PortPtr
MOV CDB,#00H
CLR AEN
; 不进行处理,直接忽略
CLR IOW
MOV CAB,#PortPtr+1
MOV CDB,#04H
CLR AEN
CLR IOW
MOV CAB,#PortRxTxData+1
MOV 90H,#0FFH
CLR AEN
CLR IOR
NOP
MOV TempH,CDB
MOV CAB,#PortRxTxData
MOV 90H,#0FFH
CLR AEN
CLR IOR
NOP
MOV TempL,CDB
; 读出数据存入PocketRAM中
MOV CAB,#PortPtr
MOV CDB,#02H
CLR AEN
CLR IOW
MOV CAB,#PortPtr+1
MOV CDB,#04H
CLR AEN
CLR IOW
MOV CAB,#PortRxTxData+1
MOV 90H,#0FFH
CLR AEN
CLR IOR
NOP
MOV TempH,CDB
MOV CAB,#PortRxTxData
MOV 90H,#0FFH
CLR AEN
CLR IOR
NOP
MOV TempL,CDB
; 长度为0则跳过当前帧
MOV A,TempH
ORL A,TempL
JZ Ignore_Frame
; 将帧长度存入PacketRAM前两个字节
MOV R0,#PacketRAM+pktLenH
MOV A,TempH
MOV @R0,A
MOV R0,#PacketRAM+pktLenL
MOV A,TempL
MOV @R0,A
; 开始接收源、目的MAC地址和pktType
MOV R0,#PacketRAM+pktDest0H
MOV R1,#14
LCALL LoadPacket
RET
;************************************
; 从CS8900A中读取数据
; R0存放读出数据的存放地址,R1存放读取数目
;************************************
; 读取数据
LoadPacket:
MOV a,r0 ; 这两步程序仅起到延时作用,并无实际意义
MOV r0,a
MOV CAB, #PortRxTxData ; 读取第一个字节
MOV 90H, #0FFH ; 读取数据之前将P3口置位
CLR AEN
CLR IOR
NOP
MOV @r0, CDB
INC r0
DEC r1
JZ LdPktDone
MOV CAB, #PortRxTxData+1 ; 读取第二个字节
MOV 90H, #0FFH
CLR AEN
CLR IOR
NOP
MOV @r0, CDB
INC r0
DEC r1
CJNE r1, #0, LoadPacket
LdPktDone: ; 读取完成
RET ; 程序返回
;************************************
; 忽略当前帧
;************************************
Ignore_Frame:
LCALL RegWrite
DW ppRxCfg
DW SKIP
JMP LOOP
;************************************
; 检查帧长度是否超过缓冲区容量
;************************************
ChkPktLen:
CLR C
MOV R0,#PacketRAM+pktLenH
MOV A,@R0
JZ HlenOK
SETB C
RET
HlenOK:
INC R0
MOV A,@R0
SUBB A,#MaxPackLen
CPL C
RET
;************************************
; 交换IP头地址并计算校验和
;************************************
IpResp:
MOV R0,#PacketRAM+ip_cksum
MOV @R0,#0
INC R0
MOV @R0,#0
MOV R0,#PacketRAM+ip_src
MOV R1,#PacketRAM+ip_dest
MOV A,@R0
MOV @R1,A
INC R0
INC R1
MOV A,@R0
MOV @R1,A
INC R0
INC R1
MOV A,@R0
MOV @R1,A
INC R0
INC R1
MOV A,@R0
MOV @R1,A
MOV R0,#PacketRAM+ip_src
MOV @R0,#IP1
INC R0
MOV @R0,#IP2
INC R0
MOV @R0,#IP3
INC R0
MOV @R0,#IP4
; 计算头校验和
MOV R1,#20
MOV R0,#PacketRAM+ip_verlen
LCALL Cksum
MOV R0,#PacketRAM+ip_cksum
MOV @R0,TempH
INC R0
MOV @R0,TempL
RET
;************************************
; 计算校验和
;************************************
CkSum:
MOV cnt_low, #0 ; 临时变量
MOV cnt_mid, #0
MOV cnt_hi, #0
CkSumL: ; 处理低8位字节
INC r0
MOV a, r1 ; 检查当前字节是否为最后一个字节
DEC a
JZ SkpLChk ; 是,跳过低8位字节处理
MOV a, cnt_low ; 低8位字节处理
ADD a, @r0
MOV cnt_low,a
PUSH psw
DEC r1
SkpLChk: ; 高8位字节处理
DEC r0
MOV a, cnt_mid
POP psw
ADDC a, @r0
MOV cnt_mid, a
PUSH psw
INC r0
INC r0
CLR a
POP psw
ADDC a, cnt_hi
MOV cnt_hi, a
DJNZ r1, CkSumL ; 如果还有数据则跳回低8位字节处理程序
QuitChk: ; 完成校验,保存计算结果
MOV a, cnt_hi
ADD a, cnt_low
MOV cnt_low, a
PUSH psw
CLR a
POP psw
ADDC a, cnt_mid
MOV cnt_mid, a
MOV a, cnt_low
CPL a
MOV TempL, a
MOV a, cnt_mid
CPL a
MOV Temp_H, a
RET ; 程序返回
;************************************
; 计算UDP校验和
;************************************
CkSumUDP:
MOV r0, #PacketRam+u_len+1
MOV a, #8
ADD a, @r0
MOV r1, a ; R1中保存要计算数据的长度
MOV r0, #PacketRam+ip_src ; R0中保存要计算数据的首地址
MOV cnt_low, #0 ; 临时变量
MOV cnt_mid, #0
MOV cnt_hi, #0
CkSumLUDP: ; 处理低8位字节
INC r0
MOV a, r1 ; 检查当前字节是否为最后一个字节
DEC a
JZ SkpLChkUDP ; 是,跳过低8位字节处理
MOV a, cnt_low ; 低8位字节处理
ADD a, @r0
MOV cnt_low,a
DEC r1
SkpLChkUDP: ; 高8位字节处理
DEC r0
MOV a, cnt_mid
ADDC a, @r0
MOV cnt_mid, a
INC r0
INC r0
CLR a
ADDC a, cnt_hi
MOV cnt_hi, a
DJNZ r1, CkSumLUDP ; 如果还有数据则跳回低8位字节处理程序
MOV a, cnt_low
ADD a, #17H
MOV cnt_low, a
MOV a, #00H
ADDC a, cnt_mid
MOV cnt_mid, a
MOV a, #00H
ADDC a, cnt_hi
MOV cnt_hi, a
MOV r0, #PacketRam+u_len+1
MOV a, cnt_low
ADD a, @r0
MOV cnt_low, a
CLR a
ADDC a, cnt_mid
MOV cnt_mid, a
CLR a
ADDC a, cnt_hi
MOV cnt_hi, a
ADD a, cnt_low
MOV cnt_low, a
MOV a, #00H
ADDC a, cnt_mid
MOV cnt_mid, a
MOV a, cnt_low ; 完成校验,保存计算结果
CPL a
MOV TempL, a
MOV a, cnt_mid
CPL a
MOV TempH, a
RET ; 程序返回
;************************************
; 调试模块
;************************************
Debug:
LCALL Regwrite
DW ppSelfCTL
DW Slfctlrst
SJMP Debug
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -