home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
lan
/
driver6s
/
tail.asm
< prev
next >
Wrap
Assembly Source File
|
1990-04-13
|
10KB
|
352 lines
; PC/FTP Packet Driver source, conforming to version 1.05 of the spec
; Russell Nelson, Clarkson University. July 20, 1988
; Updated to version 1.08 Feb. 17, 1989.
; Copyright 1988,1989 Russell Nelson
; 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
code segment byte public
assume cs:code, ds:code
extrn phd_dioa: byte
extrn phd_environ: word
;usage_msg is of the form "usage: driver <packet_int_no> <args>"
extrn usage_msg: byte
;copyright_msg is of the form:
;"Packet driver for the foobar",CR,LF
;"Portions Copyright 19xx, J. Random Hacker".
extrn copyright_msg: byte
copyleft_msg label byte
db "Packet driver skeleton copyright 1988-90, Russell Nelson.",CR,LF
db "This program is free software; see the file COPYING for details.",CR,LF
db "NO WARRANTY; see the file COPYING for details.",CR,LF
crlf_msg db CR,LF,'$'
;parse_args should parse the arguments.
;called with ds:si -> immediately after the packet_int_no.
extrn parse_args: near
extrn our_isr: near, their_isr: dword
extrn packet_int_no: byte
extrn is_at: byte, sys_features: byte
extrn int_no: byte
extrn driver_class: byte
location_msg db "Packet driver loaded at segment ",'$'
packet_int_no_name db "Packet interrupt number ",'$'
eaddr_msg db "My Ethernet address is ",'$'
aaddr_msg db "My ARCnet address is ",'$'
signature db 'PKT DRVR',0
signature_len equ $-signature
already_msg db CR,LF,"There is already a packet driver at ",'$'
packet_int_msg db CR,LF
db "Error: <packet_int_no> should be in the range 0x60 to 0x80"
db '$'
int_msg db CR,LF
db "Error: <int_no> should be no larger than "
int_msg_num label word
db "xx"
db '$'
our_address db EADDR_LEN dup(?)
public etopen_diagn
etopen_diagn db 0 ; errorlevel from etopen if set
;etopen should initialize the device. If it needs to give an error, it
;can issue the error message and quit to dos.
extrn etopen: near
;get the address of the interface.
;enter with es:di -> place to get the address, cx = size of address buffer.
;exit with nc, cx = actual size of address, or cy if buffer not big enough.
extrn get_address: near
already_error:
mov dx,offset already_msg
mov di,offset packet_int_no
call print_number
mov ax,4c05h ; give errorlevel 5
int 21h
usage_error:
mov dx,offset usage_msg
public error
error:
mov ah,9
int 21h
mov ax,4c0ah ; give errorlevel 10
int 21h
public start_1
start_1:
mov dx,offset copyright_msg
mov ah,9
int 21h
mov dx,offset copyleft_msg
mov ah,9
int 21h
mov si,offset phd_dioa+1
call skip_blanks ;end of line?
cmp al,CR
je usage_error
;print the location we were loaded at.
mov dx,offset location_msg
mov ah,9
int 21h
mov ax,cs ;print cs as a word.
call wordout
mov dx,offset crlf_msg
mov ah,9
int 21h
mov di,offset packet_int_no ;parse the packet interrupt number
mov bx,offset packet_int_no_name
call get_number ; for them.
call parse_args
jc usage_error
call skip_blanks ;end of line?
cmp al,CR
jne usage_error
mov dx,offset packet_int_msg;make sure that the packet interrupt
cmp packet_int_no,60h ; number is in range.
jb error
cmp packet_int_no,80h
ja error
mov ah,35h ;get their packet interrupt.
mov al,packet_int_no
int 21h
lea di,3[bx] ;see if there is already a signature
mov si,offset signature ; there.
mov cx,signature_len
repe cmpsb
jne not_one_yet
jmp already_error ;yes, so we can't go there.
not_one_yet:
;
; Get the feature byte (if reliable) so we can know if it is a microchannel
; computer and how many interrupts there are
mov ah,0c0h
int 15h ; es:bx <- sys features block
mov al,7 ;maximum interrupt on a PC
mov int_msg_num,'7'+' '*256
jc look_in_ROM
mov dx,es:[bx] ; # of feature bytes
cmp dx,4
jae got_features
look_in_ROM:
mov dx,0f000h ;ROM segment
mov es,dx
cmp byte ptr es:[0fffeh],0fch ;is this an AT?
jne not_at ;no.
or sys_features,040h ; ATs have 2nd 8259
jmp isa_at ; assume no microchannel
got_features:
mov ah,es:[bx+2] ; model byte
cmp ah,0fch
je at_ps2
ja not_at ; FD, FE and FF are not ATs
cmp ah,0f8h
je at_ps2
ja not_at ; F9, FA and FB are not ATs
cmp ah,09ah
jb not_at ; old non-AT Compacs go here
at_ps2: ; 9B - F8 and FC are assumed to
mov ah,es:[bx+5] ; have reliable feature byte
mov sys_features,ah
test sys_features,040h ; 2nd 8259 ?
jz not_at
isa_at:
inc is_at
mov al,15 ;maximum interrupt on an AT
mov int_msg_num,'1'+'5'*256
cmp int_no,2 ;map IRQ 2 to IRQ 9.
jne not_at
mov int_no,9
not_at:
mov dx,offset int_msg ;make sure that the packet interrupt
cmp int_no,al ; number is in range.
jbe int_ok
jmp error
int_ok:
call etopen ;init the driver. If any errors,
;this routine returns cy.
jnc yes_resident
jmp no_resident
yes_resident:
push dx ;remember where they want to end.
mov ah,35h ;remember their packet interrupt.
mov al,packet_int_no
int 21h
mov their_isr.offs,bx
mov their_isr.segm,es
mov ah,25h ;install our packet interrupt
mov dx,offset our_isr
int 21h
cmp driver_class,1 ;Ethernet?
jne print_addr_2 ;no, don't print what we don't have.
push ds
pop es
mov di,offset our_address
mov cx,EADDR_LEN
call get_address
mov dx,offset eaddr_msg
mov ah,9
int 21h
mov si,offset our_address
call print_ether_addr
mov dx,offset crlf_msg ;can't depend on DOS to newline for us.
mov ah,9
int 21h
print_addr_2:
cmp driver_class,8 ;ARCnet?
jne print_addr_3 ;no, don't print what we don't have.
push ds
pop es
mov di,offset our_address
mov cx,ARCADDR_LEN
call get_address
mov dx,offset aaddr_msg
mov ah,9
int 21h
mov al,our_address
mov cl,' ' ;Don't eliminate leading zeroes.
call byteout
mov dx,offset crlf_msg ;can't depend on DOS to newline for us.
mov ah,9
int 21h
print_addr_3:
mov ah,49h ;free our environment, because
mov es,phd_environ ; we won't need it.
int 21h
mov bx,1 ;get the stdout handle.
mov ah,3eh ;close it in case they redirected it.
int 21h
pop dx ;get their ending address.
add dx,0fh ;round up to next highest paragraph.
mov cl,4
shr dx,cl
mov ah,31h ;terminate, stay resident.
mov al,etopen_diagn ; errorlevel (0 - 9, just diagnostics)
int 21h
no_resident:
mov ax,4c00h + 32 ; give errorlevel 32
cmp al,etopen_diagn
ja no_et_diagn ; etopen gave specific reason?
mov al,etopen_diagn ; yes, use that for error level
no_et_diagn:
int 21h
; Suggested errorlevels:
;
; _____________________ 0 = normal
; 1 = unsuitable memory address given; corrected
; In most cases every- 2 = unsuitable IRQ level given; corrected
; thing should work as 3 = unsuitable DMA channel given; corrected
; expected for lev 1-5 4 = unsuitable IO addr given; corrected (only 1 card)
; _____________________ 5 = packet driver for this int # already loaded
; External errors, when 20 = general cable failure (but pkt driver is loaded)
; corrected normal 21 = network cable is open -"-
; operation starts 22 = network cable is shorted -"-
; _____________________ 23 =
; Packet driver not 30 = usage message
; loaded. A new load 31 = arguments out of range
; attempt must be done 32 = unspecified device initialization error
; 33 =
; 34 = suggested memory already occupied
; 35 = suggested IRQ already occupied
; 36 = suggested DMA channel already occupied
; 37 = could not find the network card at this IO address
public print_number
print_number:
;enter with dx -> dollar terminated name of number, di ->dword.
;exit with the number printed and the cursor advanced to the next line.
mov ah,9 ;print the name of the number.
int 21h
mov al,'0'
call chrout
mov al,'x'
call chrout
mov ax,[di] ;print the number in hex.
mov dx,[di+2]
call dwordout
mov al,' '
call chrout
mov al,'('
call chrout
mov ax,[di] ;print the number in decimal.
mov dx,[di+2]
call decout
mov al,')'
call chrout
mov al,CR
call chrout
mov al,LF
call chrout
ret
include getnum.asm
include getdig.asm
include skipblk.asm
include decout.asm
include digout.asm
include chrout.asm
include printea.asm
code ends
end