Metropoli BBS
VIEWER: oditrpkt.asm MODE: TEXT (ASCII)
; oditrpkt.ASM - Adapter provides Packet Driver interface over ODI
;
; (c) Copyright Daniel D. Lanciani 1991-1992.  All rights reserved.
;
; This unmodified source file and its executable form may be used and
; redistributed freely.  The source may be modified, and the source or
; executable versions built from the modified source may be used and
; redistributed, provided that this notice and the copyright displayed by
; the exectuable remain intact, and provided that the executable displays
; an additional message indicating that it has been modified, and by whom.
;
; Daniel D. Lanciani releases this software "as is", with no express or
; implied warranty, including, but not limited to, the implied warranties
; of merchantability and fitness for a particular purpose.
;
; This source has been modifyed by Ben James to provide Token-Ring_SNAP to 
; Ethernet class 1 packet conversion.  This source was modified using 
; computers belonging to Oklahoma State University - Computer Center - 
; Communications Department.  I release it under the same conditions as 
; the origional.
; 
version equ     1       ; for driver_info
iftype  equ     71      ; for driver_info/access_type
nhand   equ     8       ; max active handles
mmatch  equ     8       ; max length of header match
mmulti  equ     8       ; max multicast addresses
pkvec   equ     61h     ; default control vector
xbsize  equ     4096    ; max receive frame size
stksw   equ     1       ; switch stacks in upcall
nopid   equ     1       ; use prescan/default instead of pid
defstk  equ     1       ; use default instead of prescan
;debug   equ     1
headersize      equ     24
send_buf_swap   equ     1

GET_STACK_CONFIGURATION         equ     0
GET_STACK_STATISTICS            equ     1
;BIND_TO_MLID                    equ     2
;UNBIND_FROM_MLID                equ     3
;INFORM_MLID_DEREGISTERED        equ     4

LSLERR_OUT_OF_RESOURCES equ     8001h

ifndef  nopid
StackInfoStruc  Struc
	StackNamePtr            dd      0
	StackReceiveHandler     dd      0
	StackControlHandler     dd      0
StackInfoStruc  ends
endif

ProtocolConfigStructure struc
	PConfigTableMajorVer    db      1 
	PConfigTableMinorVer    db      0
	PProtocolLongName       db      8, 'ODITRPKT', 0
	PProtocolShortName      db      5, 'TCPIP',0
	PProtocolMajorVer       db      1
	PProtocolMinorVer       db      0
	PConfigTableReserved    db      16 dup (0)
ProtocolConfigStructure ends

ProtocolStatStructure   struc
	PStatTableMajorVer      db      1
	PStatTableMinorVer      db      0
	PNumGenericCounters     dw      3
	PValidCounterMask       dd      111b
	PTotalTxPackets         dw      2 dup (0)
	PTotalRxPackets         dw      2 dup (0)
	PIgnoredRxPackets       dw      2 dup (0)
	PNumCustomCounters      dw      0
ProtocolStatStructure   ends

hinfo   struc                   ; per-handle data
nmatch  dw      -1              ; header match length
match   db      mmatch dup (?)  ; header match bytes
recvo   dw      ?               ; receiver offset
recvs   dw      ?               ; receiver segment
hinfo   ends


CODE    segment word public 'CODE'
	assume cs:CODE, ds:CODE, es:nothing, ss:CODE
org     100h
prog_stack   label   byte
at100h: jmp     start


copyright       db    13, 10, 'ODITRPKT 1.0 BETA 9', 13, 10
		db      '(c) Copyright Daniel Lanciani 1991-1992.  All rights reserved.'
		db      13, 10, 'This software is provided with NO WARRANTY.', 13, 10
		db      'This version of ODIPKT 1.3 has been modified by Ben James, OSU-UCC-DataComm.', 13, 10
		db      'This driver does ODI Token-Ring_SNAP to Ethernet Class 1 Packet conversion.', 13, 10
		db      '$'
myname  db      'ODITRPKT B-9', 0     ; for driver_info
class   db      1               ; for driver_info
xbusy   db      0               ; receive buffer busy
cmap    db      0               ; class mapping flag
ifdef   stksw
inhere  db      0               ; on switched stack
endif
	
	align   2
