From df7982d9e5699f26bf1019cb95bc40a394cc4db2 Mon Sep 17 00:00:00 2001
From: Able <abl3theabove@gmail.com>
Date: Sat, 7 Dec 2024 10:44:29 -0600
Subject: [PATCH] ata pio mode

---
 repbuild/src/main.rs                       |   3 +-
 sysdata/programs/diskio_driver/src/main.hb | 147 ++++++++++++++-------
 sysdata/programs/diskio_driver/src/regs.hb |  56 +++++---
 sysdata/system_config.toml                 |  16 +--
 4 files changed, 143 insertions(+), 79 deletions(-)

diff --git a/repbuild/src/main.rs b/repbuild/src/main.rs
index 31600c4..239bf35 100644
--- a/repbuild/src/main.rs
+++ b/repbuild/src/main.rs
@@ -455,7 +455,8 @@ fn run(release: bool, target: Target, do_accel: bool) -> Result<(), Error> {
             #[rustfmt::skip]
             com.args([
                 "-bios", &ovmf_path.change_context(Error::OvmfFetch)?,
-                "-drive", "file=target/disk.img,format=raw",
+                //"-hda", "target/disk.img",
+                "-drive", "file=target/disk.img,index=0,if=ide,format=raw",
                 "-device", "vmware-svga",
                 // "-serial", "stdio",
                 "-m", "2G",
diff --git a/sysdata/programs/diskio_driver/src/main.hb b/sysdata/programs/diskio_driver/src/main.hb
index eb9a3a9..c3194fa 100644
--- a/sysdata/programs/diskio_driver/src/main.hb
+++ b/sysdata/programs/diskio_driver/src/main.hb
@@ -2,73 +2,121 @@
 .{inb, outb} := memory
 
 regs := @use("regs.hb");
-.{ATA_PRIMARY_COMM_REGSTAT, ATA_PRIMARY_DRIVE_HEAD, ATA_PRIMARY_SECCOUNT, ATA_PRIMARY_LBA_LO, ATA_PRIMARY_LBA_MID, ATA_PRIMARY_LBA_HI, STAT_BSY} := regs
+.{ATA_PRIMARY_IO, ATA_PRIMARY_DEVCTL, ATA_SECONDARY_DEVCTL, ATA_REG_STAT, ATA_SR_ERR, ATA_SR_BSY, ATA_SR_DF, ATA_SR_DRQ} := regs
+
+sloop := fn(i: u8): void {
+	// idx := 0xFFFFFFF
+	// loop {
+	// 	if idx == 0 {
+	// 		break
+	// 	} else {
+	// 		idx -= 1
+	// 	}
+	// }
 
-sloop := fn(): void {
-	idx := 0xFFFFFFF
 	loop {
-		if idx == 0 {
+		if i == 0 {
 			break
 		} else {
-			idx -= 1
+			a := inb(ATA_SECONDARY_DEVCTL)
+
+			i -= 1
 		}
 	}
 }
 
-identify := fn(): u8 {
-	a := inb(ATA_PRIMARY_COMM_REGSTAT)
-	outb(ATA_PRIMARY_DRIVE_HEAD, 0xA0)
-	log.info("Primary drive head set.\0")
+// identify := fn(): u8 {
+// 	a := inb(ATA_PRIMARY_COMM_REGSTAT)
+// 	outb(ATA_PRIMARY_DRIVE_HEAD, 0xA0)
+// 	log.info("Primary drive head set.\0")
 
-	a = inb(ATA_PRIMARY_COMM_REGSTAT)
-	outb(ATA_PRIMARY_SECCOUNT, 0)
-	a = inb(ATA_PRIMARY_COMM_REGSTAT)
-	outb(ATA_PRIMARY_LBA_LO, 0)
-	a = inb(ATA_PRIMARY_COMM_REGSTAT)
-	outb(ATA_PRIMARY_LBA_MID, 0)
-	a = inb(ATA_PRIMARY_COMM_REGSTAT)
-	outb(ATA_PRIMARY_LBA_HI, 0)
-	a = inb(ATA_PRIMARY_COMM_REGSTAT)
-	outb(ATA_PRIMARY_COMM_REGSTAT, 0xEC)
-	outb(ATA_PRIMARY_COMM_REGSTAT, 0xE7)
+// 	a = inb(ATA_PRIMARY_COMM_REGSTAT)
+// 	outb(ATA_PRIMARY_SECCOUNT, 0)
+// 	a = inb(ATA_PRIMARY_COMM_REGSTAT)
+// 	outb(ATA_PRIMARY_LBA_LO, 0)
+// 	a = inb(ATA_PRIMARY_COMM_REGSTAT)
+// 	outb(ATA_PRIMARY_LBA_MID, 0)
+// 	a = inb(ATA_PRIMARY_COMM_REGSTAT)
+// 	outb(ATA_PRIMARY_LBA_HI, 0)
+// 	a = inb(ATA_PRIMARY_COMM_REGSTAT)
+// 	outb(ATA_PRIMARY_COMM_REGSTAT, 0xEC)
+// 	outb(ATA_PRIMARY_COMM_REGSTAT, 0xE7)
 
-	status := inb(ATA_PRIMARY_COMM_REGSTAT)
-	log.info("Waiting for status.\0")
+// 	status := inb(ATA_PRIMARY_COMM_REGSTAT)
+// 	log.info("Waiting for status.\0")
+// 	loop {
+// 		if (status & STAT_BSY) == 0 {
+// 			log.info("Status got.\0")
+// 			break
+// 		} else {
+// 			sloop()
+// 		}
+// 		status = inb(ATA_PRIMARY_COMM_REGSTAT)
+// 	}
+// 	if status == 0 {
+// 		log.error("No drive detected.\0")
+
+// 		return 0
+// 	}
+// 	log.info("Status indicates presence of a drive. Polling while STAT_BSY... \0")
+// 	loop {
+// 		if (status & STAT_BSY) == 0 {
+// 			log.info("Status got.\0")
+// 			break
+// 		} else {
+// 			sloop()
+// 		}
+// 		status = inb(ATA_PRIMARY_COMM_REGSTAT)
+// 	}
+
+// 	mid := inb(ATA_PRIMARY_LBA_MID)
+// 	hi := inb(ATA_PRIMARY_LBA_HI)
+
+// 	if (mid | hi) == 0 {
+// 		log.error("The drive is not ATA. (Who knows what it is.)\0")
+// 		return 0
+// 	}
+
+// 	return 0
+// }
+
+drive_reset := fn(): void {
+	log.warn("Drive resetting.\0")
+	outb(ATA_PRIMARY_DEVCTL, 0x4)
+	sloop(4)
+	outb(ATA_PRIMARY_DEVCTL, 0x0)
+}
+
+poll := fn(): u8 {
+	sloop(4)
+	status := 0
+	// busy loop waiting for status
 	loop {
-		if (status & STAT_BSY) == 0 {
-			log.info("Status got.\0")
+		status = inb(ATA_PRIMARY_IO + ATA_REG_STAT)
+		if (status & ATA_SR_BSY) == 0 {
 			break
-		} else {
-			sloop()
 		}
-		status = inb(ATA_PRIMARY_COMM_REGSTAT)
-	}
-	if status == 0 {
-		log.error("No drive detected.\0")
-
-		return 0
-	}
-	log.info("Status indicates presence of a drive. Polling while STAT_BSY... \0")
-	loop {
-		if (status & STAT_BSY) == 0 {
-			log.info("Status got.\0")
-			break
-		} else {
-			sloop()
-		}
-		status = inb(ATA_PRIMARY_COMM_REGSTAT)
 	}
 
-	mid := inb(ATA_PRIMARY_LBA_MID)
-	hi := inb(ATA_PRIMARY_LBA_HI)
+	status = inb(ATA_PRIMARY_IO + ATA_REG_STAT)
+	if (status & ATA_SR_DF) == 0 {
+		log.error("ATA PRIMARY DRIVE FAULT\0")
+		return 1
+	}
 
-	if (mid | hi) == 0 {
-		log.error("The drive is not ATA. (Who knows what it is.)\0")
-		return 0
+	if (status & ATA_SR_ERR) == 0 {
+		log.error("ATA PRIMARY ERR\0")
+		return 2
+	}
+
+	if (status & ATA_SR_DRQ) == 0 {
+		log.error("ATA PRIMARY DRQ\0")
+		return 3
 	}
 
 	return 0
 }
+
 main := fn(): int {
 	// shuts down ableOS
 	// outb(0xF400, 0)
@@ -77,7 +125,10 @@ main := fn(): int {
 	b := inb(0x4700)
 
 	// c := buffer.search("XNumber\0")
-	c := identify()
+	// c := identify()
+
+	d := drive_reset()
+	e := poll()
 
 	return 0
 }
\ No newline at end of file
diff --git a/sysdata/programs/diskio_driver/src/regs.hb b/sysdata/programs/diskio_driver/src/regs.hb
index 5562d1b..501d539 100644
--- a/sysdata/programs/diskio_driver/src/regs.hb
+++ b/sysdata/programs/diskio_driver/src/regs.hb
@@ -1,23 +1,35 @@
-$ATA_PRIMARY_DATA := @intcast(0x1F0)
-$ATA_PRIMARY_ERR := @intcast(0x1F1)
-$ATA_PRIMARY_SECCOUNT := @intcast(0x1F2)
-$ATA_PRIMARY_LBA_LO := @intcast(0x1F3)
-$ATA_PRIMARY_LBA_MID := @intcast(0x1F4)
-$ATA_PRIMARY_LBA_HI := @intcast(0x1F5)
-$ATA_PRIMARY_DRIVE_HEAD := @intcast(0x1F6)
-$ATA_PRIMARY_COMM_REGSTAT := @intcast(0x1F7)
-$ATA_PRIMARY_ALTSTAT_DCR := @intcast(0x3F6)
+// $ATA_PRIMARY_DATA := @intcast(0x1F0)
+// $ATA_PRIMARY_ERR := @intcast(0x1F1)
+// $ATA_PRIMARY_SECCOUNT := @intcast(0x1F2)
+// $ATA_PRIMARY_LBA_LO := @intcast(0x1F3)
+// $ATA_PRIMARY_LBA_MID := @intcast(0x1F4)
+// $ATA_PRIMARY_LBA_HI := @intcast(0x1F5)
+// $ATA_PRIMARY_DRIVE_HEAD := @intcast(0x1F6)
+// $ATA_PRIMARY_COMM_REGSTAT := @intcast(0x1F7)
+// $ATA_PRIMARY_ALTSTAT_DCR := @intcast(0x3F6)
 
-// Indicates an error occurred. Send a new command to clear it
-STAT_ERR := 1 << 0
-// Set when the drive has PIO data to transfer, or is ready to accept PIO data.
-STAT_DRQ := 1 << 3
-// Overlapped Mode Service Request.
-STAT_SRV := 1 << 4
-// Drive Fault Error (does not set ERR).
-STAT_DF := 1 << 5
-// Bit is clear when drive is spun down, or after an error. Set otherwise.
-STAT_RDY := 1 << 6
-// Indicates the drive is preparing to send/receive data (wait for it to clear).
-// In case of 'hang' (it never clears), do a software reset.
-STAT_BSY := 1 << 7
\ No newline at end of file
+$ATA_PRIMARY_IO := @intcast(0x1F0)
+
+$ATA_PRIMARY_DEVCTL := @intcast(0x3F6)
+$ATA_SECONDARY_DEVCTL := @intcast(0x3F6)
+
+$ATA_REG_STAT := @intcast(0x7)
+
+// // Indicates an error occurred. Send a new command to clear it
+// STAT_ERR := 1 << 0
+// // Set when the drive has PIO data to transfer, or is ready to accept PIO data.
+// STAT_DRQ := 1 << 3
+// // Overlapped Mode Service Request.
+// STAT_SRV := 1 << 4
+// // Drive Fault Error (does not set ERR).
+// STAT_DF := 1 << 5
+// // Bit is clear when drive is spun down, or after an error. Set otherwise.
+// STAT_RDY := 1 << 6
+// // Indicates the drive is preparing to send/receive data (wait for it to clear).
+// // In case of 'hang' (it never clears), do a software reset.
+// STAT_BSY := 1 << 7
+
+$ATA_SR_BSY := 0x80
+$ATA_SR_DF := 0x20
+$ATA_SR_DRQ := 0x8
+$ATA_SR_ERR := 0x1
\ No newline at end of file
diff --git a/sysdata/system_config.toml b/sysdata/system_config.toml
index 84e2999..e90b0e2 100644
--- a/sysdata/system_config.toml
+++ b/sysdata/system_config.toml
@@ -28,8 +28,8 @@ resolution = "1024x768x24"
 [boot.limine.ableos.modules.diskio_driver]
 path = "boot:///diskio_driver.hbf"
 
-[boot.limine.ableos.modules.ps2_mouse_driver]
-path = "boot:///ps2_mouse_driver.hbf"
+# [boot.limine.ableos.modules.ps2_mouse_driver]
+# path = "boot:///ps2_mouse_driver.hbf"
 
 # [boot.limine.ableos.modules.ps2_keyboard_driver]
 # path = "boot:///ps2_keyboard_driver.hbf"
@@ -37,11 +37,11 @@ path = "boot:///ps2_mouse_driver.hbf"
 # [boot.limine.ableos.modules.ps2_driver]
 # path = "boot:///ps2_driver.hbf"
 
-[boot.limine.ableos.modules.sunset_client]
-path = "boot:///sunset_client.hbf"
+# [boot.limine.ableos.modules.sunset_client]
+# path = "boot:///sunset_client.hbf"
 
-[boot.limine.ableos.modules.sunset_server]
-path = "boot:///sunset_server.hbf"
+# [boot.limine.ableos.modules.sunset_server]
+# path = "boot:///sunset_server.hbf"
 
-[boot.limine.ableos.modules.ablefetch]
-path = "boot:///ablefetch.hbf"
+# [boot.limine.ableos.modules.ablefetch]
+# path = "boot:///ablefetch.hbf"