Classic Computer Magazine Archive COMPUTE! ISSUE 65 / OCTOBER 1985 / PAGE 110

INSIGHT: Atari

Bill Wilkinson


Atari Disk Drive Compatibility

Way back in 1978, when Atari announced the double-density 815 disk drive, Percom Data Corporation saw the prototypes displayed at several shows and decided it could easily build a better drive which would sell for less.
    Because Percom produced both single- and double-sided disk drives using both single and double density, and because it wanted to maintain compatibility with both the single-density 810 and doubledensity 815 drives, Percom invented the configuration block (more on this below). With some cooperation from a small, brand-new software company (wonder who that could be) which had inherited the source code rights to Atari's File Management System (FMS), Percom succeeded in establishing standards which have been adhered to by all other Atari-compatible drive manufacturers. All Atari-compatible drive manufacturers except one, that is: Atari. Before the 815 even hit the market, Atari dropped it from the product line. Years later, in 1984, Atari introduced the "enhanced density" 1050, which is actually somewhere between single-and double-density. Sigh.
    As of this writing, the following drives and/or modification kits are known to be capable of understanding the Percom-standard double-density mode and configuration table: Percom, Indus, Amdek, Astra, Trak, Rana, SWP (ATR-8000), Happy Doubler, and ICD's US Doubler.

The Percom Config Block
As defined by the Percom standard, a config block is a set of 12 bytes within the memory of the disk control microprocessor-which is inside your disk drive(s). You read a drive's config block by passing "N" to it as an SIO command. You can write a new config block to a drive via an "O" command. The "N" and "O" commands closely parallel the "R" and "W" sector input/output commands, except the data length is always 12 bytes and, no sector number is needed. The 12 bytes in the block are shown in the table.