savpko  dw      0               ; saved vector offset
savpks  dw      0               ; saved vector segment
psup    dd      0               ; LSL protocol support entry
gsup    dd      0               ; LSL general support entry
control dd      0               ; MLID control entry
config  dd      0               ; MLID configuration table
asup    dw      0, 0            ; for as_send_pkt
board   dw      0               ; logical board number
myvec   dw      4 * pkvec       ; 4 * my vector
ifndef  nopid
stackid dw      0               ; stackid from LSL
endif
pconfig ProtocolConfigStructure  <>
pstats  ProtocolStatStructure   <>
alen    dw      6               ; address length
off     dw      12              ; header offset for match
fmin    dw      60              ; minimum frame size
eth_min dw      60              ; ethernet min pkt size
tok_min         dw      28      ; *
rmode   dw      3               ; current receiver mode
rmmap   dw      0, 1, 5, 7, 7, 15
nmulti  dw      0               ; number of multicast addresses
mtab    db      mmulti * 6 dup (?)
htab    hinfo   nhand dup (<>)  ; the handle table
htabe   label   byte
stab    dw      14 dup (0)      ; for get_statistics
ptab    db      1, 9, 14, 6     ; for get_parameters
	dw      1514, mmulti * 6, 0, 0, 0
sECB    db      52 dup (0)      ; transmit ECB
ifdef   send_buf_swap
sb      db      xbsize dup (?)  ; Internal buffer for send buffer
endif
rECB    db      52 dup (0)      ; receive ECB
xb      db      xbsize dup (?)  ; receive buffer

upcall  proc    far

transcom:
	push   ds
	push    bp
	mov     ax, cs
	mov     ds, ax
	mov     ax, asup
	or      ax, asup + 2
	jz      trans1
	
	mov     ax, es:8[si]
	and     ax, ax
	jz      trans2
	mov     ax, 12
	add     stab + 20, 1
	adc     stab + 22, 0
	mov     word ptr sECB + 20, 0800          ; ProtocolID

trans2: 
	les     di, es:46[si]
	call    dword ptr asup
	mov     cs:asup, 0
	mov     cs:asup + 2, 0

trans1: 
	pop     bp
	pop     ds
	ret

recvcom:
	cli
	cmp     cs:xbusy, 0
	jz      havebuf
	jmp     nobuf

havebuf:
	mov     dx, ds
	cld
	push    di
	mov     cx, 4[di]            ;DataLookAheadPtr
	sub     cx, [di]             ;MediaHeaderPtr
	mov     si, cs               ; \
	mov     es, si               ;  > cs 
	mov     ds, si               ; /
rcvna1:
	mov     si, offset rECB
	mov     word ptr 46[si], offset xb   ; Fragment0Address
	add     word ptr 46[si], cx           
	mov     word ptr 50[si], xbsize      ; Fragment0Length
	sub     word ptr 50[si], cx           
	mov     ds, dx
	lds     si, [di]                     ; media header ptr ??
	mov     di, offset xb 
rcvna2:
	rep     movsb
rcvna5: 
	mov     si, offset rECB
	pop     di
	mov     ds, dx
	xor     ax, ax
	mov     cs:xbusy, 1
	ret

nobuf2: 
	pop     di
	mov     ds, dx
nobuf:  
	mov     ax, 8001h
	add     cs:stab + 16, 1
	adc     cs:stab + 18, 0
	and     ax, ax
	ret

recvcom2:
	push    bp
	push    ds
	push    es
	push    si
	mov     ax, cs
	mov     ds, ax
	cld
	cli
	
ifdef   stksw
	cmp     inhere, 0
	jz      notbusy
	add     stab + 16, 1
	adc     stab + 18, 0
	jmp     busy
	notbusy:
	inc     inhere
	mov     bx, ss
	mov     cx, sp
	mov     ss, ax
	mov     sp, offset prog_stack
	push    bx
	push    cx
endif
	push    ax
	mov     cx, es:42[si]
	add     cx, es:46[si]
	mov     si, offset xb 
	add     si, 2                   ; Offset for FC (Frame Control)
