SIO

## What is the SIO?

The SIO stands for the "Serial Input/Output". It is a data transfer protocol used by the Atari 8-bit machines to communicate with a printer, disk drive, modem etc. via the SIO connector. These transfers are controlled by the POKEY chip.

## Is this something like RS-232?

Basically, yes. It is possible to connect the SIO port to a RS-232 port, the only one you should change is the voltage: the SIO uses TTL-signals. Serial transfer parameters usually are as follows:

- 1 start bit
- 1 stop bit
- 8 data bits
- no parity control
- 19200 bits per second

The last parameter may vary, as for example so called "cassette recorders" (who can remember such data storage?) use 600 baud; also some disk drives may operate at 38400, 52000, 67000, 96000 or 125000 baud.

## SIO connector

1 | clock in
2 | clock out
3 | data in
4 | gnd
5 | data out
6 | gnd
7 | command
8 | motor control
9 | proceed
10 | +5V/ready
11 | audio in
12 | +12V (1200XL & 400/800)
13 | interrupt

## Command Frame

Offset | Name | Description
--- | --- | ---
$00 | DDEVIC | Device ID
$01 | DCOMND | Command
$02 | DAUX1 | Auxiliary byte 1
$03 | DAUX2 | Auxiliary byte 2
$04 |  | Checksum of previous bytes

## Communication

First, the computer sets the COMMAND line at the SIO connector.
Then sends the command block (4 bytes + checksum)
Then waits for a response (1 byte without a checksum):
$41 (A) = Acknowledge, the command is valid and will be executed.
$4E (N) = Negative, the command is invalid.
If the device responds "N", the transfer is aborted.
Otherwise ("A") the data block is transferred with the checksum.
Now the computer waits for a final acknowledge (1 B without a checksum):
$43 (C) = Complete, operation completed successfully.
$45 (E) = an Error has occurred.

## Device IDs

Floppy | Printer | Cassette | RS232
--- | --- | --- | ---
ID | Device | ID | Device | ID | Device | ID | Device
$31 | D1: | $40 | P1: | $60 | C: (dummy) | $50 | R1:
$32 | D2: | $41 | P2: |  |  | $51 | R2:
$33 | D3: | $42 | P3: |  |  | $52 | R3:
$34 | D4: | $43 | P4: |  |  | $53 | R4:
$35 | D5: | $44 | P5: |  |  |  |
$36 | D6: | $45 | P6: |  |  |  |
$37 | D7: | $46 | P7: |  |  |  |
$38 | D8: | $47 | P8: |  |  |  |
$39 | D9: | $48 | P9: |  |  |  |

Editor, Screen and Keyboard are not connected via SIO, hence you don't find entries here.
Cassette is a dummy. A tape recorder is an unintelligent device. It neither reads the command frame nor does it answer commands.
Sparta DOS 3.3x is said to support drives up to D15.

# Commands

Command | $20
Function | Format Auto
AUX1 | Config Byte 1 (?)
AUX2 | Config Byte 2 (?)
Description | Speedy 1050: Format automatically, acts like $21, but computer doesn't have to wait 'till drive is ready

Command | $21
Function | Format Drive
AUX1 | n/a
AUX2 | n/a
Description | Single for 810 and stock 1050 or as defined by CMD $4F for upgraded drives (Speedy, Happy, HDI, Black Box, XF 551). Returns 128 bytes (SD) or 256 bytes (DD) after format. Format ok requires that the first two bytes are $FF. It is said to return bad sector list (never seen one).

Command | $22
Function | Format Medium Density
AUX1 | n/a
AUX2 | n/a
Description | Formats medium density on an Atari 1050. Format medium density cannot be achieved via PERCOM block settings!

Command | $23
Function | Service
AUX1 | n/a
AUX2 | n/a
Description | Atari 1050 Diagnostic Software uses this. Don't use it yourself, you may lose data.

Command | $24
Function | Diagnostic
AUX1 | n/a
AUX2 | n/a
Description | Atari 1050 Diagnostic Software uses this. Don't use it yourself, you may lose data.

