Jump to content
IGNORED

SIO questions


Recommended Posts

Built-in SIO is ~1-1.5KB/s (it's 19200 BAUD but with quite a bit of overhead between sectors). With a high speed SIO patch, the speed varies based on your drives, anywhere from 19200 BAUD to the max speed of ~126,000 BAUD (~10KB/s if done right) depending on your SIO device, which requires a special VBI handler, minimal screen, and nothing really happening but loading. Altirra natively has the high speed patch in place. I based an entire custom OS around learning how to support this, and it took several months. My suggestion is to just use what the Atari OS has built in and if you want more speed on the real hardware, apply an HISIO patch such as the great one available from Hiassoft, available here: https://github.com/HiassofT/highspeed-sio

 

If you are working with just sectors, loading and saving a sector is darned-near identical. The only difference is setting a flag and whether to pass an "R" (Read) or a "P"/"W" (Put or Write, W reads from the disk and tests it matches so it's slower). Are you planning on working on the sector-level? Or did you want to work with a DOS to handle the files? It's very different for either one.

Edited by Zolaerla
Some clarification
Link to comment
Share on other sites

For several methods of doing this, you can refer to: https://www.atariarchives.org/alp/chapter_9.php

 

If you want some sample (hopefully assembler-agnostic) code for a ReadSector and WriteSector function you can use (this takes up 45 bytes in binary format):

; *************************************************************************************************
; Constants

; Atari OS ========================================================================================

; Byte, The device ID number. eg, '1' or $31 for "D1".
; We're always going to use '1' here.
DDEVIC       = $300

; Byte, The unit number.
; We're always going to use 1 here.
DUNIT        = $301

; Byte, The command to use.
; We're going to use 'R' for read and 'W' for write.
DCOMND       = $302

; Byte, The status returned by the command. Set bit 7 for write and bit 6 for read.
DSTATS       = $303

; Address, Memory pointer for disk load/save routines.
DBUF         = $304

; Word, The byte count.
DBYT         = $308

; Word, Auxiliary bytes for SIO.
; We're going to set the sector number here
DAUX         = $30A

; Address, Where the disk handler is in the built-in OS.
DSKINV       = $E453


; Custom Constants ================================================================================

; This is the sector size to use. Change to 256 if using a DD disk (sector 4+ only!).
SECTORSIZE   = 128

; DUNIT and DDEVIC values for D1
DDEVICE_D1   = '1'
DUNIT_D1     = 1

; These are named constants for the commands we'll use:
DCOMND_Read  = 'R'
DCOMND_Write = 'W'

; These are named constants for the stats we'll use:
DSTATS_Read  = $40
DSTATS_Write = $80



; *************************************************************************************************
; Writes a sector to the disk.
; Incoming:
;   DAUX            Word, The sector to write to.
;   DBUF            Address, The address in RAM to write to the sector.
; Outgoing:
;   Negative        Set on failure, clear on success.
;   All registers are lost.
WriteSector:
  ; Set DCOMND and DSTATS
  LDA #DCOMND_Write
  STA DCOMND
  LDA #DSTATS_Write
  STA DSTATS

  ; Z is always clear
  BNE ReadWriteSector
; End WriteSector



; *************************************************************************************************
; Reads a sector from the disk.
; Incoming:
;   DAUX            Word, The sector to read.
;   DBUF            Address, Where to read the sector to in RAM.
; Outgoing:
;   Negative        Set on failure, clear on success.
;   All registers are lost.
ReadSector:
  ; Set DCOMND and DSTATS
  LDA #DCOMND_Read
  STA DCOMND
  LDA #DSTATS_Read
  STA DSTATS

  ; Fall through ------>
; End ReadSector



; *************************************************************************************************
; Handles a simple SIO command and waits until it is done.
; Incoming:
;   DCOMND          Byte, The command to use.
;   DSTATS          Byte, The read/write flags.
;   DAUX            Word, Auxiliary values.
;   DBUF            Address, Address.
;   DBYT            Word, The length of the transfer.
; Outgoing:
;   Negative        Set on failure, clear on success. Error code returned in DSTATS on failure.
;   All registers are lost.
ReadWriteSector:
  ; Set the sector size.
  LDA #<SECTORSIZE
  STA DBYT
  LDA #>SECTORSIZE
  STA DBYT + 1

  ; Set unit and device
  LDA #DUNIT_D1
  STA DUNIT
  LDA #DDEVICE_D1
  STA DDEVIC

  ; Call the disk routine and RTS
  JMP DSKINV
; ReadWriteSector

 

  • Like 1
Link to comment
Share on other sites

The reference you should start with is the official one: Atari 400/800 Operating System User's Manual, Section 5, page 97, Resident Diskette Handler. It describes how to set up parameters in page 3 and invoke DSKINV to read or write sectors. Most high-speed SIO routines are based on a similar foundation and can be swapped in once you have the basics working and need something more.

 

Keep in mind that unlike some other platforms, Atari disk drives often cannot be made to run faster. Stock 810/1050 drives don't support high-speed operation or a way to upload code to add it. So if you want to target a floppy disk the way it had to be done in the 80s, you have to assume that users will be loading your game at base speed only without any high speed support. Which is not that bad, especially compared to stock C64 or Apple II, but it does mean that if you want to load a big chunk of data between sections you still have to accommodate a 10-20 second wait.

 

  • Like 2
Link to comment
Share on other sites

11 hours ago, Ecernosoft said:

Actually one last thing: Where are the bios routines to do this? 

If you haven't already got them, De-Re Atari is a good read and Mapping the Atari which is a wealth

of information on most memory locations and their uses.

If your doing low level stuff you need to know what memory you can and cannot use.

image.thumb.png.7f6830af01a5c7f4ce0277ba81effcf9.png

  • Like 1
Link to comment
Share on other sites

20 hours ago, phaeron said:

The reference you should start with is the official one: Atari 400/800 Operating System User's Manual, Section 5, page 97, Resident Diskette Handler. It describes how to set up parameters in page 3 and invoke DSKINV to read or write sectors. Most high-speed SIO routines are based on a similar foundation and can be swapped in once you have the basics working and need something more.

 

Keep in mind that unlike some other platforms, Atari disk drives often cannot be made to run faster. Stock 810/1050 drives don't support high-speed operation or a way to upload code to add it. So if you want to target a floppy disk the way it had to be done in the 80s, you have to assume that users will be loading your game at base speed only without any high speed support. Which is not that bad, especially compared to stock C64 or Apple II, but it does mean that if you want to load a big chunk of data between sections you still have to accommodate a 10-20 second wait.

 

Got a link?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...