maurice@xanth.cs.odu.edu (Dale Ross Maurice) (01/08/89)
Due to the number of responses, I've decided to post the source
to ELINK.ASM. (See the docs below to see what it does.)
I have encountered one know bug that I'm not sure how to fix;
actually I haven't had the time to find out what is causing the
problem.
It seems to work fine with all the software I've tried except
Procomm 2.4.2. Whenever the following device driver is loaded
and I attempt to run procomm I get a 'Network Retrying' error
and the machine hangs up. If someone should find what is causing
this problem PLEASE let me know what is causing it.
If there are any other questions please feel free to mail me.
;-----------------------------------------------------------------;
; Written by : Dale Ross Maurice ;
; Date : 01-06-89 ;
; ;
; maurice@xanth.cs.odu.edu maurice@cs.odu.edu ;
; maurice@xanth.uucp maurice@gwynedd.uucp ;
; ;
; ELINK.ASM - Allows config.sys modification based on hardware ;
; configuration at boot time by determining whether an etherlink ;
; I (3com 3C501) or etherlink II (3com 3C503) card is installed. ;
; Depending on the card installed it replaces a dummy config.sys ;
; entry (ELINK.DRIVER12345678) with the required 3com 3+Share ;
; driver ( eth.sys for 3C501, eth503.sys for 3C503). ;
; TASM elink ;
; TLINK elink ;
; EXE2BIN elink.exe elink.sys ;
; modify config.sys to contain: ;
; device=elink.sys ;
; device=elink.driver12345678 ;
; ( The 'elink.driver12345678' is used as a buffer for the ;
; replacement driver. This may need to be made longer ;
; depending on what configuration you are using. ;
; ie: Ours is ETH503.SYS /i:2 ;
; CONFIG_DUM DB "ELINK.DRIVER12345678" ;
; CONFIG_DUM_LEN EQU 20 ;
; The two above defines can be made larger to meet other ;
; needs. ;
; ) ;
; ;
; Assembled using Turbo Assembler 1.0 but should work with ;
; MASM 2.0 or later. Remember to EXE2BIN ;
; Based on CONFIG.CTL 1.0 (C) 1988 Ziff Communications Co. ;
;-----------------------------------------------------------------;
_TEXT SEGMENT PUBLIC 'CODE'
ASSUME CS:_TEXT,DS:_TEXT
ASSUME ES:_TEXT,SS:_TEXT
ORG 0H
;************* DEVICE_HEADER *************;
POINTER DD -1
ATTRIBUTE DW 1000000000000000B
DEVICE_STAG DW STRATEGY
DEVICE_INT DW INTERRUPT
DEVICE_NAME DB "CONFIGURE"
;************* REQUEST HEADER ************;
REQUEST_HEADER STRUC
HEADER_LENGTH DB ?
UNIT_CODE DB ?
COMMAND_CODE DB ?
STATUS DW ?
RESERVED DQ ?
REQUEST_HEADER ENDS
DONE EQU 0000000100000000B ;Status codes.
UNKNOWN EQU 1000000000000011B
;-------------------------;
INIT STRUC
HEADER DB (TYPE REQUEST_HEADER) DUP(?)
UNITS DB ?
ENDING_OFFSET DW ?
ENDING_SEGMENT DW ?
ARGUMENTS_OFF DW ?
ARGUMENTS_SEG DW ?
INIT ENDS
REQUEST_OFFSET DW ?
REQUEST_SEG DW ?
;-----------------------------------------------------------------------------;
; The only task of the strategy is to save the pointer to the request header. ;
;-----------------------------------------------------------------------------;
STRATEGY PROC FAR
MOV CS:REQUEST_OFFSET,BX ;Request header address is
MOV CS:REQUEST_SEG,ES ; passed in ES:BX.
RET
STRATEGY ENDP
;------------------------------------------------------------------------;
; The interrupt procedure will be called immediately after the strategy. ;
;------------------------------------------------------------------------;
INTERRUPT PROC FAR
PUSH AX ;Responsible for all registers.
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSHF
MOV DS,CS:REQUEST_SEG ;Retrieve request header pointer.
MOV BX,CS:REQUEST_OFFSET
OR STATUS[BX],DONE ;Tell DOS we are done.
CMP COMMAND_CODE[BX],0 ;Is it INIT command?
JZ MAKE_STACK ;If yes, do our stuff.
OR STATUS[BX],UNKNOWN ;Else, exit with confused
JMP SHORT UNKNOWN_EXIT ; message to DOS.
MAKE_STACK: MOV CX,SS ;Save DOS stack.
MOV DX,SP
MOV AX,CS
CLI
MOV SS,AX ;Make new stack.
MOV SP,0FFFEH
STI
PUSH CX ;Save old stack pointers on new.
PUSH DX
PUSH ES ;Save rest of registers.
PUSH SI
PUSH DI
PUSH BP
CALL INITIALIZE ;Go do our stuff.
POP BP ;Restore registers.
POP DI
POP SI
POP ES
POP DX ;Restore old DOS stack.
POP CX
CLI
MOV SS,CX
MOV SP,DX
STI
UNKNOWN_EXIT: POPF ;Restore rest of registers.
POP DS
POP DX
POP CX
POP BX
POP AX
RET ;Far return back to DOS.
INTERRUPT ENDP
CONFIG_CTL_END LABEL WORD
;************* END OF RESIDENT PORTION *************;
BUFFER_SEGMENT DW ? ;CONFIG.SYS buffer segment
BUFFER_START DW ? ; and offset.
BUFFER_END DW ?
ADDRESS DB 6 DUP(0)
VALID DB 02H,60H,8CH
CONFIG_DUM DB "ELINK.DRIVER12345678"
CONFIG_DUM_LEN EQU 20
; Drivers must be Null (ascii 0) padded to 20 characters,
; replace all embedded spaces with nulls
ELINKI_DRV DB "ETH.SYS",13 DUP(0)
ELINKII_DRV DB "ETH503.SYS",0,"/I:2",5 DUP(0)
BAD_DRV DB "ELINK CARD NOT FOUND"
;------------------------------------------;
; INPUT ;
; DS:BX points to request header. ;
; ;
; All registers destroyed. ;
;------------------------------------------;
INITIALIZE PROC NEAR
MOV ENDING_OFFSET[BX],OFFSET CONFIG_CTL_END
MOV ENDING_SEGMENT[BX],CS ;Resident portion setup.
MOV AX,ARGUMENTS_SEG[BX] ;Retrieve CONFIG.SYS buffer
MOV ES,AX ; pointers from INIT table.
MOV BX,ARGUMENTS_OFF[BX]
PUSH CS ;Point to our data.
POP DS
MOV BUFFER_SEGMENT,ES ;And save the segment.
;-----------------------------------------------------------------------;
; Search for dummy ELINK.DRIVER12345678 in config.sys and replace it, ;
; if found, with the required etherlink driver. ;
;-----------------------------------------------------------------------;
NEXT_BYTE: MOV SI,OFFSET CONFIG_DUM ;Pointer to CONFIG_DUM.
MOV DI,BX ;Pointer to current buffer pos.
MOV CX,CONFIG_DUM_LEN ;Is it CONFIG_DUM?
CLD
REPZ CMPSB
JZ FOUND_DUM ;If yes, found dummy.
INC BX ;Else, increment buff pos.
CMP BX,0FFFFH - CONFIG_DUM_LEN ;End of segment?
JNZ NEXT_BYTE ;If no, continue.
JMP INIT_END ;Else, give up search.
FOUND_DUM: CALL CHOOSEDRIVER
INIT_END: RET ;Exit.
INITIALIZE ENDP
CHOOSEDRIVER PROC NEAR
PUSH BX
PUSH ES
CALL GETELINKIADDR
MOV AX,CS
MOV DS,AX
MOV ES,AX
LEA DI,ADDRESS
LEA SI,VALID
MOV CX,3H
CLD
REPE CMPSB
JNZ SHORT GETELINKII
POP ES
POP BX
MOV DI,BX
LEA SI,ELINKI_DRV
MOV CX,CONFIG_DUM_LEN
CLD
REP MOVSB
JMP SHORT FINISHED
GETELINKII:
CALL GETELINKIIADDR
MOV AX,CS
MOV DS,AX
MOV ES,AX
LEA DI,ADDRESS
LEA SI,VALID
MOV CX,3H
CLD
REPE CMPSB
JNZ SHORT BADMESSAGE
POP ES
POP BX
MOV DI,BX
LEA SI,ELINKII_DRV
MOV CX,CONFIG_DUM_LEN
CLD
REP MOVSB
JMP SHORT FINISHED
BADMESSAGE:
POP ES
POP BX
MOV DI,BX
LEA SI,BAD_DRV
MOV CX,CONFIG_DUM_LEN
CLD
REP MOVSB
FINISHED:
RET
CHOOSEDRIVER ENDP
;--------------------------------------------------------------------
; GET ELINKI
GETELINKIADDR PROC NEAR
MOV CX,6
MOV SI,0
AGAINI:
MOV AX,SI
MOV DX,308H
OUT DX,AL
MOV DX,309H
MOV AL,0H
OUT DX,AL
MOV DX,30CH
IN AL,DX ; THE HEXPAIR
MOV ADDRESS[SI],AL
INC SI
LOOP AGAINI
RET
GETELINKIADDR ENDP
;--------------------------------------------------------------------
; GET ELINKII
GETELINKIIADDR PROC NEAR
MOV DX,706H
MOV AX,4
OUT DX,AX
MOV CX,6
MOV SI,0
MOV DX,300H
AGAINII:
IN AL,DX ; THE HEXPAIR
MOV ADDRESS[SI],AL
INC SI
INC DX
LOOP AGAINII
RET
GETELINKIIADDR ENDP
DATA_STORAGE EQU $
_TEXT ENDS
END
--
;Dale Ross Maurice | maurice@xanth.cs.odu.edu maurice@cs.odu.edu
;Old Dominion University | maurice@xanth.uucp maurice@gwynedd.uucp