home *** CD-ROM | disk | FTP | other *** search
- ; 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] <packet_int_no> <args>"
- 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: <hardware_irq> 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
-