Why to Change the Steprate for old Floppy Drives
Why would you even think of trying to adjust the steprate for floppy drives? I first became aware of this problem because my RX180 dual floppy drive, which I had converted to a DB37 adapter, was not working properly.
Two Shugart SA400L are installed in this double drive, which externally look exactly like the Tandon TM100-2A. But ... they did not work properly as external drives on my IBM PC 5150 with original IBM floppy controller. Why is that?
After a test on my CompatiCard IV, I changed the steprate once more by chance (on the CC IV, this can be changed quite easily by parameters). And lo and behold, suddenly everything was fine. Of course, I could have figured it out earlier by reading the manual. As the saying goes: "Those who can read have a clear advantage in life". Well then!
The Tandon TM100-1 (SS) and TM100-2A (DS) have a steprate of 5 ms and the Shugart SA400L has a steprate of 20 ms. The SA400 even has a value of 40 ms.
This is of course an extreme example: 5 ms vs. 20 or 40 ms. But it can also happen with other drives that you have the impression that the drives are „sawing“ more than „stepping“.
Here, too, it is worth changing the steprate. You will hear immediately whether it has changed for the better.
So the problem was solved - with my CC IV - and was almost forgotten until I came across the following forum thread on the internet.
@mikemcbike from VzEkC may forgive me for posting similar pictures here, but they are simply important for understanding. However, I followed a different path, namely via the Super PC/Turbo XT BIOS 3.1. This way is a little more elegant and quite simple.
Note: If you want to change the steprate or other parameters, then of course you must always keep an eye on your entire system. In my case, I had two external SA400Ls connected to the IBM PC 5150 with two internal Tandon TM100-2A. If I now globally change the steprate to 20 ms, the SA400Ls work very well, but the TM100-2As work in principle, but not optimally. Optimisation is then the order of the day. This article is basically only meant to show what is possible. However, this does not mean that it makes sense.
If you look in the right places in both BIOSs, you will find the following ...
BIOS Comparison
... the relevant parameters of the "Diskette Parameter Table" are almost identical.
The original steprate in the IBM PC BIOS (10/27/82) is 8 ms and results as follows:
SRT = 1100b = 0xCh = 2 x 4 = 8 ms (see next figures!)
This value of 8 ms corresponds very well to the steprates of earlier floppy drives. These values lie between 3 ms and 6 ms for 3.5" and 5.25" drives, or 10 ms for 8" drives.
However, the Shugart SA400 and SA400L were never used in the IBM DOS and DOS compatible computers (from August 1981). These drives date back to the 1970s.
The first IBM floppy disk drives were the single-sided TM100-1 and the double-sided TM100-2 (both Tandon) and a drive from Magnetic Peripherals Inc. (CDC). All have a steprate (SRT) of 5 ms.
I also looked in the very first IBM BIOS (04/24/81). Here, too, a value of 8 ms is stored for the steprate (SRT).
IBM Floppy Controller With NEC PD765A
A few pictures regarding to the so-called STEPRATE of the NEC PD765A
- F = 1ms
- E = 2ms
- D = 3ms
- C = 4ms
- B = 5ms
- A = 6ms
- 9 = 7ms
- 8 = 8ms
- 7 = 9ms
- 6 = 10ms
- ...
- 0 = 16ms
To reach the required 20ms, you need a value of 0x6h or 0110b for SRT (2 x 10 = 20ms); see above. It's that simple!
Patching the "Super PC/Turbo XT BIOS"
;================================================================
; Super PC/Turbo XT BIOS for Intel 8088 or NEC "V20" Motherboards
; Additions by Ya`akov Miles (1987) and Jon Petrosky (2008-2017)
; http://www.phatcode.net/
;================================================================
All you have to do now is change the PCXTBIOS.ASM file accordingly (line 3004), recompile the BIOS, burn it onto an EPROM and that's it.
Note: With this setting, which applies to all floppy drives on the computer, you can now no longer use the modern drives. 20 ms is too slow for a 3 or 6 ms drive, errors will also occur here.
The Interrupt 1Eh
But now the question arises whether this cannot be done a little more smartly. So I did a little more research and lo and behold ...
You can already see the solution in the last figure, you just have to look carefully! It is interrupt 1Eh; this points to the table with the drive parameters (diskette parameter table / DPT).
These parameters can of course be changed during operation. You just have to know where!
First of all, let's take a look at DOS system memory:
The interrupt vectors (00h-FFh) are stored in the memory at the lowest addresses from 00000h to 003FFh (1,024 byte). Exactly 256 vectors fit into this address range; each vector is two WORDS or 4 BYTES in size.
The address (the offset in the segment) of INT 1Eh is thus calculated as: 1Eh x 4 = 78h. We will need this address later.
DEBUG
And then there is the program DEBUG; simple but very powerful.
Does the result look familiar? Look at the very first figure. However, the value D for SRT is stored here with 3 ms. The steprate is therefore 6 ms.
Next, we want to write a small COM progam with DEBUG, which writes the value 6h to exactly this address. We remember that the value 6 corresponds to 10 ms, so the steprate is 2x10=20 ms.
Start any text editor, enter the following and save the file to STEPRATE.DEB:
A 100 ; this is a COM file
MOV AX,0000 ; segment DS=0000
MOV DS,AX
LDS DI,[0078] ; load pointer using DS, the DPT
MOV BYTE PTR [DI],6F ; SRT=6, HUT=F
MOV AH,00 ; reset FDC
INT 13 ; important
MOV AH,4C ; return to DOS (4C) with
INT 21 ; INT 21
R CX
14 ; length 12 byte
N STEPRATE.COM ; create filename STEPRATE.COM
W ; write
Q ; and quit
Then translate this small program with: DEBUG < STEPRATE.DEB, done. Now you only need to start STEPRATE.COM and the steprate is changed.
You can now generate the corresponding programmes for the most important step rates (3, 6, 10, 20 ms) and are thus completely flexible. Strictly speaking, the value of 3 ms cannot be entered at all. If you enter „E“ (2 ms), the step rate is 4 ms.
Assembler
Of course, the whole thing can also be done with user input, but in assembler. I found this tool by chance on the internet. The program is by Don L. Finley and free to use; there are no copyright entries.
A quick search on the internet has revealed that Don L. Finley died in 2012 at the age of 68.
Search the following source code for jump mark „valid:“ and you will immediately recognise the same code. You can easily create the EXEcutable with TASM and TLINK.
page 60,80
title STEPRATE A program to change the step rate of Floppy drives
;
; Before I receive any flames on the goodness of the following code, I
; would like to say that I find the 8088 destruction set disgusting. I
; would have written this program in C (or some language which shelters
; me from the architecture but I have an inherent abhorance of 32K programs
; which do something as simple as this.
; If you do not like the way I wrote it, the feel free to rewrite it.
; In case you have not guessed, DEMENTed REGISTERS and I do not get along
; together.
.radix 16
;***** Equates *********************************************************
cr equ 0Dh ;carriage return character
lf equ 0Ah ;line feed character
;********************************************
datarea segment
org 80h
count db ?
buffr db 20d dup (?) ;input for step rate
sm db 'Floppy Drive Step Rate is set to $'
m12 db '12$'
m8 db '9$'
m6 db '6$'
m3 db '3$'
mu db 'UNKNOWN$'
rms db ' ms.',cr,lf,'$'
minval db '3, 6, 9 or 12 are the only recognized step rates.'
db cr,lf,'$'
datarea ends
;***** Main Program ****************************************************
code segment
assume cs:code, es:code, ds:datarea, ss:stk_seg
; Start--- Set up the stack so that DOS will be able to find it's
; DS when we return. Ain't it disgusting that we have to fool with
; such nonsense!
start proc far
push ds ;save old data segment
sub ax,ax ;put zero in ax
push ax ;save it on stack
; see if a step rate entered from the keyboard
mov bx, offset count ;get the number of characters entered
mov ah,[bx]
mov al,ah ;keep count in ah
cmp al,0 ;see if any input
jz noinput
mov dx,0 ;set number to 0
loop:
inc bx ;point to character buffer
mov al,[bx]
cmp al,' '
jz aloop ;step past spaces
cmp al,'0'
jc noinput
cmp al,'9'+1
jnc noinput
sub al,'0'
push ax ;I suppose that there is some instruction
mov al,dl ; to ADD HL in the 8088 set. But I'm not gonna
add al,al ; look it up, anyhow times 2
mov ah,al ;and save it
add al,al ;times 4
add al,al ;times 8
add al,ah ;+ 2 = 10
mov dl,al
pop ax
add al,dl
mov dl,al
aloop:
sub ah,1 ;see if we are out of characters yet
jnz loop ;if not, stay at it till we run out (or bomb out)
mov al,dl
mov dl,0e0h ;set for 3 ms step rate
cmp al,3
jz valid
mov dl,0d0h
cmp al,6 ; try for 6
jz valid
mov dl,0c0h
cmp al,9 ;or 9
jz valid
mov dl,0b0h
cmp al,12d ; mayhaps 12
jz valid
; If we get to this point, we don't know what they have entered.
; Therefore, bomb out.
; set data segment register to where the messages are (I think)
mov ax,datarea
mov ds,ax
mov dx, offset minval
mov ah,9
int 21h
ret
; a valid number has been entered, change the step rate to it
valid:
push ds ; Save the data segment
mov bx,78h ;point to pointer for floppy drive tables
mov ax,0
mov ds,ax ;set to segment 0
mov ax,[bx] ;get the pointer
mov bx,ax ;into the bx register
mov al,[bx] ;now get the present step rate
and al,0fh ;remove the old step rate
or al,dl ;put in the new step rate
mov [bx],al ;and put it back where it goes
mov ah,0 ;now call on the BIOS to
int 13h ;reload the set floppy disk controller
pop ds ; Reset the Data Segment
; if we get to this point, we have either had no specified step rate
; or a new step rate has been successfully loaded. Let's tell 'em
; what they got.
noinput:
push ds ;save present data segment
mov bx,78h ;point to pointer for floppy drive tables
mov ax,0
mov ds,ax ;set to segment 0
mov ax,[bx] ;get the pointer
mov bx,ax ;into the bx register
mov al,[bx] ;now get the step rate
pop ds
push ax ;save the step rate on the stack
mov ax,datarea ;no comment
mov ds,ax
mov dx, offset sm ;print beginning of message
mov ah,9
int 21h
pop ax ;get the step rate back
and al,0f0h ;just interested in the step rate
cmp al,0b0h
jnz ms8
mov dx, offset m12
jmp pms
ms8:
cmp al,0c0h
jnz ms6
mov dx, offset m8
jmp pms
ms6:
cmp al,0d0h
jnz ms3
mov dx, offset m6
jmp pms
ms3:
cmp al,0e0h
jnz msu
mov dx, offset m3
jmp pms
msu:
mov dx, offset mu
pms:
mov ah,9
int 21h ;print step rate
mov dx, offset rms ;then print rest of message
mov ah,9
int 21h
ret ; back to DOS
start endp
code ends
;*********************************************
stk_seg segment stack
db 20 dup ('stack ')
stk_seg ends
end start
; and quit
Documents
- Super PC/Turbo XT BIOS: README.TXT
- Don L. Finley: README.TXT, STEPRATE.ASM and life tributes page.