Category : Network Files
Archive   : TCP_SRC.ZIP
Filename : NB.ASM
include defs.asm ;SEE ENCLOSED COPYRIGHT MESSAGE
NCB_NOWAIT equ 80h ; Command wait flag
NCB_RESET equ 32h ; Reset adapter
NCB_CANCEL equ 35h ; Cancel command
NCB_STATUS equ 33h ; Get NETBIOS intf status
NCB_UNLINK equ 70h ; Unlink (RPL)
NCB_ADDNAME equ 30h ; Add name
NCB_ADDGNAME equ 36h ; Add group name
NCB_DELNAME equ 31h ; Delete name
NCB_FINDNAME equ 78h ; Find name
NCB_CALL equ 10h ; Call
NCB_LISTEN equ 11h ; Listen
NCB_HANGUP equ 12h ; Hang up
NCB_SEND equ 14h ; Send
NCB_CHSEND equ 17h ; Chain send
NCB_RECEIVE equ 15h ; Receive
NCB_RECANY equ 16h ; Receive any
NCB_SESSTATUS equ 34h ; Get session status
NCB_SDATAGRAM equ 20h ; Send datagram
NCB_SBROADCAST equ 22h ; Send broadcast
NCB_RDATAGRAM equ 21h ; Receive datagram
NCB_RBROADCAST equ 23h ; Receive broadcast
NCB_TRACE equ 79h ; Start trace
ncb struc
ncb_command db ?
ncb_retcode db ?
ncb_lsn db ?
ncb_num db ?
ncb_buffer dd ?
ncb_length dw ?
ncb_callname db 16 dup(?)
ncb_name db 16 dup(?)
ncb_rto db ?
ncb_sto db ?
ncb_post dd ?
ncb_lana_num db ?
ncb_cmd_cplt db ?
ncb_reserve db 14 dup(?)
ncb ends
code segment word public
assume cs:code, ds:code
;***************************************************************
prefix db "TCPIP"
public int_no
int_no db 0,0,0,0
ip_adress dw 2 dup(0)
rq_size dw 3
padding dd 0
public driver_class, driver_type, driver_name, driver_function, parameter_list
driver_class db 6,0 ;from the packet spec
driver_type db 0 ;from the packet spec
driver_name db 'netbios',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 512 ;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 4 ;number of receive modes in our table.
dw 0,0,0,rcv_mode_3
lana_num db 0
local_ncb_num db 0 ; handle returned by add_name
public nbsend, nbrcv1, nbrcv2, rcv_buffer1, rcv_buffer2 ; MAP
nbsend ncb <>
nbrcv1 ncb <>
nbrcv2 ncb <>
MAX_DG equ 512
rcv_buffer1 db MAX_DG dup(?)
rcv_buffer2 db MAX_DG dup(?)
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:
assume ds: nothing
;enter with ds:si -> packet, cx = packet length.
;exit with nc if ok, or else cy if error, dh set to error number.
push es
push bx
push ds
push cs
pop es
mov bx,offset cs:nbsend
mov cs:[bx].ncb_buffer.offs,si
mov ax,ds
mov cs:[bx].ncb_buffer.segm,ds
mov cs:[bx].ncb_length,cx
push bx
lea di,cs:nbsend.ncb_callname
mov dh,ds:[si+16]
mov dl,ds:[si+17]
mov bh,ds:[si+18]
mov bl,ds:[si+19]
push cs
pop ds
call ip_to_nbname
pop bx
int 5ch
cmp al,0
jz send_ok
add ax,32
call tty
mov al,'S'
call tty
stc
jmp send_done
send_ok:
mov al,'s'
call tty
clc
send_done:
pop ds
pop bx
pop es
ret
public get_address
get_address:
;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.
clc
ret
public set_address
set_address:
;enter with ds:si -> Ethernet address, CX = length of address.
;exit with nc if okay, or cy, dh=error if any errors.
assume ds:nothing
ret
rcv_mode_3:
;receive mode 3 is the only one we support, so we don't have to do anything.
ret
public set_multicast_list
set_multicast_list:
;enter with ds:si ->list of multicast addresses, cx = number of addresses.
;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:
ret
public reset_interface
reset_interface:
;reset the interface.
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
extrn count_in_err: near
extrn count_out_err: near
extrn dwordout: near
extrn error: 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
ret
public nbint ; MAP
nbint proc far
push ds
push cs
pop ds
mov al,'r'
call tty
mov al,[bx].ncb_retcode
cmp al,0 ; ok
jnz bad_nbint
push bx
mov cx,[bx].ncb_length
mov di,0
mov dl,cs:driver_class
call recv_find
pop bx
mov ax,es
or ax,di
je nbint_done
; cx, di already set
mov si,[bx].ncb_buffer.offs
rep movsb
call recv_copy
mov [bx].ncb_length,MAX_DG ; reestablish dg-length
push ds
pop es
int 5ch
cmp al,0ffh
jz nbint_pending_ok1
mov al,'?'
call tty
cmp al,00h
jz nbint_pending_ok1
add ax,32
call tty
mov al,'.'
call tty
nbint_pending_ok1:
jmp short nbint_done
bad_nbint:
cmp ax,17h ; name deleted
add ax,32
call tty
mov al,'R'
call tty
nbint_done:
pop ds
iret
nbint endp
public nb_stop
nb_stop:
; unregister name
push cs
pop es
lea bx,nbrcv1
mov [bx].ncb_command,NCB_DELNAME
; mov al,lana_num
; mov [bx].ncb_lana_num,al
int 5ch
cmp al,0
jz good_delete
add ax,32
call tty
mov al,'I'
call tty
good_delete:
ret
tty:
push bx
mov ah,14
int 10h
pop bx
ret
ip_to_nbname:
; call with es:di = *ncb_name
; bx and dx = ip_address
mov cx,5
mov si,offset prefix
rep movsb
mov [di],bx
mov [di+2],dx
ret
public recv_exiting
recv_exiting:
;called from the recv isr after interrupts have been acknowledged.
;Only ds and ax have been saved.
assume ds:nothing
ret
;any code after this will not be kept after initialization.
public end_resident ; MAP
end_resident label byte
public usage_msg
usage_msg db "usage: nb [-n] [-d] [-w]
public copyright_msg
copyright_msg db "Packet driver for a netbios device, version ",'0'+majver,".",'0'+version,CR,LF
db "Portions Copyright 1990, Michael Haberler",CR,LF,'$'
ip_adress_name db "IP Adress ",'$'
rq_size_name db "Receive Queue ",'$'
bad_name_msg db " bad returncode from nb add_name",CR,LF,'$'
bad_rcv_msg db " bad returncode from nb receive dg",CR,LF,'$'
good_name_msg db " good returncode from nb add_name",CR,LF,'$'
good_rcv_msg db " good returncode from nb receive dg",CR,LF,'$'
temp_dw dw ?
extrn set_recv_isr: near
;enter with si -> argument string, di -> word to store.
;if there is no number, don't change the number.
extrn get_number: near
public parse_args
parse_args:
mov di, offset temp_dw
mov bx, offset ip_adress_name
call get_number
mov ax,temp_dw
mov byte ptr ip_adress+3,al
inc si
mov di, offset temp_dw
mov bx, offset ip_adress_name
call get_number
mov ax,temp_dw
mov byte ptr ip_adress+2,al
inc si
mov di, offset temp_dw
mov bx, offset ip_adress_name
call get_number
mov ax,temp_dw
mov byte ptr ip_adress+1,al
inc si
mov di, offset temp_dw
mov bx, offset ip_adress_name
call get_number
mov ax,temp_dw
mov byte ptr ip_adress+0,al
mov di, offset rq_size
mov bx, offset rq_size_name
call get_number
ret
public etopen
etopen:
pushf
cld
;if all is okay,
; mov bx,offset nbsend
lea bx,nbsend
mov [bx].ncb_command,NCB_ADDNAME
mov al,lana_num
mov [bx].ncb_lana_num,al
push ds
push cs
push cs
pop ds
pop es
push bx
lea di,nbsend.ncb_name
mov bx,ip_adress
mov dx,ip_adress+2
call ip_to_nbname
pop bx
mov cx,16
mov di,offset nbrcv1.ncb_name
mov si,offset nbsend.ncb_name
rep movsb
mov cx,16
mov di,offset nbrcv2.ncb_name
mov si,offset nbsend.ncb_name
rep movsb
int 5ch ; add_name, -> returns rc in al
cmp al,0
jz good_name
mov dx,0
mov ah,0
call dwordout
mov dx,offset bad_name_msg
pop ds
jmp error
good_name:
; mov dx,offset good_name_msg
; call say
mov al,[bx].ncb_num
mov local_ncb_num,al
mov [bx].ncb_command,NCB_SDATAGRAM ;set send command code
; start receive operations
; mov bx,offset nbrcv1
lea bx,nbrcv1
mov al,NCB_RDATAGRAM+NCB_NOWAIT ;set rcv command
mov [bx].ncb_command,al
mov al,local_ncb_num
mov [bx].ncb_num,al
mov ax,MAX_DG
mov [bx].ncb_length,ax
mov ax,ds
mov [bx].ncb_buffer.segm,ax
mov [bx].ncb_buffer.offs,offset rcv_buffer1
mov [bx].ncb_post.segm,ax
mov [bx].ncb_post.offs,offset nbint
mov al,lana_num
mov [bx].ncb_lana_num,al
int 5ch
cmp al,0ffh
jz pending_ok1
cmp al,00h
jnz bad_init
pending_ok1:
mov dx,offset good_rcv_msg
call say
mov dx,offset end_resident
pop ds
popf
clc
ret
;if we got an error,
bad_init:
mov ah,0
mov dx,0
call dwordout
mov dx,offset bad_rcv_msg
call say
call nb_stop
pop ds
popf
stc
ret
public print_parameters
print_parameters:
ret
say:
mov ah,9
int 21h
ret
code ends
end
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/