NETWORK - PKTD11B.ZIP - TAIL.ASM

 
Output of file : TAIL.ASM contained in archive : PKTD11B.ZIP

; PC/FTP Packet Driver source, conforming to version 1.05 of the spec
; Updated to version 1.08 Feb. 17, 1989.
; Copyright 1988-1993 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 word public
assume cs:code, ds:code

public is_eisa
is_eisa db 0 ;=0 if ISA, =1 if EISA
extrn sys_features: byte ;bitmask of system features.
extrn is_186: byte ;=0 if 808[68], =1 if 80[1234]86.
extrn is_286: byte ;=0 if 80[1]8[68], =1 if 80[234]86.
extrn is_386: byte ;=0 if 80[12]8[68], =1 if 80[34]86.
extrn int_no: byte ;the board's interrupt level.
extrn hw_int_no: byte ;the 8259 interrupt level.
extrn driver_class: byte ;the class of this driver, per the spec.
extrn rcv_modes: word ;count of modes followed by mode handles.

;-> last byte of static memory used by driver-dependent code.
extrn end_resident: byte
extrn end_free_mem: byte

;-> the fixed address of the card.
extrn rom_address: byte

;-> the current address of the card.
extrn my_address: byte

extrn phd_dioa: byte
extrn phd_environ: word
extrn flagbyte: byte

include printnum.asm
include decout.asm
include digout.asm
include crlf.asm
include chrout.asm

free_mem dw end_resident ;allocate memory from here.
;also see memory_to_keep.

public malloc
malloc:
;enter with dx = amount of memory desired.
;exit with nc, dx -> that memory, or cy if there isn't enough memory.
add dx,free_mem ;make a pointer after that much memory.
cmp dx,offset end_free_mem ;is it still in the free area?
ja malloc_1 ;no, we're in trouble.
xchg dx,free_mem ;get the pointer back, store ptr->end.
clc
ret
malloc_1:
stc
ret


end_tail_1 label byte ; end of the delayed init driver

;usage_msg is of the form "usage: driver [options] "
extrn usage_msg: byte

options_i_msg label byte
db" -i -- Force driver to report itself as IEEE 802.3 instead of Ethernet II.",CR,LF
options_msg label byte
db" -d -- Delayed initialization. Used for diskless booting",CR,LF
db" -n -- NetWare conversion. Converts 802.3 packets into 8137 packets",CR,LF
db" -w -- Windows hack, obsoleted by winpkt",CR,LF
db" -p -- Promiscuous mode disable",CR,LF
db" -u -- Uninstall",CR,LF
db '$'

;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-93, Crynwr Software.",CR,LF
db "This program is freely copyable; source must be available; NO WARRANTY.",CR,LF
db "See the file COPYING.DOC for details; send FAX to +1-315-268-9201 for a copy.",CR,LF
db CR,LF,'$'

no_resident_msg label byte
db CR,LF,"*** Packet driver failed to initialize the board ***",CR,LF,'$'

;parse_args should parse the arguments.
;called with ds:si -> immediately after the entry_point.
extrn parse_args: near

;print_parameters should print the arguments.
extrn print_parameters: near

extrn our_isr: near, their_isr: dword
extrn entry_point: byte

eisa_signature db "EISA"

system_msg db "System: ",'$'
i386_msg db "[345]86 processor",'$'
i286_msg db "286 processor",'$'
i186_msg db "186 processor",'$'
i8088_msg db "8088/8086 processor",'$'
mca_msg db ", Microchannel bus",'$'
eisa_msg db ", EISA bus",'$'
isa_msg db ", ISA bus",'$'
two_8259_msg db ", Two 8259s",'$'
entry_point_name db "Packet driver software interrupt is ",'$'
eaddr_msg db "My Ethernet address is ",'$'
aaddr_msg db "My ARCnet address is ",'$'