;       add     si, 54      ;low 54
	mov     ax, 0
	mov     ah, byte ptr es:12[si]        ;get type field or rif indicator
	push    cx                      
	test    byte ptr es:6[si], 80h
	jnz     Calc_rif
	mov     ax, 0
	jmp     norif_with_SNAP

rarp_arp:        
	mov     byte ptr es:15[di], 01h
	jmp     not_rarp_arp

Calc_rif:
	sub     byte ptr es:6[si], 80h      ;try to get rid of 9  
	;   This group gives you the ammount to offset
	mov     cl, 3                    ;
	shl     ah, cl                   ;
	mov     cl, 3                    ;
	shr     ah, cl                   ;
	mov     al, ah                   ;
	mov     ah, 0                    ; Now rif size = ax - 2

norif_with_SNAP:        
	add     ax, 6                    ; LLC + SNAP - type               
	push    di
	mov     di, si
	add     di, ax          ; adjust for RIF etc
	mov     cx, word ptr es:8[di]           ; move type from SNAP  
	mov     word ptr es:12[si], cx         ; to end of header
	; move addresses     
	mov     cx, word ptr es:10[si]         ; 1st word   [dest]
	mov     word ptr es:10[di],cx          ;
	mov     cx, word ptr es:8[si]          ; 2nd word
	mov     word ptr es:8[di], cx          ;
	mov     cx, word ptr es:6[si]          ; 3rd word
	mov     word ptr es:6[di], cx          ;
	mov     cx, word ptr es:4[si]          ; 4th word   [source]
	mov     word ptr es:4[di], cx          ;
	mov     cx, word ptr es:2[si]          ; 5th word
	mov     word ptr es:2[di], cx          ;
	mov     cx, word ptr es:[si]           ; 6th word
	mov     word ptr es:[di], cx           ;
	
	cmp     word ptr es:12[di], 0608h      ; If arp change Hardware Type to ethernet
	jz     rarp_arp  
	cmp     word ptr es:12[di], 3580h      ; If arp change Hardware Type to ethernet
	jz      rarp_arp

not_rarp_arp:
	pop     di
	pop     cx            
	add     si, ax          ; adjust pointer for RIF etc
	pop     ax
	sub     cx, si

	cmp     cx, eth_min
	jnc     enuf
	mov     cx, eth_min

enuf:   
	push    es
	push    si              ;pointer to lower level
	push    cx
	add     stab, 1
	adc     stab + 2, 0
	add     stab + 8, cx
	adc     stab + 10, 0
	mov     bx, offset htab
recv1:  
	mov     cx, [bx].nmatch
	cmp     cx, -1
	jz      recv5           ; if cx= -1     no more types
	jcxz    recv2           ; if cx=0       match types
	mov     di, si
	add     di, off
	lea     si, [bx].match          ; load si with ptr to type in hinfo
	repe    cmpsb                   ; compare the types
	jnz     recv5

recv2:  
	pop     cx                      ; else if type found 
	push    cx
	push    bx
	xor     ax, ax
	call    dword ptr [bx].recvo     ; call recever
	pop     bx
	cld
	mov     ax, es
	or      ax, di
	jz      recv7
	pop     cx
	pop     si
	pop     ds
	push    ds
	push    si
	push    cx
	push    di
	shr     cx, 1
	rep     movsw
	jnc     recv3
	movsb

recv3:  
	pop     si
	pop     cx
	push    cx
	mov     ax, es
	mov     ds, ax
	push    bx
noararp:
	mov     ax, 1
	call    dword ptr cs:[bx].recvo
	pop     bx
	cld
	cli
	mov     ax, cs
	mov     ds, ax
recv5:  
	pop     cx
	pop     si
	pop     es
	add     bx, size hinfo
	cmp     bx, offset htabe
	jnc     recv6       ; no carry
	push    es
	push    si
	push    cx
	jmp     recv1
recv7:  
	cli
	mov     ax, cs
	mov     ds, ax
	add     stab + 24, 1
	adc     stab + 26, 0
	jmp     short recv5

recv6:  
	ifdef   stksw
	pop     cx
	pop     bx
	mov     sp, cx
	mov     ss, bx
	dec     inhere
	endif
