home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1993 May
/
SIMTEL_0593.ISO
/
msdos
/
network
/
netio.asm
< prev
next >
Wrap
Assembly Source File
|
1986-01-20
|
17KB
|
444 lines
PAGE 60,132
TITLE "NETIO" -- NETWORK I/O DRIVER
CSEG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CSEG,SS:STACK
;------------------------------------------------;
; DRIVER HEADER ;
;------------------------------------------------;
DD -1 ; Ptr to next device driver
DW 1100000000000000B ; Attribute byte, char dev.
DW OFFSET STRATEGY ; OFFSET to STRATEGY routine
DW OFFSET IRPT ; OFFSET to INTERRUPT routine
DB 'NETIO ' ; Character device name
RH_PTR LABEL DWORD ; Storage of PTR to request header
RH_PTRO DW 0 ; OFFSET (filled by strat. rout)
RH_PTRS DW 0 ; SEGMENT "
;------------------------------------------------;
; REQUEST HEADER, COMMON PORTION ;
;------------------------------------------------;
RH EQU DS:[BX]
RHC STRUC
RHC_LEN DB ? ; Length of request header + data
DB ? ; unit code (Ignored)
RHC_CMD DB ? ; Command code
RHC_STA DW ? ; Status word
DQ ? ; Reserved for DOS
RHC ENDS
;------------------------------------------------;
; REQUEST HEADER FOR INIT COMMAND ;
;------------------------------------------------;
RH0 STRUC
DB (TYPE RHC) DUP (?) ;Common portion
RH0_NUM DB ? ; Number of units (Ignored)
RH0_ENDO DW ? ; OFFSET of ending address of res. code
RH0_ENDS DW ? ; SEGMENT of ending address of res. code
RH0_BPB DD ? ; Address of BPB (Ignored)
RH0_DRIV DB ? ; Drive code (Ignored)
RH0 ENDS
;------------------------------------------------;
; REQUEST HEADER FOR I/O ;
;------------------------------------------------;
RH1 STRUC
DB (TYPE RHC) DUP (?) ;Common portion
DB ? ; Media descriptor byte (Ignored)
RH1_BUFO DW ? ; OFFSET to buffer address
RH1_BUFS DW ? ; SEGMENT of buffer address
RH1_CNT DB ? ; Bytes transferred count
RH1 ENDS
RH1_BUF EQU DWORD PTR RH1_BUFO ; OFFSET/SEG of buffer
;------------------------------------------------;
; REQUEST HEADER FOR INPUT NO WAIT ;
;------------------------------------------------;
RH2 STRUC
DB (TYPE RHC) DUP (?) ;Common portion
RH2_DATA DB ? ; Data from driver service routine
RH2 ENDS
;------------------------------------------------;
; FLAGS FOR REQUEST HEADER STATUS WORD ;
;------------------------------------------------;
STAT_DONE EQU 01H ; Done flag
STAT_CMDERR EQU 8003H ; Command error flag
STAT_BUSY EQU 0200H ; Busy -- I/O in progress
CTRL_C EQU 03H
BELL EQU 07H
CR EQU 0DH
LF EQU 0AH
;------------------------------------------------;
; NETWORK CONTROL BLOCK ( GENERIC ) ;
;------------------------------------------------;
NCB EQU $
NCB_COMMAND DB 00H ; NCB Command field
NCB_RETCODE DB 00H ; NCB Return code
NCB_LSN DB 00H ; NCB Local session number
NCB_NUM DB 00H ; NCB Number of your name
NCB_BUFFER@ DW OFFSET CHAR ; NCB Ptr to message buffer
DW CSEG
NCB_LENGTH DW 0001H ; NCB Message buffer length
NCB_CALLNAME DB 'HUNTER THOMPSON '; NCB Name on remote adapter
NCB_NAME DB 'RAOUL DUKE '; NCB Name on local adapter
NCB_RTO DB 00H ; NCB Receive timeout
NCB_STO DB 00H ; NCB Send timeout
NCB_POST@ DD 00000000H ; NCB Ptr to POST routine
NCB_LANA_NUM DB 00H ; NCB Adapter number (00H = 1st Adapter)
NCB_CMD_CPLT DB 00H ; NCB Command status
NCB_RESERVE DB 14 DUP (0) ; Reserved
CHAR DB 0 ; Our 1 Character 'BUFFER'
INSTALLED DB 0 ; Network session started flag
BUFF DB 16 DUP(0)
BUFF_STAT DB 0
NEXT_TO_READ DW 0
NEXT_TO_ADD DW 0
BUFF_PTR DW 0
OUT_BUFF DB 64 DUP(0)
;------------------------------------------------;
; STRATEGY ROUTINE, STORES HEADER ADDRESS ;
;------------------------------------------------;
STRATEGY PROC FAR
MOV CS:RH_PTRS,ES
MOV CS:RH_PTRO,BX
RET
STRATEGY ENDP
;------------------------------------------------;
; JUMP TABLE FOR PROCESSING DRIVER COMMANDS;
;------------------------------------------------;
CMD_TABLE LABEL WORD
DW OFFSET INIT ; 0 - Initialization
DW OFFSET MEDIA_CHECK ; 1 - Media Check
DW OFFSET BLD_BPB ; 2 - Build BPB
DW OFFSET INPUT_IOCTL ; 3 - IOCTL Input
DW OFFSET INPUT ; 4 - Input
DW OFFSET INPUT_NDINW ; 5 - Non-Destr. Input
DW OFFSET INPUT_STATUS ; 6 - Input Status
DW OFFSET INPUT_FLUSH ; 7 - Input Flush
DW OFFSET OUTPUT ; 8 - Output
DW OFFSET OUTPUT_VER ; 9 - Output w/Verify
DW OFFSET OUTPUT_STATUS ;10 - Output Status
DW OFFSET OUTPUT_FLUSH ;11 - Output Flush
DW OFFSET OUTPUT_IOCTL ;12 - IOCTL Output
DW OFFSET DEVICE_OPEN ;13 - Device OPEN
DW OFFSET DEVICE_CLOSE ;14 - Device CLOSE
MAX_CMD EQU ($ - CMD_TABLE)/2 ;Highest Valid Command
DW OFFSET REMOVABLE_MED ;15 - Removeable Media
;------------------------------------------------;
; DEVICE INTERRUPT ENTRY POINT ;
;------------------------------------------------;
IRPT PROC FAR
PUSH DS ; Save registers
PUSH ES
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH SI
CLD ; All moves forward
LDS BX,CS:RH_PTR ; Get req header address
MOV AL,RH.RHC_CMD ; Command code from request header
CBW
CMP AL,MAX_CMD ; Valid command?
JA IRPT_CMD_HIGH ; Jump to error routine
MOV DI,OFFSET IRPT_CMD_EXIT ; Return addr from cmd proc.
PUSH DI ; Save it
ADD AX,AX ; Double command for jump table
MOV DI,AX ; Move into index register
XOR AX,AX
JMP CS:CMD_TABLE[DI] ; Go to proper processing rout.
IRPT_CMD_ERROR: ; Called for unsupported commands
MEDIA_CHECK:
BLD_BPB:
DEVICE_OPEN:
DEVICE_CLOSE:
REMOVABLE_MED:
POP AX ; POP Off return address
IRPT_CMD_HIGH:
MOV AX,STAT_CMDERR ; Set Command error flag in status
IRPT_CMD_EXIT:
LDS BX,CS:RH_PTR ; Restore DS:BX as req head. ptr
OR AH,STAT_DONE ; Set DONE flag
MOV RH.RHC_STA,AX ; Store STATUS in header
POP SI ; Restore Registers
POP DI
POP DX
POP CX
POP BX
POP AX
POP ES
POP DS
RET
IRPT ENDP
;------------------------------------------------;
; COMMAND HANDLER ROUTINES ;
;------------------------------------------------;
INPUT PROC
PUSH ES
PUSH BX ; Store OFFSET of header
CMP INSTALLED,00H ; Is NET session started?
JNE INPUT0
CALL INSTALL
INPUT0: CMP BUFF_STAT,0
JE INPUT0
MOV DI,NEXT_TO_READ
MOV AL,BUFF[DI]
INC DI
CMP DI,0FH
JLE INPUT1
XOR DI,DI
INPUT1: MOV NEXT_TO_READ,DI
DEC BUFF_STAT
POP BX
POP ES
MOV DI,RH.RH1_BUFO
MOV ES,RH.RH1_BUFS
MOV ES:[DI],AL
MOV RH.RH1_CNT,01H
XOR AX,AX
RET
INPUT ENDP
INPUT_STATUS PROC
CMP BUFF_STAT,0H
JE BUFF_EMPTY
XOR AX,AX
RET
BUFF_EMPTY: MOV AX,STAT_BUSY
RET
INPUT_STATUS ENDP
INPUT_NDINW PROC
PUSH ES
PUSH BX ; Store OFFSET of header
CMP INSTALLED,00H ; Is NET session started?
JNE NDINW0
CALL INSTALL
NDINW0: POP BX
POP ES
CMP BUFF_PTR,00H ; Is output buffer empty?
JE NDINW1
MOV DI,BUFF_PTR ; if not, empty it...
MOV NCB_BUFFER@+2,CS
MOV NCB_BUFFER@,OFFSET OUT_BUFF
MOV NCB_COMMAND,014H
MOV NCB_LENGTH,DI
MOV BX,CS
MOV ES,BX
MOV BX,OFFSET NCB
INT 5CH
MOV BUFF_PTR,00H ; now buffer is empty
CMP NCB_RETCODE,00H
JE NDINW1
JMP IRPT_CMD_ERROR ; if anything went wrong, abort
NDINW1: MOV DI,NEXT_TO_READ ; get next char in buffer
MOV AL,BUFF[DI]
MOV RH.RH2_DATA,AL ; return it via req header
CMP BUFF_STAT,0H
JE NWBUFF_EMPTY
NDINW_LOOP: CMP AL,CTRL_C ; scan active buffer for ^C
JNE NDINW2
MOV BUFF_PTR,04H ; got one!
MOV OUT_BUFF,'^' ; print ^C<CR><LF> on remote
MOV OUT_BUFF+1,'C'
MOV OUT_BUFF+2,CR
MOV OUT_BUFF+3,LF
CALL INPUT_FLUSH ; flush input buffer
INT 23H ; tell DOS
NDINW2: INC DI ; get next char in active buffer
CMP DI,0FH ; check buffer rollover
JLE NDINW3
XOR DI,DI
NDINW3: CMP DI,NEXT_TO_ADD ; check end of active buffer
JE NDINW_EXIT
MOV AL,BUFF[DI]
JMP NDINW_LOOP
NDINW_EXIT: XOR AX,AX ; clear error flag for return
RET
NWBUFF_EMPTY: MOV AX,STAT_BUSY ; set buffer empty flag
RET
INPUT_NDINW ENDP
INPUT_FLUSH PROC
MOV BUFF_STAT,0H ; 0 chars in buffer
MOV NEXT_TO_READ,0H ; offset for reading buffer
MOV NEXT_TO_ADD,0H ; offset for adding to buffer
RET
INPUT_FLUSH ENDP
INPUT_IOCTL PROC
RET
INPUT_IOCTL ENDP
OUTPUT_IOCTL PROC
RET
OUTPUT_IOCTL ENDP
OUTPUT PROC
OUTPUT_VER:
MOV RH.RH1_CNT,01H
MOV DI,RH.RH1_BUFO ; Load DTA OFFSET
MOV ES,RH.RH1_BUFS ; Load DTA SEGMENT
CMP INSTALLED,0H ; Is NETWORK session on?
JNE NET_OUT
CALL INSTALL ; If not, wait for CALL
NET_OUT:
MOV AL,ES:[DI] ; Get char to send
MOV DI,BUFF_PTR ; Put into output buffer
MOV OUT_BUFF[DI],AL
INC DI ; Update output buffer pointer
CMP DI,040H ; check for output buffer full
JNE OUT_EXIT
MOV DI,00H ; it's full, send it on its way
MOV NCB_BUFFER@+2,CS
MOV NCB_BUFFER@,OFFSET OUT_BUFF
MOV NCB_LENGTH,040H
MOV NCB_COMMAND,014H
MOV AX,CS
MOV ES,AX
MOV BX,OFFSET NCB
INT 5CH
CMP NCB_RETCODE,00H
JE OUT_EXIT
JMP IRPT_CMD_ERROR
OUT_EXIT: XOR AX,AX ; Clear error code
MOV BUFF_PTR,DI
RET
OUTPUT ENDP
OUTPUT_STATUS PROC
RET
OUTPUT_STATUS ENDP
OUTPUT_FLUSH PROC
RET
OUTPUT_FLUSH ENDP
;------------------------------------------------;
; DO A NETBIOS "ADD NAME" ;
;------------------------------------------------;
INSTALL PROC
MOV BX,CS
MOV ES,BX
MOV NCB_COMMAND,030H ; ADDNAME Command code
MOV BX,OFFSET NCB ; ES:BX points to NCB
INT 5CH ; NETWORK function call
;------------------------------------------------;
; DO A NETBIOS "LISTEN" ;
;------------------------------------------------;
LISTEN:
MOV NCB_COMMAND,011H ; LISTEN Command code
INT 5CH ; NETWORK function call
MOV INSTALLED,01H
POST_REC: MOV NCB_COMMAND,095H
MOV NCB_POST@,OFFSET POST
MOV NCB_POST@+2,CS
INT 5CH
JMP INST_EXIT
INST_ERR_EXIT: POP AX
INST_EXIT:
RET
INSTALL ENDP
INIT PROC
MOV RH.RH0_ENDS,CS
MOV RH.RH0_ENDO,OFFSET HELLO
RET
INIT ENDP
POST PROC FAR
PUSH DI
PUSH AX
PUSH BX
PUSH CX
PUSH DX
CLI
CMP CHAR,0FFH ; Is session over?
JNE NORMAL_POST
MOV CHAR,00H ; Yes, so reset everything
MOV NCB_COMMAND,012H
MOV BX,CS
MOV ES,BX
MOV BX,OFFSET NCB
INT 5CH ; RESET adapter
MOV INSTALLED,00H
POP DX
POP CX
POP BX
POP AX
POP DI
IRET
NORMAL_POST: CMP BUFF_STAT,0FH ; Is input buffer full?
JL XFER
STI
JMP XEXIT
XFER: MOV DL,CHAR ; transfer char to input buffer
MOV DI,NEXT_TO_ADD
MOV BUFF[DI],DL
INC DI ; update next_to_add pointer
CMP DI,0FH ; check for buffer rollover
JLE XFER2
XOR DI,DI
XFER2: MOV NEXT_TO_ADD,DI ; restore pointer
INC BUFF_STAT ; increment # of chars in buffer
MOV AX,CS ; POST another receive...
MOV ES,AX
MOV BX,OFFSET NCB
MOV NCB_BUFFER@,OFFSET CHAR
MOV NCB_BUFFER@+2,AX
MOV NCB_COMMAND,095H
MOV NCB_POST@,OFFSET POST
MOV NCB_POST@+2,AX
STI
INT 5CH
XEXIT: POP DX
POP CX
POP BX
POP AX
POP DI
IRET
POST ENDP
HELLO EQU $
CSEG ENDS
STACK SEGMENT PARA STACK 'STACK'
DB 64 DUP('STACK ')
STACK ENDS
END ; Eric W. DeSilva Nov 1985