already_msg db CR,LF,"Error: there is already a packet driver (you may uninstall it using -u) at ",'$'
no_pkint_msg db CR,LF,"Error: there is no packet driver at ",'$'
no_pkt_msg db CR,LF,"Error: no packet driver found between 0x60 and 0x80",CR,LF,'$'
two_pkts_msg db CR,LF,"Error: there are two packets drivers (specify the desired one after -u).",CR,LF,'$'
int_msg db CR,LF
db "Error: should be between 0 and "
int_msg_num label word
db "15 inclusive", '$'
xt_hd_warn_msg db CR,LF,"Warning: the hard disk on an XT usually uses IRQ 5. Use a different interrupt",CR,LF,'$'
no_ieee_msg db CR,LF,"Error: this driver doesn't implement both IEEE 802.3 and Ethernet II",CR,LF,'$'
terminated_msg db "Uninstall completed",'$'

handle dw ?

entry_point_fnd db 0
bogus_type db 0,0 ;totally bogus type code.
our_recv:
xor di,di
mov es,di
retf

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

memory_to_keep dw end_resident ;keep at least this much memory.
;also see free_mem.

already_error:
mov dx,offset already_msg
already_error_1:
mov di,offset entry_point
call print_number
mov ax,4c05h ; give errorlevel 5
int 21h

usage_error:
mov dx,offset usage_msg
mov ah,9
int 21h
mov dx,offset options_msg
cmp word ptr driver_class,BLUEBOOK + IEEE8023*256 ;both present?
jne error
mov dx,offset options_i_msg
public error
error:
mov ah,9
int 21h
mov ax,4c0ah ; give errorlevel 10
int 21h

;;; include timeout.asm

public start_1
start_1:
cld

mov dx,offset copyright_msg
mov ah,9
int 21h

mov dx,offset copyleft_msg
mov ah,9
int 21h

mov dx,offset branding_msg
mov ah,9
int 21h

mov dx,0f000h ;ROM segment
mov es,dx
mov di,0ffd9h
mov si,offset eisa_signature
mov cx,2
repe cmpsw
jne not_eisa
inc is_eisa
not_eisa:

;
; 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
jc look_in_ROM ; error, must use rom.
or ah,ah
jnz look_in_ROM
mov dx,es:[bx] ; # of feature bytes
cmp dx,4 ; do we have the feature byte we want?
jae got_features ;yes.
look_in_ROM:
cmp byte ptr es:[0fffeh],0fch;is this an AT?
jne identified ;no.
or sys_features,TWO_8259 ; ATs have 2nd 8259
jmp identified ; assume no microchannel
got_features:
mov ah,es:[bx+2] ; model byte
cmp ah,0fch
je at_ps2
ja identified ; FD, FE and FF are not ATs
cmp ah,0f8h
je at_ps2
ja identified ; F9, FA and FB are not ATs
cmp ah,09ah
jbe identified ; 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
identified:

;Determine the processor type. The 8088 and 8086 will actually shift ax
;over by 33 bits, while the 80[123]86 use a shift count mod 32.
mov cl,33
mov ax,0ffffh
shl ax,cl ;186 or better?
jz processor_identified ;no.
mov is_186,1

push sp
pop ax
cmp ax,sp ;286 or better?
jne processor_identified ;no.
mov is_286,1

pushf
pop ax
or ax,7000h ;the 386 lets us set these bits
push ax
popf ;this should be a real popf.
pushf
pop ax
test ax,7000h ;did the bits get set?
je processor_identified
mov is_386,1

processor_identified:

mov si,offset phd_dioa+1
call skip_blanks ;end of line?
cmp al,CR
je usage_error_j_1

chk_options:
call skip_blanks
cmp al,'-' ; any options?
jne no_more_opt
inc si ; skip past option char
lodsb ; read next char
or al,20h ; convert to lower case
cmp al,'d'
jne not_d_opt
or flagbyte,D_OPTION
jmp chk_options
not_d_opt:
cmp al,'n'
jne not_n_opt
or flagbyte,N_OPTION
jmp chk_options
not_n_opt:
cmp al,'w'