busy:   
	mov     xbusy, 0
	pop     si
	pop     es
	pop     ds
	pop     bp
	ret

pcont:  
	cmp     bx, GET_STACK_CONFIGURATION          
	jne     pcont1                  ; if not
	mov     si, offset cs:pconfig
	xor     ax, ax
	ret

pcont1: 
	cmp     bx, GET_STACK_STATISTICS        
	jne     pcont2                  ; if not
	mov     si, offset cs:pstats
	xor     ax, ax
	ret

pcont2: 
	mov     ax, LSLERR_OUT_OF_RESOURCES     
	or      ax, ax
	ret

nofunc: 
	mov     dh, 11
	jmp     bad

upcall  endp

driver_info:
	pop     bx
	mov     bx, cs
	mov     ds, bx
	mov     bx, version
	mov     ch, class
	mov     dx, iftype
	xor     cl, cl
	mov     si, offset myname
	mov     al, 6
	jmp     good1

access_type:
	pop     bx
	push    ds
	push    cs
	pop     ds
	cmp     al, class
	jz      access_type1
	mov     dh, 2                           ; Error No Class
	jmp     short access_type5
access_type1:
	cmp     bx, iftype              ; bx = if_type / iftype = 71
	jz      access_type7
	cmp     bx, -1                          ; bx = if_type
	jz      access_type7
;        mov     dh, 3                          ; Error No Type
;        jmp     short access_type5
access_type7:
	and     dl, dl
	jz      access_type2
	mov     dh, 4                           ; Error No Number
	jmp     short access_type5
access_type2:
	cmp     cx, mmatch + 1
	jc      access_type3
	mov     dh, 14                          ; Error Bad Address
	jmp     short access_type5
access_type3:   
	mov     bx, offset htab
access_type4:
	cmp     [bx].nmatch, -1
	jz      access_type6
	add     bx, size hinfo
	cmp     bx, offset htabe
	jc      access_type4
	mov     dh, 9                           ; Error No Space
access_type5:
	pop     ds
	jmp     bad1
access_type6:
	mov     [bx].nmatch, cx         ; cx = type_length
	mov     [bx].recvo, di                  ; \ Receiver offset
	mov     [bx].recvs, es                  ; / segment or vice/versa
	mov     di, ds
	mov     es, di
	lea     di, [bx].match
	pop     ds
	rep     movsb
	mov     ax, bx
	jmp     good1

release_type:
	pop     bx
	mov     cs:[bx].nmatch, -1
	jmp     good1

send_pkt:
	sti
	push    ds
	mov     bx, ds
	mov     dx, cs
	mov     ds, dx
send_pkt1:
	cmp   word ptr 8 + sECB, 0        ; status
	jg      send_pkt1
	mov   word ptr 8 + sECB, 1        ; status
	add     stab + 4, 1
	adc     stab + 6, 0
	add     stab + 12, cx
	adc     stab + 14, 0
	mov     es, bx

ifdef   send_buf_swap
	mov     di, offset sb
	push    cx
	push    bx
	push    si
loop_1: 
	cmp     cx, 0
	jl      done
	mov     bx, word ptr es:[si]
	mov     word ptr cs:[di], bx
	add     si, 2
	add     di, 2
	sub     cx, 2
	jmp     loop_1
done:
	mov     cx, cs
	mov     es, cx
	pop     si
	pop     bx
	pop     cx
	mov     di, offset sb
	mov     word ptr sECB + 48, cs          ; Fragment0address LW
	mov     es, bx
else        
	mov     word ptr sECB + 48, bx          ; Fragment0address LW
endif
	push    cx
	mov     cx, word ptr es:12[si]
	mov     word ptr sECB + 20, cx          ; ProtocolID

ifndef  nopid
	mov     cx, stackid
endif
	mov     word ptr sECB + 14, cx          ; StackID        

	mov     cx, word ptr es:0[si]
	mov     word ptr sECB + 24, cx          ; Immediate address
	mov     cx, word ptr es:2[si]
	mov     word ptr sECB + 26, cx
	mov     cx, word ptr es:4[si]
	mov     word ptr sECB + 28, cx          ; *****************
	pop     cx
	cmp     word ptr es:12[si], 0608h       ; if arp
	jz      s_rarp_arp
	cmp     word ptr es:12[si], 3580h       ; if arp
	jz      s_rarp_arp

