Diskette Sector I/O Routines

Christian Groessler

2014-04-10
The cc65 library provides functions to read and write raw disk sectors. Include the dio.h header file to get the necessary definitions.

1. Opening the disk for low level I/O

2. Reading and writing sectors

3. Querying sector size and count

4. Converting sector numbers


1. Opening the disk for low level I/O

Prior to using these functions a handle to the device has to be obtained. This is done with the dio_open function. After use, the handle should be released with the dio_close function.

    dhandle_t __fastcall__ dio_open (unsigned char device);

The device specifies the device to access, with 0 being the first device, 1 the second, and so on.

    unsigned char __fastcall__ dio_close (dhandle_t handle);

Closes a handle obtained by dio_open. Returns status code.

2. Reading and writing sectors

The read and write functions are:

    unsigned char __fastcall__ dio_read (dhandle_t handle,
                                         unsigned sect_num,
                                         void *buffer);

This function will read the sector specified by sect_num into the memory location at buffer.

    unsigned char __fastcall__ dio_write (dhandle_t handle,
                                          unsigned sect_num,
                                          const void *buffer);

This function will write the memory contents at buffer to the sector specified by sect_num. No verify is performed.

    unsigned char __fastcall__ dio_write_verify (dhandle_t handle,
                                                 unsigned sect_num,
                                                 const void *buffer);

This function will write the memory contents at buffer to the sector specified by sect_num. A verification is performed.

Use the dio_query_sectsize function to query the size of a sector and the dio_query_sectcount function to query the number of available sectors.

All these functions will return 0 for success and an OS specific error code in case of failure.

3. Querying sector size and count

Some systems support multiple diskette formats which have different sector sizes and/or different sector counts.

The following function returns the sector size of the currently inserted disk:

    unsigned __fastcall__ dio_query_sectsize (dhandle_t handle);

On the Atari platform, the sector size is handled specially. Please refer to the DIO section in the Atari-specific platform documentation.

The following function returns the sector count of the currently inserted disk:

    unsigned __fastcall__ dio_query_sectcount (dhandle_t handle);

4. Converting sector numbers

Since the read and write functions expect a sector number, for systems where the sectors aren't addressed by a logical sector number (e.g. CBM devices), there are 2 conversion functions. One of them converts a logical sector number to a head/track/sector triple. The other conversion function works the other way round.

    unsigned char __fastcall__ dio_phys_to_log (dhandle_t handle,
                                                const dio_phys_pos *physpos,
                                                unsigned *sectnum);

This function converts track/head/sector to logical sector number.

    unsigned char __fastcall__ dio_log_to_phys (dhandle_t handle,
                                                const unsigned *sectnum,
                                                dio_phys_pos *physpos);

This function converts a logical sector number to track/head/sector notation.

Note, that on systems which natively use logical sector numbers (e.g. Atari), the conversion functions are dummies. They ignore head/track (dio_phys_to_log) or return them as zero (dio_log_to_phys). The logical sector number is returned as physical sector and vice versa.