Command | $3F
Function | Get high-speed-index
AUX1 | n/a
AUX2 | n/a
Description | Returns a single byte Happy: Returns $0A US-Doubler: Returns $0A HDI: Returns $0A Speedy: Returns $09 Toms 720: Returns $06 (?)
Drive | Speed | Cmd | Data
--- | --- | --- | ---
All devices | 19120 | $28 | $28
XF551 High Speed | 39000 | $28 | $10
US-Doubler & compatibles (Happy?) | 52000 | $0A | $0A
Speedy | 57000 | $09 | $09
IndusGT Syncromesh | 72000 | $28 | $06
XF551 & Indus have bit 7 of command byte set for highspeed data frame.

Command | $41
Function | Add/Remove Command
AUX1 | n/a
AUX2 | n/a
Description | Speedy 1050, HDI: Sends 3 bytes to drive. First byte is new command. Bytes 2 and 3 are the address in Speeder RAM. Add/remove command to/from internal command table. Existing command will be overwritten. Use address of $0000 to erase command.

Command | $44
Function | Configure Drive
AUX1 | Configuration Byte
AUX2 | n/a
Description |
Bit | Description
--- | ---
Bit 0 | ERROR beep ON
Bit 1 | unused
Bit 2 | unused
Bit 3 | Don't stop drive motor upon $51 cmd
Bit 4 | Don't write VTOC and Bootsector upon $20 cmd
Bit 5 | Format without verify
Bit 6 | HEX display
Bit 7 | allow ERROR display

Command | $48
Function | Happy Command
AUX1 | $01
AUX2 | $00-$FF
Description | Set motor off delay from 0 to 6.5 seconds. Default is 3 seconds.
AUX1 | $02
AUX2 | $Bx
Description | Set new drive number You should check before if this potential drive already exists using STATUS
AUX1 | $03
AUX2 | $00
Description | Clears all Software settings. Reads disk density.
AUX1 | $18
AUX2 | $10
Description | Software write protect ON
AUX1 | $18
AUX2 | $08
Description | Software write protect OFF
AUX1 | $20
AUX2 | $00
Description | Drive uses command $50 instead of $57
AUX1 | $60
AUX2 | $60
Description | Set RAM protect. Drive does not use RAM for track buffers or something like this.
AUX1 | $00
AUX2 | $80
Description | Set RAM free. Allows RAM usage for track buffering.
AUX1 | $E0
AUX2 | $E0
Description | Set unhappy mode. Disable all speeder functions but DD.

Command | $4B
Function | Slow/Fast Config
AUX1 | Configuration Byte
AUX2 | n/a
Description |
Bit | Description
--- | ---
Bit 0 | Read sector slow
Bit 1 | Write sector slow
Bit 2 | Verify OFF
Bit 3 | Drive slow
Bit 4 | unused
Bit 5 | unused
Bit 6 | read 1 track slow (resets when track changes)
Bit 7 | read 1 disk slow (resets when disk is changed)

Command | $4C
Function | Jump without Message
AUX1 | Address LOW
AUX2 | Address HIGH
Description | Speedy 1050: Drive jumps to program address in its memory.

Command | $4D
Function | Jump with Message
AUX1 | Address LOW
AUX2 | Address HIGH
Description | Speedy 1050: Like $4C, but drive acknowledges command prior execution (sends COMPLETE).

Command | $4E
Function | Read PERCOM Block
AUX1 | n/a
AUX2 | n/a
Description | Happy, Speedy, F2000, HDI, XF551, BB: Reads 12 bytes from drive.
Offset | Description
--- | ---
$00 | Number of tracks
$01 | Step rate (00=30ms 01=20ms 10=12ms 11=6ms)
$02 | Sectors per Track HIGH
$03 | Sectors per Track LOW
$04 | Number of sides decreased by one
$05 | Record Method (0=FM single, 4=MFM double, 6=1.2M)
$06 | Bytes per Sector HIGH
$07 | Bytes per Sector LOW
$08 | Drive online ($FF or $40 for XF551)
$09 | Unused (Serial rate control?)
$0A | Unused
$0B | Unused
For harddrives or ramdisks, track equals one and byte 2 and 3 are no. of sectors per disk (minus 1 on MIO board and Black Box) I suggest ramdisks return $00 for tracks

Command | $4F
Function | Write PERCOM Block
AUX1 | n/a
AUX2 | n/a
Description | Same definition as in $4E. Send this command prior format ($21) to choose how to format a disk.

Command | $50
Function | Write Sector
AUX1 | Sector LOW
AUX2 | Sector HIGH
Description | Sends 128 or 256 (or more) bytes to drive and writes sector w/o verify.

