# pata_hard_disk

Hard disk library for communicating with parallel ata hard drives

Author | Matthew Schinkel - borntechi.com, copyright © 2009, all rights reserved.
Adapted-by |
Compiler | >=2.4q3

Description

    this library provides functions for pata/ide hard disk drives.

Sources

    "connecting ide drives by tilmann reh" - http://www.gaby.de/gide/IDE-TCJ.txt
    IDE hardware reference & information document by alex t. ivopol
    ATA Attachement with Packet Interface 6 - d1410r3-ATA-ATAPI-6.pdf

Notes

    - If you are not using Alternate Status, Digital Output or Drive Address registers
             pins cs1 & cs0 can be saved by connecting these ide pins to cs0-high, cs1-low
             at ide connector. normal operation does not require these pins. Set
             "CONST BYTE PATA_HD_USE_CS0_CS1_PINS = TRUE" if you will be using
             these registers
           - You MUST write full sectors of 512 bytes.
           - this lib does not do error checking

Dependencies

No dependency found

## Summary

### Global variables/contants

- `var byte pata_hd_sector_buffer_low[256]`
- `const SD_CARD = 1`
- `const PATA_HD_SPIN_UP = 0xE1`
- `const PATA_HARD_DISK = 0`
- `const PATA_HD_CYL_LOW_REG = 12`
- `var byte pata_hd_sector_count2 = 0`
- `const PATA_HD_SEC_NUM_REG = 11`
- `const PATA_HD_DATA_REG = 8`
- `var dword pata_hd_prev_address = 0`
- `var dword pata_hd_last_sector`
- `var bit pata_hd_last_operation`
- `const PATA_HD_IDENTIFY_DRIVE = 0xEC`
- `const PATA_HD_STATUS_REG = 15`
- `const PATA_HD_CYL_HIGH_REG = 13`
- `const PATA_HD_READ_SECTORS = 0x20`
- `const PATA_HD_COMMAND_REG = 15`
- `var bit pata_hd_byte_location = 0`
- `const DATA_MEDIA = PATA_HARD_DISK`
- `const bit PATA_HD_READ = 0`
- `var byte pata_hd_sector_buffer_high[256]`
- `const PATA_HD_SDH_REG = 14`
- `const bit PATA_HD_WAIT_READ = 0`
- `const bit PATA_HD_WAIT_WRITE = 1`
- `const PATA_HD_DODC_REG = 16`
- `const PATA_HD_SEC_COUNT_REG = 10`
- `const PATA_HD_PRECOMP_REG = 9`
- `const PATA_HD_ALT_STATUS_REG = 16`
- `const PATA_HD_ADDRESS_REG = 17`
- `const PATA_HD_SPIN_DOWN = 0xE0`
- `const PATA_HD_WRITE_SECTORS = 0x30`
- `const bit PATA_HD_WRITE = 1`
- `const PATA_HD_RECALIBRATE = 0x10`
- `var byte pata_hd_high_byte`
- `var byte pata_hd_word_count = 0`
- `var dword pata_hd_sector_select = 0`
- `var byte pata_hd_sector_count = 0`
- `const PATA_HD_ERROR_REG = 9`
- `var byte pata_hd_high_byte2`
- `var dword pata_hd_current_address = 0xFF_FF_FF_FF`

### Procedures

- `pata_hd_write_pulse( byte in z )`
- `pata_hd_read_data(byte out low_byte, byte out high_byte)`
- `pata_hd_read_pulse(dword in amount)`
- `pata_hd_read_to_sector_end()`
- `pata_hd_register_read(byte in register, byte out low_byte)`
- `pata_hd_register_write(byte in register, byte in low_byte)`
- `pata_hd_set_address(byte in pata_hd_head_addr, byte in cyl_high_addr, byte in cyl_low_addr, byte in sec_num_addr, byte in sec_count)`
- `pata_hd_write_data(byte in low_byte, byte in high_byte)`
- `pata_hd_write_sector_address(dword in address)`
- `pata_hd_drive_busy()`
- `pata_hd_read_sector_address(dword in address)`
- `pata_hd_print_sector(volatile byte out device, dword in address)`
- `pata_hd_read_sector()`
- `pata_hd_write_to_sector_end(byte in input_byte)`
- `pata_hd_print_drive_information(volatile byte out device)`
- `pata_hd_data_byte'put(byte in data_byte)`
- `pata_hd_init()`
- `pata_hd_data_request(bit in read_write)`
- `pata_hd_stop_write()`
- `pata_hd_select_register(byte in register)`
- `pata_hd_delay_100ns()`
- `pata_hd_write_sector()`
- `pata_hd_read_pulse_byte(dword in z)`
- `pata_hd_start_read(dword in address)`
- `pata_hd_set_idle()`
- `pata_hd_go_to_sector(dword in sector, byte in sec_count)`
- `pata_hd_drive_ready()`
- `pata_hd_print_sector_hex(volatile byte out device,word in bytes_per_line,dword in address)`
- `pata_hd_sector_buffer'put(word in address, byte in data)`
- `pata_hd_write_pulse_byte(dword in z)`
- `pata_hd_stop_read()`

