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

📄 il.asm

📁 dos下的网卡驱动程序。支持一般通用网卡
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	shl		bx, 01h							; Convert to a word count
	cmp		bx, offset cgroup:unknown_plc-offset cgroup:phy_layer_chip
	jb 	short phy_dev_1_ok
	mov		bx, offset cgroup:unknown_plc-offset cgroup:phy_layer_chip
phy_dev_1_ok:
	mov		dx, phy_layer_chip[bx]
	print_it
	mov		si, 0001h						; Setup physical address in si
	call	setup_routines[bx]
	mov		cx, supported_plc[bx]

	print	phys_2_msg
	mov		bx, eeprom_buff[PHY_DEV_REC_2]
	and		bx, PHY_DEV_BITS
	xchg	bl, bh
	shl		bx, 01h							; Convert to a word count
	cmp		bx, offset cgroup:unknown_plc-offset cgroup:phy_layer_chip
	jb 	short phy_dev_2_ok
	mov		bx, offset cgroup:unknown_plc-offset cgroup:phy_layer_chip
phy_dev_2_ok:
	mov		dx, phy_layer_chip[bx]
	print_it
	or		cx, supported_plc[bx]
	cmp		cx, SUPPORTED
	je		short phy_layer_supported
	or		bx, bx
	je		short one_phy_dev
	mov		dx,offset cgroup:no_support_2_phy
	jmp		short error_get_connector_info
one_phy_dev:
	mov		dx, offset cgroup:no_support_p_layer
	jmp		short error_get_connector_info

phy_layer_supported:
	cmp		duplex, HALF_DUPLEX
	je		short configed_for_half
	mov		config_duplex, FDX_PIN_ENBL + FORCE_FDX

configed_for_half:
	cmp		got_mii_phy, MII_PHY
	jne		short configed_for_503
	mov		config_mii_mode, MII_MODE
	and		config_cdt, NOT CRS_CDT		; Clear CDT for MII interface

configed_for_503:
	cmp		forced_speed_duplex, 0		; Check if forced parameters used
	je		short phy_control_reg_ok
	xor		bx, bx						; Clear negotiation bit
	cmp		speed, FAST_100
	jne		short not_fast
	or		bx, PHY_CTRL_REG_FAST
not_fast:
	cmp		duplex, FULL_DUPLEX
	jne		short not_full
	or		bx, PHY_CTRL_REG_FULL
not_full:
	mov	dx,PHY_CONTROL_REG
	call	write_phy_reg	
phy_control_reg_ok:
	clc
	jmp		short exit_get_connector_info
error_get_connector_info:
	stc
exit_get_connector_info:
	ret
get_connector_info	ENDP

write_phy_reg:
; enter with bx = new register contents, dx = register number,
;  si = phy number.
;   preserves si.
	mov		ax, si		; Get the physical address
	shl		ax, 5h		; Move to the correct position
	or		ax, dx
	or		ax, PHY_WRITE_OPCODE
	shl		eax, 10h
	mov		ax, bx
	load_port	MDI_CTRL_REG
	out		dx, eax
	STALL
	mov		ax, 1		; Wait, if necessary, for about 27ms
	call	set_timeout
write_phy_reg_1:
	in		eax, dx		; Get status of MDI command
	in		eax, dx		; Get status of MDI command
	test	eax, PHY_READY_BIT	; jump when ready
	jne		short write_phy_reg_2
	call	do_timeout		; loop until ready
	jnz		write_phy_reg_1
	stc
write_phy_reg_2:
	ret

read_phy_reg:
; enter with bx = register number, si = phy number.
; exit with ax = register value, nc, or cy if we timed out waiting for it.
;   preserves bx, si.
 	mov		ax, si		; Get the physical address
	shl		ax, 5h		; Move to the correct position
	or		ax, bx
	or		ax, PHY_READ_OPCODE
	shl		eax, 10h
	load_port	MDI_CTRL_REG
	out		dx, eax
	STALL
	mov		ax, 1		; Wait, if necessary, for about 27ms
	call	set_timeout
read_phy_reg_2:
	in		eax, dx			; Get status of MDI command
	in		eax, dx			; Get status of MDI command
	test	eax, PHY_READY_BIT		; Non-zero when ready
	jne		short read_phy_reg_3	; Jump if so
	call	do_timeout			; Any more time left ?
	jnz		read_phy_reg_2		; Continue to wait if so
	stc
