⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drivers.asm

📁 SPCE061A为核心的转换控制(Drivers汇编代码):以太网 RS232
💻 ASM
📖 第 1 页 / 共 3 页
字号:
// Page 0 -> 1, PSTART(at page 0)=0x46/CR=0x61
	R1 = RTL8019AS_CR_STOP|RTL8019AS_CR_ABORT|RTL8019AS_CR_P1
	RTL8019AS_WR_WORD RTL8019AS_ADDR_00, R1, BP
	
// 15. Write Port (IOBase + 0x01 - 0x06) with Ethernet Address Byte 0 - Byte5
// Page 1, PAR0=0x52
	R1 = [_guwEthAddr+0]	// PAR0/PAR1
	R1 = R1 lsr 4
	R1 = R1 lsr 4
	RTL8019AS_WR_WORD RTL8019AS_ADDR_01, R1, BP
	
// Page 1, PAR1=0x54
	R1 = [_guwEthAddr+0]	// PAR0/PAR1
	RTL8019AS_WR_WORD RTL8019AS_ADDR_02, R1, BP

// Page 1, PAR2=0xab
	R1 = [_guwEthAddr+1]	// PAR2/PAR3
	R1 = R1 lsr 4
	R1 = R1 lsr 4
	RTL8019AS_WR_WORD RTL8019AS_ADDR_03, R1, BP
	
// Page 1, PAR3=0x1d
	R1 = [_guwEthAddr+1]	// PAR2/PAR3
	RTL8019AS_WR_WORD RTL8019AS_ADDR_04, R1, BP

// Page 1, PAR4=0xa4
	R1 = [_guwEthAddr+2]	// PAR4/PAR5
	R1 = R1 lsr 4
	R1 = R1 lsr 4
	RTL8019AS_WR_WORD RTL8019AS_ADDR_05, R1, BP
	
// Page 1, PAR5=0xf9
	R1 = [_guwEthAddr+2]	// PAR4/PAR5
	RTL8019AS_WR_WORD RTL8019AS_ADDR_06, R1, BP


// 16. Write Port (IOBase + 0x7) with 0x47, Set Current Page Register
// 17. Write Port (IOBase + 0x08 - 0x0F) with Multicast Address Byte 0 - Byte 7
// Page 1, CPR =0x47
	R1 = RTL8019AS_CPR
	RTL8019AS_WR_WORD RTL8019AS_ADDR_07, R1, BP

// Page 1, MAR1=0x41/MAR0=0x00
	R1 = RTL8019AS_MAR0
	RTL8019AS_WR_WORD RTL8019AS_ADDR_08, R1, BP
	R1 = RTL8019AS_MAR1
	RTL8019AS_WR_WORD RTL8019AS_ADDR_09, R1, BP

// Page 1, MAR3=0x80/MAR2=0x00
	R1 = RTL8019AS_MAR2
	RTL8019AS_WR_WORD RTL8019AS_ADDR_0A, R1, BP
	R1 = RTL8019AS_MAR3
	RTL8019AS_WR_WORD RTL8019AS_ADDR_0B, R1, BP

// Page 1, MAR5=0x00/MAR4=0x00
	R1 = RTL8019AS_MAR4
	RTL8019AS_WR_WORD RTL8019AS_ADDR_0C, R1, BP
	R1 = RTL8019AS_MAR5
	RTL8019AS_WR_WORD RTL8019AS_ADDR_0D, R1, BP

// Page 1, MAR7=0x00/MAR6=0x00
	R1 = RTL8019AS_MAR6
	RTL8019AS_WR_WORD RTL8019AS_ADDR_0E, R1, BP
	R1 = RTL8019AS_MAR7
	RTL8019AS_WR_WORD RTL8019AS_ADDR_0F, R1, BP

// 18. Write Port (IOBase + 0x00) with 0x21, Set to Page 0
// Page 1 -> 0, PAR0(at page 1)=0x52/CR=0x21
	R1 = RTL8019AS_CR_P0|RTL8019AS_CR_ABORT|RTL8019AS_CR_STOP
	RTL8019AS_WR_WORD RTL8019AS_ADDR_00, R1, BP

// 19. Write Port (IOBase + 0x0E) with 0x89, Word-wide data transfer, Normal
// Page 0, IMR=0x0f/DCR=0x89
	R1 = RTL8019AS_DCR
	RTL8019AS_WR_WORD RTL8019AS_ADDR_0E, R1, BP

// 20. Write Port (IOBase + 0x0D) with 0xf0, TCR, Normal
// Page 0, TCR=0xf0/RCR=0xcc
	R1 = RTL8019AS_TCR
	RTL8019AS_WR_WORD RTL8019AS_ADDR_0D, R1, BP
	