Private

- `_pata_read_512()`

### Functions

- `pata_hd_data_byte'get() return byte`
- `pata_hd_number_of_sectors'get() return dword`
- `pata_hd_sector_buffer'get(word in address) return byte`

## API details

### Global variables/contants

- `var byte pata_hd_sector_buffer_low[256]`

      define the sector buffer. Can be read as pata_hd_sector_buffer[0-511]

- `const SD_CARD = 1`

  No documentation found

- `const PATA_HD_SPIN_UP = 0xE1`

      turn on the drive's motor

- `const PATA_HARD_DISK = 0`

      data media constants for fat32 lib

- `const PATA_HD_CYL_LOW_REG = 12`

      cylinder low

- `var byte pata_hd_sector_count2 = 0`

  No documentation found

- `const PATA_HD_SEC_NUM_REG = 11`

      sector number

- `const PATA_HD_DATA_REG = 8`

      readable/writeable registers

- `var dword pata_hd_prev_address = 0`

  No documentation found

- `var dword pata_hd_last_sector`

      read one entire sector at address. no need for start_read/stop_read

- `var bit pata_hd_last_operation`

  No documentation found

- `const PATA_HD_IDENTIFY_DRIVE = 0xEC`

      read drive info such as make/modem/sn/drive size

- `const PATA_HD_STATUS_REG = 15`

      status register  (creates interupt)

- `const PATA_HD_CYL_HIGH_REG = 13`

      cylinder high

- `const PATA_HD_READ_SECTORS = 0x20`

      reads data from sector(s)

- `const PATA_HD_COMMAND_REG = 15`

      command register

- `var bit pata_hd_byte_location = 0`

  No documentation found

- `const DATA_MEDIA = PATA_HARD_DISK`

  No documentation found

- `const bit PATA_HD_READ = 0`

      wait for sector buffer to fill it's contents with data from disk platters

- `var byte pata_hd_sector_buffer_high[256]`

      256 high bytes

- `const PATA_HD_SDH_REG = 14`

      sector/drive/head register

- `const bit PATA_HD_WAIT_READ = 0`

      other constants
      used for pata_hd_data_request()

- `const bit PATA_HD_WAIT_WRITE = 1`

      wait for sector buffer to empty it's contents to disk platters

- `const PATA_HD_DODC_REG = 16`

      digital output / device control

- `const PATA_HD_SEC_COUNT_REG = 10`

      sector count

- `const PATA_HD_PRECOMP_REG = 9`

      writeable registers

- `const PATA_HD_ALT_STATUS_REG = 16`

      alternate status (no interupt)

- `const PATA_HD_ADDRESS_REG = 17`

      drive address

- `const PATA_HD_SPIN_DOWN = 0xE0`

      turn off the drive's motor

- `const PATA_HD_WRITE_SECTORS = 0x30`

      write data to sector(s)

- `const bit PATA_HD_WRITE = 1`

      wait for sector buffer to empty it's contents to disk platters

- `const PATA_HD_RECALIBRATE = 0x10`

      common commands for command register:

- `var byte pata_hd_high_byte`

      Write one byte to disk pseudo var

- `var byte pata_hd_word_count = 0`

      other vars

- `var dword pata_hd_sector_select = 0`

  No documentation found

- `var byte pata_hd_sector_count = 0`

      counds sectors read, must be a byte.

- `const PATA_HD_ERROR_REG = 9`

      readable registers

- `var byte pata_hd_high_byte2`

      Read one byte (pseudo var)

- `var dword pata_hd_current_address = 0xFF_FF_FF_FF`

  No documentation found

### Procedures

- `pata_hd_write_pulse( byte in z )`

      Send a number of write pulses to data register sending 0's as data.
      Used to get to the end of a sector or to get to a certain
      location in a sector.
      Increment pata_hd_word_count

- `pata_hd_read_data(byte out low_byte, byte out high_byte)`

      Read two bytes from disk.

- `pata_hd_read_pulse(dword in amount)`

      Send a number of read pulses to data register without getting any data.
      Goes forward 2 bytes per amount
      Used to get to the end of a sector or to get to a certain
      location in a sector.
      Increment pata_hd_word_count

- `pata_hd_read_to_sector_end()`

      Finnish reading the current sector with input byte.

- `pata_hd_register_read(byte in register, byte out low_byte)`

      Select a register and get data from it.

- `pata_hd_register_write(byte in register, byte in low_byte)`

      Select a register and give it a command or data.