not_arp_send:        
ifdef   send_buf_swap
	add     di, 14
else        
	add     si, 14
endif        
	sub     cx, 14

send_pkt4:
	mov     word ptr sECB + 42, cx           ; Data Length
ifdef   send_buf_swap
	mov     word ptr sECB + 46, di           ; Fragment0Address
else
	mov     word ptr sECB + 46, si           ; Fragment0Address
endif   
	mov     word ptr sECB + 50, cx           ; Fragment0Legnth
	mov     si, offset sECB
ifdef   send_buf_swap
	push    cx
	mov     cx, cs
	mov     es, cx
	pop     cx
else        
	mov     es, dx
endif
	mov     bx, 12                           ; Send Packet
	call    psup
	sti
send_pkt2:
	cmp   word ptr 8 + sECB, 0              ; Status 
	jg      send_pkt2
	jnz     send_pkt3
	pop     ds
	jmp     good

send_pkt3:
	add   stab + 20, 1                     ; Stats
	adc     stab + 22, 0
	pop     ds
	mov     dh, 12
	jmp     bad

s_rarp_arp:        
	mov     byte ptr es:15[si], 06h         ; is arp
	sub     cx, 18                          ; Reduce size for arp
	jmp     not_arp_send        

terminate:
	push    ds
	mov     ax, cs
	mov     ds, ax
	mov     cx, nmulti
	jcxz    terminate2
	mov     si, offset mtab
terminate1:
	push    si
	push    cx
	mov     ax, cs
	mov     es, ax
	mov     ax, board
	mov     bx, 3
	call    control
	pop     cx
	pop     si
	add     si, alen
	loop    terminate1
terminate2:
	xor     ax, ax
	mov     es, ax
	mov     bx, myvec
	mov     ax, savpko
	mov     es:[bx], ax
	mov     ax, savpks
	mov     es:2[bx], ax
	mov     ax, board
ifdef   defstk
	mov     bx, 9
else
	mov     bx, 11
endif
	call    psup
ifndef  nopid
	mov     ax, stackid
	mov     bx, 22
	mov     cx, board
	call    psup
	mov     ax, stackid
	mov     bx, 7
	call    psup
endif
	mov     ax, cs
	mov     es, ax
	mov     ah, 49h
	int     21h
	pop     ds
	jmp     good

get_address:
	cmp     cx, cs:alen
	jnc     get_address1
	mov     dh, 9
	jmp     bad
get_address1:   
	push    ds
	lds     si, cs:config
	add     si, 28+6
	mov     cx, cs:alen
	sub     si, cx
	rep     movsb
	pop     ds
	mov     cx, cs:alen
	jmp     good

reset_interface:
	mov     dh, 15
	jmp     bad

get_parameters:
	mov     di, cs
	mov     es, di
	mov     di, offset ptab
	jmp     good


set_rcv_mode:
	mov     bx, cx
	dec     bx
	cmp     bx, 6
	jnc     set_rcv_mode1
	shl     bx, 1
	push    cx
	mov     ax, cs:rmmap[bx]
	mov     bx, 4
	mov     cx, -1
	call    cs:control
	pop     cx
;        jnz     set_rcv_mode1   ; XXX no longer supported by ODI
	mov     cs:rmode, cx
	jmp     good

set_rcv_mode1:
	mov     dh, 8
	jmp     bad

get_rcv_mode:
	mov     ax, cs:rmode
	jmp     good

set_multicast_list:
	mov     ax, cx
	xor     dx, dx
	mov     bx, cs:alen
	div     bx
	and     dx, dx
	jz      set_multicast_list1
	mov     dh, 14
	jmp     bad

set_multicast_list1:
	cmp     ax, mmulti + 1
	jc      set_multicast_list6
	mov     dh, 9
	jmp     bad

set_multicast_list6:
	push    ds
	push    cx
	push    ax
	push    es
	push    di
	mov     ax, cs
	mov     ds, ax
	mov     cx, nmulti
	jcxz    set_multicast_list3
	mov     si, offset mtab
