home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Stars of Shareware: Programmierung
/
SOURCE.mdf
/
programm
/
msdos
/
asm
/
drivers3
/
es3210.asm
< prev
next >
Wrap
Assembly Source File
|
1992-02-07
|
9KB
|
376 lines
version equ 0
;History:254,1
; The following people have contributed to this code: David Horne, Eric
; Henderson, and Bob Clements.
; Copyright, 1988-1992, Russell Nelson, Crynwr Software
; 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 1.
;
; 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.
include defs.asm
.286
code segment word public
assume cs:code, ds:code
;*****************************************************************************
;
; es3210 controller board offsets
; IO port definition (BASE in io_addr)
;*****************************************************************************
NE_RESET equ 04h ;board control bits.
EBASE equ 10h
EN_OFF equ 20h
NE_DATAPORT equ 60h ; es3210 Port Window.
include 8390.inc
; Shared memory management parameters
SM_TSTART_PG equ 000h ; First page of TX buffer
SM_RSTART_PG equ 006h ; Starting page of RX ring
SM_RSTOP_PG equ 040h ; Last page +1 of RX ring
ram_enable macro
endm
reset_8390 macro
loadport
setport NE_RESET
mov al,4 ;reset the board.
out dx,al
longpause
mov al,1 ;unreset the board.
out dx,al
endm
terminate_board macro
endm
public int_no, io_addr, mem_base
int_no db 2,0,0,0 ;must be four bytes long for get_number.
io_addr dw 0300h,0 ; I/O address for card
mem_base dw 00000h,0 ; Shared memory addr
public driver_class, driver_type, driver_name, driver_function, parameter_list
driver_class db BLUEBOOK, IEEE8023, 0 ;from the packet spec
driver_type dw 54 ;from the packet spec
driver_name db 'es3210',0 ;name of the driver.
driver_function db 2
parameter_list label byte
db 1 ;major rev of packet driver
db 9 ;minor rev of packet driver
db 14 ;length of parameter list
db EADDR_LEN ;length of MAC-layer address
dw GIANT ;MTU, including MAC headers
dw MAX_MULTICAST * EADDR_LEN ;buffer size of multicast addrs
dw 0 ;(# of back-to-back MTU rcvs) - 1
dw 0 ;(# of successive xmits) - 1
int_num dw 0 ;Interrupt # to hook for post-EOI
;processing, 0 == none,
is_186 db 0
include movemem.asm
;
; Block input routine
; CX = byte count, es:di = buffer location, ax = buffer address
public block_input
block_input:
push ds
assume ds:nothing
mov ds,mem_base ; ds:si points at first byte to move
mov si,ax
add ax,cx ; Find the end of this frame.
cmp ah,byte ptr cs:sm_rstop_ptr ; Over the top of the ring?
jb rcopy_one_piece ; Go move it
rcopy_wrap:
; Copy in two pieces due to buffer wraparound.
mov ah,byte ptr cs:sm_rstop_ptr ; Compute length of first part
xor al,al
sub ax,si ; as all of the pages up to wrap point
sub cx,ax ; Move the rest in second part
push cx ; Save count of second part
mov cx,ax ; Count for first move
shr cx,2 ; convert byte count to dword count
db 0f3h, 066h, 0a5h ;rep movsd
mov si,SM_RSTART_PG*256 ; Offset to start of first receive page
pop cx ; Bytes left to move
rcopy_one_piece:
;transfer all complete dwords.
push cx
shr cx,2 ; convert byte count to dword count
db 0f3h, 066h, 0a5h ;rep movsd
pop cx
;now take take of any trailing words and/or bytes.
db 066h, 0adh ;lodsd
test cx,2
je rcopy_one_word
stosw
db 066h, 0c1h, 0e8h, 010h ;shr eax,16
rcopy_one_word:
test cx,1
je rcopy_one_byte
stosb
rcopy_one_byte:
pop ds
ret
push ax ; save buffer address
loadport
setport EN_CCMD
pause_
mov al,ENC_NODMA+ENC_PAGE0+ENC_START
out dx,al
setport EN0_RCNTLO ; remote byte count 0
pause_
mov al,cl
out dx,al
setport EN0_RCNTHI
pause_
mov al,ch
out dx,al
pop ax ; get our page back
setport EN0_RSARLO
pause_
out dx,al ; set as hi address
setport EN0_RSARHI
pause_
mov al,ah
out dx,al
setport EN_CCMD
pause_
mov al,ENC_RREAD+ENC_START ; read and start
out dx,al
setport NE_DATAPORT
pause_
inc cx ; make even
shr cx,1 ; word count
rep insw
ret
;
; Block output routine
; CX = byte count, ds:si = buffer location, ax = buffer address
block_output:
assume ds:nothing
mov es,mem_base ; Set up ES:DI at the shared RAM
mov di,ax ; ..
add cx,3 ;round up to next highest dword.
shr cx,2
db 0f3h, 066h, 0a5h ;rep movsd
clc
ret
push ax ; save buffer address
add cx,3 ; round up to nearest dword.
and cx,0fffch
loadport
setport EN_CCMD
pause_
mov al,ENC_NODMA+ENC_START
out dx,al ; stop & clear the chip
setport EN0_RCNTLO ; remote byte count 0
pause_
mov al,cl
out dx,al
setport EN0_RCNTHI
pause_
mov al,ch
out dx,al
pop ax ; get our page back
setport EN0_RSARLO
pause_
out dx,al ; set as lo address
setport EN0_RSARHI
pause_
mov al,ah
out dx,al
setport EN_CCMD
pause_
mov al,ENC_RWRITE+ENC_START ; write and start
out dx,al
setport NE_DATAPORT
pause_
shr cx,2 ; dword count
db 0f3h, 066h, 06fh ;rep outsd
mov cx,0
setport EN0_ISR
tx_check_rdc:
in al,dx
test al,ENISR_RDC ; dma done ???
jnz tx_start
loop tx_check_rdc
stc
ret
tx_start:
clc
ret
include 8390.asm
public usage_msg
usage_msg db "usage: es3210 [-n] [-d] [-w] <packet_int_no> <int_level> <io_addr> <mem_base>",CR,LF,'$'
no_board_msg db "No es3210 detected.",CR,LF,'$'
io_addr_funny_msg label byte
db "No es3210 detected, continuing anyway.",CR,LF,'$'
public copyright_msg
copyright_msg db "Packet driver for es3210, version "
db '0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,".",'0'+dp8390_version,CR,LF,'$'
int_no_name db "Interrupt number ",'$'
io_addr_name db "I/O port ",'$'
mem_base_name db "Memory address ",'$'
extrn set_recv_isr: near
;enter with si -> argument string, di -> word to store.
;if there is no number, don't change the number.
extrn get_number: near
;enter with dx -> name of word, di -> dword to print.
extrn print_number: near
public parse_args
parse_args:
;exit with nc if all went well, cy otherwise.
mov di,offset int_no
call get_number
mov di,offset io_addr
call get_number
mov di,offset mem_base
call get_number
cmp io_addr,-1 ;Did they ask for auto-detect?
je find_board
call detect_board ;no, just verify its existance.
je find_board_found
mov dx,offset io_addr_funny_msg
mov ah,9
int 21h
jmp find_board_found
find_board:
mov io_addr,0c80h ;Search for the Ethernet address.
mov io_addr+2,0
find_board_0:
call detect_board
je find_board_found
find_board_again:
add io_addr,1000h ;not at this port, try another.
jnc find_board_0
mov dx,offset no_board_msg ;Tell them that we can't find it.
mov ah,9
int 21h
stc
ret
find_board_found:
clc
ret
extrn etopen_diagn: byte
init_card:
;get the board data. This is (16) bytes starting at remote
;dma address 0. Put it in a buffer called board_data.
assume ds:code
or endcfg,ENDCFG_WTS
push ds
pop es ; set es to ds
mov di,offset board_data
loadport ; Get our Ethernet address base.
setport EBASE
mov cx,EADDR_LEN
read_address_1:
insb ; get a byte of the eprom address
inc dx ; next register
loop read_address_1 ; go back for rest
push ds ; Copy from card's address to current address
pop es
mov si, offset board_data ; address is at start
mov di, offset curr_hw_addr
mov cx, EADDR_LEN ; Copy one address length
rep movsb ; ..
ret
public print_parameters
print_parameters:
;echo our command-line parameters
mov di,offset int_no
mov dx,offset int_no_name
call print_number
mov di,offset io_addr
mov dx,offset io_addr_name
call print_number
mov di,offset mem_base
mov dx,offset mem_base_name
call print_number
ret
detect_board:
;test to see if a board is located at io_addr.
;return nz if not.
loadport
setport EBASE
in al,dx ;Check for Interlan's prefix word.
cmp al,2
jne detect_board_exit
setport EBASE+1
in al,dx
cmp al,7
jne detect_board_exit
setport EBASE+EADDR_LEN ;first byte following should be 0
in al,dx
cmp al,0
jne detect_board_exit
setport EBASE+EADDR_LEN+1 ;second byte should be 55h
in al,dx
cmp al,55h
detect_board_exit:
ret
code ends
end