read_phy_reg_3:
	ret

else
; Routines for the 82596
init_plx_chip	PROC	NEAR
;- Program UserPins 0-3 in Write Mode. RCVDIS should default to 1.
	LOAD_PORT	PLXP_USER_PINS
	mov     al, 0F0h
	or      al, BIT_2
	out     dx, al

	LOAD_PORT	PLXP_LAN_CONTROL
    in      ax, dx
    or      ax, SOFTWARE_RESET_BIT
    out     dx, ax
    and     ax, NOT SOFTWARE_RESET_BIT
    STALL
    STALL
    out     dx, ax
    STALL
    STALL

;- Enable LAN 0 interrupt and set it to LATCHED mode
	LOAD_PORT	PLXP_INTERRUPT_CONTROL
    in      ax, dx
    or      ax, LAN_0_INTERRUPT_ENABLE
    or      ax, LATCHED_INTWRITE_BIT
    out     dx, ax
    STALL
    STALL

;- Delay 100msec after PLX reset.
	mov		ax,0004h
	call	wait
    ret
init_plx_chip	ENDP


init_scp	PROC	NEAR
; Performs the alternate SCP and ISCP initialization for the 82596
	mov		ax, cs						; Set Up the Alternate SCP Address
	mov		es, ax
	mov		si, offset cgroup:scp_buff
	call	cnvrt_to_phys_add
	jc		error_init_scp
    or      al, ALT_SCP_CMD
	LOAD_PORT	PLXP_PORT_OFFSET
	out		dx, eax
	STALL							; Hold things up - briefly
	mov		ax, 2
	call	wait					; Hold things up for 50ms

; Initialize the SYSBUS byte in System Configuration Pointer (SCP)
; Internal Triggering Of Timers, Active High Edge-Triggered Interrupt
	mov		ax, SYSBUS_CSW OR SYSBUS_LOCK_DIS OR SYSBUS_32_MODE OR SYSBUS_BIT_0
	mov     scp_buff.scp_sysbus, ax
	mov		si, offset cgroup:iscp_buff
	call	cnvrt_to_phys_add
	jc		error_init_scp

    mov     scp_buff.scp_iscp_add, eax
	mov		iscp_buff.iscp_busy, ISCP_BUSY_MARK
    mov     si, 0
	call	cnvrt_to_phys_add
	jc		short error_init_scp

    lea     si, scb_buff
    mov     iscp_buff.iscp_scb_offset, si
    mov     iscp_buff.iscp_scb_lo_add, ax
    shr     eax, 16
    mov     iscp_buff.iscp_scb_hi_add, ax
    mov     scb_buff.scb_status, 0h
    C_ATTENTION						; Issue a channel attention to the 82596

	mov		ax, 1					; Wait, if necessary, for about 27 mili-
	call	set_timeout				;    seconds (10 should be enough)
iscp_busy_wait:
	test	iscp_buff.iscp_busy, ISCP_BUSY_MARK
	jz		short iscp_success
	call	do_timeout				; Any more time left ?
	jnz		short iscp_busy_wait	; Continue to wait if so
	jmp		short iscb_problem

iscp_success:
	mov		ax, scb_buff.scb_status		;- Acknowledge any interrupts
	and		ax, SCB_STATUS_MASK
	mov		scb_buff.scb_command, ax
    C_ATTENTION						; Issue a channel attention to the 82596
	mov		ax, 1					; Minimum time out value
	call	wait_scb_non_active
	jc		short iscb_problem

    mov     ax, DEFAULT_T_OFF		; Load the Bus Throttle values.
    mov     scb_buff.scb_off_timer, ax
    mov     ax, DEFAULT_T_ON
    mov     scb_buff.scb_on_timer, ax
    mov     scb_buff.scb_command, CU_LD_B_T_R
    C_ATTENTION						; Issue a channel attention to the 82596
	mov		ax, 1					; Minimum time out value
	call	wait_scb_non_active
	jnc		short exit_init_scp
iscb_problem:
	print	iscp_init_problem		; Inform the user
	stc

exit_init_scp:
    ret
error_init_scp:
	print	problem_in_phys_add
error_init_iscp:
	stc
	jmp		short	exit_init_scp