// 21. Write Port (IOBase + 0x00) with 0x22, Set to Page 0 and Start work
// Page 0, CR=0x22
	R1 = RTL8019AS_CR_P0|RTL8019AS_CR_ABORT|RTL8019AS_CR_START
	RTL8019AS_WR_WORD RTL8019AS_ADDR_00, R1, BP

	R1 = 1

RTL8019AS_INIT_EXIT:
// Recall default IO Statue
	SP_RECALL_IO BP

	pop BP from [SP]
	retf
.endp


//////////////////////////////////////////////////////////////////
// Function: void RTL8019AS_TX(UINT16 ByteLen, UINT16 *mbuf)
// ByteLen: 传送以太包的字节数
// mbuf: 以太包缓冲区的首指针
//////////////////////////////////////////////////////////////////
.code
.public _RTL8019AS_TX
_RTL8019AS_TX: .proc
	push R1,BP to [SP]
	BP = SP + 2 + 5 + 1			//
	R4 = [BP++]					// R4 record Packet bye length	
	BP = [BP]					// Get mbuf Point to BP

// Chang IOA to output
	SP_IOA_OUT R3

// 1. Write port (IOBase + 0x05) with low byte of packet length
// Page 0, TBCR0/TPSR
	RTL8019AS_WR_WORD RTL8019AS_ADDR_05, R4, R3

// 2. Write port (IOBase + 0x06) with high byte of packet length
// Page 0, ISR=0xff/TBCR1
	R3 = R4 lsr 4
	R3 = R3 lsr 4
	RTL8019AS_WR_WORD RTL8019AS_ADDR_06, R3, R2

// 3. Write port (IOBase + 0x08) with 0x00
// 4. Write port (IOBase + 0x09) with 0x40	
// Page 0, RSAR1=0x40/RSAR0=0x00
	R3 = 0x00
	RTL8019AS_WR_WORD RTL8019AS_ADDR_08, R3, R2
	R3 = RTL8019AS_TPSR
	RTL8019AS_WR_WORD RTL8019AS_ADDR_09,R3, R2

// 5. Write port (IOBase + 0x0A) with low byte of packet length
// 6. Write port (IOBase + 0x0B) with high byte of packet length	
// Page 0, RBCR1/RBCR0
	RTL8019AS_WR_WORD RTL8019AS_ADDR_0A, R4, R3
	R3 = R4 lsr 4
	R3 = R3 lsr 4
	RTL8019AS_WR_WORD RTL8019AS_ADDR_0B, R3, R2

// 7. Write port (IOBase + 0x00) with 0x12	
// Page 0, PSTART=0x46/CR=0x12
	R3 = RTL8019AS_CR_WRITE|RTL8019AS_CR_START|RTL8019AS_CR_P0
	RTL8019AS_WR_WORD RTL8019AS_ADDR_00, R3, R2

// 8. Write port (IOBase + 0x10) with first word of packet for (packet length/2) times
RTL8019AS_TX_1:
	R1 = [BP++]					// Get data
// Exchange high 8bit to low 8bit
	R2 = R1 lsl 4
	R1 = R1 rol 4				//
	R2 = R1 lsl 4				//
	R1 = R1 rol 4				//
// Write 1 Word to RTL8019AS
	RTL8019AS_WR_WORD RTL8019AS_ADDR_10, R1, R3
// Count	
	R4 -= 2						// Count 2 byes
	jg RTL8019AS_TX_1			// Write (bye length)/2 times

// 9. Write port (IOBase + 0x00) with 0x26
// Page 0, PSTART=0x46/CR=0x26
	BP = RTL8019AS_CR_ABORT|RTL8019AS_CR_TXP|RTL8019AS_CR_START|RTL8019AS_CR_P0
	RTL8019AS_WR_WORD RTL8019AS_ADDR_00, BP, R4

// Recall default IO Statue
	SP_RECALL_IO BP

	pop R1, BP from [SP]
	retf
.endp


//////////////////////////////////////////////////////////////////
// Function: UINT16 RTL8019AS_RX(UINT16 *mbuf)
// mbuf: 以太包缓冲区的首指针
// 返回接收以太包的字节数。如果是0,则没有包。
//////////////////////////////////////////////////////////////////
.code
.public _RTL8019AS_RX
_RTL8019AS_RX: .proc
	push R2,BP to [SP]

// 1. Read port (IOBase + 0x03) to get BNRY
	RTL8019AS_RD_WORD RTL8019AS_ADDR_03, R1, BP
	BP = R1 & 0x00ff;			// 清除高8位,保留 BNRY 到 BP

