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