- `pata_hd_set_address(byte in pata_hd_head_addr, byte in cyl_high_addr, byte in cyl_low_addr, byte in sec_num_addr, byte in sec_count)`

      Go to a specific sector, select lba/chs mode and master/slave drive
      Max sector number is 0x0F_FF_FF_FF or the number of sectors the drive has.
      Max drive size is 0x0F_FF_FF_FF * 512 = 137.439 GB
      Sector count selects number of sectors that will be read
      Sector count value of 0 means 256 sectors will be read

- `pata_hd_write_data(byte in low_byte, byte in high_byte)`

      Write two bytes to disk
      Data will not be written unless 256 writes are sent.

- `pata_hd_write_sector_address(dword in address)`

      write one entire sector at address. no need for start_read/stop_read

- `pata_hd_drive_busy()`

      Registers may not be accessed unless bsy bit is
      low due to internal operations.

- `pata_hd_read_sector_address(dword in address)`

  No documentation found

- `pata_hd_print_sector(volatile byte out device, dword in address)`

      print a sector to an output device

- `pata_hd_read_sector()`

      read one entire sector

- `pata_hd_write_to_sector_end(byte in input_byte)`

      Finnish writing the current sector with input byte.

- `pata_hd_print_drive_information(volatile byte out device)`

      Read drive information (identify drive command)

- `pata_hd_data_byte'put(byte in data_byte)`

  No documentation found

- `pata_hd_init()`

      initialize startup settings

- `pata_hd_data_request(bit in read_write)`

      Wait for drive to be ready for a data transfer.
      Sets data pins as inputs or outputs for next read or write.

- `pata_hd_stop_write()`

      Tell drive you are done writing

- `pata_hd_select_register(byte in register)`

      Set register select pins to selected register, for internal use only.

- `pata_hd_delay_100ns()`

      100ns delay procedure

- `pata_hd_write_sector()`

      Write one sector to the disk, requires start write/stop write.

- `pata_hd_read_pulse_byte(dword in z)`

      goes to next byte instead of word like pata_hd_read_pulse

- `pata_hd_start_read(dword in address)`

      Get drive ready for reading at specified address

- `pata_hd_set_idle()`

      Set hard disk to idle state

- `pata_hd_go_to_sector(dword in sector, byte in sec_count)`

      Go to a specific sector number (lba mode only)
      Max sector number is 268435455 or the number of sectors the drive has.
      Max drive size is 268435455 * 512 = 137.439 GB
      Sector count selects number of sectors that will be read
      Sector count value of 0 means 256 sectors will be read

- `pata_hd_drive_ready()`

      Wait for drive to be up to speed and ready for a command.

- `pata_hd_print_sector_hex(volatile byte out device,word in bytes_per_line,dword in address)`

      print a sector to an output device in ascii hex

- `pata_hd_sector_buffer'put(word in address, byte in data)`

  No documentation found

- `pata_hd_write_pulse_byte(dword in z)`

      goes to next byte instead of word like pata_hd_write_pulse

- `pata_hd_stop_read()`

      Tell drive you are done reading

Private

- `_pata_read_512()`

      For faster reading in pata_hd_read_sector procedures

### Functions

- `pata_hd_data_byte'get() return byte`

  No documentation found

- `pata_hd_number_of_sectors'get() return dword`

      Get the size of the drive (number of sectors).
      Multiply by 512 for actual size.

- `pata_hd_sector_buffer'get(word in address) return byte`

  No documentation found

## Related samples

Here are the list of samples which use this library:

16f877 | 16f877_pata_hard_disk.jal
16f877 | 16f877_fat32_small_pata_hard_disk.jal
16f877a | 16f877a_pata_hard_disk.jal
16f877a | 16f877a_fat32_small_pata_hard_disk.jal
18f452 | 18f452_fat32_small_pata_hard_disk.jal
18f452 | 18f452_pata_hard_disk.jal
18f4525 | 18f4525_mp3_decoder_vs1053b_pata_hard_disk.jal
18f4525 | 18f4525_fat32_small_pata_hard_disk.jal
18f4525 | 18f4525_fat32_pata_hard_disk.jal
18f4525 | 18f4525_pata_hard_disk.jal
18f4620 | 18f4620_mp3_decoder_vs1053b_pata_hard_disk.jal
18f4620 | 18f4620_pata_hard_disk.jal
18f4620 | 18f4620_fat32_pata_hard_disk.jal
18f4620 | 18f4620_fat32_small_pata_hard_disk.jal
18f67j50 | 18f67j50_fat32_small_pata_hard_disk.jal
18f67j50 | 18f67j50_usb_msd_pata_hard_disk.jal
18f67j50 | 18f67j50_fat32_pata_hard_disk.jal
18f67j50 | 18f67j50_pata_hard_disk.jal
18f67j50 | 18f67j50_mp3_decoder_vs1053b_pata_hard_disk.jal
18f67j50 | 18f67j50_fat32_usb_msd_pata_hard_disk.jal