Command | $51
Function | Quit
AUX1 | n/a
AUX2 | n/a
Description | Speedy 1050, HDI: Writes buffered data to disk and stops motor

Command | $52
Function | Read Sector
AUX1 | Sector LOW
AUX2 | Sector HIGH
Description | Reads 128 or 256 (or more) bytes from drive.

Command | $53
Function | Get Status
AUX1 | n/a
AUX2 | n/a
Description | Gets status information from intelligent peripheral Reads 4 bytes
Offset | Description
--- | ---
$00 | Drive status
| bit 0 | Command frame error
| bit 1 | Checksum error (Data frame error).
| bit 2 | Write Error (Operation error/FDC error)
| bit 3 | Write protected
| bit 4 | Motor is ON
| bit 5 | Sector size (0=$80 1=$100)
| bit 6 | Unused
| bit 7 | Medium Density (MFM & $80 byte mode)
$01 | Inverted, contains WD2793 Status Register. Depends on command used prior status.
| bit 0 | Controller busy
| bit 1 | Data Request or Index (DRQ)
| bit 2 | Data lost or track 0
| bit 3 | CRC Error
| bit 4 | Record not found
| bit 5 | Record Type or Head Loaded
| bit 6 | Write Protected (Always false upon read)
| bit 7 | Not Ready (Disk Removed)
$02 | Timeout for format ($E0) - Time the drive will need to format a disk
$03 | Copy of WD2793 Master status register

Command | $54
Function | Read Memory
AUX1 | Address LOW
AUX2 | Address HIGH
Description | HDI: Reads 256 bytes of memory. In case you try to read the HDI hardware registers ($4000 to $4FFF) it may crash.

Command | $54
Function | Get drive variables
AUX1 | ?
AUX2 | ?
Description | Super Archiver: Sends 00-7F variables.

Command | $55
Function | Motor ON
AUX1 | ?
AUX2 | ?
Description | ?

Command | $56
Function | Verify Sector
AUX1 | ?
AUX2 | ?
Description | ?

Command | $57
Function | Write Sector with Verify
AUX1 | Sector LOW
AUX2 | Sector HIGH
Description | Writes Sector to drive, drive rereads the sector, but doesn't send the reread sector back to the computer

Command | $60
Function | Write Track
AUX1 | First Sector
AUX2 | Last Sector
Description | Speedy 1050: Writes multiple sectors. Amount of data equals # sectors by sector size.

Command | $62
Function | Read Track
AUX1 | First Sector
AUX2 | Last Sector
Description | Speedy 1050: Reads multiple sectors. Amount of data equals # sectors by sector size.

Command | $66
Function | Format Disk with Special Sector-Skew
AUX1 | n/a
AUX2 | n/a
Description | US-Doubler, HDI: Sends 128 byte of data to the floppy. The first 12 bytes are the Percom block. The next bytes (as many as there are sectors per track) are the sector numbers in the order you would like them to be formatted. Filler bytes must be zeroes.
    Example for SSSD:
    28 02 00 12 00 00 00 80 FF 00 00 00 12 10 0E 0C
    0A 08 06 04 02 11 0F 0D 0B 09 07 05 03 01 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Command | $68
Function | Get SIO Length
AUX1 | n/a
AUX2 | n/a
Description | Speedy 1050, HDI: Returns 2 byte value matching the length of the SIO routine which you can read from the drive using command $69.

Command | $69
Function | Get SIO Routine
AUX1 | Relocate Address LOW
AUX2 | Relocate Address HIGH
Description | Speedy 1050, HDI: Reads high speed SIO routine from Speedy 1050 relocated to any address you wish. You can use this routine on your XL/XE to perform highspeed I/O. Use this routine instead of $E459.
    LDA $300	; wanna talk to disk?
    AND #$F0
    CMP #$30
    BEQ NEWSIO	; Yes
    JMP $E459	; No
    NEWSIO ...

Command | $74
Function | Return prepared buffer
AUX1 | ?
AUX2 | ?
Description | Super-Archiver: Returns buffer as set by previous $75 command(?)

Command | $75
Function | Upload & execute code
AUX1 | ?
AUX2 | ?
Description | Super-Archiver: Writes code to $1000 and executes it.

Sources:
Mapping the Atari
Atari800 Emulator Sources
James Bradford
Erhard Puetz
Draco
Back (c) 1998-2004 Jindroush Last modified: Sat Jan 11 17:15:21 2003