set_multicast_list2:
	push    si
	push    cx
	mov     ax, cs
	mov     es, ax
	mov     ax, board
	mov     bx, 3
	call    control
	pop     cx
	pop     si
	add     si, alen
	loop    set_multicast_list2
set_multicast_list3:
	pop     si
	pop     ds
	pop     ax
	pop     cx
	mov     bx, cs
	mov     es, bx
	mov     di, offset mtab
	cld
	rep     movsb
	mov     bx, cs
	mov     ds, bx
	mov     nmulti, ax
	mov     cx, ax
	jcxz    set_multicast_list5
	mov     si, offset mtab
set_multicast_list4:
	push    si
	push    cx
	mov     ax, cs
	mov     es, ax
	mov     ax, board
	mov     bx, 2
	call    control
	pop     cx
	pop     si
	add     si, alen
	loop    set_multicast_list4
set_multicast_list5:
	pop     ds
	jmp     good

get_multicast_list:
	mov     di, cs
	mov     es, di
	mov     di, offset mtab
	mov     ax, cs:nmulti
	mov     cx, cs:alen
	mul     cx
	mov     cx, ax
	jmp     good

get_statistics:
	mov     si, cs
	mov     ds, si
	mov     si, offset stab
	jmp     good

set_address:
	mov     dh, 13
	jmp     bad

funcs   dw      nofunc
	dw      driver_info
	dw      access_type
	dw      release_type
	dw      send_pkt
	dw      terminate
	dw      get_address
	dw      reset_interface
	dw      nofunc
	dw      nofunc

	dw      get_parameters
	dw      nofunc
	dw      nofunc
	dw      nofunc
	dw      nofunc
	dw      nofunc
	dw      nofunc
	dw      nofunc
	dw      nofunc
	dw      nofunc

	dw      set_rcv_mode
	dw      get_rcv_mode
	dw      set_multicast_list
	dw      get_multicast_list
	dw      get_statistics
	dw      set_address

nfuncs  equ     ($ - offset funcs) / 2

intpk   proc    far
	jmp     short dopk
	nop
sig     db      'PKT DRVR', 0

dopk:   
	cli
	cld
	push    bx
	cmp     ah, nfuncs
	jc      dopk1
	jmp     nofunc

dopk1:          
	mov     bl, ah
	xor     bh, bh
	shl     bx, 1
	jmp     cs:funcs[bx]

bad:    
	pop     bx
bad1:   
	stc
	sti
	ret     2
good:   
	pop     bx
good1:  
	clc
	sti
	ret     2
intpk   endp

number0:
	call    number
	jmp     nothex

number: 
	xor     ax, ax
	mov     cx, -1
number1:
	cmp     byte ptr [bx], '0'
	jc      number2
	cmp     byte ptr [bx], '9' + 1
	jnc     number2
	xor     cx, cx
	mov     dx, 10
	mul     dx
	mov     dl, byte ptr [bx]
	sub     dl, '0'
	xor     dh, dh
	add     ax, dx
	inc     bx
	jmp     short number1

number2:
	add     cx, 1
	ret

calcvec:        
	xor     ax, ax
	call    calcloop
	jz      pexit
	mov     cl, 4
	shl     al, cl
	mov     ah, al
	call    calcloop1
	add     al, ah
	mov     cl, 4
	mul     cl
	mov     myvec, ax
	xor     cx, cx
	ret

calcloop:
	cmp     byte ptr [bx], '0'
	jne     number0
	inc     bx
	cmp     byte ptr [bx], 'x'
	jne     start0          ;error
calcloop1:
	inc     bx
	cmp     byte ptr [bx], '0'
	jb      start0           ;error
	cmp     byte ptr [bx], '9'
	ja      letterhex
	mov     al, byte ptr [bx]
	sub     al, '0'
	ret

letterhex:
	cmp     byte ptr [bx], 'f'
	ja      tryupp
	cmp     byte ptr [bx], 'a'
	jb      tryupp
	mov     al, byte ptr [bx]
	sub     al, 'a'-10
	ret

tryupp: 
	cmp     byte ptr [bx], 'F'
	ja      start0                  ; error
	cmp     byte ptr [bx], 'A'
	jb      start0                  ; error
	mov     al, byte ptr [bx]
	sub     al, 'A'-10
	ret

