]>
wirehaze git hosting - MS-DOS.git/blob - v1.25/source/IO.ASM
1 ; I/O System for 86-DOS version 1.20 and later. Revised 8-02-82.
3 ; Assumes a CPU Support card at F0 hex for character I/O,
4 ; with disk drivers for SCP, Tarbell, or Cromemco controllers.
6 ; Select whether console input is interrupt-driven or polled.
9 ; Select whether the auxiliary port is the Support Card parallel port
10 ; or on channel 1 of a Multiport Serial card addressed at 10H.
14 ; Select whether the printer is connected to the Support card parallel
15 ; output port (standard) or channel 0 of a Multiport Serial card
20 ; If the Multiport Serial was chosen for either the auxiliary or the
21 ; printer, select the baud rate here. Refer to Multiport Serial manual
22 ; page 11 to pick the correct value for a given baud rate.
23 PRNBAUD:EQU
7 ; 1200 baud
24 AUXBAUD:EQU
0FH ; 19200 baud
26 ; Select disk controller here.
33 ; Select if you want a special conversion version which can read/write
34 ; both the new Microsoft format and the old SCP format.
35 ; For a two drive system, drives A and B are the new Microsoft format,
36 ; and drives C and D are the old SCP format (where C is the same physical
37 ; drive as A, and D is the same drive as B). CONVERT has no effect
38 ; on 5.25-inch drives.
41 ; Select disk configuration:
42 LARGE: EQU
1 ; Large drives.
43 COMBIN: EQU
0 ; Two 8-inch and one 5.25-inch.
44 SMALL: EQU
0 ; Three 5.25-inch drives.
45 CUSTOM: EQU
0 ; User defined.
47 ; If 8-inch drives are PerSci, select FASTSEEK here:
48 ; (Fastseek with Tarbell controllers doesn't work yet).
51 ; For double-density controllers, select double-sided operation of
52 ; 8-inch disks in double-density mode.
55 ; For double-density controllers, select double-sided operation of
56 ; 5.25-inch disks in double-density mode.
59 ; Use table below to select head step speed. Step times for 5" drives
60 ; are double that shown in the table. Times for Fast Seek mode (using
61 ; PerSci drives) is very small - 200-400 microseconds.
63 ; Step value 1771 1793
72 ; ****** End of selections ********************************************
74 BIOSSEG:EQU 40H
; I/O system segment.
75 BIOSLEN:EQU
2048 ; Maximum length of I/O system.
76 DOSLEN: EQU
8192 ; Maximum length of MS-DOS.
77 QSIZE: EQU
80 ; Input queue size.
78 PBUFSIZ:EQU
128 ; Size of print buffer
79 BASE: EQU
0F0H ; CPU Support card base port number.
80 SIOBASE:EQU 10H
; Base port number of Multiport Serial card.
81 STAT: EQU BASE
+7 ; Serial I/O status port.
82 DATA: EQU BASE
+6 ; Serial I/O data port.
83 DAV: EQU
2 ; Data available bit.
84 TBMT: EQU
1 ; Transmitter buffer empty bit.
85 SERIAL: EQU SERIALPRN
+SERIALAUX
86 STCDATA:EQU BASE
+4 ; Ports for 9513 Timer chip.
100 PRNSTAT:EQU SIOBASE
+1
101 PRNDATA:EQU SIOBASE
+0
131 XOR BP,BP ; Set up stack just below I/O system.
136 MOV AL,0FFH ; Mask all interrupts.
141 DI ; Set up keyboard interrupt vector.
147 MOV [BP+4*38H
],PRNFCB
152 ; Initialize time-of-day clock.
155 MOV CX,4 ;Initialize 4 registers
159 OUT STCCOM
;Select register to initialize
173 LODB
;Baud rate for channel 0
175 LODB
;Baud rate for channel 1
179 ; Move MS-DOS down to the first segment just above the I/O system.
181 MOV SI,BIOSLEN
; Source points to where MS-DOS currently is.
182 MOV AX,DOSSEG
; Destination is beginning of DOSSEG.
185 MOV CX,DOSLEN
/2 ; CX is number of words to move.
190 MOV DX,1 ; Do auto memory scan.
193 ; Change disk read and write vectors (INT 37 and INT 38) to go to
194 ; DIRECTREAD and DIRECTWRITE rather than READ and WRITE.
197 MOV W
,[BP+37*4],DIRECTREAD
198 MOV W
,[BP+38*4],DIRECTWRITE
201 MOV AH,26 ;Set DMA address
203 MOV CX,[6] ;Get size of segment
204 MOV BX,DS ;Save segment for later
206 ; DS must be set to CS so we can point to the FCB.
210 MOV DX,FCB
;File Control Block for COMMAND.COM
212 INT 33 ;Open COMMAND.COM
214 JNZ COMERR
;Error if file not found
216 MOV [FCB
+33],AX ; Set 4-byte Random Record field to
217 MOV [FCB
+35],AX ; beginning of file.
219 MOV [FCB
+14],AX ;Set record length field
220 MOV AH,39 ;Block read (CX already set)
222 JCXZ COMERR
;Error if no records read
224 JZ COMERR
;Error if not end-of-file
226 ; Make all segment registers the same.
231 MOV SP,5
CH ;Set stack to standard value
233 PUSH AX ;Put zero on top of stack for return
236 INT 33 ;Set default transfer address (DS:0080)
237 PUSH BX ;Put segment on stack
239 PUSH AX ;Put address to execute within segment on stack
240 RET L
;Jump to COMMAND
244 MOV AH,9 ;Print string
249 STCTAB: DB 17H
;Select master mode register
250 DW 84F3H
;Enable time-of-day
251 DB 1 ;Counter 1 mode register
256 DW 0008H ;Set counter 3 to count days
259 DB 0B7H, 77H
, 4EH
, 37H
, PRNBAUD
, AUXBAUD
262 BADCOM: DB 13,10,"Error in loading Command Interpreter",13,10,"$"
263 FCB: DB 1,"COMMAND COM"
266 ; ************ Time and Date ************
269 MOV AL,0A7H ;Save counters 1,2,3
271 MOV AL,0E0H ;Enable data pointer sequencing
273 MOV AL,19H
;Select hold 1 / hold cycle
275 CALL STCTIME
;Get seconds & 1/100's
277 CALL STCTIME
;Get hours & minutes
282 XCHG AL,AH ;Count of days
295 AND AL,0FH ;Unpack BCD digits
296 AAD ;Convert to binary
304 CALL LOAD0
;Put 0 into load registers to condition timer
305 MOV AL,43H
;Load counters 1 & 2
311 OUT STCCOM
;Load counters 1&2
313 MOV AL,27H
;Arm counters 1,2,3
321 MOV AL,09 ;Counter 1 load register
323 MOV AL,0AH ;Counter 2 load register
326 OUT STCCOM
;Select a load register
331 AAM ;Convert binary to unpacked BCD
341 XCHG AX,DX ;Put date in DX
342 MOV AL,0BH ;Select Counter 3 load register
348 MOV AL,44H
;Load counter 3
352 MOV AL,1FH
;Point to status register
353 OUT STCCOM
; so power-off glitches won't hurt
357 ; ************ CONSOLE INPUT ************
360 IF INTINP
-1 ; Non-interrupt driven input.
364 JZ NOTHING
; Jump if nothing there.
369 MOV [QUEUE
],AL ; Put new character in buffer.
370 POPF ; Return with Z flag clear.
374 MOV AL,[QUEUE
] ; See if there's anything in the buffer.
375 NOT AL ; Set up the Z flag.
385 XCHG AL,[QUEUE
] ; Remove the character from the buffer.
387 JNS INRET
; Return if we have a character.
389 IN STAT
; Wait till a character is available.
398 QUEUE: DB -1 ; For storing characters from STATUS to INP.
401 IF INTINP
; Interrupt-driven input.
403 ; Console keyboard interrupt handler.
408 MOV AL,20H
;End of Interrupt command
409 OUT BASE
+2 ;Send to slave
410 IN DATA ;Get the character
419 CALL 13*3,BIOSSEG
; Call I/O system keyboard buffer flush.
422 MOV SI,[REAR
] ;Pointer to rear of queue
425 CMP SI,[FRONT
] ;Any room in queue?
428 MOV [SI],AL ;Put character in queue
430 MOV [REAR
],SI ;Save pointer
436 MOV AL,7 ; BELL character.
437 CALL 3*3,BIOSSEG
; Call I/O system console output function.
442 ;See if printer ready
449 CMP SI,[PREAR
] ;Anything in print queue?
452 CMP B
,[PRNFCB
],-1 ;Print spooling in progress?
453 JZ NOPRN
;If not, nothing to print
454 ;Print spooling in progress. Get next buffer
466 MOV AH,26 ;Set DMA address
470 MOV AH,39 ;Read buffer
474 MOV B
,[PRNFCB
],-1 ;Turn off print spooling at EOF
496 LODSB ;Get character to print
499 DI ; Disable interrupts while checking queue.
503 CMP SI,[REAR
] ; Anything in queue?
504 JZ NOCHR
; Jump if nothing in queue.
507 LODSB ;Get character (if there is one)
508 OR SI,SI ;Reset zero flag
512 RET L
;Zero clear if we have a character
515 CALL STATUS
,BIOSSEG
; Get I/O system console input status.
518 DI ; Disable interrupts while changing queue pointers.
521 CALL INCQ
; Permanently remove char from queue
539 CMP SI,ENDQ
;Exceeded length of queue?
546 CMP SI,ENDPQ
;Exceeded length of queue?
564 ; ************ Console and Printer Output ************
587 CALL STATUS
,BIOSSEG
;Poll and maybe print something
598 ; ************ Auxiliary I/O ************
617 ; ************ 1771/1793-type controller disk I/O ************
619 TARBELL:EQU TARBELLSD
+TARBELLDD
620 CROMEMCO:EQU CROMEMCO4FDC
+CROMEMCO16FDC
622 WD1791: EQU SCP
+TARBELLDD
+CROMEMCO16FDC
623 WD1771: EQU TARBELLSD
+CROMEMCO4FDC
652 BACKBIT:EQU
0FDH ; Send this to port 4 to select back.
674 ; Disk change function.
676 ; AL = disk drive number.
678 ; AH = -1 (FF hex) if disk is changed.
679 ; AH = 0 if don't know.
680 ; AH = 1 if not changed.
682 ; CF clear if no disk error.
683 ; AL = disk I/O driver number.
685 ; CF set if disk error.
686 ; AL = disk error code (see disk read below).
690 MOV AH,0 ; AH = 0 in case we don't know.
694 PUSH AX ; Save drive number.
704 AND AL,20H
; Look at head load bit
707 MOV AH,1 ; AH = 1, disk not changed.
711 ENDIF
; End of 1771 DSKCHG.
715 MOV AH,0 ; AH = 0 in case we don't know.
718 JNZ DENSCHK
; Check density if not same drive.
729 AND AL,20H
; Look at head load bit
731 JZ DENSCHK
; Check density if head not loaded.
732 MOV AH,1 ; AH = 1, disk not changed.
735 XLAT ; Get previous density
739 CALL CHKNEW
; Unload head if selecting new drive.
743 MOV CX,4 ; Try each density twice
744 MOV AH,0 ; Disk may not have been changed.
747 MOV AL,[SI] ; Get previous disk I/O driver number.
750 XLAT ; Get drive select byte for previous density
753 CALL MOTOR
; Wait for motor to come up to speed.
756 OUT DISK
+4 ; Select disk
757 MOV AL,0C4H ; READ ADDRESS command
760 IN DISK
+3 ; Eat last byte to reset DRQ
761 JZ HAVDENS
; Jump if no error in reading address.
762 NOT AH ; AH = -1 (disk changed) if new density works.
764 XOR B
,[SI],1 ; Try other density
766 MOV AX,2 ; Couldn't read disk at all, AH = 0 for don't
767 STC ; know if disk changed, AL = error code 2 -
768 RET L
; disk not ready, carry set to indicate error.
772 LODSB ; AL = disk I/O driver number.
776 PREVDENS:DB 1,3,5,7,9,11,13 ; Table of previous disk I/O driver numbers.
777 ENDIF
; End of 1793 DSKCHG function.
780 MOV AH,AL ; Save disk drive number in AH.
781 SEG
CS ; AL = previous disk drive number,
782 XCHG AL,[CURDRV
] ; make new drive current.
783 CMP AL,AH ; Changing drives?
786 ; If changing drives, unload head so the head load delay one-shot will
787 ; fire again. Do it by seeking to the same track with the H bit reset.
789 IN DISK
+1 ; Get current track number
790 OUT DISK
+3 ; Make it the track to seek to
791 MOV AL,10H
; Seek and unload head
793 MOV AL,AH ; Restore current drive number
800 IN DISK
+4 ; See if the motor is on.
803 OUTB DISK
+4 ; Select drive & start motor.
804 JNZ MOTORSON
; No delay if motors already on.
806 MOV CX,43716 ; Loop count for 1 second.
807 MOTORDELAY: ; (8 MHz, 16-bit memory).
810 LOOP MOTORDELAY
; 17 clocks.
817 ; Disk read function.
820 ; AL = Disk I/O driver number
821 ; BX = Disk transfer address in DS
822 ; CX = Number of sectors to transfer
823 ; DX = Logical record number of transfer
825 ; CF clear if transfer complete
827 ; CF set if hard disk error.
828 ; CX = number of sectors left to transfer.
829 ; AL = disk error code
830 ; 0 = write protect error
831 ; 2 = not ready error
832 ; 4 = "data" (CRC) error
834 ; 8 = sector not found
836 ; 12 = "disk" (none of the above) error
839 CALL SEEK
;Position head
841 PUSH ES ; Make ES same as DS.
845 CALL READSECT
;Perform sector read
847 INC DH ;Next sector number
848 LOOP RDLP
;Read each sector requested
850 POP ES ; Restore ES register.
853 ; Disk write function.
854 ; Registers same on entry and exit as read above.
857 CALL SEEK
;Position head
860 CALL WRITESECT
;Perform sector write
862 INC DH ;Bump sector counter
863 LOOP WRTLP
;Write CX sectors
869 POP ES ; Restore ES register.
873 MOV [DI],BL ; Indicate we don't know where head is.
876 INC BL ; Increment to next error code.
879 TEST AH,AL ; See if error code matches disk status.
880 JZ GETCOD
; Try another if not.
881 MOV AL,BL ; Now we've got the code.
882 SHL AL ; Multiply by two.
887 DB 40H
;Write protect error
888 DB 80H
;Not ready error
891 DB 10H
;Sector not found
895 ; Direct disk read and write from INT 37 and INT 38. Subroutine GETIODRIVER
896 ; calls DSKCHG to convert disk drive number to I/O driver number.
898 ; Setting CURDRV to -1 before calling DSKCHG forces DSKCHG to check the disk's
899 ; density before returning the I/O driver number. This is necessary because
900 ; programs such as FORMAT could change the density of a disk and leave the
901 ; head loaded. If the head is loaded DSKCHG assumes the disk hasn't been
902 ; changed and returns the old I/O driver number which could be wrong.
904 ; CURDRV is set to -1 before returning so when DSKCHG is called by the
905 ; operating system, it will tell the operating system the disk may have
906 ; been changed (because it may have been).
911 CALL GETIODRIVER
; Convert drive number to I/O driver number.
912 JC DIRECTRET
; Return if DSKCHG returned error.
915 CALL 7*3,BIOSSEG
; Call READ.
921 CALL GETIODRIVER
; Convert drive number to I/O driver number.
922 JC DIRECTRET
; Return if DSKCHG returned error.
925 CALL 8*3,BIOSSEG
; Call WRITE.
928 MOV B
,[CURDRV
],-1 ; Force DSKCHG to do density check.
934 MOV B
,[CURDRV
],-1 ; Force DSKCHG to do density check.
937 CALL 9*3,BIOSSEG
; Call DSKCHG.
944 ; Seeks to proper track.
946 ; Same as for disk read or write above.
948 ; AH = Drive select byte
951 ; SI = Disk transfer address in DS
952 ; DI = pointer to drive's track counter in CS
953 ; CX unchanged (number of sectors)
956 MOV SI,BX ; Save transfer address
958 MOV BX,AX ; Prepare to index on drive number
960 IF WD1791
; If two disk formats per drive.
961 SHR AL ; Convert to physical disk drive number.
964 CALL CHKNEW
; Unload head if changing drives.
966 MOV AL,[BX+DRVTAB
] ; Get drive-select byte.
969 CALL MOTOR
; Wait for the motors to come up to speed.
972 OUTB DISK
+4 ; Select drive.
975 OR AL,80H
; Set auto-wait bit.
978 MOV AH,AL ; Save drive-select byte in AH.
979 XCHG AX,DX ; AX = logical sector number.
980 MOV DL,26 ; 26 sectors/track unless changed below
983 TEST DH,SMALLBIT
; Check if small disk.
984 JZ BIGONE
; Jump if big disk.
985 MOV DL,18 ; Assume 18 sectors on small track.
986 TEST DH,DDENBIT
; Check if double-density.
987 JZ HAVSECT
; Jump if not.
988 MOV DL,SMALLDDSECT
; Number of sectors on small DD track.
991 TEST DH,DDENBIT
; Check if double-density.
992 JZ HAVSECT
; Jump if not.
993 MOV DL,LARGEDDSECT
; Number of sectors on big DD track.
996 IF TARBELLDD
; Tarbell DD controller.
997 TEST DH,DDENBIT
; Check for double-density.
999 MOV DL,LARGEDDSECT
; Number of sectors on DD track.
1003 TEST DH,SMALLBIT
; Check if small disk.
1004 JNZ HAVSECT
; Jump if not.
1005 MOV DL,18 ; 18 sectors on small disk track.
1009 TEST DH,SMALLBIT
; Check if small disk.
1010 JNZ BIGONE
; Jump if big disk.
1011 MOV DL,18 ; Assume 18 sectors on small track.
1012 TEST DH,DDENBIT
; Check if double-density.
1013 JZ HAVSECT
; Jump if not.
1014 MOV DL,SMALLDDSECT
; Number of sectors on small DD track.
1017 TEST DH,DDENBIT
; Check if double-density.
1018 JZ HAVSECT
; Jump if not.
1019 MOV DL,LARGEDDSECT
; Number of sectors on big DD track.
1023 DIV AL,DL ; AL = track, AH = sector.
1024 XCHG AX,DX ; AH has drive-select byte, DX = track & sector.
1025 INC DH ; Sectors start at one, not zero.
1027 MOV BL,[BX+TRKPT
] ; Get this drive's displacement into track table.
1028 ADD BX,TRKTAB
; BX now points to track counter for this drive.
1030 MOV AL,DL ; Move new track number into AL.
1032 XCHG AL,[DI] ; Xchange current track with desired track
1033 OUT DISK
+1 ; Inform controller chip of current track
1034 CMP AL,DL ; See if we're at the right track.
1036 MOV BH,2 ; Seek retry count
1037 CMP AL,-1 ; Head position known?
1038 JNZ NOHOME
; If not, home head
1043 MOV AL,DL ; AL = new track number.
1045 MOV AL,1
CH+STPSPD
; Seek command.
1047 AND AL,98H
; Accept not ready, seek, & CRC error bits.
1049 JS SEEKERR
; No retries if not ready
1053 MOV AH,AL ; Put status in AH.
1054 TEST AL,80H
; See if it was a Not Ready error.
1056 JNZ RET ; Status is OK for Not Ready error.
1057 MOV AH,2 ; Everything else is seek error.
1061 MOV BL,DH ; Move sector number to BL to play with
1063 IF SCP
+CROMEMCO16FDC
1064 TEST AH,DDENBIT
; Check for double density.
1065 JZ CHECKSMALL
; Not DD, check size for SD.
1069 TEST AH,DDENBIT
; Check for double density.
1070 JZ CHECK26
; Not DD.
1075 IF (SCP
+TARBELL
)*LARGEDS
+SCP
*SMALLDS
1076 MOV AL,AH ; Select front side of disk.
1080 IF CROMEMCO
*(LARGEDS
+SMALLDS
)
1081 MOV AL,0FFH ; Select front side of disk.
1085 CMP BL,8 ; See if legal DD sector number.
1086 JBE PUTSEC
; Jump if ok.
1088 IF (LARGEDS
-1)*((SMALLDS
*(SCP
+CROMEMCO
))-1)
1089 JP STEP
; If only SS drives, we gotta step.
1092 IF SCP
*LARGEDS
*(SMALLDS
-1)
1093 TEST AH,SMALLBIT
; Check for 5.25 inch disk.
1094 JNZ STEP
; Jump if small because SMALLDS is off.
1097 IF SCP
*SMALLDS
*(LARGEDS
-1)
1098 TEST AH,SMALLBIT
; Check for 8 inch disk.
1099 JZ STEP
; Jump if large because LARGEDS is off.
1102 IF CROMEMCO16FDC
*LARGEDS
*(SMALLDS
-1)
1103 TEST AH,SMALLBIT
; Check for 5.25 inch disk.
1104 JZ STEP
; Jump if small because SMALLDS is off.
1107 IF CROMEMCO16FDC
*SMALLDS
*(LARGEDS
-1)
1108 TEST AH,SMALLBIT
; Check for 8 inch disk.
1109 JNZ STEP
; Jump if large because LARGEDS is off.
1112 IF LARGEDS
+SMALLDS
*(SCP
+CROMEMCO
)
1113 SUB BL,8 ; Find true sector for back side.
1114 CMP BL,8 ; See if ok now.
1115 JA STEP
; Have to step if still too big.
1118 MOV AL,AH ; Move drive select byte into AL.
1119 OR AL,BACKBIT
; Select back side.
1124 MOV AL,BACKBIT
; Select back side.
1135 TEST AH,SMALLBIT
; See if big disk.
1136 JZ CHECK26
; Jump if big.
1141 TEST AH,SMALLBIT
; See if big disk.
1142 JNZ CHECK26
; Jump if big.
1146 CMP BL,18 ; See if legal small SD/SS sector.
1147 JA STEP
; Jump if not.
1151 CMP BL,26 ; See if legal large SD/SS sector.
1152 JBE PUTSEC
; Jump if ok.
1154 INC DL ; Increment track number.
1155 MOV AL,58H
; Step in with update.
1158 INC B
,[DI] ; Increment the track pointer.
1159 MOV DH,1 ; After step, do first sector.
1160 MOV BL,DH ; Fix temporary sector number also.
1162 MOV AL,BL ; Output sector number to controller.
1164 DI ; Interrupts not allowed until I/O done
1167 INB DISK
+4 ; Get head-load bit.
1175 AND AL,20H
; Check head load status
1182 MOV BL,10 ; Retry count for hard error.
1183 XCHG DI,SI ; Transfer address to DI.
1184 PUSH DX ; Save track & sector number.
1185 MOV DL,DISK
+3 ; Disk controller data port.
1191 MOV AL,AH ; Turn on auto-wait.
1195 MOV BP,DI ; Save address for retry.
1198 STOB
; Write into memory.
1202 IN DISK
+5 ; Wait for DRQ or INTRQ.
1211 INB
DX ; Read data from disk controller chip.
1217 INB
DX ; Read data from disk controller chip.
1221 EI
; Interrupts OK now
1225 MOV DI,BP ; Get origainal address back for retry.
1226 MOV BH,AL ; Save error status for report
1230 MOV AH,BH ; Put error status in AH.
1233 POP DX ; Get back track & sector number.
1234 XCHG SI,DI ; Address back to SI.
1238 MOV AL,0D0H ; Tarbell controllers need this Force Interrupt
1239 OUT DISK
; so that Type I status is always available
1240 MOV AL,10 ; at the 1771/1793 status port so we can find
1241 INTDLY: ; out if the head is loaded. SCP and Cromemco
1242 DEC AL ; controllers have head-load status available
1243 JNZ INTDLY
; at the DISK+4 status port.
1251 PUSH DX ; Save track & sector number.
1252 MOV DL,DISK
+3 ; Disk controller data port.
1258 MOV AL,AH ; Turn on auto-wait.
1275 LODB
; Get data from memory.
1276 OUTB
DX ; Write to disk.
1282 LODB
; Get data from memory.
1283 OUTB
DX ; Write to disk.
1287 EI
; Interrupts OK now.
1297 MOV AH,BH ; Error status to AH.
1300 POP DX ; Get back track & sector number.
1310 ; Subroutine to restore the read/write head to track 0.
1312 IF SCP
+CROMEMCO
+TARBELL
*(FASTSEEK
-1)
1316 IF FASTSEEK
*CROMEMCO
1317 TEST AH,SMALLBIT
; Check for large disk.
1318 JNZ RESTORE ; Big disks are fast seek PerSci.
1325 MOV AL,AH ; Turn on Restore to PerSci.
1330 MOV AL,0CH+STPSPD
; Restore with verify command.
1335 MOV AL,AH ; Restore off.
1340 JS HOMERR
; No retries if not ready
1341 MOV AL,58H
+STPSPD
; Step in with update
1349 ; RESTORE for PerSci drives.
1350 ; Doesn't exist yet for Tarbell controllers.
1358 IF FASTSEEK
*CROMEMCO4FDC
1360 MOV AL,0C4H ;READ ADDRESS command to keep head loaded
1372 JP RESTORE ;Reload head
1378 OUT DISK
+1 ;Tell 1771 we're now on track 0
1382 IF FASTSEEK
*CROMEMCO16FDC
1384 MOV AL,0D7H ; Turn on Drive-Select and Restore.
1390 INB
4 ; Wait till Seek Complete is active.
1393 MOV AL,0FFH ; Turn off Drive-Select and Restore.
1395 SUB AL,AL ; Tell 1793 we're on track 0.
1400 ; Subroutine to move the read/write head to the desired track.
1401 ; Usually falls through to DCOM unless special handling for
1402 ; PerSci drives is required in which case go to FASTSK.
1404 IF SCP
+CROMEMCO
+TARBELL
*(FASTSEEK
-1)
1408 IF CROMEMCO
*FASTSEEK
1409 TEST AH,SMALLBIT
; Check for PerSci.
1416 AAM ;Delay 10 microseconds
1433 ; Fast seek code for PerSci drives.
1434 ; Tarbell not installed yet.
1442 IF FASTSEEK
*CROMEMCO
1460 ; Explanation of tables below.
1462 ; DRVTAB is a table of bytes which are sent to the disk controller as drive-
1463 ; select bytes to choose which physical drive is selected for each disk I/O
1464 ; driver. It also selects whether the disk is 5.25-inch or 8-inch, single-
1465 ; density or double-density. Always select side 0 in the drive-select byte if
1466 ; a side-select bit is available. There should be one entry in the DRVTAB
1467 ; table for each disk I/O driver. Exactly which bits in the drive-select byte
1468 ; do what depends on which disk controller is used.
1470 ; TRKTAB is a table of bytes used to store which track the read/write
1471 ; head of each drive is on. Each physical drive should have its own
1474 ; TRKPT is a table of bytes which indicates which TRKTAB entry each
1475 ; disk I/O driver should use. Since each physical drive may be used for
1476 ; more than one disk I/O driver, more than one entry in TRKPT may point
1477 ; to the same entry in TRKTAB. Drives such as PerSci 277s which use
1478 ; the same head positioner for more than one drive should share entrys
1481 ; INITTAB is the initialization table for 86-DOS as described in the
1482 ; 86-DOS Programer's Manual under "Customizing the I/O System."
1484 IF SCP
*COMBIN
*FASTSEEK
1486 ; A PerSci 277 or 299 and one 5.25-inch drive.
1488 DRVTAB: DB 00H,08H,01H,09H,10H
,18H
,00H,08H,01H,09H
1489 TRKPT: DB 0,0,0,0,1,1,0,0,0,0
1493 DB 6 ; Number of disk I/O drivers.
1500 DB 0 ; Disk I/O driver 0 uses disk drive 0.
1501 DW LSDRIVE
; Disk I/O driver 0 is 8-inch single-density.
1502 DB 0 ; Disk I/O driver 1 uses disk drive 0.
1503 DW LDDRIVE
; Disk I/O driver 1 is 8-inch double-density.
1525 IF SCP
*LARGE*FASTSEEK
1527 ; PerSci 277 or 299.
1529 DRVTAB: DB 00H,08H,01H,09H,00H,08H,01H,09H
1530 TRKPT: DB 0,0,0,0,0,0,0,0
1564 ; Two 8-inch Shugart-type drives.
1566 DRVTAB: DB 0,8,10H
,18H
,0,8,10H
,18H
1567 TRKPT: DB 0,0,1,1,0,0,1,1
1602 ; Four 8-inch Shugart-type drives.
1604 DRVTAB: DB 0F2H,0E2H,0F2H,0E2H
1630 ; Cromemco drive select byte is derived as follows:
1632 ; Bit 6 = 1 if double density (if 16FDC)
1633 ; Bit 5 = 1 (motor on)
1634 ; Bit 4 = 0 for 5", 1 for 8" drives
1635 ; Bit 3 = 1 for drive 3
1636 ; Bit 2 = 1 for drive 2
1637 ; Bit 1 = 1 for drive 1
1638 ; Bit 0 = 1 for drive 0
1640 IF CROMEMCO4FDC
*LARGE
1644 DRVTAB: DB 31H
,32H
,31H
,32H
1670 IF CROMEMCO4FDC
*COMBIN
1672 ; A PerSci 277 and one 5.25-inch drive.
1674 DRVTAB: DB 31H
,32H
,24H
,31H
,32H
1702 IF CROMEMCO4FDC
*SMALL
1704 ; Three 5.25-inch drives.
1706 DRVTAB: DB 21H
,22H
,24H
1720 ; Cromemco 4FDC with two 8-inch Shugart-type drives.
1722 DRVTAB: DB 31H
,32H
,31H
,32H
1747 IF CROMEMCO16FDC
*SMALL
1749 ; Three 5.25-inch drives.
1751 DRVTAB: DB 21H
,61H
,22H
,62H
,24H
,64H
1752 TRKPT: DB 0,0,1,1,2,2
1769 IF CROMEMCO16FDC
*COMBIN
1771 ; A PerSci 277 or 299 and one 5.25-inch drive.
1773 DRVTAB: DB 31H
,71H
,32H
,72H
,24H
,64H
,31H
,71H
,32H
,72H
1774 TRKPT: DB 0,0,0,0,1,1,0,0,0,0
1810 IF CROMEMCO16FDC
*LARGE
1812 ; A PerSci 277 or 299.
1814 DRVTAB: DB 31H
,71H
,32H
,72H
,31H
,71H
,32H
,72H
1815 TRKPT: DB 0,0,0,0,0,0,0,0
1849 DW 128 ; Sector size in bytes.
1850 DB 2 ; Sector per allocation unit.
1851 DW 54 ; Reserved sectors.
1852 DB 2 ; Number of allocation tables.
1853 DW 64 ; Number of directory entrys.
1854 DW 720 ; Number of sectors on the disk.
1857 SDDRIVE: ; This is the IBM Personal Computer
1858 DW 512 ; disk format.
1875 ENDIF
; End of small drive DPTs.
1879 DW 128 ; Size of sector in bytes.
1880 DB 4 ; Sectors per allocation unit.
1881 DW 1 ; Number of reserved sectors.
1882 DB 2 ; Number of File Allocation Tables.
1883 DW 68 ; Number of directory entrys.
1884 DW 77*26 ; Number of sectors on the disk.
1890 DW 52 ; Old format had two tracks reserved.
1892 DW 64 ; 64 directory entrys.
1913 DW 192 ; 192 directory entrys in new 8-inch DD/DS format.
1922 DW 128 ; 128 directory entrys in old 8-inch DD/DS format.
1927 ENDIF
; End of large drive DPTs.
1929 DOSSEG: EQU
($+15)/16+BIOSSEG
; Compute segment to use for 86-DOS.
1930 DOSDIF: EQU
16*(DOSSEG
-BIOSSEG
)
1931 STKSAV: EQU 1701H
+DOSDIF
1932 DMAADD: EQU 15B4H
+DOSDIF