home *** CD-ROM | disk | FTP | other *** search
- TITLE DRIVEIO
- ;
- ; --- CORVUS/IBM DRIVE INTERFACE UNIT FOR MICROSOFT ---
- ; PASCAL AND BASIC COMPILERS
- ; CONST ][ VERSION FOR DOS 1.10 & 2.0
- ;
- ; VERSION 1.41 BY BRK
- ; (MICROSOFT ASSEMBLER VERSION )
- ;
- ;
- ; NOTE: THIS INTERFACE UNIT NOW SUPPORTS BOTH PASCAL AND BASIC
- ; COMPILERS BUT IT MUST BE RE-ASSEMBLED WITH THE APPROPRIATE
- ; SETTING OF THE "LTYPE" EQUATE TO DO THIS FOR EACH LANGUAGE.
- ;
- ;
- ;
- ; THIS UNIT IMPLEMENTS 9 PROCEDURES:
- ;
- ; INITIO
- ; BIOPTR - CONST. ][
- ; SETSRVR - CONST. ][
- ; FINDSRVR - CONST. ][
- ; NETCMD - CONST. ][
- ; CDRECV = DRVRECV
- ; CDSEND = DRVSEND
- ;
- ; THE CALLING PROCEDURE IN PASCAL IS :
- ;
- ; CDSEND (VAR st : longstring )
- ;
- ; THE FIRST TWO BYTES OF THE STRING ARE THE LENGTH
- ; OF THE STRING TO BE SENT OR THE LENGTH OF THE
- ; STRING RECEIVED.
- ;
- ; function INITIO : INTEGER
- ;
- ; THE FUNCTION RETURNS A VALUE TO INDICATE THE STATUS OF
- ; THE INITIALIZATION OPERATION. A VALUE OF ZERO INDICATES
- ; THAT THE INITIALIZATION WAS SUCCESSFUL. A NON-ZERO VALUE
- ; INDICATES THE I/O WAS NOT SETUP AND THE CALLING PROGRAM
- ; SHOULD NOT ATTEMPT TO USE THE CORVUS DRIVERS.
- ;
- ; function BIOPTR : INTEGER
- ;
- ; THE FUNCTION RETURNS A 16 BIT POINTER TO THE "CORTAB"
- ; BIOS TABLE IN THE CORVUS "BIOS" DRIVERS. THIS ROUTINE
- ; SHOULD NOT BE EXECUTED BEFORE A SUCCESSFUL USE OF THE
- ; "INITIO" ROUTINE (ABOVE). NOTE: THE RETURNED VALUE IS
- ; RELATIVE TO "SEGMENT" ZERO, AND A RETURNED VALUE OF ZERO
- ; INDICATES THAT THE "CORTAB" TABLE COULD NOT BE FOUND.
- ;
- ; function SETSRVR ( srvr : integer): INTEGER
- ;
- ; THE FUNCTION RETURNS THE "BOOT SERVER" NETWORK ADDRESS.
- ; IF THE INPUT PARAMETER IS LESS THAN 255 ( BUT NOT NEGATIVE ),
- ; IT WILL BE TAKEN AS A RESET OF THE DEFAULT SERVER # WHEN
- ; USING THE SEND & RECIEVE ROUTINES. IF IT IS GREATER THAN 255
- ; OR NEGATIVE, NO CHANGE OF THE DEFAULT SERVER # WILL BE MADE.
- ; NOTE: THE DEFAULT SERVER # IS AUTOMATICALLY SET TO THE
- ; BOOT SERVER # WHEN THE "INITIO" FUNCTION IS EXECUTED.
- ;
- ; function FINDSRVR : INTEGER
- ;
- ; THE FUNCTION RETURNS THE NETWORK ADDRESS OF A VALID DISK SERVER.
- ; IF THE RETURNED VALUE IS GREATER THAN 63 OR NEGATIVE, THE COMMAND
- ; FAILED TO FIND A SERVER ( THE FLAT CABLE CARDS WOULD DO THIS ).
- ;
- ; function CARDID : INTEGER
- ;
- ; THE FUNCTION RETURNS THE CORVUS INTERFACE CARD TYPE ( 0 - OMNINET,
- ; 1 - FLAT CABLE ).
- ;
- ; function NETCMD ( VAR inp, VAR out: longstring) : INTEGER
- ;
- ; THE FUNCTION IS USED TO SEND/RECIEVE DATA TO A NETWORK SERVER.
- ; STRING inp SPECIFIES THE COMMAND TO SEND TO THE SERVER,
- ; AND STRING out IS WHERE ANY RETURNED DATA WILL BE PLACED
- ; ( THE STRING LENGTH OF out WILL NOT BE CHANGED BY THIS
- ; OPERATION UNLESS THE COMMAND FAILED- IN WHICH CASE THE LENGTH
- ; WILL BE SET TO ZERO). THE VALUE OF THE FUNCTION WILL BE
- ; RETURNED AS ZERO IF THE OPERATION WAS SUCCESSFUL, AND
- ; NON-ZERO IF IT FAILED.
- ; NOTE: THE SERVER # USED WILL BE THE "BOOT SERVER" # UNLESS
- ; THE DEFAULT IS CHANGED BY THE "SETSRVR" CMD.
- ;
- ;
- ;
- ;
- ; THE CALLING PROCEDURE BASIC IS :
- ;
- ; CALL CDSEND (B$ )
- ;
- ; THE FIRST TWO BYTES OF THE STRING ARE THE LENGTH
- ; OF THE STRING TO BE SENT OR THE LENGTH OF THE
- ; STRING RECEIVED ( I.E. LEFT$(B$,2) ).
- ;
- ; CALL INITIO (A%)
- ;
- ; THE FUNCTION RETURNS A VALUE TO INDICATE THE STATUS OF
- ; THE INITIALIZATION OPERATION. A VALUE OF ZERO INDICATES
- ; THAT THE INITIALIZATION WAS SUCCESSFUL. A NON-ZERO VALUE
- ; INDICATES THE I/O WAS NOT SETUP AND THE CALLING PROGRAM
- ; SHOULD NOT ATTEMPT TO USE THE CORVUS DRIVERS.
- ;
- ; CALL BIOPTR (A%)
- ;
- ; THE FUNCTION RETURNS A 16 BIT POINTER TO THE "CORTAB"
- ; BIOS TABLE IN THE CORVUS "BIOS" DRIVERS. THIS ROUTINE
- ; SHOULD NOT BE EXECUTED BEFORE A SUCCESSFUL USE OF THE
- ; "INITIO" ROUTINE (ABOVE). NOTE: THE RETURNED VALUE IS
- ; RELATIVE TO "SEGMENT" ZERO, AND A RETURNED VALUE OF ZERO
- ; INDICATES THAT THE "CORTAB" TABLE COULD NOT BE FOUND.
- ;
- ; CALL SETSRVR (A%) here A% is used for input and output
- ;
- ; THE FUNCTION RETURNS THE "BOOT SERVER" NETWORK ADDRESS.
- ; IF THE INPUT PARAMETER IS LESS THAN 255 ( BUT NOT NEGATIVE ),
- ; IT WILL BE TAKEN AS A RESET OF THE DEFAULT SERVER # WHEN
- ; USING THE SEND & RECIEVE ROUTINES. IF IT IS GREATER THAN 255
- ; OR NEGATIVE, NO CHANGE OF THE DEFAULT SERVER # WILL BE MADE.
- ; NOTE: THE DEFAULT SERVER # IS AUTOMATICALLY SET TO THE
- ; BOOT SERVER # WHEN THE "INITIO" FUNCTION IS EXECUTED.
- ;
- ; CALL FINDSRVR (A%)
- ;
- ; THE FUNCTION RETURNS THE NETWORK ADDRESS OF A VALID DISK SERVER.
- ; IF THE RETURNED VALUE IS GREATER THAN 63 OR NEGATIVE, THE COMMAND
- ; FAILED TO FIND A SERVER ( THE FLAT CABLE CARDS WOULD DO THIS ).
- ;
- ; CALL CARDID (A%)
- ;
- ; THE FUNCTION RETURNS THE CORVUS INTERFACE CARD TYPE ( 0 - OMNINET,
- ; 1 - FLAT CABLE ).
- ;
- ; CALL NETCMD ( A$,B$,C%)
- ;
- ; THE FUNCTION IS USED TO SEND/RECIEVE DATA TO A NETWORK SERVER.
- ; STRING A$ SPECIFIES THE COMMAND TO SEND TO THE SERVER,
- ; AND STRING B$ IS WHERE ANY RETURNED DATA WILL BE PLACED
- ; ( THE STRING LENGTH OF out WILL NOT BE CHANGED BY THIS
- ; OPERATION UNLESS THE COMMAND FAILED- IN WHICH CASE THE LENGTH
- ; WILL BE SET TO ZERO). THE VALUE OF THE FUNCTION WILL BE
- ; RETURNED ( IN C% ) AS ZERO IF THE OPERATION WAS SUCCESSFUL, AND
- ; NON-ZERO IF IT FAILED.
- ; NOTE: THE SERVER # USED WILL BE THE "BOOT SERVER" # UNLESS
- ; THE DEFAULT IS CHANGED BY THE "SETSRVR" CMD.
- ;
- ;=============================================================
- ; REVISION HISTORY
- ;
- ; FIRST VERSION : 10-05-82 BY BRK
- ; : 11-01-82 improved turn around delay for mirror
- ; : 02-16-83 CONST. ][ version
- ; : 05-16-83 added support for Basic
- ; : 07-06-83 fixed bug in FINDSRVR routine
- ; V1.40 : 07-29-83 updated for DOS 2.0
- ; V1.41 : 08-04-83 set timeout to zero to avoid ROM bug
- ;
- ;=============================================================
- ;
- TRUE EQU 0FFFFH
- FALSE EQU 0
- ;
- PASCAL EQU 1 ; LANGUAGE TYPE DESCRIPTOR
- BASIC EQU 2 ; LANGUAGE TYPE DESCRIPTOR
- ;
- LTYPE EQU PASCAL ; SET TO LANGUAGE TYPE TO BE USED WITH
- INTDVR EQU FALSE ; SET TO FALSE TO DISABLE INTERNAL FLAT CABLE DRIVER
- ;
- ;
- ; ----- CORVUS EQUATES -----
- ;
- DATA EQU 2EEH ; DISC I/O PORT #
- STAT EQU 2EFH ; DISC STATUS PORT
- DRDY EQU 1 ; MASK FOR DRIVE READY BIT
- DIFAC EQU 2 ; MASK FOR BUS DIRECTION BIT
- ROMSEG EQU 0DF00H ; LOCATION OF CORVUS ROM
- BIOSSEG EQU 60H ; STD IBM BIOS SEGMENT ADDRESS
- ABTCTR EQU 0A00H ; VALUE TO SET TIMEOUT AND # OF RETRYS
- ; ; v1.41 timeouts=0
- ;
- FCALL EQU 9AH ; OPCODE FOR FAR CALL
- FJMP EQU 0EAH ; OPCODE FOR FAR JUMP
- ;
- ; --- MSDOS EQUATES ( V2.0 ) ---
- ;
- VERCMD EQU 30H ; BDOS COMMAND TO GET VERSION #
- HOPEN EQU 3DH ; BDOS COMMAND TO "OPEN" A FILE HANDLE
- HCLOSE EQU 3EH ; BDOS COMMAND TO "CLOSE" A FILE HANDLE
- HREAD EQU 3FH ; BDOS COMMAND TO "READ" FROM A FILE
- HWRITE EQU 40H ; BDOS COMMAND TO "WRITE" TO A FILE
- ;
- PGSEG SEGMENT 'CODE'
- ASSUME CS:PGSEG
- ;
- ;
- IF LTYPE EQ PASCAL
- DB 'CORVUS/IBM PC CONST. ][ PASCAL DRIVER AS OF 08-04-83'
- ENDIF
- ;
- IF LTYPE EQ BASIC
- DB 'CORVUS/IBM PC CONST. ][ BASIC DRIVER AS OF 08-04-83'
- ENDIF
- ;
- ; --- COPY OF "ROM" FAR JUMP TABLE ---
- ;
- ROMTAB PROC NEAR
- DB FJMP
- DW 0,ROMSEG ; FAR JUMP TO COLD BOOT ROM ENTRY
- DB FJMP
- DW 3,ROMSEG ; FAR JUMP TO WARM START ROM ENTRY
- DB FJMP
- DW 6,ROMSEG ; FAR JUMP TO I/O ROM ENTRY
- DB FJMP
- DW 9,ROMSEG ; FAR JUMP TO DUMMY "IRET" ENTRY
- LENTAB EQU offset $-offset ROMTAB ; LENGTH OF TABLE
- ROMTAB ENDP
- ;
- ; --- COPY OF CORVUS TABLE IDENTIER ---
- ;
- CORTAB DB 'CORTAb' ; VERSION FOR CONST. ][
- ;
- ; --- COPY OF UTILITY "HOOK" DRIVER NAME ---
- ;
- UTILPTR DB 'UTILHOOK',0
- ;
- ;
- ; --- THESE DATA POINTERS MUST BE KEPT IN THE SAME RELATIVE ORDER
- ;
- SNDPTR DW 0 ; BUFFER TO SAVE POINTER TO 'SEND' STRING
- SNDSEG DW 0 ; BUFFER TO SAVE 'SEND' STRING SEGMENT #
- ;
- CORVEC DW 0,0 ; BUF TO SAVE DOUBLE WORD POINTER TO "CORTAB"
- ;
- ; --- MISC DATA AND BUFFERS ----
- ;
- CORPTR DW 0 ; BUFFER FOR "CORTAB" POINTER
- ; ; INITIALIZE INITIALLY TO ZERO
- CRDTYPE DB 1 ; BUFFER TO SAVE "CARD TYPE" BYTE
- BOOTSRVR DB 0FFH ; BUFFER FOR "BOOT SERVER"
- SRVR DB 0FFH ; BUFFER FOR "DEFAULT SERVER"
- ;
- ;
- ; === INITIALIZE CORVUS I/O DRIVERS ===
- ;
- ; THIS ROUTINE MUST BE CALLED
- ; ONCE TO SETUP THE DRIVERS BEFORE
- ; THEY ARE USED. IF THE ROUTINE DOES
- ; ANYTHING THAT CAN ONLY BE DONE ONCE,
- ; IT MUST DISABLE THIS SECTION SO THAT
- ; AND ACCIDENTAL SECOND CALL WILL NOT
- ; LOCK UP THE HARDWARE.
- ;
- PUBLIC INITIO
- ;
- INITIO PROC FAR
- PUSH DS
- PUSH ES
- PUSH CS
- POP ES ; SET ES=CS
- CLD
- ;
- MOV AH,VERCMD ; MSDOS VERSION CHECK COMMAND
- INT 21H ; GET VERSION # OF DOS
- OR AL,AL ; IS IT V 1.1 OR 1.0?
- JZ IV11 ; YES, SO TRY FINDING "CORTAb"
- ;
- PUSH CS
- POP DS ; SET TO LOCAL SEGMENT FOR TESTING
- ;
- MOV AH,HOPEN ; SET MSDOS 2.X, OPEN HANDLE COMMAND
- MOV AL,2 ; OPEN FOR R/W
- MOV DX,offset UTILPTR ; POINT TO "HOOK" DRIVER NAME
- INT 21H ; DO IT
- JC IV12 ; IF ERROR, TRY FOR IBM ROM
- ;
- MOV BX,AX ; GET "HANDLE" IN (BX)
- MOV AH,HWRITE ; GET WRITE CMD
- MOV CX,2 ; SET TO WRITE 2 CHARS
- MOV DX,offset UTILPTR ; USE NAME FOR SOURCE OF CHARACTERS
- INT 21H ; THIS SHOULD RESET "POINTER" IN DRIVER
- ;
- MOV AH,HREAD ; SET READ CMD
- MOV CX,4 ; SET TO READ DOUBLE WORD
- MOV DX,offset CORVEC ; POINT TO DESTINATION OF READ
- INT 21H ; DO IT
- ;
- MOV AH,HCLOSE ; GET CLOSE CMD
- INT 21H ; CLOSE HANDLE
- ;
- LDS BX,dword ptr CORVEC ; GET POSSIBLE POINTER TO "CORTAb"
- CALL BIOT1 ; TEST FOR "CORTAb"
- JNC OKEXIT ; IF OK, EXIT
- JMP IV12 ; OTHERWISE PROCEED
- ;
- IV11: MOV AX,BIOSSEG ; SET TO TEST STD IBM SEGMENT ADD
- CALL BIOTST ; TEST BIOS AND LINK TO IT IF OK
- JNC OKEXIT ; IF OK, EXIT
- MOV AX,BIOSSEG-20H ; TRY MICROSOFT STD LOCATION (40H)
- CALL BIOTST
- JNC OKEXIT ; IF OK, EXIT
- ;
- IV12: MOV AX,ROMSEG
- MOV DS,AX ; SET DS=ROM SEGMENT
- XOR AX,AX ; GET A ZERO
- MOV BX,AX ; POINT TO START OF ROM
- MOV DI,AX ; INIT CHECKSUM COUNTER
- MOV CX,4 ; CHECK FOR 4 JUMPS AT START OF ROM
- ;
- CKROM: MOV AL,[BX] ; READ POSSIBLE OPCODE BYTE
- ADD DI,AX ; SUM THE TEST BYTES
- ADD BX,3 ; POINT TO POSSIBLE NEXT OPCODE
- LOOP CKROM ; SUM THE OPCODES
- ;
- CMP DI,4*(0E9H) ; SHOULD BE 4 0E9H OPCODES (JMP)
- ;
- IF INTDVR
- JNZ OKEXIT ; NO, SO LEAVE DEFAULT DRIVERS
- ENDIF
- ;
- IF NOT INTDVR
- JNZ BDEXIT ; NO, SO LEAVE WITH ERROR CONDITION
- ENDIF
- ;
- PUSH CS
- POP DS ; DS=ES=CS
- ;
- MOV SI,offset ROMTAB ; POINT TO SOURCE (ROM CALL TABLE COPY)
- CALL CPYTAB ; COPY TABLES
- ;
- DB FCALL
- DW 3,ROMSEG ; FAR CALL TO ROM "INIT" ROUTINE
- ;
- MOV AH,0 ; COMMAND FOR CARD TYPE IDENTIFY
- ;
- DB FCALL
- DW 6,ROMSEG ; FAR CALL TO DRIVE I/O ROM ENTRY
- ;
- MOV CS:CRDTYPE,AL ; SAVE CARD TYPE []
- ;
- OR AL,AL ; TEST FOR OMNINET
- JNZ OKEXIT ; IF FLAT, EXIT
- MOV AH,4 ; SET TO FIND SERVER ADDRESS
- MOV BX,ABTCTR ; SET ABORT TIME AND RETRYS
- ;
- DB FCALL
- DW 6,ROMSEG ; FAR CALL TO DRIVE I/O ROM ENTRY
- ;
- MOV CS:BOOTSRVR,AH ; SAVE SERVER #
- MOV CS:SRVR,AH
- OR AL,AL ; WAS SERVER # ACTUALLY FOUND
- BDEXIT: MOV AX,1 ; SET FOR ERROR CONDITION
- JNZ INEXIT ; NO, SO SHOW ERROR AND EXIT
- ;
- OKEXIT: MOV AX,0 ; RETURN A ZERO
- INEXIT: POP ES
- POP DS
- ;
- IF LTYPE EQ PASCAL
- RET
- ENDIF
- ;
- IF LTYPE EQ BASIC
- PUSH BP
- MOV BP,SP
- MOV BX,6 [BP] ; GET POINTER TO DATA "INTEGER"
- MOV [BX],AX ; RETURN ERROR CONDITION BYTE
- POP BP
- RET 2
- ENDIF
- ;
- INITIO ENDP
- ;
- ; --- COPY ADDRESS INFORMATION FROM SOURCE POINTED TO BY DS:SI ---
- ;
- CPYTAB PROC NEAR
- MOV DI,offset LNKTAB ; POINT TO ROUTINE LINKAGE TABLE
- MOV CX,LENTAB ; SET TO COPY
- REP MOVSB ; DO COPY
- RET
- CPYTAB ENDP
- ;
- ; --- TEST FOR "CORVUS" CONST ][ BIOS ---
- ;
- BIOTST PROC NEAR
- MOV DS,AX ; SET DATA SEGMENT TO THAT OF "BIOS"
- MOV BX,1 ; POINT TO "INIT" ADDRESS FIELD OF JUMP
- MOV BX,[BX] ; GET THIS ADDRESS IN BX
- ADD BX,1 ; OFFSET FOR INSTRUCTION SIZE
- MOV BX,[BX] ; GET POSSIBLE POINTER TO "CORTAb" STRING
- ;
- BIOT1 PROC NEAR
- MOV SI,BX ; SAVE IT
- MOV DI,offset CORTAB ; POINT TO LOCAL COPY OF STRING
- MOV CX,6 ; LENGTH OF STRING
- REPZ CMPSB ; COMPARE STRINGS
- STC ; SET CARRY TO INDICATE POSSIBLE MISMATCH
- JNZ BIOE ; EXIT IF MISMATCH
- ;
- MOV AX,DS ; GET "BIOS" SEGMENT
- MOV CL,4 ; SET TO MULTIPLY BY 16
- SHL AX,CL ; CONVERT SEGMENT # TO ADDRESS
- ADD AX,BX ; FIND "CORTAb" ADDRESS RELATIVE TO SEG. 0
- MOV CS:CORPTR,AX ; SAVE FOR POSSIBLE USE []
- ;
- MOV AL,35 [BX] ; GET "BOOT SERVER" # FROM BIOS
- MOV CS:BOOTSRVR,AL ; SAVE IT []
- MOV CS:SRVR,AL ; INIT "DEFAULT SERVER" AS "BOOT SERVER" []
- ;
- ADD BX,23 ; OFFSET TO ROM FUNCTION TABLE POINTER
- MOV SI,[BX] ; GET IT
- CALL CPYTAB ; COPY TABLE INTO THIS DRIVER
- MOV AH,0 ; ID COMMAND
- CALL far ptr CRVIO ; DO IT
- MOV CS:CRDTYPE,AL ; SAVE CARD TYPE
- CLC ; CLEAR CARRY TO INDICATE SUCCESS
- BIOE: RET
- ;
- BIOT1 ENDP
- BIOTST ENDP
- ;
- ;
- ; === RETURN POINTER TO "CORTAb" IN CORVUS BIOS ===
- ;
- PUBLIC BIOPTR
- ;
- BIOPTR PROC FAR
- MOV AX,CS:CORPTR ; GET POINTER []
- ;
- IF LTYPE EQ PASCAL
- RET
- ENDIF
- ;
- IF LTYPE EQ BASIC
- PUSH BP
- MOV BP,SP
- MOV BX,6 [BP] ; GET POINTER TO DATA "INTEGER"
- MOV [BX],AX ; RETURN POINTER
- POP BP
- RET 2
- ENDIF
- ;
- BIOPTR ENDP
- ;
- ; ==== SET SERVER # AND READ BOOT SERVER # ====
- ;
- PUBLIC SETSRVR
- ;
- SETSRVR PROC FAR
- PUSH BP ; SAVE FRAME POINTER
- MOV BP,SP ; SET NEW ONE
- ;
- IF LTYPE EQ PASCAL
- MOV CX,6 [BP] ; GET PASSED VALUE
- ENDIF
- ;
- IF LTYPE EQ BASIC
- MOV BX,6 [BP] ; GET POINTER TO VALUE
- MOV CX,[BX] ; GET ITS VALUE
- ENDIF
- ;
- OR CH,CH ; IS IT TOO BIG?
- JNZ SETS1 ; YES, SO DO NOT CHANGE PRESENT VALUE
- MOV CS:SRVR,CL ; NO, SO SET NEW DEFAULT SERVER #
- SETS1: XOR AX,AX ; GET A ZERO
- MOV AL,CS:BOOTSRVR ; GET "BOOT SERVER" # AS RETURN VALUE
- ;
- IF LTYPE EQ BASIC
- MOV [BX],AX ; SET RETURNED VALUE
- ENDIF
- ;
- POP BP ; RESTORE FRAME
- RET 2
- SETSRVR ENDP
- ;
- ; === FIND A VALID NETWORK SERVER ADDRESS ===
- ;
- PUBLIC FINDSRVR
- ;
- FINDSRVR PROC FAR
- MOV AH,4 ; FIND SERVER COMMAND ( 1.31 bug fix )
- MOV BX,ABTCTR ; SET MAX RETRY COUNT AND ABORT TIME
- CALL far ptr CRVIO ; CALL I/O DRIVER
- XCHG AL,AH ; GET SERVER # IN LSB
- ;
- IF LTYPE EQ PASCAL
- RET
- ENDIF
- ;
- IF LTYPE EQ BASIC
- PUSH BP
- MOV BP,SP
- MOV BX,6 [BP] ; GET POINTER TO DATA "INTEGER"
- MOV [BX],AX ; RETURN SERVER #
- POP BP
- RET 2
- ENDIF
- ;
- FINDSRVR ENDP
- ;
- ; === IDENTIFY CORVUS I/O CARD TYPE ===
- ;
- PUBLIC CARDID
- ;
- CARDID PROC FAR
- MOV AH,0 ; ZERO MSB
- MOV AL,CS:CRDTYPE ; GET CARD IDENTIFIER
- ;
- IF LTYPE EQ PASCAL
- RET
- ENDIF
- ;
- IF LTYPE EQ BASIC
- PUSH BP
- MOV BP,SP
- MOV BX,6 [BP] ; GET POINTER TO DATA "INTEGER"
- MOV [BX],AX ; RETURN CARD TYPE
- POP BP
- RET 2
- ENDIF
- ;
- CARDID ENDP
- ;
- ; === SEND/RECEIVE A COMMAND TO A NETWORK SERVER ===
- ;
- PUBLIC NETCMD
- ;
- NETCMD PROC FAR
- PUSH BP ; SAVE FRAME POINTER
- MOV BP,SP ; SET NEW ONE
- ;
- IF LTYPE EQ PASCAL
- MOV SI,6 [BP] ; GET ADDRESS OF INPUT STRING
- MOV DI,8 [BP] ; GET ADDRESS OF OUTPUT STRING
- ENDIF
- ;
- IF LTYPE EQ BASIC
- MOV BX,6 [BP] ; GET ADDRESS OF STRING DESCRIPTOR
- MOV SI,[BX] ; GET ADDRESS OF INPUT STRING
- MOV BX,8 [BP] ; GET ADDRESS OF STRING DESCRIPTOR
- MOV DI,[BX] ; GET ADDRESS OF OUTPUT STRING
- ENDIF
- ;
- PUSH DS
- POP ES ; SET ES=DS (SAVE SEGMENT)
- ;
- MOV CX,[SI] ; LOOK AT LENGTH
- MOV AL,CL ; SAVE FOR RETURN STATUS
- JCXZ NETE ; IF ZERO, SET RET LENGTH TO ZERO AND RET
- ;
- PUSH DI
- INC SI
- INC SI ; POINT TO SEND DATA ( DS:SI )
- ;
- INC DI
- INC DI ; POINT TO PLACE TO SAVE RETURNED DATA ( ES:DI)
- ;
- MOV DX,530 ; SET MAX # OF RETURNED BYTES
- ;
- MOV AH,3 ; SET FOR SERVER CMD
- MOV AL,CS:SRVR ; SET DISK SERVER #
- MOV BX,ABTCTR ; SET ABORT TIME AND # OF RETRYS
- CALL far ptr CRVIO ; DO DISK I/O
- ;
- POP DI ; GET POINTER BACK TO LENGTH
- MOV CX,[DI] ; GET LENGTH PREVIOUSLY SET
- NETE: MOV [DI],CX ; SET LENGTH OF RETURNED STRING
- MOV AH,0 ; CLEAR MSB OF RETURNED VALUE
- ;
- IF LTYPE EQ PASCAL
- POP BP ; GET FRAME POINTER BACK
- RET 4 ; CLEAR RETURN STACK
- ENDIF
- ;
- IF LTYPE EQ BASIC
- MOV BX,10 [BP] ; GET POINTER TO DATA "INTEGER"
- MOV [BX],AX ; RETURN ERROR CONDITION BYTE
- POP BP
- RET 6
- ENDIF
- ;
- NETCMD ENDP
- ;
- ; === RECEIVE A STRING OF BYTES FROM THE DRIVE ===
- ;
- PUBLIC CDRECV, DRVRECV
- ;
- CDRECV PROC FAR
- DRVRECV:
- PUSH BP ; SAVE FRAME POINTER
- MOV BP,SP ; SET NEW ONE
- ;
- IF LTYPE EQ PASCAL
- MOV DI,6 [BP] ; GET ADDRESS OF STRING TO SAVE DATA IN
- ENDIF
- ;
- IF LTYPE EQ BASIC
- MOV BX,6 [BP] ; GET ADDRESS OF STRING DESCRIPTOR
- INC BX
- INC BX ; POINT TO STRING POINTER
- MOV DI,[BX] ; GET ADDRESS OF STRING TO SAVE DATA IN
- ENDIF
- ;
- PUSH DS
- POP ES ; SET ES=DS (SAVE SEGMENT)
- ;
- PUSH DI
- PUSH DS
- ;
- LDS SI,CS:dword ptr SNDPTR ; GET POINTER TO SOURCE STRING
- MOV CX,[SI] ; LOOK AT LENGTH
- MOV AL,CL ; SAVE FOR RETURN STATUS
- JCXZ RLPE ; IF ZERO, SET RET LENGTH TO ZERO AND RET
- ;
- INC SI
- INC SI ; POINT TO SEND DATA ( DS:SI )
- ;
- INC DI
- INC DI
- INC DI ; POINT TO PLACE TO SAVE RETURNED DATA ( ES:DI)
- ;
- MOV DX,530 ; SET MAX # OF RETURNED BYTES
- ;
- MOV AH,1 ; SET FOR "BCI" LIKE COMMAND
- MOV AL,CS:SRVR ; SET DISK SERVER #
- MOV BX,ABTCTR ; SET ABORT TIME AND # OF RETRYS
- CALL far ptr CRVIO ; DO DISK I/O
- ;
- RLPE: POP DS
- POP DI ; GET POINTER BACK TO LENGTH
- MOV [DI],CX ; SET LENGTH OF RETURNED STRING
- MOV 2 [DI],AL ; SAVE RETURN STATUS
- POP BP ; GET FRAME POINTER BACK
- RET 2 ; CLEAR RETURN STACK
- CDRECV ENDP
- ;
- ; === SEND STRING OF BYTES TO DRIVE ===
- ;
- ; THIS CONSTELLATION VERSION
- ; JUST SAVES TWO POINTERS TO
- ; THE DATA STRING TO SEND. THE
- ; CDRECV ROUTINE ACTUALLY SENDS
- ; THE DATA AND RECEIVES THE
- ; RETURN STATUS
- ;
- PUBLIC CDSEND, DRVSEND
- ;
- CDSEND PROC FAR
- DRVSEND:
- PUSH BP ; SAVE FRAME POINTER
- MOV BP,SP ; SET NEW ONE
- ;
- IF LTYPE EQ PASCAL
- MOV AX,6 [BP] ; GET ADDRESS OF STRING TO SEND
- ENDIF
- ;
- IF LTYPE EQ BASIC
- MOV BX,6 [BP] ; GET ADDRESS OF STRING DESCRIPTOR
- INC BX
- INC BX ; POINT TO STRING POINTER
- MOV AX,[BX] ; GET ADDRESS OF STRING TO SAVE DATA IN
- ENDIF
- ;
- MOV CS:SNDPTR,AX ; SAVE IT []
- ;
- MOV AX,DS ; GET DATA SEGMENT
- MOV CS:SNDSEG,AX ; SAVE IT []
- ;
- POP BP ; GET FRAME POINTER BACK
- RET 2 ; CLEAR RETURN STACK
- CDSEND ENDP
- ;
- ;
- ;
- ;
- ; ============ FLAT CABLE R/W ROUTINES ==============
- ;
- ; THESE ROUTINES ARE ESSENTIALLY THE SAME AS THE FLAT CABLE
- ; DRIVERS IN THE "ROM". THEY ARE REPRODUCED HERE SO THAT
- ; SYSTEMS WITH FLAT CABLE INTERFACES NEED NOT HAVE A "ROM"
- ; TO WORK WITH CONSTELLATION ][ SOFTWARE.
- ;
- ; --- BUFFERS USED BY "ROM" DRIVER ROUTINES ---
- ;
- CLICKS DB 0 ; BUFFER FOR SAVING # OF CLOCK TICKS
- STOPTM DW 0 ; BUFFER FOR SAVING STOP TIME
- RMCMD DB 0 ; BUFFER FOR SAVING PASSED "ROM" CMD
- BLKLEN DW 512 ; BUFFER FOR SAVING # OF BYTES TO XFER
- CMDLEN DW 4 ; BUFFER FOR SAVING LENGTH OF CMD
- RTNCODE DB 0 ; BUFFER FOR SAVING DISK RETURN CODE
- ;
- ; --- SET TIMER ---
- ;
- STIME PROC NEAR
- XOR AH,AH ; READ TIME OF DAY CLOCK
- INT 1AH
- JMP STIME1
- ;
- ; --- CHECK FOR TIMOUT ---
- ;
- CKTIME: CMP CS:CLICKS,0 ; WAS A WAIT REQUESTED? []
- CLC
- JZ CKRET ; NO, SO RETURN WITH CARRY CLEAR
- XOR AH,AH ; TIME OF DAY CALL
- INT 1AH
- OR AL,AL ; HAS CLOCK WRAPPED AROUND TO ZERO?
- JZ CKT1 ; NO
- ;
- ; IF CLOCK HAS PASSED 24 HOURS, RECALCULATE STOP TIME
- ;
- STIME1: MOV AL,CS:CLICKS ; GET # OF CLOCK TICKS OF DELAY []
- XOR AH,AH
- MOV CL,4 ; SET TO MULTIPLY BY 16
- SHL AX,CL ; DO IT BY SHIFTING
- ADD DX,AX
- MOV CS:STOPTM,DX ; SAVE STOP TIME []
- CHKOK: CLC ; CLEAR CARRY ( TIME CHECK IS OK )
- RET
- ;
- CKT1: CMP DX,CS:STOPTM ; TIMEOUT? []
- JB CHKOK
- ;
- STC ; SET CARRY IF TIMEOUT
- CKRET: RET
- STIME ENDP
- ;
- ; ---- MAIN DRIVER ENTRY POINT ---
- ;
- DRVIO PROC FAR
- CLD ; SET FOR "INCREMENT"
- MOV CS:RMCMD,AH ; SAVE COMMAND []
- CMP AH,1 ; IS IT A "BCI" COMMAND?
- JZ RW15 ; YES, SO DO IT
- CMP AH,5 ; IS IT A "WRITE" COMMAND?
- JZ RW15 ; YES, SO DO IT
- CMP AH,0 ; IS IT AN "IDENTIFY" COMMAND
- JZ RW00 ; YES, SO DO IT
- MOV AL,0FFH ; IF ANY OTHER, INDICATE "ABORT" OR ERROR
- MOV CX,0
- RET ; LONG RET
- ;
- RW00: MOV AL,1 ; INDICATE FLAT CABLE
- RET ; LONG RET
- ;
- ;
- RW15: PUSH DS ; SAVE REGISTERS THAT MAY BE CHANGED
- PUSH SI
- PUSH DI
- PUSH BX
- PUSH DX
- ;
- MOV CS:CLICKS,BL ; SAVE # OF TIMER CLICKS []
- MOV CS:BLKLEN,DX ; SAVE BLOCK LENGTH []
- MOV CS:CMDLEN,CX ; SAVE CMD LENGTH []
- CALL ROMIO ; DO DISK I/O
- POP DX
- POP BX
- POP DI
- POP SI
- POP DS
- MOV AL,CS:RTNCODE ; GET RETURN CODE []
- ;
- DMYLRET LABEL FAR
- RET ; LONG RET
- ;
- DMYIRET LABEL FAR
- IRET ; DUMMY "IRET"
- ;
- DRVIO ENDP
- ;
- ROMIO PROC NEAR
- CALL STIME ; SETUP TIMER COUNT
- ;
- RO1: MOV DX,STAT ; POINT TO STATUS PORT
- CLI ; DISABLE INTERRUPTS FOR TEST
- IN AL,DX ; READ DRIVE STATUS BYTE
- TEST AL,DRDY ; IS IT READY?
- JZ RO2 ; YES, SO PROCEED
- STI ; NO, SO RE-ENABLE INTERRUPTS
- CALL CKTIME ; CHECK IF TIMED OUT
- JNC RO1 ; IF NOT, TRY AGAIN
- ARET: MOV CS:RTNCODE,0FFH ; IF TIMED OUT, SET ERROR []
- MOV CX,0 ; INDICATE NO DATA RETURNED
- RET
- ;
- RO2: MOV CX,CS:CMDLEN ; GET CMD LENGTH []
- CALL SNDBLK ; SEND BLOCK OF DATA TO DRIVE
- CMP CS:RMCMD,5 ; WAS CMD A "WRITE" CMD? []
- JNZ RCVBLK ; NO, SO GO RECEIVE DATA
- ;
- MOV SI,DI ; YES, POINT TO SECTOR DATA
- MOV AX,ES
- MOV DS,AX
- MOV CX,CS:BLKLEN ; GET LENGTH OF DATA BLOCK []
- CALL SNDBLK ; SEND SECTOR DATA
- ;
- RCVBLK: CALL STIME ; SET TIMER
- ;
- CALL DELAY1 ; DELAY
- ;
- RCV1: CALL CKTIME ; TIMED OUT YET?
- JC ARET ; YES, SO RETURN WITH ERROR
- ;
- RCV2: MOV DX,STAT ; POINT TO STATUS PORT
- IN AL,DX ; READ DRIVE STATUS BYTE
- TEST AL,DIFAC ; TEST BUS DIRECTION
- JNZ RCV1 ; WAIT FOR "HOST TO DRIVE"
- TEST AL,DRDY ; TEST IF ALSO READY
- JNZ RCV1
- ;
- CALL DELAY1 ; WAIT TO BE SURE
- ;
- IN AL,DX ; TEST STATUS AGAIN
- TEST AL,DIFAC
- JNZ RCV1 ; IF FALSE ALARM, TRY AGAIN
- TEST AL,DRDY
- JNZ RCV1 ; IF NOT READY, TRY AGAIN
- ;
- DEC DX ; POINT TO DATA PORT
- IN AL,DX ; GET RETURN CODE
- INC DX ; POINT BACK TO STATUS PORT
- ;
- MOV CX,1 ; INDICATE 1 BYTE WAS RETURNED
- MOV CS:RTNCODE,AL ; SAVE IT []
- CMP CS:RMCMD,5 ; WAS CMD A "WRITE" CMD []
- JZ RCRET ; YES, SO RETURN
- ;
- MOV BX,CX ; OTHERWISE SET COUNTER
- MOV CX,CS:BLKLEN ; GET LENGTH OF EXPECTED DATA
- ;
- RCV3: IN AL,DX ; GET STATUS AGAIN
- TEST AL,DRDY ; IS DRIVE READY?
- JNZ RCV3 ; NO, SO WAIT
- TEST AL,DIFAC ; ARE WE DONE?
- JNZ RCV4 ; POSSIBLY, ...
- ;
- DEC DX ; POINT TO DATA PORT
- IN AL,DX ; GET DATA FROM DRIVE
- INC DX ; POINT BACK TO STATUS PORT
- ;
- JCXZ RCVS ; IF DATA NOT WANTED
- STOSB ; SAVE DATA IN BUFFER
- DEC CX ; COUNT DOWN # TO SAVE
- ;
- RCVS: INC BX ; COUNT UP # RECEIVED
- JMP RCV3 ; LOOP UNTIL EXIT
- ;
- RCV4: IN AL,DX ; GET STATUS BYTE
- TEST AL,DRDY ; IS DRIVE READY
- JNZ RCV3 ; NO, SO PREVIOUS RESULT MAY BE FALSE
- TEST AL,DIFAC ; IS IT STILL "HOST TO DRIVE"?
- JZ RCV3 ; NO, SO TRY AGAIN
- ;
- MOV CX,BX ; GET # OF BYTES RECEIVED
- RCRET: RET
- ;
- DELAY1: MOV BL,15 ; SET DELAY
- DELAY: DEC BL
- JNZ DELAY ; LOOP UNTIL DONE
- RET
- ;
- ; --- SEND BLOCK OF DATA TO DRIVE ---
- ;
- SNDBLK: MOV DX,STAT ; POINT TO STATUS PORT
- ;
- SND1: IN AL,DX ; GET STATUS BYTE
- TEST AL,DRDY ; IS DRIVE READY?
- JNZ SND1 ; NO, SO LOOP
- ;
- DEC DX ; POINT TO DATA PORT
- LODSB ; GET DATA FROM MEMORY
- OUT DX,AL ; SEND DATA TO DRIVE
- INC DX ; POINT BACK TO STATUS PORT
- ;
- STI ; RE-ENABLE INTERRUPTS
- LOOP SND1 ; CONTINUE UNTIL DONE
- RET
- ;
- ROMIO ENDP
- ;
- ;
- ; ---- INTERFACE "FAR" CALL TABLE ---
- ; THIS TABLE GETS PATCHED
- ; TO EITHER "BIOS" CALLS OR
- ; "ROM" CALLS IF THE APPROPRIATE
- ; LINK IS FOUND
- ;
- LNKTAB PROC NEAR
- JMP DMYLRET ;
- JMP DMYLRET ;
- ;
- CRVIO LABEL FAR
- JMP DRVIO ; THIS SHOULD BE A FAR CALL
- ;
- JMP DMYIRET ; THIS SHOULD BE A FAR JUMP
- LNKTAB ENDP
- ;
- ; =========================================================
- ;
- PGSEG ENDS
- ;
- ;
- END
-