jne not_w_opt
or flagbyte,W_OPTION
jmp chk_options
not_w_opt:
cmp al,'p'
jne not_p_opt
cmp rcv_modes,6 ;do they even *have* a promiscuous mode?
jbe chk_options ;no.
mov rcv_modes+2[6*2],0 ;yes, nuke it.
jmp chk_options
not_p_opt:
cmp al,'u'
jne not_u_opt
or flagbyte,U_OPTION
jmp chk_options
not_u_opt:
cmp al,'i'
jne not_i_opt
cmp word ptr driver_class,BLUEBOOK + IEEE8023*256 ;both present?
mov dx,offset no_ieee_msg
jne usage_error_j_1 ;no - give error
mov word ptr driver_class,IEEE8023 + BLUEBOOK*256 ;yes, swap them.
jmp chk_options
not_i_opt:
usage_error_j_1:
jmp usage_error
no_more_opt:

mov di,offset entry_point ;parse the packet interrupt number
call get_number ; for them.

test flagbyte,U_OPTION ;should we terminate the driver?
jne terminate
jmp not_terminate
terminate:

cmp entry_point,0 ;did they ask for the default?
jne terminate_int_ok ;no, run with it.

mov entry_point,60h
terminate_check_int:
call verify_packet_int
jc terminate_check_int_1
jne terminate_check_int_1
cmp entry_point_fnd,0 ;did we already find one?
jne terminate_check_int_2 ;yes, it's ambiguous - give error.
mov al,entry_point ;no, remember it.
mov entry_point_fnd,al
terminate_check_int_1:
inc entry_point ;go look at the next one
cmp entry_point,80h
jbe terminate_check_int ;keep going to the end.

mov al,entry_point_fnd ;restore the last one found.
mov entry_point,al
cmp entry_point_fnd,0 ;did we find one?
jne terminate_int_ok ;yes.
mov dx,offset no_pkt_msg ;no packet drivers installed!
jmp error
terminate_check_int_2:
mov dx,offset two_pkts_msg ;two packet drivers - which one??
jmp error

terminate_int_ok:
call verify_packet_int ;is the one they specified acceptable?
jnc terminate_1 ;no, it's not in range.
jmp error
terminate_1:
je terminate_2 ;go if we found a signature.
mov dx,offset no_pkint_msg ;no packet driver there.
jmp already_error_1
terminate_2:

mov their_isr.offs,bx
mov their_isr.segm,es


mov ax,1ffh ;driver_info
pushf
cli
call their_isr
call fatal_error
movseg ds,cs

mov ah,2 ;access_type
mov al,ch ;their class from driver_info().
mov bx,dx ;their type from driver_info().
mov dl,cl ;their number from driver_info().
mov cx,2 ;use type length 2.
mov si,offset bogus_type
movseg es,cs
mov di,offset our_recv
pushf
cli
call their_isr
call fatal_error
mov handle,ax

mov ah,5 ;terminate the driver.
mov bx,handle
pushf
cli
call their_isr
jnc now_close
call print_error
mov ah,3 ;release_type
mov bx,handle
pushf
cli
call their_isr
int 20h
now_close:
mov dx,offset terminated_msg
mov ah,9
int 21h
int 20h

usage_error_j_2:
jmp usage_error
not_terminate:

call parse_args
jc usage_error_j_2

call skip_blanks ;end of line?
cmp al,CR
jne usage_error_j_2

call verify_packet_int
jnc packet_int_ok
jmp error
packet_int_ok:
jne packet_int_unused
jmp already_error ;give an error if there's one there.
packet_int_unused:
;
; Verify that the interrupt number they gave is valid.
;
cmp int_no,15 ;can't possibly be > 15.
ja int_bad
test sys_features,TWO_8259 ; 2nd 8259 ?
jnz int_ok ;yes, no need to check for <= 7.
mov int_msg_num,'7'+' '*256 ;correct the error message, just in case.
cmp int_no,7 ;make sure that the packet interrupt
jbe int_ok_7 ; number is in range.
int_bad:
mov dx,offset int_msg
jmp error
int_ok_7:
cmp int_no,5 ;Are they trying to use irq 5 on an XT?
jne int_ok ;no.

