Diskette Sector I/O Routines

Christian Groessler


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.

    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.