init_scp	ENDP


read_ia_pci	PROC	NEAR
	; For the 82596 the Ethernet address is obtained from PCI configuration
	mov		ah, PCI_FUNCTION_ID		; Get IO base
	mov		al, READ_PCI_CONFIG_DWORD
	mov		bx, pci_bus_dev_no		; Recover the bus / device number
    mov     di, PLXP_NODE_ADDR_REGISTER
	int		PCI_BIOS_INTERRUPT
	cmp		ah, PCI_SUCCESSFULL
	jne		short error_read_ia_pci
	mov		DWORD PTR rom_address, ecx
	mov		ah, PCI_FUNCTION_ID		; Get IO base
	mov		al, READ_PCI_CONFIG_WORD
    add     di, 4					; Advance to the next 4 bytes
	int		PCI_BIOS_INTERRUPT
	cmp		ah, PCI_SUCCESSFULL
	jne		short error_read_ia_pci
	mov		WORD PTR rom_address+4, cx
	clc
exit_read_ia_pci:
	ret
error_read_ia_pci:
	stc
	jmp		short exit_read_ia_pci
read_ia_pci	ENDP

endif

setup_cmd_buffs	PROC	NEAR
; Setup buffer for commands
	mov		word ptr cmd_buff1, C_DONE_BIT	; Mark buffer as available
	mov		word ptr cmd_buff2, C_DONE_BIT	; Mark buffer as available
	mov		buff_ptrs[0], offset cgroup:cmd_buff1	; Settup buffer 'array'
	mov		buff_ptrs[2], offset cgroup:cmd_buff2
	mov		tx_buff_no, 0					; Set next buffer # to use
	ret
setup_cmd_buffs	ENDP

setup_receive	PROC	NEAR
	mov		cx, RBD_COUNT 			; Setup the receive buffer descriptors
	mov		ax, cs
	mov		es, ax
	mov		si, offset cgroup:start_rx_buff
	mov		bx, si					; Bx holds a copy of the virtual offset
	call	cnvrt_to_phys_add
	mov		esi, eax
	mov		di, offset cgroup:start_rbd
	mov		first_rbd, di
	mov		ax, di
next_rbd:
	mov		[di].rbd_status, 0
	add		ax, size rbd_struct				; Pointer to the next RBD
if	CHIP EQ INTEL_82596
	mov		[di].rbd_link, ax
else
	movzx	eax, ax
	mov		[di].rbd_link, eax
	mov		[di].rbd_filler2, 0
endif
	mov		[di].rbd_ptr, esi				; Store physical address
	mov		[di].rbd_size, SIZE_ONE_DATA_BUFF
	mov		[di].rbd_filler1, 0
	mov		[di].rbd_voffset, bx			; Store the virtual offset
	add		esi, SIZE_ONE_DATA_BUFF			; Physical address of next buffer
	add		bx, SIZE_ONE_DATA_BUFF			; Virtual offset of next buffer
	mov		di, ax							; Advance to the next RBD
	loop	next_rbd

	sub		di, size rbd_struct				; Return to previous RBD
	mov		last_rbd, di
	or		[di].rbd_size, EL_BIT			; Mark end of chain
	mov		[di].rbd_link, offset cgroup:start_rbd

	mov		cx, RFD_COUNT 				; Setup the receive buffer descriptors
	mov		di, offset cgroup:start_rfd
	mov		first_rfd, di
	mov		ax, di
next_rfd:
	mov		[di].rfd_status, 0
	mov		[di].rfd_eol, FLEXIBLE_MODE
	add		ax, size rfd_struct		 		; Pointer to the next RFD
if	CHIP EQ INTEL_82596
	mov		[di].rfd_link, ax
else
	movzx	eax, ax
	mov		[di].rfd_link, eax
endif
	mov		[di].rfd_ptr, -1
	mov		[di].rfd_cnt, 0
	mov		[di].rfd_size, 0
	mov		di, ax							; Advance to the next RFD
	loop	next_rfd

	sub		di, size rfd_struct				; Get back to last RFD
	mov		last_rfd, di
	mov		[di].rfd_eol, EL_BIT+FLEXIBLE_MODE	; Mark end of chain
if	CHIP EQ INTEL_82596
	mov		[di].rfd_link, offset cgroup:start_rfd	; Wrap around to start