push ds
mov ax,40h
mov ds,ax
mov al,ds:[75h] ;get the number of hard disks.
pop ds

or al,al ;do they have one?
je int_ok ;unbelievably, no.
mov dx,offset xt_hd_warn_msg
mov ah,9
int 21h
int_ok:

;
; Map IRQ 2 to IRQ 9 if needed.
;
test sys_features,TWO_8259 ; 2nd 8259 ?
je no_mapping_needed ;no, no mapping needed
cmp int_no,2 ;map IRQ 2 to IRQ 9.
jne no_mapping_needed
mov int_no,9
no_mapping_needed:

; If they chose the -d option, don't call etopen when we are loaded,
; but when we are called for the first time
;
; Save part of the tail, needed by delayed etopen
test flagbyte,D_OPTION
jz open_now
mov memory_to_keep,offset end_tail_1 ; save first part of tail
jmp delayed_open_1
open_now:
call etopen ;init the driver. If any errors,
;this routine returns cy.
jnc yes_resident
jmp no_resident

yes_resident:
mov si,offset rom_address ;copy their original address to
movseg es,ds
mov di,offset my_address ; their current address.
mov cx,MAX_ADDR_LEN/2
rep movsw

; tell them what kind of system they have.
mov dx,offset system_msg
mov ah,9
int 21h

mov dx,offset i386_msg
cmp is_386,0
jne have_processor
mov dx,offset i286_msg
cmp is_286,0
jne have_processor
mov dx,offset i186_msg
cmp is_186,0
jne have_processor
mov dx,offset i8088_msg
have_processor:
mov ah,9
int 21h

mov dx,offset mca_msg
test sys_features,SYS_MCA
jne have_bus
mov dx,offset eisa_msg
cmp is_eisa,0
jne have_bus
mov dx,offset isa_msg
have_bus:
mov ah,9
int 21h

test sys_features,TWO_8259
je only_one_8259
mov dx,offset two_8259_msg
mov ah,9
int 21h
only_one_8259:

call crlf

mov di,offset entry_point
mov dx,offset entry_point_name
call print_number

call print_parameters ;echo our parameters.
or flagbyte,CALLED_ETOPEN

cmp driver_class,BLUEBOOK ;Blue Book Ethernet?
je print_eaddr ;yes.
cmp driver_class,IEEE8023 ;IEEE 802.3 Ethernet?
jne print_addr_2 ;no, don't print what we don't have.

print_eaddr:
mov dx,offset eaddr_msg
mov ah,9
int 21h

mov si,offset rom_address
call print_ether_addr

call crlf

print_addr_2:

cmp driver_class,8 ;ARCnet?
jne print_addr_3 ;no, don't print what we don't have.

mov dx,offset aaddr_msg
mov ah,9
int 21h

mov al,rom_address
mov cl,' ' ;Don't eliminate leading zeroes.
call byteout

call crlf

print_addr_3:
delayed_open_1:
mov ah,35h ;remember their packet interrupt.
mov al,entry_point
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

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

test flagbyte,D_OPTION
jne f_release_type_1 ;no.
cmp rcv_modes+2[3*2],0 ;does mode 3 exist?
je f_release_type_1 ;no.
call rcv_modes+2[3*2] ; call it.
f_release_type_1:

mov dx,memory_to_keep ;keep the greater of this and
cmp dx,free_mem ; free_mem.
jae go_resident
mov dx,free_mem
go_resident:
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 ah,9 ;print their error message.
int 21h

mov dx,offset no_resident_msg
mov ah,9
int 21h

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


include verifypi.asm
include getnum.asm
include getdig.asm
include skipblk.asm
include printea.asm
include pkterr.asm
include getenv.asm

public branding_msg
branding_msg db '$'

code ends

end