// 2. Read port (IOBase + 0x07), Get CPR

	// 2.1 Change IOA to output
	SP_IOA_OUT R4

	// 2.2 Page 0 -> 1
	R4 = RTL8019AS_CR_START|RTL8019AS_CR_ABORT|RTL8019AS_CR_P1
	RTL8019AS_WR_WORD RTL8019AS_ADDR_00, R4, R3

	// 2.3 Change IOA to input
	SP_IOA_IN R4

	// 2.4 Read port (IOBase + 0x07), Get CURR
	RTL8019AS_RD_WORD RTL8019AS_ADDR_07, R1, R4
	R4 = R1&0x00ff			// 清除高8位,保留 CURR 给 R4

	// 2.5 Change IOA to output
	SP_IOA_OUT R3

	// 2.6 Page 1 -> 0
	R3 = RTL8019AS_CR_START|RTL8019AS_CR_ABORT|RTL8019AS_CR_P0
	RTL8019AS_WR_WORD RTL8019AS_ADDR_00, R3, R2

// 3. Compare: if BNRY+1 != CURR? Some Packet is coming! goto 6.
	BP += 1					// 从这里开始,以下程序不允许改变 BP 值,保存将要读取的包的CPR
	cmp BP, R4				// BNRY+1 == CURR ?
	jnz RTL8019AS_RX_2		// 从这里开始,以下程序可以改变 R4 值。
	// 3.1 Change IOA to input
	SP_IOA_IN R4

// 4. If no packet is received, Read port (IOBase + 0x07), Get ISR
	RTL8019AS_RD_WORD RTL8019AS_ADDR_07, R1, R3
// 5 Check RTL8019AS buffer is overflow? If yes, call RTL8019AS_INIT and return 0.
	test R1, RTL8019AS_ISR_OVW
	jz RTL8019AS_RX_1			// no packet reived! Normal statue.
	PC = RTL8019AS_RX_ERROR		// no packet reived! 8019AS memory overflow!!!

RTL8019AS_RX_1:	
	R4 = 0						// Return 0 Packet length
	PC = RTL8019AS_RX_EXIT
	
RTL8019AS_RX_2:	
// Change IOA to output
	SP_IOA_OUT R3

// 6. Write port (IOBase + 0x08) with 0x00
// 7. Write port (IOBase + 0x09) with value of last current page register
// Page 0, Remote Start page Address
	R3 = 0x00
	RTL8019AS_WR_WORD RTL8019AS_ADDR_08, R3, R2
	RTL8019AS_WR_WORD RTL8019AS_ADDR_09, BP, R3

// 8. Write port (IOBase + 0x0A) with 0x04
// 9. Write port (IOBase + 0x0B) with 0x00
// Page 0, Remote Byte Count
	R3 = 0x04
	RTL8019AS_WR_WORD RTL8019AS_ADDR_0A, R3, R2
	R3 = 0x00
	RTL8019AS_WR_WORD RTL8019AS_ADDR_0B, R3, R2

// 10. Write port (IOBase + 0x00) with 0x0A
// Page 0, Remote Read Command
	R3 = RTL8019AS_CR_READ|RTL8019AS_CR_START|RTL8019AS_CR_P0
	RTL8019AS_WR_WORD RTL8019AS_ADDR_00, R3, R2

// Change IOA to input
	SP_IOA_IN R3

// 11. Read port (IOBase + 0x10) and get first word of packet
//    (Next Page Number-high_8bit and RX STATUS-low_8bit)
// Page 0, Read 'RTL8019AS Data Port'
	RTL8019AS_RD_WORD RTL8019AS_ADDR_10, R3, R4
// R3 Saved (Next Page Number and RX STATUS)


// 12. Read port (IOBase + 0x10) and get second word of packet
// (Packet Length)		
	RTL8019AS_RD_WORD RTL8019AS_ADDR_10, R4, R2
	R4 -= 4
// R4 Saved (Packet Length), Throw away 4 byte CRC

// 13. Check Receice Error. Yes, call RTL8019AS_INIT and return. 
	test R3, 0x0001		// Error Receiver
	jnz RTL8019AS_RX_3
	PC = RTL8019AS_RX_ERROR

// 14. Check Packet Length <= 1514?  If no, call RTL8019AS_INIT and return 0.
RTL8019AS_RX_3:
	cmp R4, 1514
	jna RTL8019AS_RX_4
	PC = RTL8019AS_RX_ERROR
	
RTL8019AS_RX_4:
// Chang IOA to output
	SP_IOA_OUT R2

// 15. Write port (IOBase + 0x08) with 0x04
// 16. Write port (IOBase + 0x09) with value of last current page register
// Page 0, Remote Start page Address
	R2 = 0x04
	RTL8019AS_WR_WORD RTL8019AS_ADDR_08, R2, R1
	RTL8019AS_WR_WORD RTL8019AS_ADDR_09, BP, R2		// 从这里开始,以下程序可以改变 BP 值