else
	mov		ax, offset cgroup:start_rfd	; Wrap around to start
	movzx	eax, ax
	mov		[di].rfd_link, eax
endif

							; Setup the start rdf to point to the start rbd
	mov		[start_rfd].rfd_ptr, offset cgroup:start_rbd	

	WAIT_CMD_ACCEPTED 					; Wait for acceptance of last command
if	CHIP EQ INTEL_82596
	mov		scb_buff.scb_rfa_add, offset cgroup:start_rfd
	mov		scb_buff.scb_command, RU_START
	C_ATTENTION
else
	LOAD_PORT	SCB_GEN_PTR
	mov		ax, offset cgroup:start_rfd
	movzx	eax, ax
	out		dx, eax					; Issue the address - upper word is low
	add		dx, SCB_CMD - SCB_GEN_PTR	; Get back to cmd port
	mov		al, RU_START
	out		dx, al					; Issue the command
endif
	ret
setup_receive	ENDP

config_chip	PROC	NEAR
if	CHIP EQ INTEL_82557
	call	load_base_regs
	mov		dx, offset cgroup:load_base_msg
	jc		short exit_config_chip		; Exit if there is a problem
endif

	call	do_config
	mov		dx, offset cgroup:config_msg
	jc		short exit_config_chip	; Exit if there is a problem

	mov		ax, 8					; Wait for the command
	call	wait
; Set the Individual address registers with the Ethernet address
	mov		si, offset cgroup:rom_address
	call	set_ether
;	mov		dx, offset cgroup:ether_add_msg
	jc		short exit_config_chip	; Exit if there is a problem
	clc
exit_config_chip:
	ret
config_chip	ENDP

if	CHIP EQ INTEL_82557
load_base_regs	PROC	NEAR
	WAIT_CMD_ACCEPTED 				; Wait for acceptance of last command
	LOAD_PORT	SCB_GEN_PTR			; Load port address for SCB general pointer
	xor		eax, eax
	mov		ax, cs
	shl		eax, 4
	out		dx, eax					; Load the port with the segment address
	LOAD_PORT	SCB_CMD				; Load port address for SCB command
	mov		al, CU_LD_BASE			; Command to set the CU base register
	out		dx, al					; Issue the command

	WAIT_CMD_ACCEPTED 				; Wait for acceptance of last command
	LOAD_PORT	SCB_STATUS			; Load port address for SCB status
	mov		ax, 1					; Use minimum time-out in the wait routine
	call	wait_scb_non_active		; Can't issue a command if chip is active
	jc		short exit_load_base_regs	; Exit if there is a problem
	LOAD_PORT	SCB_GEN_PTR			; Load port address for SCB general pointer
	xor		eax, eax
	mov		ax, cs
	shl		eax, 4
	out		dx, eax					; Load the port with the segment address
	LOAD_PORT	SCB_CMD				; Load port address for SCB command
	mov		al, RU_LD_BASE			; Command to set the RU base register
	out		dx, al					; Issue the command
exit_load_base_regs:
	ret
load_base_regs	ENDP
endif

do_select_media	PROC NEAR
; First check to see if connector type has been specified
if	CHIP EQ INTEL_82557
	cmp		temp_connector, TPE_CONNECTOR	; Found 100Mbs capability
	clc
	je		short using_tpe					; Jump if so
	print	auto_detect_nr_msg
	jmp		short using_tpe
endif

	cmp		temp_connector, TPE_CONNECTOR
	je		short test_TPE
	cmp		temp_connector, BNC_CONNECTOR
	je		short test_BNC
	cmp		temp_connector, AUI_CONNECTOR
	je		short test_AUI

	print	using_auto_msg		; Auto detecting media
	call	setup_test_packet

test_AUI:						; Try the AUI connector first
	mov		connector, AUI
if	CHIP EQ INTEL_82596
	LOAD_PORT	PLXP_USER_PINS
	in		al, dx
	or		al, PLXP_USER_1
	and		al, NOT PLXP_USER_0
	out		dx, al
else
; debug 82557 code required from Intel to select AUI connector
endif
	mov		ax,0016h	; Delay about 600 msec for front_end setup
	call	wait
	cmp     temp_connector, AUI_CONNECTOR
	je		short using_aui
	call	send_on_connector

⌨️ 快捷键说明

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