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

📄 etherdrv.inc

📁 VRTX 商用嵌入式实时操作系统
💻 INC
字号:
;==============================================================================
;       @(#)ne2000.inc
;
;
;
; Module Name:  ne2000.inc
; Module Desc:  include file (as hwequ.inc) for board.src 
; Created:      Nov. 1996
;
;
; Revision:     1.0
; --------------------------------------------------------------------
; General Information:
;
;==============================================================================
;==============================================================================
; ETHERNET INITIALIZATION ROUTINE.
;==============================================================================
public          IO_INIT
extrn   set_isr_offs:near       ;a xmasprt routine to set interrupts

;                                       ;INITIALIZE UART

; Initialization items picked up from "hwequ.inc".
;
mon_et_addr	label	BYTE			; Board's ethernet address
		public	mon_et_addr
		db	ETH_ADDR0
		db	ETH_ADDR1
		db	ETH_ADDR2
		db	ETH_ADDR3
		db	ETH_ADDR4
		db	ETH_ADDR5

mon_ip_addr	label	BYTE			; Board's IP address
		public	mon_ip_addr
		db	IP_ADDR0
		db	IP_ADDR1
		db	IP_ADDR2
		db	IP_ADDR3

mon_udp_port	dw	MON_UDP_PORT		; UDP port for XRAY monitor
		public	mon_udp_port
		

eth_ioaddr	dw	NIC_IOADDR		; Adapter I/O base address
eth_irq		db	NIC_IRQ			; Adapter's IRQ
eth_cable	db	NIC_CABLE_T		; Ethernet cable type
		public	eth_ioaddr
		public	eth_irq
		public	eth_cable


%IF ((%CONIO AND %INITIO) ne 0) THEN
(
		extrn   init_ethernet:NEAR
		extrn   get_char:NEAR
		extrn   ether_rx_interrupt:NEAR
		extrn   tx_char:NEAR
		extrn   ether_irq_get:NEAR
		extrn   ether_int_enable:NEAR

IO_INIT         proc    near
		cmp     ax,0
		jnz     INIT_RESET              ;not first init

;****************** INSTALL AND INIT ETHERNET CONTROLLER *********************

		mov     ether_int_active, 0
		call    init_ethernet           ; Initialize NIC
		or      eax,eax
		jz      SHORT ether_init_ok

		ret
ether_init_ok:


  ; if interrupt driven, set them up
  %IF ((%CONIO AND %INTRPT) ne 0) THEN
  (
	
;************************************************************************
;
;       :SETUP 8259 CONTROLLER
;
; SET (NUM_8259, 2)              ;set the number of 8259's 1 or 2
; MASTER_8259 EQU 020H
; SLAVE_8259  EQU 0A0H
; MASTER_8259_BASE EQU 038H           ;base for interrupts from the 1st 8259
; SLAVE_8259_BASE  EQU 040H           ;base of interrupts for the 2nd 8259 lwr 3 bits
				     ;must be 0

    %IF (%NUM_8259 EQ 2) THEN
    (
		mov     al, 11h                 ;ICW 1, bit 0 = for ICW4 used,
						;  bit 4 = ICW1
    )
    ELSE
    (
		mov     al, 13h                 ;ICW 1, no slaves, bit 1= 1
						;  for no slaves
    ) FI
		push    esi                     ; ESI used below
		pushfd
		cli                             ;*********** INTS OFF *********

		out     MASTER_8259, al		;Write ICW 1

		mov     al, MASTER_8259_BASE    ;ICW 2 set the base of vectors
						;  from this 8259
		out     MASTER_8259+1,al	;Write ICW 2

		mov     al, 04H                 ;ICW 3 the other 8259 is
						;  cascaded to this unit
		out     MASTER_8259+1,al	;Write ICW 3

		mov     al, 01h                 ;ICW 4  NO EOI, NO SPECIAL
						;  NESTED MODE
		out     MASTER_8259+1,al	;Write ICW 4

						;OCW 1 ENABLE interrupts in
						;  controller

		call    ether_irq_get           ; Get ethernet IRQ #
		mov     ether_int_number, eax
		mov     edx, eax                ; IRQ in DL

		mov	eax, 0FFH		; Assume Ether IRQ on master
		cmp	edx, 07H		; Ether IRQ on SLAVE?
		jbe	SHORT cascade_n		; No, don't cascade
		mov     eax, 0FBH               ; Yes, get mask with cascade
		jmp	SHORT master_enable_n   ;  and don't enable in MASTER
cascade_n:
		btr     eax, edx                ; Enable requested IRQ
		add     edx, MASTER_8259_BASE   ; Compute vector number
		mov     esi, edx                ;  and remember it
master_enable_n:
		out     MASTER_8259+1, al       ;Write OCW 1 (Mask)
		mov     al, 20h                 ;OCW2  NON SPECIFIC EOI

		out     MASTER_8259, al		;Write OCW 2 with non sp EOI
		mov     al, 08H                 ;OCW3  Operation command word
						;  no action
		out     MASTER_8259, al;	;Write OCW 3

    %IF (%NUM_8259 EQ 2) THEN
    (
				;initialize the second 8259
		mov     al, 11h                 ;ICW 1, this is the slave unit
		out     SLAVE_8259,al
		mov     al, SLAVE_8259_BASE     ;ICW 2 set the base of vectors
						;  from this 8259
		out     SLAVE_8259+1,al
		mov     al, 02H                 ;ICW 3 the other 8259 is
						;  cascaded to this unit
		out     SLAVE_8259+1,al
		mov     al, 01h                 ;ICW 4  NO EOI, NO SPECIAL
						;  NESTED MODE
		out     SLAVE_8259+1,al
						;OCW 1 ENABLE interrupts in
						;  controller

		mov     edx, ether_int_number	; IRQ in DL
		mov     eax, 0FFH               ; Get SLAVE int mask
		sub     edx, 8

		cmp     dl, 07H                 ; IRQ > 15?
		ja      SHORT slave_enable_n    ; Yes, don't enable in SLAVE
		mov     esi, edx                ; ESI = IRQ - 8
		add     esi, SLAVE_8259_BASE    ; Compute vector number
		btr     eax, edx                ; Enable requested IRQ
slave_enable_n:
		out     SLAVE_8259+1,al         ; OCW1
		mov     al, 20h                 ;OCW2  NON SPECIFIC EOI
		out     SLAVE_8259,al;
		mov     al, 08H                 ;OCW2  Operation command word
						;  no action
		out     SLAVE_8259,al;
    ) FI
		;  setup the IDT descriptor to point at the desired ISR
		;  entry point to handle an ethernet interrupt

		push    OFFSET RX_INT
		push    esi                     ;this is the interrupt taken
						;  by ethernet IRQ 
		call    set_isr_offs            ;and set the interrupt in the
						;  IVT table
		add     esp,8                   ;pop the two long words
						;  off the esp
		call    ether_int_enable        ; Enable NIC interrupts

		popfd                           ;******* RESTORE INTS *********
		pop     esi

		xor     eax, eax
		ret
  ) FI

INIT_RESET:                                     ;reset port from aux-mon
						;  (interrupt, etc)
		xor     eax, eax
		ret
  
IO_TERM:                                        ;reset port to aux-mon
						;  (disable int, etc)
		xor     eax, eax
		ret

IO_INIT         endp

) FI  ; INITIO


ether_in_int_mode proc  near
		public  ether_in_int_mode
%IF ((%CONIO AND %INTRPT) ne 0) THEN
(
		mov     eax, 1
		ret
)
else
(
		xor     eax,eax
		ret
) FI
ether_in_int_mode endp


;==============================================================================
;
; Polled (OR Interrupt driven) output
;
;  -> DL  = character to transmit
;     EAX = Control Code: 0 = Normal char, 1 = Last char
;  <- EAX = RET_OK (transmitted ok)
;           ER_TBF (transmit buffer full)
;
;==============================================================================
CON_OUT         proc    near
		push    ebx
		push    ecx
		push    edx

;************************  PROCESS OUTPUT CHARACTER **************************

		and     edx, 0FFH
		and     eax, 0FFH
		push    eax                     ; Pass control code
		push    edx                     ; Pass character
		
;                push    eax
;                push    edx
;                push    ecx

;                mov     cl, dl
;OUT_CHAR('O')
;OUT_CHAR( cl )
;                pop     ecx
;                pop     edx
;                pop     eax
		
		call    tx_char                 ; Transmit character
		add     esp, 2*4                ; Flush args

;*********************************** EXIT ************************************
		pop     edx
		pop     ecx
		pop     ebx
		ret                             ;return to caller
con_out40:
		mov     ax,ER_TBF
		ret

CON_OUT         endp
;******************************* END CON_OUT *********************************


;==============================================================================
;
; Polled input
;
;  <- DL  = received character
;  -> EAX = RET_OK (received ok)
;           ER_NCA (no character available)
;           ER_REC (receive error)
;
;==============================================================================
%IF ((%CONIO AND %POLLED) ne 0) THEN
(

;******************************* CON_IN ENTRY ********************************

CON_IN          proc    near
		push    ebx
		push    ecx

;******************************* CON_IN CODE *********************************

		push    0                       ; Make room for return char
		mov     eax, esp                ; Set ptr to return value
						;  (safer than pushing ESP)
		push    eax                     ; Push char ptr
		call    get_char                ; Get ethernet character
		pop     edx                     ; Flush pointer
		pop     edx                     ; Pickup charater

;                or      eax, eax
;                jnz     SHORT ichar_print_n
;                push    eax
;                push    edx
;                push    ecx

;                mov     cl, dl
;OUT_CHAR('I')
;OUT_CHAR( cl )
;                pop     ecx
;                pop     edx
;                pop     eax
;ichar_print_n:

;******************************* CON_IN EXIT *********************************
		pop     ecx
		pop     ebx
		ret

CON_IN          endp

) FI


;==============================================================================
;
; Interrupt input
;
;==============================================================================
%IF ((%CONIO AND %INTRPT) ne 0) THEN
(
		public  RX_INT   
RX_INT          proc    near                    ; Receive interrupt
		cli                             ;******** INTS OFF ************
		pushad                          ; Save all data registers

		mov     ether_int_active, 1     ; Remember INT active

;************************ GET CHARACTER(S) FROM NIC **************************

		call    ether_rx_interrupt      ; Execute NIC interrupt

;*************************** CHARECTER INPUT LOOP ****************************

rx_loop:        push    0                       ; Make room in local stack
		mov     eax, esp                ; Create character pointer
		push    eax                     ; Pass pointer of char buff
		call    get_char                ; Get character from rx packet
		pop     edx                     ; Flush pointer
		pop     edx                     ; Get charater from stack

		cmp     eax, ER_NCA             ; Buffer empty?
		je      SHORT rx_int_done       ; Yes, quit

						; EDX = input character
						; EAX = receive code
		or      eax, eax
		jnz     SHORT intchar_print_n
		push    eax
		push    edx
		push    ecx

		mov     cl, dl
;OUT_CHAR('X')
;OUT_CHAR( cl )
		pop     ecx
		pop     edx
		pop     eax
intchar_print_n:
		call    NEAR PTR mo_start + MORXCHR ;Send char to monitor
		cmp     eax, ER_HLT             ;should we stop?
		jne     SHORT rx_loop           ;no, check for next char

;************************* MONITOR TELLS US TO STOP **************************
; if have interrupt controller would do an EOI here

;*************************** SEND EOI TO 8259(S) *****************************

		mov     al,20h                  ;OCW2 output a non specific
						;  EOI
		cmp     ether_int_number, 8
		jb      SHORT rx_i1_slave_n
		out     SLAVE_8259, al
rx_i1_slave_n:
		out     MASTER_8259,al


		mov     ether_int_active, 0     ; Exiting INT
		popad
		jmp     mo_start + MOHALT       ; Enter monitor HALT state


;**************************** RX_INT NORMAL EXIT *****************************

rx_int_done:

;*************************** SEND EOI TO 8259(S) *****************************

		mov     al,20h                  ;OCW2 output a non specific
						;  EOI
		cmp     ether_int_number, 8
		jb      SHORT rx_i2_slave_n
		out     SLAVE_8259, al
rx_i2_slave_n:
		out     MASTER_8259,al


		mov     ether_int_active, 0     ; Exiting INT
		popad                           ; Restore all data registers
		iretd                           ; Return from interrupt

RX_INT          endp


)
ELSE
(
RX_INT          proc    near
		public  RX_INT
		push    eax
		mov     al,20h                  ;OCW2 output a non specific
						;  EOI
		out     MASTER_8259, al

		pop     eax
		iretd                           ; Return from interrupt

RX_INT          endp

) FI

;*****************************************************************************
;
;       int in_ether_interrupt( void )
;
;*****************************************************************************
		public  in_ether_interrupt
in_ether_interrupt proc NEAR

		mov     eax, ether_int_active
		ret

in_ether_interrupt endp

⌨️ 快捷键说明

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