// 17. Write port (IOBase + 0x0A) with low byte of packet length
// 18. Write port (IOBase + 0x0B) with high byte of packet length
// Page 0, Remote Bye Count,Throw away 4 CRC bytes
	RTL8019AS_WR_WORD RTL8019AS_ADDR_0A, R4, BP
	BP = R4 lsr 4
	BP = BP lsr 4
	RTL8019AS_WR_WORD RTL8019AS_ADDR_0B, BP, R2

// 19. Write port (IOBase + 0x00) with 0x0A
// Page 0, Remote Read Command
	BP = RTL8019AS_CR_READ|RTL8019AS_CR_START|RTL8019AS_CR_P0
	RTL8019AS_WR_WORD RTL8019AS_ADDR_00, BP, R2

// Change IOA to input
	SP_IOA_IN BP

// Get Point mbuf
	BP = SP + 2 + 4 + 1
	BP = [BP]

// push (Next Page Number and RX STATUS) and (Packet Length) to [SP]
	push R3,R4 to [SP]

RTL8019AS_RX_5:
// 20. Read port (IOBase + 0x10) for (packet length / 2) times 
//     to get packet data
	RTL8019AS_RD_WORD RTL8019AS_ADDR_10, R1, R3
// Exchange high 8bit to low 8bit
	R2 = R1 lsl 4
	R1 = R1 rol 4
	R2 = R1 lsl 4
	R1 = R1 rol 4
// Write to mbuf
	[BP++] = R1
// Count
	R4 -= 2
	jg RTL8019AS_RX_5			// if (R4 > 0) continue.

	pop R3, R4 from [SP]		// Restore (Next Page Number and RX STATUS) and (Packet length)

// Chang IOA into output
	SP_IOA_OUT BP

// 21. Write port (IOBase + 0x03) with the value of next_page _point -1
	R2 = R3 lsr 4				// Clear RX STATUS, R2 = Next_Page_Point(high 8bit)
	R2 = R2 lsr 4
	R2 -= 1 					// BNRY = (Next Page Number) - 1
	RTL8019AS_WR_WORD RTL8019AS_ADDR_03, R2, BP
	jmp RTL8019AS_RX_EXIT
	
RTL8019AS_RX_ERROR:
	call _RTL8019AS_INIT
	R4 = 0						// Return 0 Packet length

RTL8019AS_RX_EXIT:
// Recall default IO Statue
	SP_RECALL_IO BP

	R1 = R4						// Return Packet length

	pop R2, BP from [SP]
	retf
.endp


//////////////////////////////////////////////////////////////////
// Function: void MEMCPY(UINT16 ByteLen, UINT16 *inbuf, UINT16 *outbuf)
// Function: copy memory regions
// Description: <outbuf>表示输出word类型的内存指针
//              <inbuf>表示输入word类型的内存指针
//              <Byte>表示要拷贝的字节数(bytes)
// 不对<outbuf>做边界校验!!!
//////////////////////////////////////////////////////////////////
.code
.public _MEMCPY
_MEMCPY: .proc
	push R2, BP to [SP]
	
	BP = SP + 2 + 4 + 1
	R4 = [BP++]			// Get: ByteLen
	R3 = [BP++]			// Get: inbuf
	BP = [BP]			// Get: outbuf

MEMCPY_1:
	R2 = [R3++]
	[BP++] = R2
	R4 -= 2
	jg MEMCPY_1
	
	pop R2, BP from [SP]
	retf
.endp


////////////////////////////////////////////////////////////////////////
// UINT16 checksum(UINT16 ByteLen, UINT16 *mbuf)
// TCP/IP 通用校验和过程。由于用汇编,所以只适宜BIG_ENDIAN模式。
// ByteLen: 长度bytes,必须满足条件:ByteLen >= 2 否则计算没有意义
// mbuf: 存放Word缓冲区首指针
////////////////////////////////////////////////////////////////////////
.code
.public _checksum
_checksum: .proc
	push R3, BP to [SP]
	
	BP = SP + 2 + 3 + 1
	R4 = [BP++]			// Get: uwByteLen
	BP = [BP]			// Get: inbuf

	R3 = R4 lsr 1
	R1 = 0
checksum_1:
	R1 += [BP++]
	R1 += 0, Carry
	R3 -= 1
	jnz checksum_1
	
	test R4, 0x0001		// 奇偶测试
	jz checksum_even
// 是奇数长度:处理最后1个byte
	R3 = [BP]
	R3 &= 0xff00
	R1 += R3
	R1 += 0, Carry	
checksum_even:	
// 是偶数,结束处理
	
	pop R3, BP from [SP]
	retf
.endp

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -