home *** CD-ROM | disk | FTP | other *** search
- version equ 2
-
- include defs.asm
-
- ;Ported from Bill Doster's il.c, a C-language driver for the Interlan NI5010
- ;by Russell Nelson. Any bugs are due to Russell Nelson.
- ;Updated to version 1.08 Feb. 17, 1989 by Russell Nelson.
-
- ; 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.
-
- code segment word public
- assume cs:code, ds:code
-
- ; The various IE command registers
- EDLC_XSTAT equ 0 ; EDLC transmit csr
- EDLC_XCLR equ 0 ; EDLC transmit "Clear IRQ"
- EDLC_XMASK equ 1 ; EDLC transmit "IRQ Masks"
- EDLC_RSTAT equ 2 ; EDLC receive csr
- EDLC_RCLR equ 2 ; EDLC receive "Clear IRQ"
- EDLC_RMASK equ 3 ; EDLC receive "IRQ Masks"
- EDLC_XMODE equ 4 ; EDLC transmit Mode
- EDLC_RMODE equ 5 ; EDLC receive Mode
- EDLC_RESET equ 6 ; EDLC RESET register
- EDLC_TDR1 equ 7 ; "Time Domain Reflectometry" reg1
- EDLC_ADDR equ 8 ; EDLC station address, 6 bytes
- ; 0Eh doesn't exist for r/w
- EDLC_TDR2 equ 0fh ; "Time Domain Reflectometry" reg2
- IE_GP equ 10h ; GP pointer (word register)
- ; 11h is 2nd byte of GP Pointer
- IE_RCNT equ 10h ; Count of bytes in rcv'd packet
- ; 11h is 2nd byte of "Byte Count"
- IE_MMODE equ 12h ; Memory Mode register
- IE_DMA_RST equ 13h ; IE DMA Reset. write only
- IE_ISTAT equ 13h ; IE Interrupt Status. read only
- IE_RBUF equ 14h ; IE Receive Buffer port
- IE_XBUF equ 15h ; IE Transmit Buffer port
- IE_SAPROM equ 16h ; window on station addr prom
- IE_RESET equ 17h ; any write causes Board Reset
-
- ; bits in EDLC_XSTAT, interrupt clear on write, status when read
- XS_TPOK equ 80h ; transmit packet successful
- XS_CS equ 40h ; carrier sense
- XS_RCVD equ 20h ; transmitted packet received
- XS_SHORT equ 10h ; transmission media is shorted
- XS_UFLW equ 08h ; underflow. iff failed board
- XS_COLL equ 04h ; collision occurred
- XS_16COLL equ 02h ; 16th collision occurred
- XS_PERR equ 01h ; parity error
-
- XS_CLR_UFLW equ 08h ; clear underflow
- XS_CLR_COLL equ 04h ; clear collision
- XS_CLR_16COLL equ 02h ; clear 16th collision
- XS_CLR_PERR equ 01h ; clear parity error
-
- ; bits in EDLC_XMASK, mask/enable transmit interrupts. register is r/w
- XM_TPOK equ 80h ; =1 to enable Xmt Pkt OK interrupts
- XM_RCVD equ 20h ; =1 to enable Xmt Pkt Rcvd ints
- XM_UFLW equ 08h ; =1 to enable Xmt Underflow ints
- XM_COLL equ 04h ; =1 to enable Xmt Collision ints
- XM_COLL16 equ 02h ; =1 to enable Xmt 16th Coll ints
- XM_PERR equ 01h ; =1 to enable Xmt Parity Error ints
- ; note: always clear this bit
-
- ; bits in EDLC_RSTAT, interrupt clear on write, status when read
- RS_PKT_OK equ 80h ; received good packet
- RS_RST_PKT equ 10h ; RESET packet received
- RS_RUNT equ 08h ; Runt Pkt rcvd. Len < 64 Bytes
- RS_ALIGN equ 04h ; Alignment error. not 8 bit aligned
- RS_CRC_ERR equ 02h ; Bad CRC on rcvd pkt
- RS_OFLW equ 01h ; overflow for rcv FIFO
- RS_VALID_BITS equ RS_PKT_OK or RS_RST_PKT or RS_RUNT or RS_ALIGN or RS_CRC_ERR or RS_OFLW
- ; all valid RSTAT bits
-
- RS_CLR_PKT_OK equ 80h ; clear rcvd packet interrupt
- RS_CLR_RST_PKT equ 10h ; clear RESET packet received
- RS_CLR_RUNT equ 08h ; clear Runt Pckt received
- RS_CLR_ALIGN equ 04h ; clear Alignment error
- RS_CLR_CRC_ERR equ 02h ; clear CRC error
- RS_CLR_OFLW equ 01h ; clear rcv FIFO Overflow
-
- ; bits in EDLC_RMASK, mask/enable receive interrupts. register is r/w
- RM_PKT_OK equ 80h ; =1 to enable rcvd good packet ints
- RM_RST_PKT equ 10h ; =1 to enable RESET packet ints
- RM_RUNT equ 08h ; =1 to enable Runt Pkt rcvd ints
- RM_ALIGN equ 04h ; =1 to enable Alignment error ints
- RM_CRC_ERR equ 02h ; =1 to enable Bad CRC error ints
- RM_OFLW equ 01h ; =1 to enable overflow error ints
-
- ; bits in EDLC_RMODE, set Receive Packet mode. register is r/w
- RMD_TEST equ 80h ; =1 for Chip testing. normally 0
- RMD_ADD_SIZ equ 10h ; =1 5-byte addr match. normally 0
- RMD_EN_RUNT equ 08h ; =1 enable runt rcv. normally 0
- RMD_EN_RST equ 04h ; =1 to rcv RESET pkt. normally 0
-
- RMD_PROMISC equ 03h ; receive *all* packets. unusual
- RMD_MULTICAST equ 02h ; receive multicasts too. unusual
- RMD_BROADCAST equ 01h ; receive broadcasts & normal. usual
- RMD_NO_PACKETS equ 00h ; don't receive any packets. unusual
-
- ; bits in EDLC_XMODE, set Transmit Packet mode. register is r/w
- XMD_COLL_CNT equ 0f0h ; coll's since success. read-only
- XMD_IG_PAR equ 008h ; =1 to ignore parity. ALWAYS set
- XMD_T_MODE equ 004h ; =1 to power xcvr. ALWAYS set this
- XMD_LBC equ 002h ; =1 for loopbakc. normally set
- XMD_DIS_C equ 001h ; =1 disables contention. normally 0
-
- ; bits in EDLC_RESET, write only
- RS_RESET equ 80h ; =1 to hold EDLC in reset state
-
- ; bits in IE_MMODE, write only
- MM_EN_DMA equ 80h ; =1 begin DMA xfer, Cplt clrs it
- MM_EN_RCV equ 40h ; =1 allows Pkt rcv. clr'd by rcv
- MM_EN_XMT equ 20h ; =1 begin Xmt pkt. Cplt clrs it
- MM_BUS_PAGE equ 18h ; =00 ALWAYS. Used when MUX=1
- MM_NET_PAGE equ 06h ; =00 ALWAYS. Used when MUX=0
- MM_MUX equ 01h ; =1 means Rcv Buff on system bus
- ; =0 means Xmt Buff on system bus
-
- ; bits in IE_ISTAT, read only
- IS_TDIAG equ 80h ; =1 if Diagnostic problem
- IS_EN_RCV equ 20h ; =1 until frame is rcv'd cplt
- IS_EN_XMT equ 10h ; =1 until frame is xmt'd cplt
- IS_EN_DMA equ 08h ; =1 until DMA is cplt or aborted
- IS_DMA_INT equ 04h ; =0 iff DMA done interrupt.
- IS_R_INT equ 02h ; =0 iff unmasked Rcv interrupt
- IS_X_INT equ 01h ; =0 iff unmasked Xmt interrupt
-
- BFRSIZ equ 2048 ;number of bytes in a buffer
-
- public int_no
- int_no db 3,0,0,0 ; interrupt number.
- io_addr dw 0300h,0 ; I/O address for card (jumpers)
- ipkt_size dw ?
- opkt_size dw ?
-
- public driver_class, driver_type, driver_name, driver_function, parameter_list
- driver_class db BLUEBOOK, IEEE8023, 0 ;from the packet spec
- driver_type db 3 ;from the packet spec
- driver_name db 'NI5010',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,
-
- public rcv_modes
- rcv_modes dw 7 ;number of receive modes in our table.
- dw 0 ;There is no mode zero
- dw rcv_mode_1
- dw 0 ;don't want to bother.
- dw rcv_mode_3
- dw 0 ;haven't set up perfect filtering yet.
- dw rcv_mode_5
- dw rcv_mode_6
-
- extrn is_186: byte ;=0 if 808[68], =1 if 80[123]86.
- our_type dw ?,?
- intstat db ?
-
- include popf.asm
- include io8.asm
-
- public bad_command_intercept
- bad_command_intercept:
- ;called with ah=command, unknown to the skeleton.
- ;exit with nc if okay, cy, dh=error if not.
- mov dh,BAD_COMMAND
- stc
- ret
-
- public as_send_pkt
- ; The Asynchronous Transmit Packet routine.
- ; Enter with es:di -> i/o control block, ds:si -> packet, cx = packet length,
- ; interrupts possibly enabled.
- ; Exit with nc if ok, or else cy if error, dh set to error number.
- ; es:di and interrupt enable flag preserved on exit.
- as_send_pkt:
- ret
-
- public drop_pkt
- ; Drop a packet from the queue.
- ; Enter with es:di -> iocb.
- drop_pkt:
- assume ds:nothing
- ret
-
- public xmit
- ; Process a transmit interrupt with the least possible latency to achieve
- ; back-to-back packet transmissions.
- ; May only use ax and dx.
- xmit:
- assume ds:nothing
- ret
-
-
- public send_pkt
- send_pkt:
- ;enter with es:di->upcall routine, (0:0) if no upcall is desired.
- ; (only if the high-performance bit is set in driver_function)
- ;enter with ds:si -> packet, cx = packet length.
- ;exit with nc if ok, or else cy if error, dh set to error number.
- assume ds:nothing
- cmp cx,GIANT ; Is this packet too large?
- ja send_pkt_toobig
-
- cmp cx,RUNT ; minimum length for Ether
- jae oklen
- mov cx,RUNT ; make sure size at least RUNT
- oklen:
- ;Wait for transmitter ready, if necessary. IE_XMTBSY is valid
- ;only in the transmit mode, hence the initial check.
-
- loadport
- setport IE_ISTAT
- in al,dx
- and al,IS_EN_XMT ;on-going xmit
- je send_pkt_2
-
- mov bx,20000 ;try this many times.
- send_pkt_3:
- in al,dx ;if not busy, exit.
- and al,IS_EN_XMT
- je send_pkt_2
- dec bx
- jne send_pkt_3
- mov dh,CANT_SEND ;timed out, can't send.
- stc
- ret
-
- send_pkt_toobig:
- mov dh,NO_SPACE
- stc
- ret
-
- send_pkt_2:
-
- pushf ; No distractions from the receiver
- cli
-
- ; Disable the Receiver
- mov al, 0 ; Mask all Receive Interrupts
- loadport
- setport EDLC_RMASK
- out dx,al
-
- mov al, 0 ; Put Xmt Buffer on System Bus
- setport IE_MMODE
- out dx,al
-
- mov al, 0FFh ; Clear out any pending Rcv Ints
- setport EDLC_RCLR
- out dx,al
-
- mov ax, BFRSIZ ; Point GP at beginning of packet
- sub ax,cx
- setport IE_GP
- out dx,ax
-
- setport IE_XBUF
-
- mov opkt_size,cx ; opkt_size = cx;
- call repoutsb
-
- ; Rewrite where packet starts
- mov ax,BFRSIZ
- sub ax,opkt_size
- setport IE_GP
- out dx,ax
-
- ; Flip Xmt Buffer to EDLC Bus so it can be transmitted
- mov al, MM_MUX
- setport IE_MMODE
- out dx,al
-
- ; Begin transmission.
- mov al, MM_EN_XMT or MM_MUX
- setport IE_MMODE
- out dx,al
-
- ; Cause interrupt after completion (or if something fails)
- mov al, XM_TPOK or XM_RCVD or XM_UFLW or XM_COLL or XM_COLL16
- setport EDLC_XMASK
- out dx,al
-
- popf
- clc
- ret
-
-
- ;Set Ethernet address on controller
- public set_address
- set_address:
- assume ds:nothing
- ;enter with ds:si -> Ethernet address, CX = length of address.
- ;exit with nc if okay, or cy, dh=error if any errors.
- ;
- cmp cx,EADDR_LEN ;ensure that their address is okay.
- je set_address_4
- mov dh,BAD_ADDRESS
- stc
- jmp short set_address_done
- set_address_4:
-
- loadport
- setport EDLC_ADDR
- set_address_1:
- lodsb
- out dx,al
- inc dx
- loop set_address_1
- set_address_okay:
- mov cx,EADDR_LEN ;return their address length.
- clc
- set_address_done:
- movseg ds,cs
- assume ds:code
- ret
-
-
- ;skip past the following two bytes while destroying BX.
- skip2 macro
- db 0bbh ;opcode of "mov bx,0000"
- endm
-
- rcv_mode_1:
- mov al,RMD_NO_PACKETS ;receive nothing
- skip2
- rcv_mode_3:
- mov al,RMD_BROADCAST ;receive individual address+broadcast
- skip2
- rcv_mode_5:
- mov al,RMD_MULTICAST ;receive individual address+group addr(multicast)
- skip2
- rcv_mode_6:
- mov al,RMD_PROMISC + RMD_EN_RUNT ;receive all packets (incl runts).
- loadport
- setport EDLC_RMODE
- out dx,al
- in al,dx ;flush status.
- ret
-
-
- public set_multicast_list
- set_multicast_list:
- ;enter with ds:si ->list of multicast addresses, ax = number of addresses,
- ; cx = number of bytes.
- ;return nc if we set all of them, or cy,dh=error if we didn't.
- mov dh,NO_MULTICAST
- stc
- ret
-
-
- public terminate
- terminate:
- ; put card in held-RESET state
- loadport
- setport IE_MMODE
- mov al,0
- out dx,al
-
- setport EDLC_RESET
- mov al,RS_RESET
- out dx,al
-
- ret
-
-
- public reset_interface
- reset_interface:
- ;reset the interface.
- ;we don't do anything.
- ret
-
-
- ;called when we want to determine what to do with a received packet.
- ;enter with cx = packet length, es:di -> packet type, dl = packet class.
- extrn recv_find: near
-
- ;called after we have copied the packet into the buffer.
- ;enter with ds:si ->the packet, cx = length of the packet.
- extrn recv_copy: near
-
- ;call this routine to schedule a subroutine that gets run after the
- ;recv_isr. This is done by stuffing routine's address in place
- ;of the recv_isr iret's address. This routine should push the flags when it
- ;is entered, and should jump to recv_exiting_exit to leave.
- ;enter with ax = address of routine to run.
- extrn schedule_exiting: near
-
- ;recv_exiting jumps here to exit, after pushing the flags.
- extrn recv_exiting_exit: near
-
- extrn count_in_err: near
- extrn count_out_err: near
-
- public recv
- recv:
- ;called from the recv isr. All registers have been saved, and ds=cs.
- ;Upon exit, the interrupt will be acknowledged.
- assume ds:code
-
- loadport
- setport IE_ISTAT
- in al,dx
- mov intstat,al
-
- ; DMA Complete Interrupt. We don't use DMA, but just in case ...
- test al,IS_DMA_INT
- jne recv_isr_3
-
- mov al, 0 ; Reset DMA Interrupt
- setport IE_DMA_RST
- out dx,al
-
- recv_isr_3:
-
- ; Transmit Complete/Fail Interrupt
- test intstat,IS_X_INT
- jne recv_isr_1
-
- loadport
- setport EDLC_XSTAT
- in al,dx
- mov ah,al
-
- mov al, 0 ; Disable Xmt IRQ's
- setport EDLC_XMASK
- out dx,al
-
- mov al, 0FFh ; clr all Xmt IRQ's
- setport EDLC_XCLR
- out dx,al
-
- test ah,XS_COLL
- je recv_isr_1
- ;Crank counter back to beginning and restart xmt
-
- mov ax,BFRSIZ ; Point GP at beginning of packet
- sub ax,opkt_size
- setport IE_GP
- out dx,ax
-
- mov al, 0 ; De-assert MM_EN_RCV bit Just In Case
- setport IE_MMODE
- out dx,al
-
- ; Flip Xmt Buffer to EDLC Bus and restart xmt
- mov al, MM_EN_XMT or MM_MUX
- setport IE_MMODE
- out dx,al
-
- ; Interrupt for all Transmit errors along with TPOK
- mov al, XM_TPOK or XM_RCVD or XM_UFLW or XM_COLL or XM_COLL16
- setport EDLC_XMASK
- out dx,al
-
- ret ; Wait for it to complete again
-
- recv_isr_1:
- ; Is this a Receive Packet Interrupt?
- test intstat,IS_R_INT
- jne recv_isr_9_j_1 ;no.
-
- loadport
- setport EDLC_RSTAT ;get the status of this packet
- in al,dx
- and al,RS_VALID_BITS
- cmp al,RS_PKT_OK ;is it ok?
- jne recv_isr_7 ;yes.
-
- ; Clear the interrupt
- mov al, 0FFh
- setport EDLC_RCLR
- out dx,al
-
- ; Flip Rcv Buffer onto the system bus
- mov al, MM_MUX
- setport IE_MMODE
- out dx,al
-
- ; Get the size of the packet.
- setport IE_RCNT
- in ax,dx
- mov ipkt_size,ax
-
- cmp ax,GIANT ;greater than GIANT?
- jbe recv_isr_8 ;no.
- recv_isr_7:
- call count_in_err
- recv_isr_9_j_1:
- jmp recv_isr_9
- recv_isr_8:
- ;Put it on the receive queue
-
- loadport
- mov ax,EADDR_LEN+EADDR_LEN ;seek to the type word.
- setport IE_GP
- out dx,ax
-
- setport IE_RBUF
- in al,dx ;read the type word out of the board.
- mov ah,al
- in al,dx
- xchg al,ah ;should be in network byte order.
- mov our_type,ax
- in al,dx ;read the type word out of the board.
- mov ah,al
- in al,dx
- xchg al,ah ;should be in network byte order.
- mov our_type+2,ax
-
- mov ax,ds ;look up our type.
- mov es,ax
- mov di,offset our_type
- mov cx,ipkt_size
-
- mov dl, BLUEBOOK ;assume bluebook Ethernet.
- mov ax, es:[di]
- xchg ah, al
- cmp ax, 1500
- ja BlueBookPacket
- inc di ;set di to 802.2 header
- inc di
- mov dl, IEEE8023
- BlueBookPacket:
- call recv_find
-
- mov ax,es ;is this pointer null?
- or ax,di
- je recv_isr_9 ;yes - just free the frame.
-
- push es ;remember where the buffer pointer is.
- push di
-
- xor ax,ax ;seek to the beginning again.
- loadport
- setport IE_GP
- out dx,ax
-
- mov cx,ipkt_size
- setport IE_RBUF
-
- call repinsb
-
- pop si
- pop ds
- assume ds:nothing
- mov cx,ipkt_size
- call recv_copy ;tell them that we copied it.
-
- mov ax,cs ;restore our ds.
- mov ds,ax
- assume ds:code
-
- recv_isr_9:
-
- ; Prime Interlan card for another Receive
- il_rcv_reset:
-
- ; Rcv packet at start of Boards buffer
- mov ax,0
- loadport
- setport IE_GP
- out dx,ax
-
- ; Clear any remaining Interrupt conditions
- mov al,0FFh
- setport EDLC_RCLR
- out dx,al
-
- ; Set MUX to allow EDLC to access Rcv Buffer
- mov al,0
- setport IE_MMODE
- out dx,al
-
- ;
- ; Next section commented out to make promiscous mode work.
- ; It makes no sense to reset the receive mode after each
- ; received packet. M.K.
- ;
- ; Enable Receive of Normal and Broadcast Packets only.
- ; mov al,RMD_BROADCAST
- ; setport EDLC_RMODE
- ; out dx,al
-
- ; Enable Receive Interrupts
- mov al,MM_EN_RCV
- setport IE_MMODE
- out dx,al
-
- ; Unmask *all* Receive related interrupts
- mov al,0FFh
- setport EDLC_RMASK
- out dx,al
-
- ret
-
-
- public timer_isr
- timer_isr:
- ;if the first instruction is an iret, then the timer is not hooked
- iret
-
- ;any code after this will not be kept. Buffers used by the program, if any,
- ;are allocated from the memory between end_resident and end_free_mem.
- public end_resident,end_free_mem
- end_resident label byte
- end_free_mem label byte
-
- public usage_msg
- usage_msg db "usage: NI5010 [options] <packet_int_no> <hardware_irq> <io_addr>",CR,LF,'$'
-
- public copyright_msg
- copyright_msg db "Packet driver for the Interlan NI5010, version ",'0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,CR,LF
- db "Portions Copyright 1988 Bill Doster",CR,LF,CR,LF
- db "Promiscous mode fixed by Martin Knoblauch (22-Aug-90).",CR,LF
- db "Flame <XBR2D96D@DDATHD21.BITNET> for related problems",CR,LF,CR,LF,'$'
-
- no_ni5010_msg db "No NI5010 found at that address.",CR,LF,'$'
- ether_bdcst db EADDR_LEN dup(-1) ;ethernet broadcast address.
-
- int_no_name db "Interrupt number ",'$'
- io_addr_name db "I/O port ",'$'
-
- extrn set_recv_isr: near
- extrn maskint: 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
-
- ;-> the assigned Ethernet address of the card.
- extrn rom_address: byte
-
- 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
- clc
- ret
-
-
- no_ni5010_error:
- mov dx,offset no_ni5010_msg
- stc
- ret
-
-
- public etopen
- etopen:
- ; Initialize the Ethernet board, set receive type.
- ;
- ; check for correct EPROM location
- ;
- mov al,int_no
- call maskint ;disable these interrupts.
-
- ; Hold up EDLC RESET while the board is configured
- mov al,RS_RESET
- loadport
- setport EDLC_RESET
- out dx,al
-
- ; Hardware reset of Interlan Board
- mov al,0
- setport IE_RESET
- out dx,al
-
- call set_recv_isr
-
- mov al,XMD_LBC
- loadport
- setport EDLC_XMODE
- out dx,al
-
- movseg es,ds
- mov di,offset rom_address
- mov cx,EADDR_LEN+3 ;get three extra signature bytes.
- xor bx,bx
- get_address_1:
- mov ax,bx
- loadport
- setport IE_GP
- out dx,ax
-
- setport IE_SAPROM
- in al,dx
- stosb
- inc bx
- loop get_address_1
-
- mov si,offset rom_address
- mov cx,EADDR_LEN
- call set_address
-
- ;See if there really is a ni5010 there.
- cmp rom_address+EADDR_LEN+0,0
- jne no_ni5010
- cmp rom_address+EADDR_LEN+1,055h
- jne no_ni5010
- cmp rom_address+EADDR_LEN+2,0aah
- jne no_ni5010
-
- mov cx,EADDR_LEN
- mov di,offset ether_bdcst
- repe cmpsb
- jne have_ni5010 ;not broadcast address -- must be real.
- no_ni5010:
- jmp no_ni5010_error ;not there -- no ni5010.
- have_ni5010:
-
- ; Only enable Transmit-type interrupts while Transmitting
- mov al,0
- loadport
- setport EDLC_XMASK
- out dx,al
-
- ; Establish generic Transmit mode
- mov al,XMD_IG_PAR or XMD_T_MODE or XMD_LBC
- setport EDLC_XMODE
- out dx,al
-
- ; Clear any startup related Transmit interrupts
- mov al,0FFh
- setport EDLC_XCLR
- out dx,al
-
- ; Establish generic Receive mode
- mov al,RMD_BROADCAST
- setport EDLC_RMODE
- out dx,al
-
- ; Reset Rcv State to allow receives
- call il_rcv_reset
-
- ; Finally un-reset the EDLC
- mov al,0
- loadport
- setport EDLC_RESET
- out dx,al
-
- mov al, int_no ; Get board's interrupt vector
- add al, 8
- cmp al, 8+8 ; Is it a slave 8259 interrupt?
- jb set_int_num ; No.
- add al, 70h - 8 - 8 ; Map it to the real interrupt.
- set_int_num:
- xor ah, ah ; Clear high byte
- mov int_num, ax ; Set parameter_list int num.
-
- clc
- 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
- ret
-
- code ends
-
- end
-