From 19d9a04e36e7fb96eebe89e24311408460c29a70 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Mon, 30 Sep 2024 11:08:46 -0400 Subject: reorganize files --- src/ata.hpp | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/ata.hpp (limited to 'src/ata.hpp') diff --git a/src/ata.hpp b/src/ata.hpp new file mode 100644 index 0000000..5394c31 --- /dev/null +++ b/src/ata.hpp @@ -0,0 +1,131 @@ +#ifndef ATA_HPP +#define ATA_HPP + +#include "portio.hpp" + +#include +#include + +namespace ATA +{ + enum class Type { + None, + ATA, + ATAPI + }; + + enum class Base : std::uint16_t { + Primary = 0x01F0, + Secondary = 0x0170 + }; + + enum class Drive : std::uint8_t { + Master = 0xA0, + Slave = 0xB0 + }; + + enum class Command : std::uint8_t { + Identify = 0xEC, + IdentifyPacketDevice = 0xA1 + }; + + namespace Status { + static constexpr std::uint8_t Busy = 0x80; + static constexpr std::uint8_t Ready = 0x40; + static constexpr std::uint8_t DF = 0x20; + static constexpr std::uint8_t DSC = 0x10; + static constexpr std::uint8_t DRQ = 0x08; + static constexpr std::uint8_t CORR = 0x04; + static constexpr std::uint8_t Index = 0x02; + static constexpr std::uint8_t Error = 0x01; + } + + static constexpr std::uint8_t ATAPIIdentify0 = 0x14; + static constexpr std::uint8_t ATAPIIdentify1 = 0xEB; + + using enum Base; + using enum Drive; + + template + struct Bus + { + template + using BPort = Port; + + [[no_unique_address]] BPort data; + [[no_unique_address]] BPort errFeats; + [[no_unique_address]] BPort count; + [[no_unique_address]] BPort lba0; + [[no_unique_address]] BPort lba1; + [[no_unique_address]] BPort lba2; + [[no_unique_address]] BPort select; + [[no_unique_address]] BPort cmdStat; + + Type identify(Drive drv) { + auto type = Type::None; + + data = std::to_underlying(drv); + count = '\0'; + lba0 = '\0'; + lba1 = '\0'; + lba2 = '\0'; + cmdStat = std::to_underlying(Command::Identify); + + if (cmdStat == '\0') + return type; + + type = Type::ATA; + while (cmdStat & Status::Busy); + + std::uint8_t stat; + do { + stat = cmdStat; + + if (stat & Status::Error) { + if (lba1 == ATAPIIdentify0 && lba2 == ATAPIIdentify1) { + type = identifyAtapi(drv); + break; + } else { + return type; + } + } + } while (!(stat & Status::DRQ)); + + if (type != Type::None) { + for (int i = 0; i < 256; ++i) { + volatile std::uint16_t w = data; + (void)w; + } + } + + return type; + } + + Type identifyAtapi(Drive drv) { + data = std::to_underlying(drv); + count = '\0'; + lba0 = '\0'; + lba1 = '\0'; + lba2 = '\0'; + cmdStat = std::to_underlying(Command::IdentifyPacketDevice); + + if (cmdStat == '\0') + return Type::None; + + while (cmdStat & Status::Busy); + + std::uint8_t stat; + do { + stat = cmdStat; + + if (stat & Status::Error) + return Type::None; + } while (!(stat & Status::DRQ)); + + return Type::ATAPI; + } + }; +} // ATA + +#endif // ATA_HPP + -- cgit v1.2.3