📄 packet.asm
字号:
; RTL8019 & 8052 Packet driver (c)Copyright 2000, Radek Benedikt; benedikt@lphard.cz, http://benedikt.lphard.cz; History: 1.0b -- Radek Benedikt 04-Sep-2001; binutils version ; History: 1.01 -- Radek Benedikt 31-Oct-2000; without callback ProcessEthPacket; History: 1.00 -- Radek Benedikt 26-Feb-2000; initial version;*************************************************************;*** PROJECT WWW8052 http://8052.lphard.cz **;*************************************************************; This program is free software; you can redistribute it and/or modify; it under the terms of the GNU General Public License as published by; the Free Software Foundation, version 2.;; This program is distributed in the hope that it will be useful,; but WITHOUT ANY WARRANTY; without even the implied warranty of; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License; along with this program; if not, write to the Free Software; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.; Tento program je volne programove vybaveni; muzete jej sirit a; modifikovat podle ustanoveni Obecne verejne licence GNU, vydavane Free; Software Foundation, verze 2;; Tento program je rozsirovan v nadeji, ze bude uzitecny, avsak BEZ; JAKEKOLI ZARUKY; neposkytuji se ani odvozene zaruky PRODEJNOSTI anebo; VHODNOSTI PRO URCITY UCEL.; Dalsi podrobnosti hledejte v Obecne verejne licenci GNU.;; Kopii Obecne verejne licence GNU jste mel obdrzet spolu s timto; programem; pokud se tak nestalo, napiste o ni Free Software Foundation,; Inc., 675 Mass Ave, Cambridge, MA 02139, USA.; .global network_init .global InitRTL8019 .global tx_wait .global xmit_frame .global send_pkt .global rcv_pkt .global DMARead .global DMAWrite .global icall_load .global icall_save .global plongpause .global eth_state1 .global eth_state2 .global flagResend .global next_packet .global curr_recv .global curpage.nolist.include "param.inc".include "8019.inc".list; .equ endport, 0x40 .equ portind, 0x20; .equ my_ether, buf ;6 my ethernet address .macro BEGINPORTDATA lcall send_port .endm; .macro PORTDATA prtaddr, prtdata .byte \prtaddr, \prtdata .endm; .macro ENDPORTDATA .byte endport .endm; .macro ISAREAD.ifdef MOVXMODE MOVX A,@R0.else MOV P0,#0xFF CLR P3.7 NOP MOV A,P0 SETB P3.7.endif .endm; .macro ISAWRITE.ifdef MOVXMODE MOVX @R0,A.else MOV P0,A CLR P3.6 NOP SETB P3.6.endif .endm; .macro ISAIN IO_ADDR MOV ADDRPORT,#(\IO_ADDR+I2CBUS).ifdef MOVXMODE MOVX A,@R0.else MOV P0,#0xFF CLR P3.7 NOP MOV A,P0 SETB P3.7.endif .endm; .macro ISAOUTA IO_ADDR MOV ADDRPORT,#(\IO_ADDR+I2CBUS).ifdef MOVXMODE MOVX @R0,A.else MOV P0,A CLR P3.6 NOP SETB P3.6.endif .endm; .macro ISAOUT IO_ADDR, IO_DATA.ifdef MOVXMODE MOV ADDRPORT,#(\IO_ADDR+I2CBUS) MOV A,\IO_DATA MOVX @R0,A.else MOV ADDRPORT,#(\IO_ADDR+I2CBUS) MOV P0,IO_DATA CLR P3.6 NOP SETB P3.6.endif .endm; .bitcomm eth_state1, 1 .bitcomm eth_state2, 1 .bitcomm flagResend, 1; .comm next_packet, 1 ;pointer to next packet in Rx ring .comm curr_recv, 1 ;pointer to current packet in Rx ring .comm curpage, 1 ;current page of rcv ring;;************************************************************* .text .using 0;*************************************************************.ifdef HW45.elseReset_ISA: SETB RESETBIT ;Reset ISA bus lcall waitbus CLR RESETBIT ;End of Reset ISA bus; sjmp waitbus;waitbus: PUSH AR1 PUSH AR0 MOV R0,#0waitbus1: MOV R1,#0waitbus2: DJNZ R1,waitbus2 DJNZ R0,waitbus1 POP AR0 POP AR1 RET.endif;*************************************************************;DMA Read;input: R2R3 Remote Byte Count; R4R5 Remote Start Address Register; DPTR Pointer to ProcedureDMARead: ISAOUT EN_CMD, #EN_PAGE0+EN_NODMA+EN_START ;Remote DMA, Start the chip, clear reset;Set Remote byte count;input: R2R3 Byte Count mov a,r2 ISAOUTA EN0_RCNTHI ;MSB Remote byte count reg mov a,r3 ISAOUTA EN0_RCNTLO ;LSB Remote byte count reg;Set Remote Start Address;input: R4R5 mov a,r4 ISAOUTA EN0_RSARHI ;MSB Remote start address reg mov a,r5 ISAOUTA EN0_RSARLO ;LSB Remote start address reg ISAOUT EN_CMD, #EN_PAGE0+EN_RREAD+EN_START ;Remote Read, Start the chip, clear resetDMAReadLoop: MOV A,R3 JNZ DMAReadLoop1 MOV A,R2 JZ DMAReadEndDMAReadLoop1: ISAIN EN_DATA MOV R7,A ;save data from NIC to R7 lcall ICALL ;call save/compare... ;dec R2R3 Remote Byte Count XCH A,R3 ;Exchange A for R3 DEC A ;Decrement A (which is R3) CJNE A,#0xFF,r_dec_R23 ;If A (R3) is not #0FFh, continue normally DEC R2 ;If A=FFh, we need to decrement R2r_dec_R23: XCH A,R3 ;Exchange A for R3 (thus saving R3 and restoring A) SJMP DMAReadLoopDMAReadEnd: RET;;*************************************************************ICALL: CLR A JMP @A+DPTR;;*************************************************************icall_saveskip: MOV A,R3 JB Acc.0,proc0ret ; skip MOV A,R7 MOV @R1,A ; save INC R1proc0ret: RET;icall_save: MOV A,R7 MOV @R1,A INC R1 RET;*************************************************************;DMA Write;input: R2R3 Remote Byte Count; R4R5 Remote Start Address Register; DPTR Pointer to ProcedureDMAWrite: ISAOUT EN_CMD, #EN_PAGE0+EN_NODMA+EN_START ;Remote DMA, Start the chip, clear reset mov a,r2 ISAOUTA EN0_TCNTHI ;High byte of tx byte count mov a,r3 ISAOUTA EN0_TCNTLO ;Low byte of tx byte count;Set Remote byte count;input: R2R3 Byte Count mov a,r2 ISAOUTA EN0_RCNTHI ;MSB Remote byte count reg mov a,r3 ISAOUTA EN0_RCNTLO ;LSB Remote byte count reg;Set Remote Start Address;input: R4R5 mov a,r4 ISAOUTA EN0_RSARHI ;MSB Remote start address reg mov a,r5 ISAOUTA EN0_RSARLO ;LSB Remote start address reg ISAOUT EN_CMD, #EN_PAGE0+EN_RWRITE+EN_START ;Remote Write, Start the chip, clear resetDMAWriteLoop: MOV A,R3 JNZ DMAWriteLoop1 MOV A,R2 JZ DMAWriteEndDMAWriteLoop1: lcall ICALL ;call save... ISAOUTA EN_DATA ;dec R2R3 Remote Byte Count XCH A,R3 ;Exchange A for R3 DEC A ;Decrement A (which is R3) CJNE A,#0xFF,w_dec_R23 ;If A (R3) is not #0FFh, continue normally DEC R2 ;If A=FFh, we need to decrement R2w_dec_R23: XCH A,R3 ;Exchange A for R3 (thus saving R3 and restoring A) SJMP DMAWriteLoopDMAWriteEnd: RET;;*************************************************************icall_load: MOV A,@R1 INC R1 RET;;*************************************************************tx_wait:.ifge CPUFRQ - 258000 MOV DPTR,#-(CPUFRQ/7+1000) ;(CPUFRQ*367)/(12*10*21).else MOV DPTR,#-(CPUFRQ/4+1000) ;(CPUFRQ*367)/(12*10*12).endif ;max coll time = 1024*7 Ethernet slot units (51.2us)tx_wait1: ISAIN EN_CMD ;~4 JB BIT_TRANS,tx_wait0 ;2.ifge CPUFRQ - 258000 nop ;1 nop ;1 nop ;1 nop ;1 nop ;1 nop ;1 nop ;1 nop ;1 nop ;1.endif INC DPTR ;2 MOV A,DPH ;1 ORL A,DPL ;1 JNZ tx_wait1 ;2.ifdef TESTMODE lcall OutStrg ;Transmit, with error .asciz "\r\nTimeout Xmit error";; set errors flag....endiftx_wait0: ret;*************************************************************; *** XMIT_FRAME *** transmit frame; xmit_frame length; R6R7 ;Transmit Byte Countxmit_frame:send_pkt: ISAIN EN_CMD JNB BIT_TRANS,no_tx_wait LCALL tx_wait SJMP tx_idle0no_tx_wait:; Check for recent TX completions in the interrupt status register ISAIN EN0_ISR ; Interrupt status reg.ifdef TESTMODE MOV R2,A ; save Interrupt status reg.endif ANL A,#ENISR_TX_ERR+ENISR_TX ; Pending Tx interrupts? JZ tx_idle ; No, Go on new Tx.ifdef TESTMODE JNB BITISR_TX_ERR, XmitFrameNoErr lcall OutStrg ; Transmit, with error .asciz "\r\nXmit error: " MOV A,R2 lcall OutHexb ; print hex from Acc;; set errors flag...XmitFrameNoErr:.endiftx_idle0: ISAIN EN0_TSR ; Read Transmit status reg;; save transmit status...; Acknowledge the TX interrupt ISAOUT EN0_ISR, #ENISR_TX_ERR+ENISR_TX ; Interrupt status reg ; Set Transmitter Interrupt, with/no errortx_idle: MOV A,R7 ADD A,#LOW(-GIANT-1) MOV A,R6 ADD A,#HIGH(-GIANT-1) JNC XmitNoGiant.ifdef TESTMODE JNB BITISR_TX_ERR, XmitFrameNoErr lcall OutStrg ; Transmit, with error .asciz "\r\nGiant Xmit error: " MOV A,R6 lcall OutHexb ; print hex from Acc MOV A,R7 lcall OutHexb ; print hex from Acc.endif;; set errors flag... RETXmitNoGiant: MOV A,R6 ; Is the frame long enought ? JNZ XmitNoRunt MOV A,R7 ADD A,#-RUNT JC XmitNoRunt;; MOV R6,#HIGH(RUNT) ; Stretch frame to minimum allowed MOV R7,#LOW(RUNT)XmitNoRunt: BEGINPORTDATA .using 0 PORTDATA EN0_TCNTHI+portind,AR6 ; High byte of tx byte count .using 0 PORTDATA EN0_TCNTLO+portind,AR7 ; Low byte of tx byte count PORTDATA EN0_TPSR+portind,stackOffset ; Transmit starting page ; First page of TX buffer PORTDATA EN_CMD, EN_PAGE0+EN_NODMA+EN_TRANS+EN_START ; Remote DMA, Transmit a frame, ; Start the chip, clear reset ENDPORTDATA RET;*************************************************************ResetRTL8019: ISAIN EN_RESET ; Reset Port (for all pages); lcall longpause ISAOUTA EN_RESET ; Reset Port (for all pages) ISAOUT EN_CMD, #EN_PAGE0+EN_NODMA+EN_STOP ; Remote DMA, Stop and reset the chip; lcall longpause;while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0)waitEndOfReset: ISAIN EN0_ISR ; Interrupt status reg jnb BITISR_RESET, waitEndOfReset ;Wait for Reset completed
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -