home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / BBS_UTIL / BM0406_A.ZIP / BMASM.ZIP / BDRIVEC2.ASM < prev    next >
Assembly Source File  |  1992-08-02  |  25KB  |  937 lines

  1.     TITLE    DRIVEIO
  2. ;
  3. ; Changes made by Scott McNay (1:395/11) July 26, 1992, to allow routine to be
  4. ; used with code compiled with BC's /Fs option.  (Most) changes marked with
  5. ; ;BCFS0726.  May have optimized some code also.  This is a plug-in replacement
  6. ; for the original code.
  7.  
  8. ;BCFS0801: Standardized code format.  Made sure that DI, SI, BP, and DS are
  9. ;  saved to meet requirements of BC 7.x.  Commented out routines not used by
  10. ;  RBBS.
  11. ;
  12. ;
  13. ; --- CORVUS/IBM DRIVE INTERFACE UNIT FOR MICROSOFT ---
  14. ;    PASCAL AND BASIC COMPILERS
  15. ;    CONST ][ VERSION FOR DOS 1.10 & 2.0
  16. ;
  17. ;    VERSION 1.41 BY BRK
  18. ;    (MICROSOFT ASSEMBLER VERSION)
  19. ;
  20. ;
  21. ; NOTE: THIS INTERFACE UNIT NOW SUPPORTS BOTH PASCAL AND BASIC
  22. ;    COMPILERS BUT IT MUST BE RE-ASSEMBLED WITH THE APPROPRIATE
  23. ;    SETTING OF THE  "LTYPE"  EQUATE TO DO THIS FOR EACH LANGUAGE.
  24. ;
  25. ;
  26. ;
  27. ;    THIS UNIT IMPLEMENTS 9 PROCEDURES:
  28. ;
  29. ;    INITIO
  30. ;    BIOPTR        - CONST. ][
  31. ;    SETSRVR        - CONST. ][
  32. ;    FINDSRVR    - CONST. ][
  33. ;    NETCMD        - CONST. ][
  34. ;    CDRECV = DRVRECV
  35. ;    CDSEND = DRVSEND
  36. ;
  37. ;    THE CALLING PROCEDURE IN PASCAL IS :
  38. ;
  39. ;        CDSEND (VAR st : longstring)
  40. ;
  41. ;    THE FIRST TWO BYTES OF THE STRING ARE THE LENGTH
  42. ;    OF THE STRING TO BE SENT OR THE LENGTH OF THE 
  43. ;    STRING RECEIVED.
  44. ;
  45. ;        function INITIO    : INTEGER
  46. ;
  47. ;    THE FUNCTION RETURNS A VALUE TO INDICATE THE STATUS OF
  48. ;    THE INITIALIZATION OPERATION.  A VALUE OF ZERO INDICATES
  49. ;    THAT THE INITIALIZATION WAS SUCCESSFUL.  A NON-ZERO VALUE
  50. ;    INDICATES THE I/O WAS NOT SETUP AND THE CALLING PROGRAM
  51. ;    SHOULD NOT ATTEMPT TO USE THE CORVUS DRIVERS.
  52. ;
  53. ;        function BIOPTR    : INTEGER
  54. ;
  55. ;    THE FUNCTION RETURNS A 16 BIT POINTER TO THE "CORTAB"
  56. ;    BIOS TABLE IN THE CORVUS "BIOS" DRIVERS.  THIS ROUTINE
  57. ;    SHOULD NOT BE EXECUTED BEFORE A SUCCESSFUL USE OF THE
  58. ;    "INITIO" ROUTINE (ABOVE).  NOTE: THE RETURNED VALUE IS
  59. ;    RELATIVE TO "SEGMENT" ZERO, AND A RETURNED VALUE OF ZERO
  60. ;    INDICATES THAT THE "CORTAB" TABLE COULD NOT BE FOUND.
  61. ;
  62. ;        function SETSRVR (srvr : integer): INTEGER
  63. ;
  64. ;    THE FUNCTION RETURNS THE "BOOT SERVER" NETWORK ADDRESS.
  65. ;    IF THE INPUT PARAMETER IS LESS THAN 255 (BUT NOT NEGATIVE),
  66. ;    IT WILL BE TAKEN AS A RESET OF THE DEFAULT SERVER # WHEN
  67. ;    USING THE SEND & RECIEVE ROUTINES.  IF IT IS GREATER THAN 255
  68. ;    OR NEGATIVE, NO CHANGE OF THE DEFAULT SERVER # WILL BE MADE.
  69. ;    NOTE: THE DEFAULT SERVER # IS AUTOMATICALLY SET TO THE
  70. ;    BOOT SERVER # WHEN THE "INITIO" FUNCTION IS EXECUTED.
  71. ;    
  72. ;        function FINDSRVR : INTEGER
  73. ;
  74. ;    THE FUNCTION RETURNS THE NETWORK ADDRESS OF A VALID DISK SERVER.
  75. ;    IF THE RETURNED VALUE IS GREATER THAN 63 OR NEGATIVE, THE COMMAND
  76. ;    FAILED TO FIND A SERVER (THE FLAT CABLE CARDS WOULD DO THIS).
  77. ;
  78. ;        function CARDID : INTEGER
  79. ;
  80. ;    THE FUNCTION RETURNS THE CORVUS INTERFACE CARD TYPE (0 - OMNINET,
  81. ;    1 - FLAT CABLE).
  82. ;
  83. ;        function NETCMD (VAR inp, VAR out: longstring) : INTEGER
  84. ;
  85. ;    THE FUNCTION IS USED TO SEND/RECIEVE DATA TO A NETWORK SERVER.
  86. ;    STRING  inp  SPECIFIES THE COMMAND TO SEND TO THE SERVER,
  87. ;    AND STRING  out  IS WHERE ANY RETURNED DATA WILL BE PLACED
  88. ;    ( THE STRING LENGTH OF  out  WILL NOT BE CHANGED BY THIS
  89. ;    OPERATION UNLESS THE COMMAND FAILED- IN WHICH CASE THE LENGTH
  90. ;    WILL BE SET TO ZERO).  THE VALUE OF THE FUNCTION WILL BE
  91. ;    RETURNED AS  ZERO  IF THE OPERATION WAS SUCCESSFUL, AND
  92. ;    NON-ZERO IF IT FAILED.
  93. ;    NOTE: THE SERVER # USED WILL BE THE "BOOT SERVER" # UNLESS
  94. ;    THE DEFAULT IS CHANGED BY THE  "SETSRVR" CMD.
  95. ;
  96. ;
  97. ;
  98. ;
  99. ;    THE CALLING PROCEDURE BASIC IS :
  100. ;
  101. ;        CALL CDSEND (B$)
  102. ;
  103. ;    THE FIRST TWO BYTES OF THE STRING ARE THE LENGTH
  104. ;    OF THE STRING TO BE SENT OR THE LENGTH OF THE 
  105. ;    STRING RECEIVED (I.E. LEFT$(B$,2)).
  106. ;
  107. ;        CALL INITIO (A%)
  108. ;
  109. ;    THE FUNCTION RETURNS A VALUE TO INDICATE THE STATUS OF
  110. ;    THE INITIALIZATION OPERATION.  A VALUE OF ZERO INDICATES
  111. ;    THAT THE INITIALIZATION WAS SUCCESSFUL.  A NON-ZERO VALUE
  112. ;    INDICATES THE I/O WAS NOT SETUP AND THE CALLING PROGRAM
  113. ;    SHOULD NOT ATTEMPT TO USE THE CORVUS DRIVERS.
  114. ;
  115. ;        CALL BIOPTR (A%)
  116. ;
  117. ;    THE FUNCTION RETURNS A 16 BIT POINTER TO THE "CORTAB"
  118. ;    BIOS TABLE IN THE CORVUS "BIOS" DRIVERS.  THIS ROUTINE
  119. ;    SHOULD NOT BE EXECUTED BEFORE A SUCCESSFUL USE OF THE
  120. ;    "INITIO" ROUTINE (ABOVE).  NOTE:  THE RETURNED VALUE IS
  121. ;    RELATIVE TO "SEGMENT" ZERO, AND A RETURNED VALUE OF ZERO
  122. ;    INDICATES THAT THE "CORTAB" TABLE COULD NOT BE FOUND.
  123. ;
  124. ;        CALL SETSRVR (A%)     here A% is used for input and output
  125. ;
  126. ;    THE FUNCTION RETURNS THE "BOOT SERVER" NETWORK ADDRESS.
  127. ;    IF THE INPUT PARAMETER IS LESS THAN 255 (BUT NOT NEGATIVE),
  128. ;    IT WILL BE TAKEN AS A RESET OF THE DEFAULT SERVER # WHEN
  129. ;    USING THE  SEND & RECIEVE  ROUTINES.  IF IT IS GREATER THAN 255
  130. ;    OR NEGATIVE, NO CHANGE OF THE DEFAULT SERVER # WILL BE MADE.
  131. ;    NOTE: THE DEFAULT SERVER # IS AUTOMATICALLY SET TO THE
  132. ;    BOOT SERVER # WHEN THE  "INITIO" FUNCTION IS EXECUTED.
  133. ;    
  134. ;        CALL FINDSRVR (A%)
  135. ;
  136. ;    THE FUNCTION RETURNS THE NETWORK ADDRESS OF A VALID DISK SERVER.
  137. ;    IF THE RETURNED VALUE IS GREATER THAN 63 OR NEGATIVE, THE COMMAND
  138. ;    FAILED TO FIND A SERVER (THE FLAT CABLE CARDS WOULD DO THIS).
  139. ;
  140. ;        CALL CARDID (A%)
  141. ;
  142. ;    THE FUNCTION RETURNS THE CORVUS INTERFACE CARD TYPE (0 - OMNINET,
  143. ;    1 - FLAT CABLE).
  144. ;
  145. ;        CALL NETCMD (A$,B$,C%)
  146. ;
  147. ;    THE FUNCTION IS USED TO SEND/RECIEVE DATA TO A NETWORK SERVER.
  148. ;    STRING A$ SPECIFIES THE COMMAND TO SEND TO THE SERVER,
  149. ;    AND STRING B$ IS WHERE ANY RETURNED DATA WILL BE PLACED
  150. ;    (THE STRING LENGTH OF out WILL NOT BE CHANGED BY THIS
  151. ;    OPERATION UNLESS THE COMMAND FAILED- IN WHICH CASE THE LENGTH
  152. ;    WILL BE SET TO ZERO).  THE VALUE OF THE FUNCTION WILL BE
  153. ;    RETURNED (IN C%) AS ZERO IF THE OPERATION WAS SUCCESSFUL, AND
  154. ;    NON-ZERO IF IT FAILED.
  155. ;    NOTE: THE SERVER # USED WILL BE THE "BOOT SERVER" # UNLESS
  156. ;    THE DEFAULT IS CHANGED BY THE  "SETSRVR" CMD.
  157. ;
  158. ;=============================================================
  159. ;            REVISION HISTORY
  160. ;
  161. ; FIRST VERSION : 10-05-82  BY BRK
  162. ;         : 11-01-82  improved turn around delay for mirror
  163. ;        : 02-16-83  CONST. ][ version
  164. ;        : 05-16-83  added support for Basic
  165. ;        : 07-06-83  fixed bug in FINDSRVR routine
  166. ; V1.40        : 07-29-83  updated for DOS 2.0 
  167. ; V1.41        : 08-04-83  set timeout to zero to avoid ROM bug
  168. ;
  169. ;=============================================================
  170. ;
  171.  
  172.     extrn    StringAddress:far
  173.  
  174. ;TRUE    EQU    0FFFFH
  175. FALSE    EQU    0
  176. ;
  177. LPASCAL    EQU    1    ; LANGUAGE TYPE DESCRIPTOR
  178. LBASIC    EQU    2    ; LANGUAGE TYPE DESCRIPTOR
  179. ;
  180. LTYPE    EQU    LBASIC    ; SET TO LANGUAGE TYPE TO BE USED WITH
  181. INTDVR    EQU    FALSE    ; SET TO FALSE TO DISABLE INTERNAL FLAT CABLE DRIVER
  182. ;
  183. ;
  184. ; ----- CORVUS EQUATES -----
  185. ;
  186. ;DATA    EQU    2EEH    ; DISC I/O PORT #
  187. STAT    EQU    2EFH    ; DISC STATUS PORT
  188. DRDY    EQU    1    ; MASK FOR DRIVE READY BIT
  189. DIFAC    EQU    2    ; MASK FOR BUS DIRECTION BIT
  190. ROMSEG    EQU    0DF00H    ; LOCATION OF CORVUS ROM
  191. BIOSSEG    EQU    60H    ; STD IBM BIOS SEGMENT ADDRESS
  192. ABTCTR    EQU    0A00H    ; VALUE TO SET TIMEOUT AND # OF RETRYS
  193. ;            ;   v1.41  timeouts=0
  194. ;
  195. FCALL    EQU    9AH    ; OPCODE FOR FAR CALL
  196. FJMP    EQU    0EAH    ; OPCODE FOR FAR JUMP
  197. ;
  198. ; --- MSDOS EQUATES ( V2.0 ) ---
  199. ;
  200. VERCMD    EQU    30H    ; BDOS COMMAND TO GET VERSION #
  201. HOPEN    EQU    3DH    ; BDOS COMMAND TO "OPEN" A FILE HANDLE
  202. HCLOSE    EQU    3EH    ; BDOS COMMAND TO "CLOSE" A FILE HANDLE
  203. HREAD    EQU    3FH    ; BDOS COMMAND TO "READ" FROM A FILE
  204. HWRITE    EQU    40H    ; BDOS COMMAND TO "WRITE" TO A FILE
  205. ;
  206. PGSEG    SEGMENT 'CODE'
  207.     ASSUME    CS:PGSEG
  208. ;
  209. ;
  210. ; I hope no one complains about these being left out.
  211. ;    IF    LTYPE EQ LPASCAL
  212. ;    DB    "CORVUS/IBM PC CONST. ][ PASCAL DRIVER AS OF 08-04-83"
  213. ;    ENDIF
  214. ;
  215. ;    IF    LTYPE EQ LBASIC
  216. ;    DB    "CORVUS/IBM PC CONST. ][ BASIC  DRIVER AS OF 08-04-83"
  217. ;    ENDIF
  218. ;
  219. ; --- COPY OF "ROM" FAR JUMP TABLE ---
  220. ;
  221. ROMTAB    PROC    NEAR
  222.     DB    FJMP
  223.     DW    0,ROMSEG    ; FAR JUMP TO COLD BOOT ROM ENTRY
  224.     DB    FJMP
  225.     DW    3,ROMSEG    ; FAR JUMP TO WARM START ROM ENTRY
  226.     DB    FJMP
  227.     DW    6,ROMSEG    ; FAR JUMP TO I/O ROM ENTRY
  228.     DB    FJMP
  229.     DW    9,ROMSEG    ; FAR JUMP TO DUMMY "IRET" ENTRY
  230. LENTAB    EQU    offset $-offset ROMTAB    ; LENGTH OF TABLE
  231. ROMTAB    ENDP
  232. ;
  233. ; --- COPY OF CORVUS TABLE IDENTIER ---
  234. ;
  235. CORTAB    DB    'CORTAb'    ; VERSION FOR CONST. ][
  236. ;
  237. ; --- COPY OF UTILITY "HOOK" DRIVER NAME ---
  238. ;
  239. UTILPTR    DB    'UTILHOOK',0
  240. ;
  241. ;
  242. ; --- THESE DATA POINTERS MUST BE KEPT IN THE SAME RELATIVE ORDER
  243. ;
  244. SNDPTR    DW    0        ; BUFFER TO SAVE POINTER TO 'SEND' STRING
  245. SNDSEG    DW    0        ; BUFFER TO SAVE 'SEND' STRING SEGMENT #
  246. ;
  247. CORVEC    DW    0,0        ; BUF TO SAVE DOUBLE WORD POINTER TO "CORTAB"
  248. ;
  249. ; --- MISC DATA AND BUFFERS ----
  250. ;
  251. CORPTR    DW    0        ; BUFFER FOR "CORTAB" POINTER
  252. ;                ;  INITIALIZE INITIALLY TO ZERO
  253. CRDTYPE    DB    1        ; BUFFER TO SAVE "CARD TYPE" BYTE
  254. BOOTSRVR DB    0FFH        ; BUFFER FOR "BOOT SERVER"
  255. SRVR    DB    0FFH        ; BUFFER FOR "DEFAULT SERVER"
  256. ;
  257. ;
  258. ; === INITIALIZE CORVUS I/O DRIVERS ===
  259. ;
  260. ;    THIS ROUTINE MUST BE CALLED
  261. ;    ONCE TO SETUP THE DRIVERS BEFORE
  262. ;    THEY ARE USED. IF THE ROUTINE DOES
  263. ;    ANYTHING THAT CAN ONLY BE DONE ONCE,
  264. ;    IT MUST DISABLE THIS SECTION SO THAT
  265. ;    AND ACCIDENTAL SECOND CALL WILL NOT
  266. ;    LOCK UP THE HARDWARE.
  267. ;
  268.     PUBLIC INITIO
  269. ;
  270. INITIO    PROC    FAR
  271. int    3        ;For debugging.  Remove when verified
  272.     PUSH    DS
  273.     PUSH    ES
  274.     PUSH    DI                                  ;BCFS0801
  275.     PUSH    SI                                  ;BCFS0801
  276.     PUSH    CS
  277.     POP    ES        ; SET ES=CS
  278.     CLD
  279. ;
  280.     MOV    AH,VERCMD    ; MSDOS VERSION CHECK COMMAND
  281.     INT    21H        ; GET VERSION # OF DOS
  282.     OR    AL,AL        ; IS IT V 1.1 OR 1.0?
  283.     JZ    IV11        ; YES, SO TRY FINDING "CORTAb"
  284. ;
  285.     PUSH    CS
  286.     POP    DS        ; SET TO LOCAL SEGMENT FOR TESTING
  287. ;
  288.     MOV    AH,HOPEN    ; SET MSDOS 2.X, OPEN HANDLE COMMAND
  289.     MOV    AL,2        ; OPEN FOR R/W
  290.     MOV    DX,offset UTILPTR ; POINT TO "HOOK" DRIVER NAME
  291.     INT    21H        ; DO IT
  292.     JC    IV12        ; IF ERROR, TRY FOR IBM ROM
  293. ;
  294.     MOV    BX,AX        ; GET "HANDLE" IN (BX)
  295.     MOV    AH,HWRITE    ; GET WRITE CMD
  296.     MOV    CX,2        ; SET TO WRITE 2 CHARS
  297.     MOV    DX,offset UTILPTR ; USE NAME FOR SOURCE OF CHARACTERS
  298.     INT    21H        ; THIS SHOULD RESET "POINTER" IN DRIVER
  299. ;
  300.     MOV    AH,HREAD    ; SET READ CMD
  301.     MOV    CX,4        ; SET TO READ  DOUBLE WORD
  302.     MOV    DX,offset CORVEC ; POINT TO DESTINATION OF READ
  303.     INT    21H        ; DO IT
  304. ;
  305.     MOV    AH,HCLOSE    ; GET CLOSE CMD
  306.     INT    21H        ; CLOSE HANDLE
  307. ;
  308.     LDS    BX,dword ptr CORVEC ; GET POSSIBLE POINTER TO "CORTAb"
  309.     CALL    BIOT1        ; TEST FOR "CORTAb"
  310.     JNC    OKEXIT        ; IF OK, EXIT
  311.     JMP    IV12        ; OTHERWISE PROCEED
  312. ;
  313. IV11:    MOV    AX,BIOSSEG    ; SET TO TEST STD IBM SEGMENT ADD
  314.     CALL    BIOTST        ; TEST BIOS AND LINK TO IT IF OK
  315.     JNC    OKEXIT        ; IF OK, EXIT
  316.     MOV    AX,BIOSSEG-20H    ; TRY MICROSOFT STD LOCATION (40H)
  317.     CALL    BIOTST
  318.     JNC    OKEXIT        ; IF OK, EXIT
  319. ;
  320. IV12:    MOV    AX,ROMSEG
  321.     MOV    DS,AX        ; SET DS=ROM SEGMENT
  322.     XOR    AX,AX        ; GET A ZERO
  323.     MOV    BX,AX        ; POINT TO START OF ROM
  324.     MOV    DI,AX        ; INIT CHECKSUM COUNTER
  325.     MOV    CX,4        ; CHECK FOR  4  JUMPS AT START OF ROM
  326. ;
  327. CKROM:    MOV    AL,[BX]        ; READ POSSIBLE OPCODE BYTE
  328.     ADD    DI,AX        ; SUM THE TEST BYTES
  329.     ADD    BX,3        ; POINT TO POSSIBLE NEXT OPCODE
  330.     LOOP    CKROM        ; SUM THE OPCODES
  331. ;
  332.     CMP    DI,4*(0E9H)    ; SHOULD BE 4  0E9H  OPCODES (JMP)
  333. ;
  334.      IF    INTDVR
  335.     JNZ    OKEXIT        ; NO, SO LEAVE DEFAULT DRIVERS
  336.      ENDIF
  337. ;
  338.      IF    NOT INTDVR
  339.     JNZ    BDEXIT        ; NO, SO LEAVE WITH ERROR CONDITION
  340.      ENDIF
  341. ;
  342.     PUSH    CS
  343.     POP    DS        ; DS=ES=CS
  344. ;
  345.     MOV    SI,offset ROMTAB    ; POINT TO SOURCE (ROM CALL TABLE COPY)
  346.     CALL    CPYTAB        ; COPY TABLES
  347. ;
  348.     DB    FCALL
  349.     DW    3,ROMSEG    ; FAR CALL TO ROM "INIT" ROUTINE
  350. ;
  351.     MOV    AH,0        ; COMMAND FOR CARD TYPE IDENTIFY
  352. ;
  353.     DB    FCALL
  354.     DW    6,ROMSEG    ; FAR CALL TO DRIVE I/O ROM ENTRY
  355. ;
  356.     MOV    CS:CRDTYPE,AL    ; SAVE CARD TYPE []
  357. ;
  358.     OR    AL,AL        ; TEST FOR OMNINET
  359.     JNZ    OKEXIT        ; IF FLAT, EXIT
  360.     MOV    AH,4        ; SET TO FIND SERVER ADDRESS
  361.     MOV    BX,ABTCTR    ; SET ABORT TIME AND RETRYS
  362. ;
  363.     DB    FCALL
  364.     DW    6,ROMSEG    ; FAR CALL TO DRIVE I/O ROM ENTRY
  365. ;
  366.     MOV    CS:BOOTSRVR,AH    ; SAVE SERVER #
  367.     MOV    CS:SRVR,AH
  368.     OR    AL,AL        ; WAS SERVER # ACTUALLY FOUND
  369. BDEXIT:    MOV    AX,1        ; SET FOR ERROR CONDITION
  370.     JNZ    INEXIT        ; NO, SO SHOW ERROR AND EXIT
  371. ;
  372. OKEXIT:    XOR    AX,AX    ; RETURN A ZERO                          ;BCFS0801
  373. INEXIT:    POP    SI                                  ;BCFS0801
  374.     POP    DI                                  ;BCFS0801
  375.     POP    ES                                  ;BCFS0801
  376.     POP    DS
  377. ;
  378.     IF    LTYPE EQ LPASCAL
  379.     RET
  380.     ENDIF
  381. ;
  382.     IF    LTYPE EQ LBASIC
  383.     PUSH    BP
  384.     MOV    BP,SP
  385.     MOV    BX,6 [BP]    ; GET POINTER TO DATA "INTEGER"
  386.     MOV    [BX],AX        ; RETURN ERROR CONDITION BYTE
  387.     POP    BP
  388.     RET    2
  389.     ENDIF
  390. ;
  391. INITIO    ENDP
  392. ;
  393. ; --- COPY ADDRESS INFORMATION FROM SOURCE POINTED TO BY DS:SI ---
  394. ;
  395. CPYTAB    PROC    NEAR
  396.     MOV    DI,offset LNKTAB    ; POINT TO ROUTINE LINKAGE TABLE
  397.     MOV    CX,LENTAB        ; SET TO COPY
  398.     REP    MOVSB            ; DO COPY
  399.     RET
  400. CPYTAB    ENDP
  401. ;
  402. ; --- TEST FOR "CORVUS" CONST ][ BIOS ---
  403. ;
  404. BIOTST    PROC    NEAR
  405.     MOV    DS,AX        ; SET DATA SEGMENT TO THAT OF "BIOS"
  406.     MOV    BX,1        ; POINT TO "INIT" ADDRESS FIELD OF JUMP
  407.     MOV    BX,[BX]        ; GET THIS ADDRESS IN  BX
  408.     ADD    BX,1        ; OFFSET FOR INSTRUCTION SIZE
  409.     MOV    BX,[BX]        ; GET POSSIBLE POINTER TO "CORTAb" STRING
  410. ;
  411. BIOT1    PROC    NEAR
  412.     MOV    SI,BX        ; SAVE IT
  413.     MOV    DI,offset CORTAB    ; POINT TO LOCAL COPY OF STRING
  414.     MOV    CX,6        ; LENGTH OF STRING
  415.     REPZ    CMPSB        ; COMPARE STRINGS
  416.     STC            ; SET CARRY TO INDICATE POSSIBLE MISMATCH
  417.     JNZ    BIOE        ; EXIT IF MISMATCH
  418. ;
  419.     MOV    AX,DS        ; GET "BIOS" SEGMENT
  420.     MOV    CL,4        ; SET TO MULTIPLY BY 16
  421.     SHL    AX,CL        ; CONVERT SEGMENT # TO ADDRESS
  422.     ADD    AX,BX        ; FIND "CORTAb" ADDRESS RELATIVE TO SEG. 0
  423.     MOV    CS:CORPTR,AX    ; SAVE FOR POSSIBLE USE []
  424. ;
  425.     MOV    AL,35 [BX]    ; GET "BOOT SERVER" # FROM BIOS
  426.     MOV    CS:BOOTSRVR,AL    ; SAVE IT []
  427.     MOV    CS:SRVR,AL    ; INIT "DEFAULT SERVER" AS "BOOT SERVER" []
  428. ;
  429.     ADD    BX,23        ; OFFSET TO ROM FUNCTION TABLE POINTER
  430.     MOV    SI,[BX]        ; GET IT
  431.     CALL    CPYTAB        ; COPY TABLE INTO THIS DRIVER
  432.     MOV    AH,0        ; ID COMMAND
  433.     CALL    far ptr CRVIO    ; DO IT
  434.     MOV    CS:CRDTYPE,AL    ; SAVE CARD TYPE
  435.     CLC            ; CLEAR CARRY TO INDICATE SUCCESS
  436. BIOE:    RET            
  437. ;
  438. BIOT1    ENDP
  439. BIOTST    ENDP
  440. ;
  441. ;
  442. ; === RETURN POINTER TO "CORTAb" IN CORVUS BIOS ===
  443. ;
  444. ;    PUBLIC    BIOPTR
  445. ;
  446. ;BIOPTR    PROC    FAR
  447. ;    MOV    AX,CS:CORPTR    ; GET POINTER []
  448. ;
  449. ;     IF    LTYPE EQ LPASCAL
  450. ;    RET
  451. ;     ENDIF
  452. ;
  453. ;     IF    LTYPE EQ LBASIC
  454. ;    PUSH    BP
  455. ;    MOV    BP,SP
  456. ;    MOV    BX,6 [BP]    ; GET POINTER TO DATA "INTEGER"
  457. ;    MOV    [BX],AX        ; RETURN POINTER
  458. ;    POP    BP
  459. ;    RET    2
  460. ;     ENDIF
  461. ;
  462. ;BIOPTR    ENDP
  463. ;
  464. ; ==== SET SERVER # AND READ BOOT SERVER # ====
  465. ;
  466. ;    PUBLIC    SETSRVR
  467. ;
  468. ;SETSRVR    PROC    FAR
  469. ;    PUSH    BP        ; SAVE FRAME POINTER
  470. ;    MOV    BP,SP        ; SET NEW ONE
  471. ;
  472. ;     IF    LTYPE EQ LPASCAL
  473. ;    MOV    CX,6 [BP]    ; GET PASSED VALUE
  474. ;     ENDIF
  475. ;
  476. ;     IF    LTYPE EQ LBASIC
  477. ;    MOV    BX,6 [BP]    ; GET POINTER TO VALUE
  478. ;    MOV    CX,[BX]        ; GET ITS VALUE
  479. ;     ENDIF
  480. ;
  481. ;    OR    CH,CH        ; IS IT TOO BIG?
  482. ;    JNZ    SETS1        ; YES, SO DO NOT CHANGE PRESENT VALUE
  483. ;    MOV    CS:SRVR,CL    ; NO, SO SET NEW DEFAULT SERVER #
  484. ;SETS1:    XOR    AX,AX        ; GET A ZERO
  485. ;    MOV    AL,CS:BOOTSRVR    ; GET "BOOT SERVER" # AS RETURN VALUE
  486. ;
  487. ;     IF    LTYPE EQ LBASIC
  488. ;    MOV    [BX],AX        ; SET RETURNED VALUE
  489. ;     ENDIF
  490. ;
  491. ;    POP    BP        ; RESTORE FRAME
  492. ;    RET    2
  493. ;SETSRVR    ENDP
  494. ;
  495. ; === FIND A VALID NETWORK SERVER ADDRESS ===
  496. ;
  497. ;    PUBLIC    FINDSRVR
  498. ;
  499. ;FINDSRVR PROC    FAR
  500. ;    MOV    AH,4        ; FIND SERVER COMMAND (1.31 bug fix)
  501. ;    MOV    BX,ABTCTR    ; SET MAX RETRY COUNT AND ABORT TIME
  502. ;    CALL    far ptr CRVIO    ; CALL I/O DRIVER
  503. ;    XCHG    AL,AH        ; GET SERVER # IN LSB
  504. ;
  505. ;     IF    LTYPE EQ LPASCAL
  506. ;    RET
  507. ;     ENDIF
  508. ;
  509. ;     IF    LTYPE EQ LBASIC
  510. ;    PUSH    BP
  511. ;    MOV    BP,SP
  512. ;    MOV    BX,6 [BP]    ; GET POINTER TO DATA "INTEGER"
  513. ;    MOV    [BX],AX        ; RETURN SERVER #
  514. ;    POP    BP
  515. ;    RET    2
  516. ;     ENDIF
  517. ;
  518. ;FINDSRVR ENDP
  519. ;
  520. ; === IDENTIFY CORVUS I/O CARD TYPE ===
  521. ;
  522. ;    PUBLIC    CARDID
  523. ;
  524. ;CARDID    PROC    FAR
  525. ;    MOV    AH,0        ; ZERO MSB
  526. ;    MOV    AL,CS:CRDTYPE    ; GET CARD IDENTIFIER
  527. ;
  528. ;     IF    LTYPE EQ LPASCAL
  529. ;    RET
  530. ;     ENDIF
  531. ;
  532. ;     IF    LTYPE EQ LBASIC
  533. ;    PUSH    BP
  534. ;    MOV    BP,SP
  535. ;    MOV    BX,6 [BP]    ; GET POINTER TO DATA "INTEGER"
  536. ;    MOV    [BX],AX        ; RETURN CARD TYPE
  537. ;    POP    BP
  538. ;    RET    2
  539. ;     ENDIF
  540. ;
  541. ;CARDID    ENDP
  542. ;
  543. ; === SEND/RECEIVE A COMMAND TO A NETWORK SERVER ===
  544. ;
  545. ;    PUBLIC    NETCMD
  546. ;
  547. ;NETCMD    PROC    FAR
  548. ;    PUSH    BP        ; SAVE FRAME POINTER
  549. ;    MOV    BP,SP        ; SET NEW ONE
  550. ;    PUSH    DS                                  ;BCFS0726
  551. ;    PUSH    ES                                  ;BCFS0726
  552. ;
  553. ;     IF    LTYPE EQ LPASCAL
  554. ;    MOV    SI,6 [BP]    ; GET ADDRESS OF INPUT STRING
  555. ;    MOV    DI,8 [BP]    ; GET ADDRESS OF OUTPUT STRING
  556. ;    PUSH    DS
  557. ;    POP    ES        ; SET ES=DS (SAVE SEGMENT)
  558. ;     ENDIF
  559. ;
  560. ;     IF    LTYPE EQ LBASIC
  561. ;    PUSH    [BP+6]        ; GET A$ STRING DESCRIPTOR ADDRESS          ;BCFS0726
  562. ;    CALL    StringAddress                              ;BCFS0726
  563. ;    MOV    SI,AX                                  ;BCFS0726
  564. ;    MOV    DS,DX                                  ;BCFS0726
  565. ;    PUSH    [BP+8]        ; GET A$ STRING DESCRIPTOR ADDRESS          ;BCFS0726
  566. ;    CALL    StringAddress                              ;BCFS0726
  567. ;    MOV    DI,AX                                  ;BCFS0726
  568. ;    MOV    ES,DX                                  ;BCFS0726
  569. ;     ENDIF
  570. ;
  571. ;
  572. ;    MOV    CX,[SI]        ; LOOK AT LENGTH
  573. ;    MOV    AL,CL        ; SAVE FOR RETURN STATUS
  574. ;    JCXZ    NETE        ; IF ZERO, SET RET LENGTH TO ZERO AND RET
  575. ;
  576. ;    PUSH    DI
  577. ;    INC    SI
  578. ;    INC    SI        ; POINT TO SEND DATA ( DS:SI )
  579. ;
  580. ;    INC    DI
  581. ;    INC    DI        ; POINT TO PLACE TO SAVE RETURNED DATA ( ES:DI)
  582. ;
  583. ;    MOV    DX,530        ; SET MAX # OF RETURNED BYTES
  584. ;
  585. ;    MOV    AH,3        ; SET FOR  SERVER CMD
  586. ;    MOV    AL,CS:SRVR    ; SET DISK SERVER #
  587. ;    MOV    BX,ABTCTR    ; SET ABORT TIME AND # OF RETRYS
  588. ;    CALL    far ptr CRVIO    ; DO DISK I/O
  589. ;
  590. ;    POP    DI        ; GET POINTER BACK TO LENGTH
  591. ;    MOV    CX,[DI]        ; GET LENGTH PREVIOUSLY SET
  592. ;NETE:    MOV    [DI],CX        ; SET LENGTH OF RETURNED STRING
  593. ;    MOV    AH,0        ; CLEAR MSB OF RETURNED VALUE
  594. ;
  595. ;    POP    ES                                  ;BCFS0726
  596. ;    POP    DS                                  ;BCFS0726
  597. ;
  598. ;     IF    LTYPE EQ LPASCAL
  599. ;    POP    BP        ; GET FRAME POINTER BACK
  600. ;    RET    4        ; CLEAR RETURN STACK
  601. ;     ENDIF
  602. ;
  603. ;     IF    LTYPE EQ LBASIC
  604. ;    MOV    BX,10 [BP]    ; GET POINTER TO DATA "INTEGER"
  605. ;    MOV    [BX],AX        ; RETURN ERROR CONDITION BYTE
  606. ;    POP    BP
  607. ;    RET    6
  608. ;     ENDIF
  609. ;
  610. ;NETCMD    ENDP
  611. ;
  612. ; === RECEIVE A STRING OF BYTES FROM THE DRIVE ===
  613. ;
  614.     PUBLIC    CDRECV, DRVRECV
  615. ;
  616. CDRECV    PROC    FAR
  617. DRVRECV:
  618. INT    3    ;For debugging.  Remove when operation verified
  619.     PUSH    BP        ; SAVE FRAME POINTER
  620.     MOV    BP,SP        ; SET NEW ONE
  621.     PUSH    ES                                  ;BCFS0801
  622.     PUSH    DI                                  ;BCFS0801
  623.     PUSH    SI                                  ;BCFS0801
  624. ;
  625.      IF    LTYPE EQ LPASCAL
  626.     MOV    DI,6 [BP]    ; GET ADDRESS OF STRING TO SAVE DATA IN
  627.     PUSH    DS
  628.     POP    ES        ; SET ES=DS (SAVE SEGMENT)
  629.      ENDIF
  630. ;
  631.      IF    LTYPE EQ LBASIC
  632.     PUSH    [BP+6]        ; GET A$ STRING DESCRIPTOR ADDRESS          ;BCFS0726
  633.     CALL    StringAddress                              ;BCFS0726
  634.     MOV    DI,AX                                  ;BCFS0726
  635.     MOV    ES,DX                                  ;BCFS0726
  636.      ENDIF
  637. ;
  638.     PUSH    DI
  639.     PUSH    DS
  640. ;
  641.     LDS    SI,CS:dword ptr SNDPTR ; GET POINTER TO SOURCE STRING
  642.     MOV    CX,[SI]        ; LOOK AT LENGTH
  643.     MOV    AL,CL        ; SAVE FOR RETURN STATUS
  644.     JCXZ    RLPE        ; IF ZERO, SET RET LENGTH TO ZERO AND RET
  645. ;
  646.     INC    SI
  647.     INC    SI        ; POINT TO SEND DATA ( DS:SI )
  648. ;
  649.     INC    DI
  650.     INC    DI
  651.     INC    DI        ; POINT TO PLACE TO SAVE RETURNED DATA (ES:DI)
  652. ;
  653.     MOV    DX,530        ; SET MAX # OF RETURNED BYTES
  654. ;
  655.     MOV    AH,1        ; SET FOR "BCI" LIKE COMMAND
  656.     MOV    AL,CS:SRVR    ; SET DISK SERVER #
  657.     MOV    BX,ABTCTR    ; SET ABORT TIME AND # OF RETRYS
  658.     CALL    far ptr CRVIO    ; DO DISK I/O
  659. ;
  660. RLPE:    POP    DS
  661.     POP    DI        ; GET POINTER BACK TO LENGTH
  662.     MOV    [DI],CX        ; SET LENGTH OF RETURNED STRING
  663.     MOV    2 [DI],AL    ; SAVE RETURN STATUS
  664.     POP    SI                                  ;BCFS0801
  665.     POP    DI                                  ;BCFS0801
  666.     POP    ES                                  ;BCFS0801
  667.     POP    BP        ; GET FRAME POINTER BACK
  668.     RET    2        ; CLEAR RETURN STACK
  669. CDRECV    ENDP
  670. ;
  671. ; === SEND STRING OF BYTES TO DRIVE ===
  672. ;
  673. ;    THIS CONSTELLATION VERSION
  674. ;    JUST SAVES TWO POINTERS TO 
  675. ;    THE DATA STRING TO SEND.  THE
  676. ;    CDRECV  ROUTINE ACTUALLY SENDS
  677. ;    THE DATA AND RECEIVES THE
  678. ;    RETURN STATUS
  679. ;
  680.     PUBLIC    CDSEND, DRVSEND
  681. ;
  682. CDSEND    PROC    FAR
  683. DRVSEND:
  684. INT    3    ;For debugging.  Remove when operation verified
  685.     PUSH    BP        ; SAVE FRAME POINTER
  686.     MOV    BP,SP        ; SET NEW ONE
  687. ;
  688.     IF    LTYPE EQ LPASCAL
  689.     MOV    AX,6 [BP]    ; GET ADDRESS OF STRING TO SEND
  690.     MOV    CS:SNDPTR,AX    ; SAVE IT []
  691.     MOV    AX,DS        ; GET DATA SEGMENT
  692.     MOV    CS:SNDSEG,AX    ; SAVE IT []
  693.     ENDIF
  694. ;
  695.     IF    LTYPE EQ LBASIC
  696.     PUSH    [BP+6]        ; GET A$ STRING DESCRIPTOR ADDRESS          ;BCFS0726
  697.     CALL    StringAddress                              ;BCFS0726
  698.     MOV    CS:SNDPTR,AX                              ;BCFS0726
  699.     MOV    CS:SNDSEG,DX                              ;BCFS0726
  700.     ENDIF
  701. ;
  702.     POP    BP        ; GET FRAME POINTER BACK
  703.     RET    2        ; CLEAR RETURN STACK
  704. CDSEND    ENDP
  705. ;
  706. ;
  707. ;
  708. ;
  709. ; ============ FLAT CABLE R/W ROUTINES ==============
  710. ;
  711. ;  THESE ROUTINES ARE ESSENTIALLY THE SAME AS THE FLAT CABLE
  712. ;  DRIVERS IN THE "ROM".  THEY ARE REPRODUCED HERE SO THAT
  713. ;  SYSTEMS WITH FLAT CABLE INTERFACES NEED NOT HAVE A "ROM"
  714. ;  TO WORK WITH  CONSTELLATION ][  SOFTWARE.
  715. ;
  716. ; --- BUFFERS USED BY "ROM" DRIVER ROUTINES ---
  717. ;
  718. CLICKS    DB    0        ; BUFFER FOR SAVING # OF CLOCK TICKS
  719. STOPTM    DW    0        ; BUFFER FOR SAVING STOP TIME
  720. RMCMD    DB    0        ; BUFFER FOR SAVING PASSED "ROM" CMD
  721. BLKLEN    DW    512        ; BUFFER FOR SAVING # OF BYTES TO XFER
  722. CMDLEN    DW    4        ; BUFFER FOR SAVING LENGTH OF CMD
  723. RTNCODE DB    0        ; BUFFER FOR SAVING DISK RETURN CODE
  724. ;
  725. ; --- SET TIMER ---
  726. ;
  727. STIME    PROC    NEAR
  728.     XOR    AH,AH        ; READ TIME OF DAY CLOCK
  729.     INT    1AH
  730.     JMP    STIME1
  731. ;
  732. ; --- CHECK FOR TIMOUT ---
  733. ;
  734. CKTIME:    CMP    CS:CLICKS,0    ; WAS A WAIT REQUESTED? []
  735.     CLC
  736.     JZ    CKRET        ; NO, SO RETURN WITH CARRY CLEAR
  737.     XOR    AH,AH        ; TIME OF DAY CALL
  738.     INT    1AH
  739.     OR    AL,AL        ; HAS CLOCK WRAPPED AROUND TO ZERO?
  740.     JZ    CKT1        ; NO
  741. ;
  742. ;  IF CLOCK HAS PASSED 24 HOURS, RECALCULATE STOP TIME
  743. ;
  744. STIME1:    MOV    AL,CS:CLICKS    ; GET # OF CLOCK TICKS OF DELAY []
  745.     XOR    AH,AH
  746.     MOV    CL,4        ; SET TO MULTIPLY BY 16
  747.     SHL    AX,CL        ; DO IT BY SHIFTING
  748.     ADD    DX,AX
  749.     MOV    CS:STOPTM,DX    ; SAVE STOP TIME []
  750. CHKOK:    CLC            ; CLEAR CARRY ( TIME CHECK IS OK )
  751.     RET
  752. ;
  753. CKT1:    CMP    DX,CS:STOPTM    ; TIMEOUT? []
  754.     JB    CHKOK
  755. ;
  756.     STC            ; SET CARRY IF TIMEOUT
  757. CKRET:    RET
  758. STIME    ENDP
  759. ;
  760. ; ---- MAIN DRIVER ENTRY POINT ---
  761. ;
  762. DRVIO    PROC    FAR
  763.     CLD            ; SET FOR "INCREMENT"
  764.     MOV    CS:RMCMD,AH    ; SAVE COMMAND []
  765.     CMP    AH,1        ; IS IT A "BCI" COMMAND?
  766.     JZ    RW15        ; YES, SO DO IT
  767.     CMP    AH,5        ; IS IT A "WRITE" COMMAND?
  768.     JZ    RW15        ; YES, SO DO IT
  769.     CMP    AH,0        ; IS IT AN "IDENTIFY" COMMAND
  770.     JZ    RW00        ; YES, SO DO IT
  771.     MOV    AL,0FFH        ; IF ANY OTHER, INDICATE "ABORT" OR ERROR
  772.     MOV    CX,0        
  773.     RET            ; LONG RET
  774. ;
  775. RW00:    MOV    AL,1        ; INDICATE FLAT CABLE
  776.     RET            ; LONG RET
  777. ;
  778. ;
  779. RW15:    PUSH    DS        ; SAVE REGISTERS THAT MAY BE CHANGED
  780.     PUSH    SI
  781.     PUSH    DI
  782.     PUSH    BX
  783.     PUSH    DX
  784. ;
  785.     MOV    CS:CLICKS,BL    ; SAVE # OF TIMER CLICKS  []
  786.     MOV    CS:BLKLEN,DX    ; SAVE BLOCK LENGTH []
  787.     MOV    CS:CMDLEN,CX    ; SAVE CMD LENGTH []
  788.     CALL    ROMIO        ; DO DISK I/O
  789.     POP    DX
  790.     POP    BX
  791.     POP    DI
  792.     POP    SI
  793.     POP    DS
  794.     MOV    AL,CS:RTNCODE    ; GET RETURN CODE []
  795. ;
  796. DMYLRET    LABEL    FAR
  797.     RET            ; LONG RET
  798. ;
  799. DMYIRET    LABEL    FAR
  800.     IRET            ; DUMMY  "IRET"
  801. ;
  802. DRVIO    ENDP
  803. ;
  804. ROMIO    PROC    NEAR
  805.     CALL    STIME        ; SETUP TIMER COUNT
  806. ;
  807. RO1:    MOV    DX,STAT        ; POINT TO STATUS PORT
  808.     CLI            ; DISABLE INTERRUPTS FOR TEST
  809.     IN    AL,DX        ; READ DRIVE STATUS BYTE
  810.     TEST    AL,DRDY        ; IS IT READY?
  811.     JZ    RO2        ; YES, SO PROCEED
  812.     STI            ; NO, SO RE-ENABLE INTERRUPTS
  813.     CALL    CKTIME        ; CHECK IF TIMED OUT
  814.     JNC    RO1        ; IF NOT, TRY AGAIN
  815. ARET:    MOV    CS:RTNCODE,0FFH ; IF TIMED OUT, SET ERROR []
  816.     MOV    CX,0        ; INDICATE NO DATA RETURNED
  817.     RET
  818. ;
  819. RO2:    MOV    CX,CS:CMDLEN    ; GET CMD LENGTH []
  820.     CALL    SNDBLK        ; SEND BLOCK OF DATA TO DRIVE
  821.     CMP    CS:RMCMD,5    ; WAS CMD A "WRITE" CMD? []
  822.     JNZ    RCVBLK        ; NO, SO GO RECEIVE DATA
  823. ;
  824.     MOV    SI,DI        ; YES, POINT TO SECTOR DATA
  825.     MOV    AX,ES
  826.     MOV    DS,AX
  827.     MOV    CX,CS:BLKLEN    ; GET LENGTH OF DATA BLOCK []
  828.     CALL    SNDBLK        ; SEND SECTOR DATA
  829. ;
  830. RCVBLK:    CALL    STIME        ; SET TIMER
  831. ;
  832.     CALL    DELAY1        ; DELAY
  833. ;
  834. RCV1:    CALL    CKTIME        ; TIMED OUT YET?
  835.     JC    ARET        ; YES, SO RETURN WITH ERROR
  836. ;
  837. RCV2:    MOV    DX,STAT        ; POINT TO STATUS PORT
  838.     IN    AL,DX        ; READ DRIVE STATUS BYTE
  839.     TEST    AL,DIFAC    ; TEST BUS DIRECTION
  840.     JNZ    RCV1        ; WAIT FOR "HOST TO DRIVE"
  841.     TEST    AL,DRDY        ; TEST IF ALSO READY
  842.     JNZ    RCV1
  843. ;
  844.     CALL    DELAY1        ; WAIT TO BE SURE
  845. ;
  846.     IN    AL,DX        ; TEST STATUS AGAIN
  847.     TEST    AL,DIFAC        
  848.     JNZ    RCV1        ; IF FALSE ALARM, TRY AGAIN
  849.     TEST    AL,DRDY
  850.     JNZ    RCV1        ; IF NOT READY, TRY AGAIN
  851. ;
  852.     DEC    DX        ; POINT TO DATA PORT
  853.     IN    AL,DX        ; GET RETURN CODE
  854.     INC    DX        ; POINT BACK TO STATUS PORT
  855. ;
  856.     MOV    CX,1        ; INDICATE 1 BYTE WAS RETURNED
  857.     MOV    CS:RTNCODE,AL    ; SAVE IT []
  858.     CMP    CS:RMCMD,5    ; WAS CMD A "WRITE" CMD []
  859.     JZ    RCRET        ; YES, SO RETURN
  860. ;
  861.     MOV    BX,CX        ; OTHERWISE SET COUNTER
  862.     MOV    CX,CS:BLKLEN    ; GET LENGTH OF EXPECTED DATA
  863. ;
  864. RCV3:    IN    AL,DX        ; GET STATUS AGAIN
  865.     TEST    AL,DRDY        ; IS DRIVE READY?
  866.     JNZ    RCV3        ; NO, SO WAIT
  867.     TEST    AL,DIFAC    ; ARE WE DONE?
  868.     JNZ    RCV4        ; POSSIBLY, ...
  869. ;
  870.     DEC    DX        ; POINT TO DATA PORT
  871.     IN    AL,DX        ; GET DATA FROM DRIVE
  872.     INC    DX        ; POINT BACK TO STATUS PORT
  873. ;
  874.     JCXZ    RCVS        ; IF DATA NOT WANTED
  875.     STOSB            ; SAVE DATA IN BUFFER
  876.     DEC    CX        ; COUNT DOWN # TO SAVE
  877. ;
  878. RCVS:    INC    BX        ; COUNT UP # RECEIVED
  879.     JMP    RCV3        ; LOOP UNTIL EXIT
  880. ;
  881. RCV4:    IN    AL,DX        ; GET STATUS BYTE
  882.     TEST    AL,DRDY        ; IS DRIVE READY
  883.     JNZ    RCV3        ; NO, SO PREVIOUS RESULT MAY BE FALSE
  884.     TEST    AL,DIFAC    ; IS IT STILL "HOST TO DRIVE"?
  885.     JZ    RCV3        ; NO, SO TRY AGAIN
  886. ;
  887.     MOV    CX,BX        ; GET # OF BYTES RECEIVED
  888. RCRET:    RET
  889. ;
  890. DELAY1:    MOV    BL,15        ; SET DELAY
  891. DELAY:    DEC    BL
  892.     JNZ    DELAY        ; LOOP UNTIL DONE
  893.     RET
  894. ;
  895. ; --- SEND BLOCK OF DATA TO DRIVE ---
  896. ;
  897. SNDBLK:    MOV    DX,STAT        ; POINT TO STATUS PORT
  898. ;
  899. SND1:    IN    AL,DX        ; GET STATUS BYTE
  900.     TEST    AL,DRDY        ; IS DRIVE READY?
  901.     JNZ    SND1        ; NO, SO LOOP
  902. ;
  903.     DEC    DX        ; POINT TO DATA PORT
  904.     LODSB            ; GET DATA FROM MEMORY
  905.     OUT    DX,AL        ; SEND DATA TO DRIVE
  906.     INC    DX        ; POINT BACK TO STATUS PORT
  907. ;
  908.     STI            ; RE-ENABLE INTERRUPTS
  909.     LOOP    SND1        ; CONTINUE UNTIL DONE
  910.     RET
  911. ;
  912. ROMIO    ENDP
  913. ;
  914. ;
  915. ; ---- INTERFACE "FAR" CALL TABLE ---
  916. ;    THIS TABLE GETS PATCHED
  917. ;    TO EITHER "BIOS" CALLS OR
  918. ;    "ROM" CALLS IF THE APPROPRIATE
  919. ;           LINK IS FOUND
  920. ;
  921. LNKTAB    PROC    NEAR
  922.     JMP    DMYLRET
  923.     JMP    DMYLRET
  924. ;
  925. CRVIO    LABEL    FAR
  926.     JMP    DRVIO        ; THIS SHOULD BE A FAR CALL
  927. ;
  928.     JMP    DMYIRET        ; THIS SHOULD BE A FAR JUMP
  929. LNKTAB    ENDP
  930. ;
  931. ; =========================================================
  932. ;
  933. PGSEG    ENDS
  934. ;
  935. ;
  936.     END
  937.