Byte # # of
Bytes
Description
0
1
Number of Tracks
1
1
Step Rate
2-3
2
Sectors per Track
4
1
Number of Sides or Heads
5
1
Density (0=Single, 4=Double)
6-7
2
Bytes per Sector
8
1
Drive Selected?
9
1
Serial Rate Control
10-11
2
Miscellaneous (reserved)

    This table requires some explanation. First, all the double-byte values are in high-byte/low-byte order, the opposite of normal 6502 practice (because that's how the microprocessor Percom used in their drives worked). Also, not all these values have meaning to all manufacturers. In fact, some don't allow you to change more than two or three of the values listed here.
    The Step Rate controls the speed of a drive's head stepping motor, and the values used here have no universal meaning. A step rate of 2 may mean 6 milliseconds per track to one drive, 20 milliseconds per track to another, or be illegal to yet another.
    Number of Sides is actually one less than the actual number. So most drives use a zero here, meaning one head.
    Changing the value of Drive Selected may turn the drive off as far as the computer is concerned. Percom must have had its reasons for this, but I don't know what they were.

Changing The Config Block
For the Density byte of the config block, I don't know of any drives which use values other than 0 (FM mode, single density) or 4 (MFM mode, double density). If you find a drive that actually uses some other value (not just ignores it), let me know.
    The Serial Rate Control value and Miscellaneous bytes have no universal meanings. Some drives will remember these values if you change them; other drives ignore your values.
    So that leaves Number of Tracks, Sectors per Track, and Bytes per Sector, all of which should be self-explanatory. Again, though, many drives ignore values outside certain legal ranges. Indus drives, for example, reject any changes to the number of tracks or sectors. In fact, Indus pays attention only to the Bytes per Sector and the Density bytes. Experiment with your own drive(s). See what they will and will not allow. And even if they seem to allow a change, do they execute it or ignore it? (Fun, if you're a masochist, right?)
    And just how do you read and/or change the config block? Have a look at the BASIC program following this column. It should be pretty much self-explanatory. You can use the subroutines at 8010, 8210, and 9010 in your own programs. Remember what we said at the beginning, however: Atari drives do not follow the Percom config block standard. As a result, this program works only on Atari-compatible disk drives, not on the Atari 810 or 1050.

Configuration Block Modifier
For instructions on entering this listing, please refer to "COMPUTE!'s Guide to Typing In Programs" published bimonthly in COMPUTE!.

KG 1010 REM
NP 1020 REM CONFIGURE FROM B
        ASIC
KI 1030 REM
DJ 1050 DIM TEMP$(20),TBL$(1
        2),CMD$(1)
GK 1060 GRAPHICS 0:PRINT "
        *** DISK CONFIGURATI
        ON PROGRAM ***"
MO 1070 PRINT :PRINT :PRINT
        "What disk drive wil
        l we work with";
ND 1080 INPUT DRIVE
EA 1090 IF DRIVE<1 OR DRIVE>
        8 OR DRIVE<>INT(DRIV
        E) THEN RUN
NL 1100 GRAPHICS 0:PRINT "DR
        IVE #";DRIVE;
AL 1110 GOSUB 8000
PB 1120 IF SIOSTATUS<128 THE
        N 1170
DI 1130 PRINT " won't let me
        read"
IJ 1140 PRINT "{3 SPACES}the
         configuration block
        ."
OI 1150 PRINT SPRINT "It gav
        e me error #";SIOSTA
        TUS
AO 1160 STOP
CA 1170 PRINT " looks like t
        his:":PRINT
CI 1180 PRINT TRACKS;" TRACK
        S of ";SECTORSPERTRA
        CK;" SECTORS each"
JB 1190 PRINT :PRINT "each s
        actor has ";BYTESPER
        SECTOR;" BYTES, & de
        nsity"
NB 1200 PRINT "  is ";DENSIT
        Y;", considered ";
MO 1210 IF DENSITY=0 THEN PR
        INT "SINGLE density,
MM 1220 IF DENSITY=4 THEN PR
        INT "DOUBLE density,
        "
DM 1230 IF DENSITY<>0 AND DE
        NSITY<>4 THEN PRINT
        "UNKNOWN DENSITY,"
JN 1240 PRINT " with ";SIDE
        S;" SIDE(s)."
IG 1250 PRINT :PRINT "the ST
        EP RATE setting is "
        ;STEPRATE
AI 1260 PRINT "other setting
        s are SELECT";SELEC
        T;","
NN 1270 PRINT "  ACIA=";ACIA
        ;", and MISC=";MISC
EJ 1280 PRINT :PRINT "SELECT
         A CHOICE:"
BH 1290 PRINT "{3 SPACES}0 -
         quit and save confi
        guration"
DF 1300 PRINT "{3 SPACES}1 -
         change drive settin
        g(s)"
HP 1310 PRINT "{3 SPACES}2 -
         work with another d
        rive"
EI 1320 PRINT :PRINT "your c
        hoice ";:INPUT CHOIC
        E
GK 1330 IF CHOICE=0 THEN JUN
        K=USR(58484)
JF 1340 IF CHOICE=2 THEN RUN
ED 1350 GRAPHICS 0:PRINT "En
        ter new values. Hit
         RETURN to"
AB 1360 PRINT "  leave a val
        ue unchanged."
FI 1370 PRINT
BF 1380 PRINT "TRACKS";:TEMP
        =TRACKS
IJ 1390 GOSUB 7000:TRACKS=TE
        MP
HM 1400 PRINT "SECTORS PER T
        RACK";:TEMP=SECTORSP
        ERTRACK
DJ 1410 GOSUB 7000:SECTORSPE
        RTRACK=TEMP
PM 1420 PRINT "BYTES PER SEC
        TOR";:TEMP=BYTESPERS
        ECTOR
PK 1430 GOSUB 7000:BYTESPERS
        ECTOR=TEMP
NA 1440 PRINT "NUMBER OF SID
        ES";:TEMP=SIDES
DG 1450 GOSUB 7000:SIDES=TEM
        P
ME 1460 PRINT "DENSITY";:TEM
        P=DENSITY
OA 1470 GOSUB 7000:DENSITY=T
        EMP
FK 1480 PRINT
FN 1490 PRINT "STEP RATE";:T
        EMP=STEPRATE
CC 1500 GOSUB 7000:STEPRATE=
        TEMP
AA 1510 PRINT "SELECT";:TEMP
        =SELECT
HM 1520 GOSUB 7000:SELECT=TE
        MP
JO 1530 PRINT "ACIA";:TEMP=A
        CIA
MM 1540 GOSUB 7000:ACIA=TEMP
MA 1550 PRINT "MISCELLANEOUS
        WORD";:TEMP=MISC
ON 1560 GOSUB 7000:MISC=TEMP
BH 1570 GOSUB 8200
PE 1580 IF SIOSTATUS<128 THE
        N 1100
CD 1590 PRINT :PRINT
GI 1600 PRINT "Unable to set
         that configuration!
        "
JH 1610 PRINT " drive issue
        d error #";SIOSTATUS
BP 1620 PRINT :PRINT "(hit R
        ETURN to continue)"
NF 1630 GOTO 1100
CH 7000 REM ENTER DATA OR NO
         CHANGE
LN 7030 PRINT " [";TEMP;"] ?
        ";
LF 7040 INPUT TEMP$
BF 7050 IF LEN(TEMP$) THEN T
        EMP=VAL(TEMP$)
KN 7060 RETURN
IP 8000 REM EXTRACT INFO FRO
        M TABLE
IM 8030 TBL=ADR(TBL$):ADDR=T
        BL
MJ 8040 CMD$="N":GOSUB 9000:
        REM ---READ BLOCK---
IF 8050 TRACKS=PEEK(TBL+0)
CH 8060 STEPRATE=PEEK(TBL+1)
OI 8070 SECTORSPERTRACK=PEEK
        (TBL+2)*256+PEEK(TBL
        +3)
JI 8080 SIDES=PEEK(TBL+4)+1
OG 8090 DENSITY=PEEK(TBL+5)
KJ 8100 BYTESPERSECTOR=PEEK(
        TBL+6)*256+PEEK(TBL+
        7)
IC 8110 SELECT=PEEK(TBL+8)
NC 8120 ACIA=PEEK(TBL+9)
PA 8130 MISC=PEEK(TBL+10)*25
        6+PEEK(TBL+11)
KN 8140 RETURN
FP 8200 REM PUT NEW INFO INT
        O TABLE
IO 8230 TBL=ADR(TBL$):ADDR=T
        BL
CO 8240 POKE TBL+0,TRACKS
NA 8250 POKE TBL+1,STEPRATE
PB S260 POKE TBL+2,INT(SECTO
        RSPERTRACK/256)
JE S270 POKE TBL+3,SECTORSPE
        RTRACK-PEEK(TBL+2)*2
        56
EE 8280 POKE TBL+4,SIDES-1
JA 8290 POKE TBL+5,DENSITY
KP 8300 POKE TBL+6,INT(BYTES
        PERSECTOR/256)
FG 8310 POKE TBL+7,BYTESPERS
        ECTOR-PEEK(TBL+6)*25
        6
CN 8320 POKE TBL+8,SELECT
HN 8330 POKE TBL+9,ACIA
MM 8340 POKE TBL+10,INT(MISC
        /256)
JO 8350 POKE TBL+11,MISC-PEE
        K(TBL+10)*256
DO 8360 CMD$="O":GOSUB 9000:
        REM ---WRITE BLOCK--
        -
LC 8370 RETURN
NE 9000 REM DISK DENSITY CHA
        NGE ROUTINE
LA 9030 REM
LN 9040 REM ENTER: DRIVE NU
        MBER IN DRIVE
DC 9050 REM .{5 SPACES}buffe
        r address in ADDR
IP 9060 REM .{12 SPACES}comma
        nd in CMD$
LE 9070 REM
GH 9080 REM (ONLY "N" AND "O
        " ARE VALID FOR CMD$
        )
L6 9090 REM
GM 9100 REM EXITS status in
        SIOSTATUS
KP 9110 REM
OL 9130 TRAP 9190:REM activa
        ted if SIOCALL$ alre
        ady DIM'd
IL 9140 DIM SIOCALL$(16)
NF 9150 RESTORE 9180
JM 9160 FOR CNT=1 TO 14:READ
         BYTE
FD 9170 SIOCALL$(CNT)=CHR$(B
        YTE):NEXT CNT
MI 9180 DATA 104,32,89,228,1
        73,3,3,133,212,169,0
        ,133,213,96
FH 9190 TRAP 40000:REM turn
        off TRAP
ML 9200 POKE 768,ASC("1"):RE
        M don't ask me why
FP 9210 POKE 769,DRIVE:REM m
        ust be 1 through 8
OG 9220 POKE 770,ASC(CMD$)
MA 9230 POKE 771,128:REM ass
        ume output
LI 9240 IF CMD$="N" THEN POK
        E 771,64
GN 9250 POKE 773,INT(ADDR/25
        6):REM buffer addres
        s
PC 9260 POKE 772,ADDR-256*PE
        EK(773)
FH 9270 POKE 774,3:REM short
         timeout
KA 9280 POKE 775,0:REM (high
         byte of timeout)
BI 9290 POKE 776,12:POKE 777
        ,0:REM assume std co
        nfig block
HG 9300 SIOSTATUS=USR(ADR(SI
        OCALL$))
KN 9310 RETURN