# 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.