From 60c5febc60eb6c8d721a86361f9a6e267b5f6c7e Mon Sep 17 00:00:00 2001
From: aaron <aaron@6dbc8c32-bb84-406f-8558-d1cf31a0ab0c>
Date: Thu, 26 Oct 2017 00:47:08 +0000
Subject: [PATCH] git-svn-id: https://spexeah.com:8443/svn/Asuro@258
 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c

---
 src/driver/ATA.pas | 85 +++++++++++++++++++++++++++++++++++++++++-----
 src/kernel.pas     |  8 +++++
 2 files changed, 84 insertions(+), 9 deletions(-)

diff --git a/src/driver/ATA.pas b/src/driver/ATA.pas
index d43aa10a..0b18fb2b 100644
--- a/src/driver/ATA.pas
+++ b/src/driver/ATA.pas
@@ -68,7 +68,7 @@ var
 
 procedure init(_controller : TPCI_device);
 procedure read(address : uint32; data_lba : uint32; data_bytes : uint32);
-procedure write(address : uint32);
+procedure write(address : uint32; data_lba : uint32; data_bytes : uint32);
 procedure callback(data : void);
 
 implementation
@@ -155,7 +155,66 @@ begin
     
 end;
 
-procedure write(address : uint32); begin
+procedure write(address : uint32; data_lba : uint32; data_bytes : uint32);
+var
+    PRD : Physical_Region_Descriptor;
+    empty_table : array[0..100] of Physical_Region_Descriptor;
+    i : uint32;
+    ptr : intptr;
+    sector_count : uint8;
+    cb : ATA_Command_Buffer;
+begin
+    devices[0].device_lba := data_lba;
+    devices[0].reading := true;
+    PRD_Table := empty_table;
+    PRD.MRPB_Address := address;
+
+    //limit
+    if data_bytes > 6400000 then exit;
+
+    if data_bytes < 64001 then begin
+        PRD.EOT := 1;
+        if data_bytes = 64000 then begin
+            PRD.Byte_Count := 0
+        end else begin
+            PRD.Byte_Count := data_bytes;
+        end;
+    end else begin
+        while data_bytes > 64000 do begin
+            PRD.EOT := 0;
+            PRD.MRPB_Address := address;
+            PRD.Byte_Count := 0;
+
+            data_bytes := data_bytes - 64000;
+            address := address + 64000;
+        end;
+
+        PRD.EOT := 1;
+        PRD.MRPB_Address := address;
+        PRD.Byte_Count := data_bytes;
+
+    end;
+
+    ptr := intptr(devices[0].PRDT_Address_Reg);
+    ptr^ := uint32(@PRD_Table);
+
+    ptr := intptr(devices[0].Status_Register);
+    ptr^ := 0;
+
+    outb(ports.drive, $A0);
+    outb(ports.sector_count, 125);
+    outb(ports.lba_low, (data_lba and $000000FF));
+    outb(ports.lba_mid, (data_lba and $0000FF00) SHR 8);
+    outb(ports.lba_hi, (data_lba and $0000FF00) SHR 16);
+    outb(ports.command, $CA);
+    devices[0].currentIndex := 1;
+
+    cb.start_stop_bit := 1;
+    cb.read_write_bit := 1;
+
+    ptr := intptr(devices[0].Command_Register);
+    ptr^ := uint8(cb);
+    
 end;
 
 procedure callback(data : void); //need r/w, is last
@@ -163,36 +222,44 @@ var
     cb : ATA_Command_Buffer;
     ptr : intptr;
     tmp : uint16;
+    mode : uint8;
 begin
     if(PRD_Table[devices[0].currentIndex - 1].EOT = 1) then begin
         //other stuff
         exit;
     end;
 
-    if(devices[0].reading = true) then begin
+    //if(devices[0].reading = true) then begin
         if(PRD_Table[devices[0].currentIndex].EOT = 0) then begin 
             outb(ports.sector_count, 125);
             outb(ports.lba_low, (devices[0].device_lba + (64000 * devices[0].currentIndex)) and $000000FF);
             outb(ports.lba_mid, (((devices[0].device_lba + (64000 * devices[0].currentIndex))) and $0000FF00) SHR 8);
             outb(ports.lba_hi, (((devices[0].device_lba + (64000 * devices[0].currentIndex))) and $0000FF00) SHR 16); 
-            outb(ports.command, $C8);
+            //outb(ports.command, $C8);
         end else begin
            tmp := uint16((PRD_Table[devices[0].currentIndex].Byte_Count and $FFFF) DIV 512); 
             outb(ports.sector_count, uint16(tmp)); // wont work if 64k
             outb(ports.lba_low, (devices[0].device_lba + (64000 * devices[0].currentIndex)) and $000000FF);
             outb(ports.lba_mid, (((devices[0].device_lba + (64000 * devices[0].currentIndex))) and $0000FF00) SHR 8);
             outb(ports.lba_hi, (((devices[0].device_lba + (64000 * devices[0].currentIndex))) and $0000FF00) SHR 16);
-            outb(ports.command, $C8);
+            //outb(ports.command, $C8);
         end;
 
+        if(devices[0].reading = true) then begin
+            outb(ports.command, $C8);
             cb.start_stop_bit := 1;
             cb.read_write_bit := 0;
-
-            ptr := intptr(devices[0].Command_Register);
-            ptr^ := uint8(cb);
+        end else begin            
+            outb(ports.command, $CA);
+            cb.start_stop_bit := 1;
+            cb.read_write_bit := 1;
+        end;
+        ptr := intptr(devices[0].Command_Register);
+        ptr^ := uint8(cb);
+            
 
         devices[0].currentIndex := devices[0].currentIndex + 1;
-    end;
+    //end;
 end;
 
 
diff --git a/src/kernel.pas b/src/kernel.pas
index 18cd1c63..ee5cdaca 100644
--- a/src/kernel.pas
+++ b/src/kernel.pas
@@ -65,6 +65,8 @@ var
    keyboard_layout : array [0..1] of TKeyInfo;
    i               : uint32;
    cEIP            : uint32;
+
+   temp            : uint32;
    
 begin
      multibootinfo:= mbinfo;
@@ -116,6 +118,12 @@ begin
      mouse.init();
      console.writestringln('DRIVERS: INIT END.');
 
+     //temp := 8294;
+     //ata.write(uint32(@temp), 0, 4);
+     //temp := 1234;
+     //ata.read(uint32(@temp), 0, 4);
+     //console.writeintln(temp);
+
      console.writestringln('');
      console.setdefaultattribute(console.combinecolors(Green, Black));
      console.writestringln('Asuro Booted Correctly!');