pexit:  
	mov     ah, 9
	int     21h
	int     20h
 
start:  
	mov     ax, cs
	mov     ds, ax
	cld
	mov     dx, offset copyright
	mov     ah, 9
	int     21h
	mov     bx, 81h
	call    space
	call    number
	jc      start0
	sub     ax, 1
	mov     board, ax
	call    space
;       call    number
	call    calcvec
	jz      start0
nothex: 
	jc      start0
	add     ax, ax
	add     ax, ax
	mov     myvec, ax
start0: 
	xor     ax, ax
	mov     es, ax
	mov     bx, myvec
	les     di, es:[bx]
	add     di, 3
	mov     si, offset sig
	mov     cx, 9
	repe    cmpsb
	jnz     start1
	mov     dx, offset already
	mov     ah, 9
	int     21h
	int     20h
start1:         
	xor     ax, ax
	mov     es, ax
	xor     bx, bx
	xor     dx, dx
	mov     ah, 0c0h
start11:
	push    ax
	int     2fh
	cmp     al, 0ffh
	pop     ax
	jz      start13
start12:
	inc     ah
	jnz     start11
	mov     dx, offset nolsl
	jmp     pexit
start13:
	mov     ax, dx
	or      ax, bx
	jz      start12
	mov     di, si
	mov     si, offset lslname
	cld
	mov     cx, 8
	repe    cmpsb
	jz      start14
	xor     bx, bx
	xor     dx, dx
	jmp     start12

start14:
	mov     word ptr psup, bx
	mov     word ptr psup + 2, dx
	mov     si, cs
	mov     es, si
	mov     si, offset psup
	mov     bx, 2
	call    psup
	mov     ax, word ptr gsup
	or      ax, word ptr gsup + 2
	jnz     start2
	mov     dx, offset lslfail
	jmp     pexit

start2: 
	mov     bx, 18
	mov     ax, board
	call    psup
	jz      start3
	mov     dx, offset nocont
	jmp     pexit
start3: 
	mov     word ptr control, si
	mov     word ptr control + 2, es
	mov     ax, board
	xor     bx, bx
	call    control
	jz      start4
	mov     dx, offset noconf
	jmp     pexit
	
start4: 
	mov     word ptr config, si
	mov     word ptr config + 2, es
	mov     al, es:114[si]
	xor     ah, ah
	cmp     al, 8
	jnc     noloirq
	add     ax, 8
	jmp     short haveirq
noloirq:
	cmp     al, 16
	jnc     noirq
	add     ax, 70h - 8
haveirq:
	mov     word ptr ptab + 12, ax
noirq:          
	mov     ax, es:60[si]
	cmp     ax, 4
	jz      use_TR_SNAP
	cmp     ax, 11
	jz      istok
	cmp     ax, 3
	jz      will_not_support
	cmp     ax, 5
	jz      will_not_support
	cmp     ax, 10
	jz      will_not_support
	cmp     ax, 7
	jz      will_not_support
	cmp     ax, 15
	jz      will_not_support
	cmp     ax, 16
	jz      will_not_support
	cmp     ax, 14

will_not_support:
	mov     dx, offset not_sup
	jmp     pexit

use_TR_SNAP:
	mov     dx, offset tok_not_sup
	jmp     pexit

istok:  
	mov     dx, offset t_tok
	mov     ax, es:40[si]           ; Max size from MLID config Table
	add     ax, 14
	cmp     ax, xbsize
	jc      istok1
	mov     ax, xbsize
istok1: 
	mov     word ptr ptab + 4, ax
	mov     class, 1
	mov     fmin, 14
	jmp     short gottype

gottype:
	mov     ah, 9
	int     21h

	mov     rinfo, offset recvcom
	mov     rinfo + 2, cs
	mov     rinfo + 4, offset pcont
	mov     rinfo + 6, cs
	mov     si, cs
	mov     es, si
	mov     si, offset rinfo
	mov     ax, board
ifdef   defstk
	mov     bx, 8
else
	mov     bx, 10
endif
	call    psup
ifdef   nopid
	jz      start5
