home *** CD-ROM | disk | FTP | other *** search
- 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
-