else
	jz      startb
endif
	mov     dx, offset rfail
	jmp     pexit

ifndef   nopid
startb:        
	mov     rinfo, offset sname
	mov     rinfo + 2, cs
	mov     rinfo + 4, offset recvcom
	mov     rinfo + 6, cs
	mov     rinfo + 8, offset pcont
	mov     rinfo + 10, cs
	mov     si, cs
	mov     es, si
	mov     si, offset rinfo
	mov     ax, board
	mov     bx, 6
	call    psup
	jz      start51
	mov     dx, offset rfail
	jmp     pexit

start51:
	mov     stackid, bx 
	mov     ax, bx
	mov     bx, 21
	mov     cx, board
	call    psup
	jz      start5
	mov     ax, stackid
	mov     bx, 7
	call    psup
	jz      start5
	mov     dx, offset bfail
	jmp     pexit
endif

start5: 
	mov     word ptr sECB + 10, offset transcom    ; Call Transcom when transmit complete
	mov     word ptr sECB + 12, cs                 ; MW   ; Also ptr to transcom
	mov     word ptr sECB + 14, -1                 ; stack ID
	mov     ax, board                              ; Board #
	mov     word ptr sECB + 22, ax                 ; Board # 
	mov     word ptr sECB + 44, 1                  ; Fragment0Count
	mov     word ptr sECB + 48, cs                 ; Fragment0Address LW

	mov     word ptr rECB + 10, offset recvcom2    ; Call Recvcom2 when recieve complete
	mov     word ptr rECB + 12, cs                 ; 
	mov     word ptr rECB + 14, -1                 ; stack id
	mov     ax, board                              ; Board #
	mov     word ptr rECB + 22, ax                 ; Board #  
	mov     word ptr rECB + 44, 1                  ; Fragment0Count
	mov     word ptr rECB + 48, cs                 ; Fragment0Address LW
	xor     ax, ax
	mov     es, ax
	pushf
	cli
	mov     bx, myvec
	mov     ax, es:[bx]
	mov     savpko, ax
	mov     ax, es:2[bx]
	mov     savpks, ax
	mov     es:[bx], offset intpk
	mov     es:2[bx], cs
	popf
	mov     dx, offset goodins
	mov     ah, 9
	int     21h
	mov     es, ds:[2ch]
	mov     ah, 49h
	int     21h
	mov     word ptr ds:[2ch], 0
	mov     cx, 5
	xor     bx, bx
cloop:  
	mov     ah, 3eh
	int     21h
	inc     bx
	loop    cloop
	mov     dx, offset start
	int     27h


space:  
	cmp     byte ptr [bx], ' '
	jz      space1
	cmp     byte ptr [bx], 9
	jz      space1
	ret

space1: 
	inc     bx
	jmp     short space

ifdef   nopid
rinfo   dw      4 dup (0)
else
sname   db      8, 'ODITRPKT', 0
rinfo   dw      6 dup (0)
bfail db      'Failed to bind protocol stack', 13, 10, '$'
endif
lslname db      'LINKSUP$'
already db      'A driver is already installed at this vector.', 13, 10, '$'
t_tok   db      'Token-Ring_Snap using ethernet framing, class 1', 13, 10, '$'
goodins db      'ODITRPKT is installed and ready.', 13, 10, 10, '$'
nolsl   db      'The Link Support Layer is not loaded.', 13, 10, '$'
lslfail db      'The Link Support Layer failed to init.', 13, 10, '$'
nocont  db      'Cannot get MLID control entry', 13, 10, '$'
noconf  db      'Cannot get MLID configuration', 13, 10, '$'
rfail   db      'Failed to register protocol stack', 13, 10, '$'
not_sup db      'That Frame type is not supported by this driver. ', 13, 10,
	db      'This driver only supports binding to Token-Ring_SNAP.  (Initialization Failed) ', 13, 10, 10, '$'

	db      'ODIPKT.COM will support that board. ', 13, 10, 10, '$'
tok_not_sup     db      'This driver only supports binding to Token-Ring_SNAP.  (Initialization Failed) ', 13, 10, 10, '$'

CODE    ends
end     at100h
[ RETURN TO DIRECTORY ]