]> git.sesse.net Git - pistorm/commitdiff
[WIP] PiSCSI custom file system experiments
authorbeeanyew <beeanyew@gmail.com>
Tue, 16 Feb 2021 07:03:46 +0000 (08:03 +0100)
committerbeeanyew <beeanyew@gmail.com>
Tue, 16 Feb 2021 07:03:46 +0000 (08:03 +0100)
Still not quite working, only FFS working for now.

23 files changed:
.gitignore
default.cfg
emulator.c
platforms/amiga/Gayle.c
platforms/amiga/amiga-platform.c
platforms/amiga/hunk-reloc.c
platforms/amiga/hunk-reloc.h
platforms/amiga/piscsi/device_driver_amiga/bootrom
platforms/amiga/piscsi/device_driver_amiga/bootrom.s
platforms/amiga/piscsi/device_driver_amiga/build.sh
platforms/amiga/piscsi/device_driver_amiga/makerom.c
platforms/amiga/piscsi/device_driver_amiga/pi-scsi.device
platforms/amiga/piscsi/device_driver_amiga/piscsi-amiga-2.c
platforms/amiga/piscsi/piscsi-enums.h
platforms/amiga/piscsi/piscsi.c
platforms/amiga/piscsi/piscsi.h
platforms/amiga/piscsi/piscsi.rom
platforms/amiga/piscsi/readme.md
platforms/amiga/rtg/rtg.c
platforms/amiga/rtg/rtg.h
platforms/amiga/rtg/rtg_driver_amiga/pigfx.c
platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card
platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card

index aaf0cccdd4eba0a0ea22277793b55aeea8f8b6c8..8e3ac16796957a585b970c612e38f1959deeac18 100644 (file)
@@ -2,6 +2,10 @@
 *.img
 *.hdf
 *.rom
 *.img
 *.hdf
 *.rom
+*.dll
+*.bin
+*.exe
+*.stackdump
 !/platforms/amiga/piscsi/*.rom
 /m68kmake
 /m68kmake.exe
 !/platforms/amiga/piscsi/*.rom
 /m68kmake
 /m68kmake.exe
index 5160d846606d1efe50966be0f57b9c96930fa392..0cea4a090713cd89613811fcb11a48a0296a3826 100644 (file)
@@ -26,14 +26,14 @@ loopcycles 300
 platform amiga
 # Uncomment to let reads/writes through from/to the RTC memory range
 #setvar enable_rtc_emulation 0
 platform amiga
 # Uncomment to let reads/writes through from/to the RTC memory range
 #setvar enable_rtc_emulation 0
-# Uncomment to set a custom HD image file for ide0 drive 0/1
+# Uncomment to set a HD image file for ide0 drive 0/1
 #setvar hdd0 snakes.img
 #setvar hdd1 snakes2.img
 # Uncomment to enable RTG
 #setvar rtg
 # Uncomment to enable CDTV mode (not working, requires Kickstart 1.3+CDTV extended ROM)
 #setvar cdtv
 #setvar hdd0 snakes.img
 #setvar hdd1 snakes2.img
 # Uncomment to enable RTG
 #setvar rtg
 # Uncomment to enable CDTV mode (not working, requires Kickstart 1.3+CDTV extended ROM)
 #setvar cdtv
-# Uncomment this line to enabled the PiSCSI interface
+# Uncomment this line to enable the PiSCSI interface
 #setvar piscsi
 # Use setvar piscsi0 through piscsi6 to add up to seven mapped drives to the interface.
 #setvar piscsi0 PI0.hdf
 #setvar piscsi
 # Use setvar piscsi0 through piscsi6 to add up to seven mapped drives to the interface.
 #setvar piscsi0 PI0.hdf
index b13bbdc5ff93b8468879326287022af627b46f44..b4ca6b0cf779a2f15ec6a858d2a86b4a3bbd0e43 100644 (file)
@@ -23,6 +23,7 @@
 #include "platforms/amiga/gayle-ide/ide.h"
 #include "platforms/amiga/amiga-registers.h"
 #include "platforms/amiga/rtg/rtg.h"
 #include "platforms/amiga/gayle-ide/ide.h"
 #include "platforms/amiga/amiga-registers.h"
 #include "platforms/amiga/rtg/rtg.h"
+#include "platforms/amiga/hunk-reloc.h"
 #include "platforms/amiga/piscsi/piscsi.h"
 #include "platforms/amiga/piscsi/piscsi-enums.h"
 #include "platforms/amiga/net/pi-net.h"
 #include "platforms/amiga/piscsi/piscsi.h"
 #include "platforms/amiga/piscsi/piscsi-enums.h"
 #include "platforms/amiga/net/pi-net.h"
@@ -46,6 +47,8 @@ char mouse_dx = 0, mouse_dy = 0;
 char mouse_buttons = 0;
 
 extern uint8_t gayle_int;
 char mouse_buttons = 0;
 
 extern uint8_t gayle_int;
+extern uint8_t gayle_ide_enabled;
+extern uint8_t gayle_emulation_enabled;
 extern uint8_t gayle_a4k_int;
 extern volatile unsigned int *gpio;
 extern volatile uint16_t srdata;
 extern uint8_t gayle_a4k_int;
 extern volatile unsigned int *gpio;
 extern volatile uint16_t srdata;
@@ -60,7 +63,6 @@ char disasm_buf[4096];
 
 int mem_fd, mouse_fd = -1, keyboard_fd = -1;
 int mem_fd_gpclk;
 
 int mem_fd, mouse_fd = -1, keyboard_fd = -1;
 int mem_fd_gpclk;
-int gayle_emulation_enabled = 1;
 int irq;
 int gayleirq;
 
 int irq;
 int gayleirq;
 
@@ -81,7 +83,7 @@ void *iplThread(void *args) {
     else
       irq = 0;
 
     else
       irq = 0;
 
-    if (gayle_emulation_enabled) {
+    if (gayle_ide_enabled) {
       if (((gayle_int & 0x80) || gayle_a4k_int) && (get_ide(0)->drive[0].intrq || get_ide(0)->drive[1].intrq)) {
         //get_ide(0)->drive[0].intrq = 0;
         gayleirq = 1;
       if (((gayle_int & 0x80) || gayle_a4k_int) && (get_ide(0)->drive[0].intrq || get_ide(0)->drive[1].intrq)) {
         //get_ide(0)->drive[0].intrq = 0;
         gayleirq = 1;
@@ -111,8 +113,6 @@ void stop_cpu_emulation(uint8_t disasm_cur) {
   do_disasm = 0;
 }
 
   do_disasm = 0;
 }
 
-//unsigned char g_kick[524288];
-//unsigned char g_ram[FASTSIZE + 1]; /* RAM */
 int ovl;
 static volatile unsigned char maprom;
 
 int ovl;
 static volatile unsigned char maprom;
 
@@ -140,10 +140,7 @@ int main(int argc, char *argv[]) {
 
   // Some command line switch stuffles
   for (g = 1; g < argc; g++) {
 
   // Some command line switch stuffles
   for (g = 1; g < argc; g++) {
-    if (strcmp(argv[g], "--disable-gayle") == 0) {
-      gayle_emulation_enabled = 0;
-    }
-    else if (strcmp(argv[g], "--cpu_type") == 0 || strcmp(argv[g], "--cpu") == 0) {
+    if (strcmp(argv[g], "--cpu_type") == 0 || strcmp(argv[g], "--cpu") == 0) {
       if (g + 1 >= argc) {
         printf("%s switch found, but no CPU type specified.\n", argv[g]);
       } else {
       if (g + 1 >= argc) {
         printf("%s switch found, but no CPU type specified.\n", argv[g]);
       } else {
index 520ca9bdfab867a737f3fb3888af314a8c57cd62..cf5729ad7406782c6db8a3ae6a1f1e4562a5fb80 100644 (file)
@@ -25,6 +25,9 @@
 #include "gayle-ide/ide.h"
 #include "amiga-registers.h"
 
 #include "gayle-ide/ide.h"
 #include "amiga-registers.h"
 
+//#define DEBUG(...)
+#define DEBUG printf
+
 uint8_t gary_cfg[8];
 
 uint8_t ramsey_cfg = 0x08;
 uint8_t gary_cfg[8];
 
 uint8_t ramsey_cfg = 0x08;
@@ -32,7 +35,7 @@ static uint8_t ramsey_id = RAMSEY_REV7;
 
 int counter;
 static uint8_t gayle_irq, gayle_cs, gayle_cs_mask, gayle_cfg;
 
 int counter;
 static uint8_t gayle_irq, gayle_cs, gayle_cs_mask, gayle_cfg;
-static struct ide_controller *ide0;
+static struct ide_controller *ide0 = NULL;
 int fd;
 
 uint8_t rtc_type = RTC_TYPE_RICOH;
 int fd;
 
 uint8_t rtc_type = RTC_TYPE_RICOH;
@@ -49,10 +52,12 @@ uint8_t gayle_int = 0;
 
 uint32_t gayle_ide_mask = ~GDATA;
 uint32_t gayle_ide_base = GDATA;
 
 uint32_t gayle_ide_mask = ~GDATA;
 uint32_t gayle_ide_base = GDATA;
+uint8_t gayle_ide_enabled = 1;
+uint8_t gayle_emulation_enabled = 1;
 uint8_t gayle_ide_adj = 0;
 
 struct ide_controller *get_ide(int index) {
 uint8_t gayle_ide_adj = 0;
 
 struct ide_controller *get_ide(int index) {
-  //if (index) {}
+  if (index) {}
   return ide0;
 }
 
   return ide0;
 }
 
@@ -74,16 +79,16 @@ void set_hard_drive_image_file_amiga(uint8_t index, char *filename) {
 }
 
 void InitGayle(void) {
 }
 
 void InitGayle(void) {
-  if (!hdd_image_file[0]) {
-    hdd_image_file[0] = calloc(1, 64);
-    sprintf(hdd_image_file[0], "hd0.img");
-  }
-
-  ide0 = ide_allocate("cf");
+  uint8_t num_ide_drives = 0;
 
   for (int i = 0; i < GAYLE_MAX_HARDFILES; i++) {
     if (hdd_image_file[i]) {
       fd = open(hdd_image_file[i], O_RDWR);
 
   for (int i = 0; i < GAYLE_MAX_HARDFILES; i++) {
     if (hdd_image_file[i]) {
       fd = open(hdd_image_file[i], O_RDWR);
+      if (fd != -1) {
+        if (!ide0)
+            ide0 = ide_allocate("cf");
+      }
+
       if (fd == -1) {
         printf("[HDD%d] HDD Image %s failed open\n", i, hdd_image_file[i]);
       } else {
       if (fd == -1) {
         printf("[HDD%d] HDD Image %s failed open\n", i, hdd_image_file[i]);
       } else {
@@ -91,16 +96,25 @@ void InitGayle(void) {
         if (strcmp(hdd_image_file[i] + (strlen(hdd_image_file[i]) - 3), "img") != 0) {
           printf("No header present on HDD image %s.\n", hdd_image_file[i]);
           ide_attach_hdf(ide0, i, fd);
         if (strcmp(hdd_image_file[i] + (strlen(hdd_image_file[i]) - 3), "img") != 0) {
           printf("No header present on HDD image %s.\n", hdd_image_file[i]);
           ide_attach_hdf(ide0, i, fd);
+          num_ide_drives++;
         }
         else {
           printf("Attaching HDD image with header.\n");
           ide_attach(ide0, i, fd);
         }
         else {
           printf("Attaching HDD image with header.\n");
           ide_attach(ide0, i, fd);
+          num_ide_drives++;
         }
         printf("[HDD%d] HDD Image %s attached\n", i, hdd_image_file[i]);
       }
     }
   }
         }
         printf("[HDD%d] HDD Image %s attached\n", i, hdd_image_file[i]);
       }
     }
   }
-  ide_reset_begin(ide0);
+  if (ide0)
+    ide_reset_begin(ide0);
+  
+  if (num_ide_drives == 0) {
+    // No IDE drives mounted, disable IDE component of Gayle
+    printf("No IDE drives mounted, disabling Gayle IDE component.\n");
+    gayle_ide_enabled = 0;
+  }
 }
 
 uint8_t CheckIrq(void) {
 }
 
 uint8_t CheckIrq(void) {
@@ -118,47 +132,49 @@ uint8_t CheckIrq(void) {
 static uint8_t ide_action = 0;
 
 void writeGayleB(unsigned int address, unsigned int value) {
 static uint8_t ide_action = 0;
 
 void writeGayleB(unsigned int address, unsigned int value) {
-  if (address >= gayle_ide_base) {
-    switch ((address - gayle_ide_base) - gayle_ide_adj) {
-      case GFEAT_OFFSET:
-        //printf("Write to GFEAT: %.2X.\n", value);
-        ide_action = ide_feature_w;
-        goto idewrite8;
-      case GCMD_OFFSET:
-        //printf("Write to GCMD: %.2X.\n", value);
-        ide_action = ide_command_w;
-        goto idewrite8;
-      case GSECTCOUNT_OFFSET:
-        ide_action = ide_sec_count;
-        goto idewrite8;
-      case GSECTNUM_OFFSET:
-        ide_action = ide_sec_num;
-        goto idewrite8;
-      case GCYLLOW_OFFSET:
-        ide_action = ide_cyl_low;
-        goto idewrite8;
-      case GCYLHIGH_OFFSET:
-        ide_action = ide_cyl_hi;
-        goto idewrite8;
-      case GDEVHEAD_OFFSET:
-        //printf("Write to GDEVHEAD: %.2X.\n", value);
-        ide_action = ide_dev_head;
-        goto idewrite8;
-      case GCTRL_OFFSET:
-        //printf("Write to GCTRL: %.2X.\n", value);
-        ide_action = ide_devctrl_w;
-        goto idewrite8;
-      case GIRQ_4000_OFFSET:
-        gayle_a4k_irq = value;
-      case GIRQ_OFFSET:
-        gayle_irq = (gayle_irq & value) | (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR));
-        return;
-    }
-    goto skip_idewrite8;
+  if (ide0) {
+    if (address >= gayle_ide_base) {
+      switch ((address - gayle_ide_base) - gayle_ide_adj) {
+        case GFEAT_OFFSET:
+          //printf("Write to GFEAT: %.2X.\n", value);
+          ide_action = ide_feature_w;
+          goto idewrite8;
+        case GCMD_OFFSET:
+          //printf("Write to GCMD: %.2X.\n", value);
+          ide_action = ide_command_w;
+          goto idewrite8;
+        case GSECTCOUNT_OFFSET:
+          ide_action = ide_sec_count;
+          goto idewrite8;
+        case GSECTNUM_OFFSET:
+          ide_action = ide_sec_num;
+          goto idewrite8;
+        case GCYLLOW_OFFSET:
+          ide_action = ide_cyl_low;
+          goto idewrite8;
+        case GCYLHIGH_OFFSET:
+          ide_action = ide_cyl_hi;
+          goto idewrite8;
+        case GDEVHEAD_OFFSET:
+          //printf("Write to GDEVHEAD: %.2X.\n", value);
+          ide_action = ide_dev_head;
+          goto idewrite8;
+        case GCTRL_OFFSET:
+          //printf("Write to GCTRL: %.2X.\n", value);
+          ide_action = ide_devctrl_w;
+          goto idewrite8;
+        case GIRQ_4000_OFFSET:
+          gayle_a4k_irq = value;
+        case GIRQ_OFFSET:
+          gayle_irq = (gayle_irq & value) | (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR));
+          return;
+      }
+      goto skip_idewrite8;
 idewrite8:;
 idewrite8:;
-    ide_write8(ide0, ide_action, value);
-    return;
+      ide_write8(ide0, ide_action, value);
+      return;
 skip_idewrite8:;
 skip_idewrite8:;
+    }
   }
 
   switch (address) {
   }
 
   switch (address) {
@@ -206,14 +222,16 @@ skip_idewrite8:;
 }
 
 void writeGayle(unsigned int address, unsigned int value) {
 }
 
 void writeGayle(unsigned int address, unsigned int value) {
-  if (address - gayle_ide_base == GDATA_OFFSET) {
-    ide_write16(ide0, ide_data, value);
-    return;
-  }
+  if (ide0) {
+    if (address - gayle_ide_base == GDATA_OFFSET) {
+      ide_write16(ide0, ide_data, value);
+      return;
+    }
 
 
-  if (address == GIRQ_A4000) {
-    gayle_a4k_irq = value;
-    return;
+    if (address == GIRQ_A4000) {
+      gayle_a4k_irq = value;
+      return;
+    }
   }
 
   if ((address & GAYLEMASK) == CLOCKBASE) {
   }
 
   if ((address & GAYLEMASK) == CLOCKBASE) {
@@ -254,100 +272,100 @@ void writeGayleL(unsigned int address, unsigned int value) {
 }
 
 uint8_t readGayleB(unsigned int address) {
 }
 
 uint8_t readGayleB(unsigned int address) {
-  uint8_t ide_action = 0, ide_val = 0;
-
-  if (address >= gayle_ide_base) {
-    switch ((address - gayle_ide_base) - gayle_ide_adj) {
-      case GERROR_OFFSET:
-        ide_action = ide_error_r;
-        goto ideread8;
-      case GSTATUS_OFFSET:
-        ide_action = ide_status_r;
-        goto ideread8;
-      case GSECTCOUNT_OFFSET:
-        ide_action = ide_sec_count;
-        goto ideread8;
-      case GSECTNUM_OFFSET:
-        ide_action = ide_sec_num;
-        goto ideread8;
-      case GCYLLOW_OFFSET:
-        ide_action = ide_cyl_low;
-        goto ideread8;
-      case GCYLHIGH_OFFSET:
-        ide_action = ide_cyl_hi;
-        goto ideread8;
-      case GDEVHEAD_OFFSET:
-        ide_action = ide_dev_head;
-        goto ideread8;
-      case GCTRL_OFFSET:
-        ide_action = ide_altst_r;
-        goto ideread8;
-      case GIRQ_4000_OFFSET:
-      case GIRQ_OFFSET:
-        return 0x80;
-        //gayle_irq = (gayle_irq & value) | (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR));
-    }
-    goto skip_ideread8;
+  if (ide0) {
+    uint8_t ide_action = 0, ide_val = 0;
+
+    if (address >= gayle_ide_base) {
+      switch ((address - gayle_ide_base) - gayle_ide_adj) {
+        case GERROR_OFFSET:
+          ide_action = ide_error_r;
+          goto ideread8;
+        case GSTATUS_OFFSET:
+          ide_action = ide_status_r;
+          goto ideread8;
+        case GSECTCOUNT_OFFSET:
+          ide_action = ide_sec_count;
+          goto ideread8;
+        case GSECTNUM_OFFSET:
+          ide_action = ide_sec_num;
+          goto ideread8;
+        case GCYLLOW_OFFSET:
+          ide_action = ide_cyl_low;
+          goto ideread8;
+        case GCYLHIGH_OFFSET:
+          ide_action = ide_cyl_hi;
+          goto ideread8;
+        case GDEVHEAD_OFFSET:
+          ide_action = ide_dev_head;
+          goto ideread8;
+        case GCTRL_OFFSET:
+          ide_action = ide_altst_r;
+          goto ideread8;
+        case GIRQ_4000_OFFSET:
+        case GIRQ_OFFSET:
+          return 0x80;
+          //gayle_irq = (gayle_irq & value) | (value & (GAYLE_IRQ_RESET | GAYLE_IRQ_BERR));
+      }
+      goto skip_ideread8;
 ideread8:;
 ideread8:;
-    ide_val = ide_read8(ide0, ide_action);
-    //if (((address - gayle_ide_base) - gayle_ide_adj) == GDEVHEAD_OFFSET)
-      //printf("Read from GDEVHEAD: %.2X\n", ide_val);
-    return ide_read8(ide0, ide_action);
+      ide_val = ide_read8(ide0, ide_action);
+      return ide_val;
 skip_ideread8:;
 skip_ideread8:;
-  }
+    }
 
 
-  switch (address) {
-    case GIDENT: {
-      uint8_t val;
-      if (counter == 0 || counter == 1 || counter == 3) {
-        val = 0x80;  // 80; to enable gayle
-      } else {
-        val = 0x00;
+    switch (address) {
+      case GIDENT: {
+        uint8_t val;
+        if (counter == 0 || counter == 1 || counter == 3) {
+          val = 0x80;  // 80; to enable gayle
+        } else {
+          val = 0x00;
+        }
+        counter++;
+        //printf("Read from GIDENT: %.2X.\n", val);
+        return val;
       }
       }
-      counter++;
-      //printf("Read from GIDENT: %.2X.\n", val);
-      return val;
-    }
-    case GINT:
-      return gayle_int;
-    case GCONF:
-      //printf("Read from GCONF: %d\n", gayle_cfg & 0x0F);
-      return gayle_cfg & 0x0f;
-    case GCS: {
-      uint8_t v;
-      v = gayle_cs_mask | gayle_cs;
-      printf("Read from GCS: %d\n", v);
-      return v;
-    }
-    // This seems incorrect, GARY_REG3 is the same as GIDENT, and the A4000
-    // service manual says that Gary is accessible in the address range $DFC000 to $DFFFFF.
-    case GARY_REG0:
-    case GARY_REG1:
-    case GARY_REG2:
-      return gary_cfg[address - GARY_REG0];
-      break;
-    //case GARY_REG3:
-    case GARY_REG4:
-    //case GARY_REG5:
-      return gary_cfg[address - GARY_REG4];
-    case RAMSEY_ID:
-      return ramsey_id;
-    case RAMSEY_REG:
-      return ramsey_cfg;
-    case GARY_REG5: { // This makes no sense.
-      uint8_t val;
-      if (counter == 0 || counter == 1 || counter == 3) {
-        val = 0x80;  // 80; to enable GARY
-      } else {
-        val = 0x00;
+      case GINT:
+        return gayle_int;
+      case GCONF:
+        //printf("Read from GCONF: %d\n", gayle_cfg & 0x0F);
+        return gayle_cfg & 0x0f;
+      case GCS: {
+        uint8_t v;
+        v = gayle_cs_mask | gayle_cs;
+        printf("Read from GCS: %d\n", v);
+        return v;
       }
       }
-      counter++;
-      return val;
+      // This seems incorrect, GARY_REG3 is the same as GIDENT, and the A4000
+      // service manual says that Gary is accessible in the address range $DFC000 to $DFFFFF.
+      case GARY_REG0:
+      case GARY_REG1:
+      case GARY_REG2:
+        return gary_cfg[address - GARY_REG0];
+        break;
+      //case GARY_REG3:
+      case GARY_REG4:
+      //case GARY_REG5:
+        return gary_cfg[address - GARY_REG4];
+      case RAMSEY_ID:
+        return ramsey_id;
+      case RAMSEY_REG:
+        return ramsey_cfg;
+      case GARY_REG5: { // This makes no sense.
+        uint8_t val;
+        if (counter == 0 || counter == 1 || counter == 3) {
+          val = 0x80;  // 80; to enable GARY
+        } else {
+          val = 0x00;
+        }
+        counter++;
+        return val;
+      }
+      //case 0xDD203A:
+        // This can't be correct, as this is the same address as GDEVHEAD on the A4000 Gayle.
+        //printf("Read Byte from Gayle A4k: %.2X\n", gayle_a4k);
+        //return gayle_a4k;
     }
     }
-    //case 0xDD203A:
-      // This can't be correct, as this is the same address as GDEVHEAD on the A4000 Gayle.
-      //printf("Read Byte from Gayle A4k: %.2X\n", gayle_a4k);
-      //return gayle_a4k;
   }
 
   if ((address & GAYLEMASK) == CLOCKBASE) {
   }
 
   if ((address & GAYLEMASK) == CLOCKBASE) {
@@ -367,16 +385,18 @@ skip_ideread8:;
 }
 
 uint16_t readGayle(unsigned int address) {
 }
 
 uint16_t readGayle(unsigned int address) {
-  if (address - gayle_ide_base == GDATA_OFFSET) {
-    uint16_t value;
-    value = ide_read16(ide0, ide_data);
-    // value = (value << 8) | (value >> 8);
-    return value;
-  }
+  if (ide0) {
+    if (address - gayle_ide_base == GDATA_OFFSET) {
+      uint16_t value;
+      value = ide_read16(ide0, ide_data);
+      //       value = (value << 8) | (value >> 8);
+      return value;
+    }
 
 
-  if (address == GIRQ_A4000) {
-    gayle_a4k_irq = 0x8000;
-    return 0x8000;
+    if (address == GIRQ_A4000) {
+      gayle_a4k_irq = 0x8000;
+      return 0x8000;
+    }
   }
 
   if ((address & GAYLEMASK) == CLOCKBASE) {
   }
 
   if ((address & GAYLEMASK) == CLOCKBASE) {
index ed887baf4ff1083e76b2f25ba971f282617896e7..82301791bfd9714dc01bd44d10f1580151474c93 100644 (file)
@@ -6,6 +6,7 @@
 #include "amiga-autoconf.h"
 #include "amiga-registers.h"
 #include "../shared/rtc.h"
 #include "amiga-autoconf.h"
 #include "amiga-registers.h"
 #include "../shared/rtc.h"
+#include "hunk-reloc.h"
 #include "piscsi/piscsi.h"
 #include "piscsi/piscsi-enums.h"
 #include "net/pi-net.h"
 #include "piscsi/piscsi.h"
 #include "piscsi/piscsi-enums.h"
 #include "net/pi-net.h"
@@ -398,6 +399,9 @@ void handle_reset_amiga(struct emulator_config *cfg) {
     ac_z2_current_pic = 0;
     ac_z3_current_pic = 0;
 
     ac_z2_current_pic = 0;
     ac_z3_current_pic = 0;
 
+    if (piscsi_enabled)
+        piscsi_refresh_drives();
+
     adjust_ranges_amiga(cfg);
 }
 
     adjust_ranges_amiga(cfg);
 }
 
index 6421c06d3f67b7f45b26ce0f1da1d5799aab5f2c..4869600f95571b6515a4dae8580fc20afd6db0dc 100644 (file)
@@ -6,13 +6,21 @@
 #include <endian.h>
 #include "hunk-reloc.h"
 
 #include <endian.h>
 #include "hunk-reloc.h"
 
+#ifdef FAKESTORM
+#define lseek64 lseek
+#endif
+
 #define DEBUG(...)
 //#define DEBUG printf
 
 #define DEBUG(...)
 //#define DEBUG printf
 
+#define BE(val) be32toh(val)
+#define BE16(val) be16toh(val)
+
 #define READLW(a, b) fread(&a, 4, 1, b); a = be32toh(a);
 #define READW(a, b) fread(&a, 2, 1, b); a = be16toh(a);
 
 #define READLW(a, b) fread(&a, 4, 1, b); a = be32toh(a);
 #define READW(a, b) fread(&a, 2, 1, b); a = be16toh(a);
 
-uint32_t lw;
+uint32_t lw = 0;
+static uint32_t file_offset = 0, add_size = 0;
 
 char *hunk_id_name(uint32_t index) {
     switch (index) {
 
 char *hunk_id_name(uint32_t index) {
     switch (index) {
@@ -70,7 +78,7 @@ int process_hunk(uint32_t index, struct hunk_info *info, FILE *f, struct hunk_re
         case HUNKTYPE_CODE:
             DEBUG("Hunk %d: CODE.\n", info->current_hunk);
             READLW(discard, f);
         case HUNKTYPE_CODE:
             DEBUG("Hunk %d: CODE.\n", info->current_hunk);
             READLW(discard, f);
-            info->hunk_offsets[info->current_hunk] = ftell(f);
+            info->hunk_offsets[info->current_hunk] = ftell(f) - file_offset;
             DEBUG("Code hunk size: %d (%.8X)\n", discard * 4, discard * 4);
             fseek(f, discard * 4, SEEK_CUR);
             return 0;
             DEBUG("Code hunk size: %d (%.8X)\n", discard * 4, discard * 4);
             fseek(f, discard * 4, SEEK_CUR);
             return 0;
@@ -80,7 +88,7 @@ int process_hunk(uint32_t index, struct hunk_info *info, FILE *f, struct hunk_re
             DEBUG("Processing Reloc32 hunk.\n");
             do {
                 READLW(discard, f);
             DEBUG("Processing Reloc32 hunk.\n");
             do {
                 READLW(discard, f);
-                if (discard) {
+                if (discard && discard != 0xFFFFFFFF) {
                     READLW(cur_hunk, f);
                     DEBUG("Relocating %d offsets pointing to hunk %d.\n", discard, cur_hunk);
                     for(uint32_t i = 0; i < discard; i++) {
                     READLW(cur_hunk, f);
                     DEBUG("Relocating %d offsets pointing to hunk %d.\n", discard, cur_hunk);
                     for(uint32_t i = 0; i < discard; i++) {
@@ -114,13 +122,14 @@ int process_hunk(uint32_t index, struct hunk_info *info, FILE *f, struct hunk_re
         case HUNKTYPE_BSS:
             DEBUG("Hunk %d: BSS.\n", info->current_hunk);
             READLW(discard, f);
         case HUNKTYPE_BSS:
             DEBUG("Hunk %d: BSS.\n", info->current_hunk);
             READLW(discard, f);
-            info->hunk_offsets[info->current_hunk] = ftell(f);
+            info->hunk_offsets[info->current_hunk] = ftell(f) - file_offset;
             DEBUG("Skipping BSS hunk. Size: %d\n", discard * 4);
             DEBUG("Skipping BSS hunk. Size: %d\n", discard * 4);
+            add_size += (discard * 4);
             return 0;
         case HUNKTYPE_DATA:
             DEBUG("Hunk %d: DATA.\n", info->current_hunk);
             READLW(discard, f);
             return 0;
         case HUNKTYPE_DATA:
             DEBUG("Hunk %d: DATA.\n", info->current_hunk);
             READLW(discard, f);
-            info->hunk_offsets[info->current_hunk] = ftell(f);
+            info->hunk_offsets[info->current_hunk] = ftell(f) - file_offset;
             DEBUG("Skipping data hunk. Size: %d.\n", discard * 4);
             fseek(f, discard * 4, SEEK_CUR);
             return 0;
             DEBUG("Skipping data hunk. Size: %d.\n", discard * 4);
             fseek(f, discard * 4, SEEK_CUR);
             return 0;
@@ -148,24 +157,87 @@ void reloc_hunk(struct hunk_reloc *h, uint8_t *buf, struct hunk_info *i) {
     *src_ptr = htobe32(dst);
 }
 
     *src_ptr = htobe32(dst);
 }
 
-void process_hunks(FILE *in, struct hunk_info *h_info, struct hunk_reloc *r) {
+void process_hunks(FILE *in, struct hunk_info *h_info, struct hunk_reloc *r, uint32_t offset) {
     READLW(lw, in);
     DEBUG("Hunk ID: %.8X (%s)\n", lw, hunk_id_name(lw));
 
     READLW(lw, in);
     DEBUG("Hunk ID: %.8X (%s)\n", lw, hunk_id_name(lw));
 
-    while(!feof(in) && process_hunk(lw, h_info, in, r) != -1) {
+    file_offset = offset;
+    add_size = 0;
+
+    while (!feof(in) && process_hunk(lw, h_info, in, r) != -1) {
         READLW(lw, in);
         if (feof(in)) goto end_parse;
         DEBUG("Hunk ID: %.8X (%s)\n", lw, hunk_id_name(lw));
         READLW(lw, in);
         if (feof(in)) goto end_parse;
         DEBUG("Hunk ID: %.8X (%s)\n", lw, hunk_id_name(lw));
-        DEBUG("File pos: %.8lX\n", ftell(in));
+        DEBUG("File pos: %.8lX\n", ftell(in) - file_offset);
     }
     end_parse:;
     DEBUG("Done processing hunks.\n");
 }
 
 void reloc_hunks(struct hunk_reloc *r, uint8_t *buf, struct hunk_info *h_info) {
     }
     end_parse:;
     DEBUG("Done processing hunks.\n");
 }
 
 void reloc_hunks(struct hunk_reloc *r, uint8_t *buf, struct hunk_info *h_info) {
-    for(uint32_t i = 0; i < h_info->reloc_hunks; i++) {
-        reloc_hunk(&r[i], buf, h_info);
+    DEBUG("Relocating %d offsets.\n", h_info->reloc_hunks);
+    for (uint32_t i = 0; i < h_info->reloc_hunks; i++) {
         DEBUG("Relocating offset %d.\n", i);
         DEBUG("Relocating offset %d.\n", i);
+        reloc_hunk(&r[i], buf, h_info);
     }
     DEBUG("Done relocating offsets.\n");
 }
     }
     DEBUG("Done relocating offsets.\n");
 }
+
+struct LoadSegBlock {
+    uint32_t   lsb_ID;
+    uint32_t   lsb_SummedLongs;
+    int32_t    lsb_ChkSum;
+    uint32_t   lsb_HostID;
+    uint32_t   lsb_Next;
+    uint32_t   lsb_LoadData[123]; // Assumes 512 byte blocks
+};
+#define        LOADSEG_IDENTIFIER 0x4C534547
+
+int load_lseg(int fd, uint8_t **buf_p, struct hunk_info *i, struct hunk_reloc *relocs) {
+    if (fd == -1)
+        return -1;
+
+    uint8_t *block = malloc(512);
+    uint32_t next_blk = 0;
+    struct LoadSegBlock *lsb = (struct LoadSegBlock *)block;
+
+    read(fd, block, 512);
+    if (BE(lsb->lsb_ID) != LOADSEG_IDENTIFIER) {
+        DEBUG("[LOAD_LSEG] Attempted to load a non LSEG-block: %.8X", BE(lsb->lsb_ID));
+        goto fail;
+    }
+
+    char *filename = "data/lsegout.bin";
+    FILE *out = fopen(filename, "wb+");
+
+    DEBUG("[LOAD_LSEG] LSEG data:\n");
+    DEBUG("[LOAD_LSEG] Longs: %d HostID: %d\n", BE(lsb->lsb_SummedLongs), BE(lsb->lsb_HostID));
+    DEBUG("[LOAD_LSEG] Next: %d LoadData: %p\n", BE(lsb->lsb_Next), (void *)lsb->lsb_LoadData);
+    next_blk = BE(lsb->lsb_Next);
+    do {
+        next_blk = BE(lsb->lsb_Next);
+        fwrite(lsb->lsb_LoadData, 4, 123, out);
+        lseek64(fd, next_blk * 512, SEEK_SET);
+        read(fd, block, 512);
+    } while (next_blk != 0xFFFFFFFF);
+    
+    uint32_t file_size = ftell(out);
+    fseek(out, 0, SEEK_SET);
+    uint8_t *buf = malloc(file_size + 1024);
+    fread(buf, file_size, 1, out);
+    fseek(out, 0, SEEK_SET);
+    process_hunks(out, i, relocs, 0x0);
+
+    fclose(out);
+    *buf_p = buf;
+    i->byte_size = file_size;
+    i->alloc_size = file_size + add_size;
+
+    return 0;
+
+fail:;
+    if (block)
+        free(block);
+
+    return -1;
+}
index afd6c0275eb725e72bd6e5a7be5c5f6b0859dc7a..c153ac6c69fd47373f030eee1dc9dda68f447dd6 100644 (file)
@@ -8,7 +8,7 @@ struct hunk_info {
     uint16_t current_hunk;
     uint16_t num_libs;
     uint8_t *libnames[256];
     uint16_t current_hunk;
     uint16_t num_libs;
     uint8_t *libnames[256];
-    uint32_t table_size;
+    uint32_t table_size, byte_size, alloc_size;
     uint32_t base_offset;
     uint32_t first_hunk, last_hunk, num_hunks;
     uint32_t reloc_hunks;
     uint32_t base_offset;
     uint32_t first_hunk, last_hunk, num_hunks;
     uint32_t reloc_hunks;
@@ -27,6 +27,8 @@ enum hunk_types {
 };
 
 int process_hunk(uint32_t index, struct hunk_info *info, FILE *f, struct hunk_reloc *r);
 };
 
 int process_hunk(uint32_t index, struct hunk_info *info, FILE *f, struct hunk_reloc *r);
+int load_lseg(int fd, uint8_t **buf_p, struct hunk_info *i, struct hunk_reloc *relocs);
+
 void reloc_hunk(struct hunk_reloc *h, uint8_t *buf, struct hunk_info *i);
 void reloc_hunk(struct hunk_reloc *h, uint8_t *buf, struct hunk_info *i);
-void process_hunks(FILE *in, struct hunk_info *h_info, struct hunk_reloc *r);
+void process_hunks(FILE *in, struct hunk_info *h_info, struct hunk_reloc *r, uint32_t offset);
 void reloc_hunks(struct hunk_reloc *r, uint8_t *buf, struct hunk_info *h_info);
 void reloc_hunks(struct hunk_reloc *r, uint8_t *buf, struct hunk_info *h_info);
index 416c9608bdd17111cc8f0a5426e16441c4e65456..fe3d33a7be850f347fcb8d7203d478fb2d29b1be 100644 (file)
Binary files a/platforms/amiga/piscsi/device_driver_amiga/bootrom and b/platforms/amiga/piscsi/device_driver_amiga/bootrom differ
index f27ac5f70f1d661913988f3942f9be03721d861b..0696d8367819b420d1b076d46df4ab22aa8885cb 100644 (file)
@@ -62,6 +62,8 @@ InitResident    EQU -102
 FindResident    EQU -96
 OpenLibrary     EQU -552
 CloseLibrary    EQU -414
 FindResident    EQU -96
 OpenLibrary     EQU -552
 CloseLibrary    EQU -414
+OpenResource    EQU -$1F2
+AddResource     EQU -$1E6
 
 ; Expansion stuff
 MakeDosNode     EQU -144
 
 ; Expansion stuff
 MakeDosNode     EQU -144
@@ -70,11 +72,28 @@ AddBootNode     EQU -36
 
 ; PiSCSI stuff
 PiSCSIAddr1     EQU $80000010
 
 ; PiSCSI stuff
 PiSCSIAddr1     EQU $80000010
+PiSCSIAddr2     EQU $80000014
+PiSCSIAddr3     EQU $80000018
+PiSCSIAddr4     EQU $8000001C
 PiSCSIDebugMe   EQU $80000020
 PiSCSIDriver    EQU $80000040
 PiSCSINextPart  EQU $80000044
 PiSCSIGetPart   EQU $80000048
 PiSCSIGetPrio   EQU $8000004C
 PiSCSIDebugMe   EQU $80000020
 PiSCSIDriver    EQU $80000040
 PiSCSINextPart  EQU $80000044
 PiSCSIGetPart   EQU $80000048
 PiSCSIGetPrio   EQU $8000004C
+PiSCSIGetFS     EQU $80000060
+PiSCSINextFS    EQU $80000064
+PiSCSICopyFS    EQU $80000068
+PiSCSIFSSize    EQU $8000006C
+PiSCSISetFSH    EQU $80000070
+PiSCSIDbg1      EQU $80001010
+PiSCSIDbg2      EQU $80001014
+PiSCSIDbg3      EQU $80001018
+PiSCSIDbg4      EQU $8000101C
+PiSCSIDbg5      EQU $80001020
+PiSCSIDbg6      EQU $80001024
+PiSCSIDbg7      EQU $80001028
+PiSCSIDbg8      EQU $8000102C
+PiSCSIDbgMsg    EQU $80001000
 
 *******  RomStart  ***************************************************
 **********************************************************************
 
 *******  RomStart  ***************************************************
 **********************************************************************
@@ -238,7 +257,7 @@ Init:       ; After Diag patching, our romtag will point to this
             ;
             align 2
             move.l a6,-(a7)             ; Push A6 to stack
             ;
             align 2
             move.l a6,-(a7)             ; Push A6 to stack
-            ;move.w #$00B8,$dff09a       ; Disable interrupts during init
+            move.w #$00B8,$dff09a       ; Disable interrupts during init
             move.l  #3,PiSCSIDebugMe
 
             move.l  #11,PiSCSIDebugMe
             move.l  #3,PiSCSIDebugMe
 
             move.l  #11,PiSCSIDebugMe
@@ -265,37 +284,138 @@ Init:       ; After Diag patching, our romtag will point to this
             jsr InitResident(a6)        ; Initialize the PiSCSI driver
 
 SkipDriverLoad:
             jsr InitResident(a6)        ; Initialize the PiSCSI driver
 
 SkipDriverLoad:
+            move.l  #9,PiSCSIDebugMe
+            bra.w LoadFileSystems
+
+FSLoadExit:
             lea ExpansionName(pc),a1
             moveq #0,d0
             jsr OpenLibrary(a6)         ; Open expansion.library to make this work, somehow
             move.l d0,a6
 
             lea ExpansionName(pc),a1
             moveq #0,d0
             jsr OpenLibrary(a6)         ; Open expansion.library to make this work, somehow
             move.l d0,a6
 
+            move.l  #7,PiSCSIDebugMe
 PartitionLoop:
 PartitionLoop:
-            move.l  #9,PiSCSIDebugMe
             move.l PiSCSIGetPart,d0     ; Get the available partition in the current slot
             beq.s EndPartitions         ; If the next partition returns 0, there's no additional partitions
             move.l d0,a0
             jsr MakeDosNode(a6)
             move.l PiSCSIGetPart,d0     ; Get the available partition in the current slot
             beq.s EndPartitions         ; If the next partition returns 0, there's no additional partitions
             move.l d0,a0
             jsr MakeDosNode(a6)
-            move.l  #7,PiSCSIDebugMe
+            move.l d0,PiSCSISetFSH
             move.l d0,a0
             move.l PiSCSIGetPrio,d0
             move.l #0,d1
             move.l PiSCSIAddr1,a1
             jsr AddBootNode(a6)
             move.l d0,a0
             move.l PiSCSIGetPrio,d0
             move.l #0,d1
             move.l PiSCSIAddr1,a1
             jsr AddBootNode(a6)
-            move.l  #8,PiSCSIDebugMe
             move.l #1,PiSCSINextPart    ; Switch to the next partition
             bra.w PartitionLoop
 
 
 EndPartitions:
             move.l #1,PiSCSINextPart    ; Switch to the next partition
             bra.w PartitionLoop
 
 
 EndPartitions:
+            move.l  #8,PiSCSIDebugMe
             move.l a6,a1
             move.l a6,a1
+            move.l  #800,PiSCSIDebugMe
             movea.l 4,a6
             movea.l 4,a6
+            move.l  #801,PiSCSIDebugMe
             jsr CloseLibrary(a6)
             jsr CloseLibrary(a6)
-            move.l  #6,PiSCSIDebugMe
+            move.l  #802,PiSCSIDebugMe
 
             move.l  (a7)+,a6            ; Pop A6 from stack
 
             move.l  (a7)+,a6            ; Pop A6 from stack
+            move.l  #803,PiSCSIDebugMe
 
 
-            ;move.w #$80B8,$dff09a       ; Re-enable interrupts
+            move.w #$80B8,$dff09a       ; Re-enable interrupts
+            move.l  #804,PiSCSIDebugMe
             moveq.l #1,d0               ; indicate "success"
             moveq.l #1,d0               ; indicate "success"
+            move.l  #805,PiSCSIDebugMe
             rts
             rts
-            END
+
+            align 4
+FileSysName     dc.b    'FileSystem.resource',0
+FileSysCreator  dc.b    'PiStorm',0
+
+CurFS:          dc.l    $0
+FSResource:     dc.l    $0
+
+            align 2
+LoadFileSystems:
+            movem.l d0-d7/a0-a6,-(sp)       ; Push registers to stack
+            move.l #30,PiSCSIDebugMe
+            lea FileSysName(pc),a1
+            jsr OpenResource(a6)
+            tst.l d0
+            bne FSRExists
+
+            move.l #33,PiSCSIDebugMe        ; FileSystem.resource isn't open, create it
+            lea FSRes(pc),a1
+            move.l a1,-(a7)
+            jsr AddResource(a6)
+            move.l (a7)+,a0
+            move.l a0,d0
+
+FSRExists:  
+            move.l d0,PiSCSIAddr2             ; PiSCSIAddr2 is now FileSystem.resource
+            move.l #31,PiSCSIDebugMe
+            move.l PiSCSIAddr2,a0
+            move.l PiSCSIGetFS,d0
+            cmp.l #0,d0
+            beq.w FSDone
+            move.l d0,d7
+
+FSNext:     
+            move.l #45,PiSCSIDebugMe
+            lea fsr_FileSysEntries(a0),a0
+            move.l a0,d2
+            move.l LH_HEAD(a0),d0
+            beq.w NoEntries
+
+FSLoop:     
+            move.l #34,PiSCSIDebugMe
+            move.l d0,a1
+            move.l #35,PiSCSIDebugMe
+            cmp.l fse_DosType(a1),d7
+            move.l #36,PiSCSIDebugMe
+            beq.w AlreadyLoaded
+            move.l #37,PiSCSIDebugMe
+            move.l LN_SUCC(a1),d0
+            bne.w FSLoop
+            move.l #390,PiSCSIDebugMe
+            bra.w NoEntries
+
+            align 2
+NoEntries:  
+            move.l #39,PiSCSIDebugMe
+            move.l PiSCSIFSSize,d0
+            move.l #40,PiSCSIDebugMe
+            move.l #0,d1
+            move.l #41,PiSCSIDebugMe
+            jsr AllocMem(a6)
+            move.l d0,PiSCSIAddr3
+            move.l #1,PiSCSICopyFS
+
+AlreadyLoaded:
+            move.l #480,PiSCSIDebugMe
+            move.l PiSCSIAddr2,a0
+            move.l #1,PiSCSINextFS
+            move.l PiSCSIGetFS,d0
+            move.l d0,d7
+            cmp.l #0,d0
+            bne.w FSNext
+
+FSDone:     move.l #37,PiSCSIDebugMe
+            move.l #32,PiSCSIDebugMe    ; Couldn't open FileSystem.resource, Kick 1.2/1.3?
+
+            movem.l (sp)+,d0-d7/a0-a6   ; Pop registers from stack
+            bra.w FSLoadExit
+
+FileSysRes
+    dc.l    0
+    dc.l    0
+    dc.b    NT_RESOURCE
+    dc.b    0
+    dc.l    FileSysName
+    dc.l    FileSysCreator
+.Head
+    dc.l    .Tail
+.Tail
+    dc.l    0
+    dc.l    .Head
+    dc.b    NT_RESOURCE
+    dc.b    0
index a09dad83089e7f5d1b64f035a8ff59ab06174b88..349737229ae6754e643d0debb1ab0880e0b99b57 100644 (file)
@@ -2,7 +2,7 @@
 #m68k-amigaos-gcc -m68020 -O2 -o pi-scsi.device -ramiga-dev -noixemul -fbaserel piscsi-amiga.c -ldebug -lamiga
 #m68k-amigaos-gcc -m68020 -O2 -o scsi.device -ramiga-dev -noixemul -fbaserel piscsi-amiga.c -ldebug -lamiga -D_FSCSIDEV
 #m68k-amigaos-gcc -m68020 -O2 -o 2nd.scsi.device -ramiga-dev -noixemul -fbaserel piscsi-amiga.c -ldebug -lamiga -D_FSCSI2ND
 #m68k-amigaos-gcc -m68020 -O2 -o pi-scsi.device -ramiga-dev -noixemul -fbaserel piscsi-amiga.c -ldebug -lamiga
 #m68k-amigaos-gcc -m68020 -O2 -o scsi.device -ramiga-dev -noixemul -fbaserel piscsi-amiga.c -ldebug -lamiga -D_FSCSIDEV
 #m68k-amigaos-gcc -m68020 -O2 -o 2nd.scsi.device -ramiga-dev -noixemul -fbaserel piscsi-amiga.c -ldebug -lamiga -D_FSCSI2ND
-vasmm68k_mot.exe -m68020 -Fhunk -I$VBCC/NDK39/include/include_i bootrom.s -o a.out
+vasmm68k_mot.exe -m68000 -Fhunk -I$VBCC/NDK39/include/include_i bootrom.s -o bootrom
 #m68k-amigaos-as -m68020 bootrom.s &&
 #m68k-amigaos-as -m68020 bootrom.s &&
-m68k-amigaos-objcopy --strip-all ./a.out ./bootrom
-rm ./a.out
+#m68k-amigaos-objcopy --strip-all ./a.out ./bootrom
+#rm ./a.out
index 0a5ccda2839e5e20010f9140eb1a456bd00026c0..e63c777c796de7f088f4e503efac892b5598b69f 100644 (file)
@@ -3,7 +3,7 @@
 #include <string.h>
 #include <stdlib.h>
 
 #include <string.h>
 #include <stdlib.h>
 
-#define BOOTLDR_SIZE 0x400
+#define BOOTLDR_SIZE 0x1000
 #define DIAG_TOTAL_SIZE 0x4000
 
 char *rombuf, *zerobuf, *devicebuf;
 #define DIAG_TOTAL_SIZE 0x4000
 
 char *rombuf, *zerobuf, *devicebuf;
index 2e1e1e5d96a33b67348921519a3e97805651e4af..c57df2bd9171447eeb8746f03382b1a36fd5a8b3 100644 (file)
Binary files a/platforms/amiga/piscsi/device_driver_amiga/pi-scsi.device and b/platforms/amiga/piscsi/device_driver_amiga/pi-scsi.device differ
index 8a76d3fd1de8d6eee6801bca6a0feada71b2324a..fd0a0e2ee98f4c961766763d2597f5f9e5cf6e13 100644 (file)
@@ -47,6 +47,7 @@ struct piscsi_base {
         uint8_t read_only;
         uint8_t motor;
         uint8_t unit_num;
         uint8_t read_only;
         uint8_t motor;
         uint8_t unit_num;
+        uint16_t scsi_num;
         uint16_t h, s;
         uint32_t c;
 
         uint16_t h, s;
         uint32_t c;
 
@@ -115,6 +116,7 @@ static struct Library __attribute__((used)) *init_device(uint8_t *seg_list asm("
         dev_base->units[i].present = r;
         dev_base->units[i].valid = r;
         dev_base->units[i].unit_num = i;
         dev_base->units[i].present = r;
         dev_base->units[i].valid = r;
         dev_base->units[i].unit_num = i;
+        dev_base->units[i].scsi_num = i * 10;
         if (dev_base->units[i].present) {
             READLONG(PISCSI_CMD_CYLS, dev_base->units[i].c);
             READSHORT(PISCSI_CMD_HEADS, dev_base->units[i].h);
         if (dev_base->units[i].present) {
             READLONG(PISCSI_CMD_CYLS, dev_base->units[i].c);
             READSHORT(PISCSI_CMD_HEADS, dev_base->units[i].h);
@@ -320,11 +322,11 @@ uint8_t piscsi_scsi(struct piscsi_unit *u, struct IORequest *io)
     //iostd->io_Actual = sizeof(*scsi);
 
     switch (scsi->scsi_Command[0]) {
     //iostd->io_Actual = sizeof(*scsi);
 
     switch (scsi->scsi_Command[0]) {
-        case 0x00:      // TEST_UNIT_READY
+        case SCSICMD_TEST_UNIT_READY:
             err = 0;
             break;
         
             err = 0;
             break;
         
-        case 0x12:      // INQUIRY
+        case SCSICMD_INQUIRY:
             for (i = 0; i < scsi->scsi_Length; i++) {
                 uint8_t val = 0;
 
             for (i = 0; i < scsi->scsi_Length; i++) {
                 uint8_t val = 0;
 
@@ -357,42 +359,35 @@ uint8_t piscsi_scsi(struct piscsi_unit *u, struct IORequest *io)
             err = 0;
             break;
         
             err = 0;
             break;
         
-        case 0x08: // READ (6)
-        case 0x0a: // WRITE (6)
-        case 0x28: // READ (10)
-        case 0x2A: // WRITE (10)
-            switch (scsi->scsi_Command[0]) {
-                case 0x0A:
-                    write = 1;
-                case 0x08:
-                    block = scsi->scsi_Command[1] & 0x1f;
-                    block = (block << 8) | scsi->scsi_Command[2];
-                    block = (block << 8) | scsi->scsi_Command[3];
-                    blocks = scsi->scsi_Command[4];
-                    break;
-                case 0x2A:
-                    write = 1;
-                case 0x28:
-                    block = scsi->scsi_Command[2];
-                    block = (block << 8) | scsi->scsi_Command[3];
-                    block = (block << 8) | scsi->scsi_Command[4];
-                    block = (block << 8) | scsi->scsi_Command[5];
-
-                    blocks = scsi->scsi_Command[7];
-                    blocks = (blocks << 8) | scsi->scsi_Command[8];
-                    break;
-            }
-
-            WRITESHORT(PISCSI_CMD_DRVNUM, u->unit_num);
+        case SCSICMD_WRITE_6:
+            write = 1;
+        case SCSICMD_READ_6:
+            block = *(uint32_t *)(&scsi->scsi_Command[0]) & 0x001FFFFF;
+            /*block = scsi->scsi_Command[1] & 0x1f;
+            block = (block << 8) | scsi->scsi_Command[2];
+            block = (block << 8) | scsi->scsi_Command[3];*/
+            blocks = scsi->scsi_Command[4];
+            goto scsireadwrite;
+        case SCSICMD_WRITE_10:
+            write = 1;
+        case SCSICMD_READ_10:
+            block = *(uint32_t *)(&scsi->scsi_Command[2]);
+            /*block = scsi->scsi_Command[2];
+            block = (block << 8) | scsi->scsi_Command[3];
+            block = (block << 8) | scsi->scsi_Command[4];
+            block = (block << 8) | scsi->scsi_Command[5];*/
+
+            blocks = *(uint16_t *)(&scsi->scsi_Command[7]);
+            /*blocks = scsi->scsi_Command[7];
+            blocks = (blocks << 8) | scsi->scsi_Command[8];*/
+
+scsireadwrite:;
+            WRITESHORT(PISCSI_CMD_DRVNUM, (u->scsi_num));
             READLONG(PISCSI_CMD_BLOCKS, maxblocks);
             if (block + blocks > maxblocks || blocks == 0) {
                 err = IOERR_BADADDRESS;
                 break;
             }
             READLONG(PISCSI_CMD_BLOCKS, maxblocks);
             if (block + blocks > maxblocks || blocks == 0) {
                 err = IOERR_BADADDRESS;
                 break;
             }
-            /*if (scsi->scsi_Length < (blocks << SD_SECTOR_SHIFT)) {
-                err = IOERR_BADLENGTH;
-                break;
-            }*/
             if (data == NULL) {
                 err = IOERR_BADADDRESS;
                 break;
             if (data == NULL) {
                 err = IOERR_BADADDRESS;
                 break;
@@ -415,20 +410,18 @@ uint8_t piscsi_scsi(struct piscsi_unit *u, struct IORequest *io)
             err = 0;
             break;
         
             err = 0;
             break;
         
-        case 0x25: // READ CAPACITY (10)
+        case SCSICMD_READ_CAPACITY_10:
             if (scsi->scsi_CmdLength < 10) {
                 err = HFERR_BadStatus;
                 break;
             }
 
             if (scsi->scsi_CmdLength < 10) {
                 err = HFERR_BadStatus;
                 break;
             }
 
-            block = *((uint32_t*)&scsi->scsi_Command[2]);
-
             if (scsi->scsi_Length < 8) {
                 err = IOERR_BADLENGTH;
                 break;
             }
             
             if (scsi->scsi_Length < 8) {
                 err = IOERR_BADLENGTH;
                 break;
             }
             
-            WRITESHORT(PISCSI_CMD_DRVNUM, u->unit_num);
+            WRITESHORT(PISCSI_CMD_DRVNUM, (u->scsi_num));
             READLONG(PISCSI_CMD_BLOCKS, blocks);
             ((uint32_t*)data)[0] = blocks - 1;
             ((uint32_t*)data)[1] = PISCSI_BLOCK_SIZE;
             READLONG(PISCSI_CMD_BLOCKS, blocks);
             ((uint32_t*)data)[0] = blocks - 1;
             ((uint32_t*)data)[1] = PISCSI_BLOCK_SIZE;
@@ -437,13 +430,16 @@ uint8_t piscsi_scsi(struct piscsi_unit *u, struct IORequest *io)
             err = 0;
 
             break;
             err = 0;
 
             break;
-        case 0x1a: // MODE SENSE (6)    
+        case SCSICMD_MODE_SENSE_6:
             data[0] = 3 + 8 + 0x16;
             data[1] = 0; // MEDIUM TYPE
             data[2] = 0;
             data[3] = 8;
 
             data[0] = 3 + 8 + 0x16;
             data[1] = 0; // MEDIUM TYPE
             data[2] = 0;
             data[3] = 8;
 
-            WRITESHORT(PISCSI_CMD_DRVNUM, u->unit_num);
+            debugval(PISCSI_DBG_VAL1, ((uint32_t)scsi->scsi_Command));
+            debug(PISCSI_DBG_MSG, DBG_SCSI_DEBUG_MODESENSE_6);
+
+            WRITESHORT(PISCSI_CMD_DRVNUM, (u->scsi_num));
             READLONG(PISCSI_CMD_BLOCKS, maxblocks);
             (blocks = (maxblocks - 1) & 0xFFFFFF);
 
             READLONG(PISCSI_CMD_BLOCKS, maxblocks);
             (blocks = (maxblocks - 1) & 0xFFFFFF);
 
@@ -498,9 +494,9 @@ uint8_t piscsi_scsi(struct piscsi_unit *u, struct IORequest *io)
             }
             break;
         
             }
             break;
         
-        case 0x37: // READ DEFECT DATA (10)
+        case SCSICMD_READ_DEFECT_DATA_10:
             break;
             break;
-        case 0x40: // CHANGE DEFINITION
+        case SCSICMD_CHANGE_DEFINITION:
             break;
 
         default:
             break;
 
         default:
index 235d7f2e9b7fcef93e0af015f86cda19f941af15..5d4efa44908160354930953e4097a0c124189b26 100644 (file)
@@ -37,6 +37,11 @@ enum piscsi_cmds {
     PISCSI_CMD_GETPRIO  = 0x4C,
     PISCSI_CMD_WRITE64  = 0x50,
     PISCSI_CMD_READ64   = 0x52,
     PISCSI_CMD_GETPRIO  = 0x4C,
     PISCSI_CMD_WRITE64  = 0x50,
     PISCSI_CMD_READ64   = 0x52,
+    PISCSI_CMD_CHECKFS  = 0x60,
+    PISCSI_CMD_NEXTFS   = 0x64,
+    PISCSI_CMD_COPYFS   = 0x68,
+    PISCSI_CMD_FSSIZE   = 0x6C,
+    PISCSI_CMD_SETFSH   = 0x70,
     PISCSI_DBG_MSG      = 0x1000,
     PISCSI_DBG_VAL1     = 0x1010,
     PISCSI_DBG_VAL2     = 0x1014,
     PISCSI_DBG_MSG      = 0x1000,
     PISCSI_DBG_VAL1     = 0x1010,
     PISCSI_DBG_VAL2     = 0x1014,
@@ -65,6 +70,155 @@ enum piscsi_dbg_msgs {
     DBG_SCSI_UNKNOWN_COMMAND,
     DBG_SCSIERR,
     DBG_IOCMD_UNHANDLED,
     DBG_SCSI_UNKNOWN_COMMAND,
     DBG_SCSIERR,
     DBG_IOCMD_UNHANDLED,
+    DBG_SCSI_DEBUG_MODESENSE_6,
+    DBG_SCSI_DEBUG_MODESENSE_10,
+};
+
+enum scsi_commands {
+    SCSICMD_TEST_UNIT_READY = 0x00,
+    SCSICMD_REWIND = 0x01,
+    SCSICMD_REQUEST_SENSE = 0x03,
+    SCSICMD_FORMAT = 0x04,
+    SCSICMD_READ_BLOCK_LIMITS = 0x05,
+    SCSICMD_REASSIGN_BLOCKS = 0x07,
+    SCSICMD_INITIALIZE_ELEMENT_STATUS = 0x07,
+    SCSICMD_READ_6 = 0x08,
+    SCSICMD_WRITE_6 = 0x0A,
+    SCSICMD_SEEK_6 = 0x0B,
+    SCSICMD_READ_REVERSE_6 = 0x0F,
+    SCSICMD_WRITE_FILEMARKS_6 = 0x10,
+    SCSICMD_SPACE_6 = 0x11,
+    SCSICMD_INQUIRY = 0x12,
+    SCSICMD_VERIFY_6 = 0x13,
+    SCSICMD_RECOVER_BUFFERED_DATA = 0x14,
+    SCSICMD_MODE_SELECT_6 = 0x15,
+    SCSICMD_RESERVE_6 = 0x16,
+    SCSICMD_RELEASE_6 = 0x17,
+    SCSICMD_COPY = 0x18,
+    SCSICMD_ERASE_6 = 0x19,
+    SCSICMD_MODE_SENSE_6 = 0x1A,
+    SCSICMD_START_STOP_UNIT = 0x1B,
+    SCSICMD_LOAD_UNLOAD = 0x1B,
+    SCSICMD_RECEIVE_DIAGNOSTIC_RESULTS = 0x1C,
+    SCSICMD_SEND_DIAGNOSTIC = 0x1D,
+    SCSICMD_PREVENT_ALLOW_MEDIUM_REMOVAL = 0x1E,
+    SCSICMD_READ_FORMAT_CAPACITIES = 0x23,
+    SCSICMD_READ_CAPACITY_10 = 0x25,
+    SCSICMD_READ_10 = 0x28,
+    SCSICMD_READ_GENERATION = 0x29,
+    SCSICMD_WRITE_10 = 0x2A,
+    SCSICMD_SEEK_10 = 0x2B,
+    SCSICMD_LOCATE_10 = 0x2B,
+    SCSICMD_ERASE_10 = 0x2C,
+    SCSICMD_READ_UPDATED_BLOCK = 0x2D,
+    SCSICMD_WRITE_AND_VERIFY_10 = 0x2E,
+    SCSICMD_VERIFY_10 = 0x2F,
+    SCSICMD_SET_LIMITS_10 = 0x33,
+    SCSICMD_PREFETCH_10 = 0x34,
+    SCSICMD_READ_POSITION = 0x34,
+    SCSICMD_SYNCHRONIZE_CACHE_10 = 0x35,
+    SCSICMD_LOCK_UNLOCK_CACHE_10 = 0x36,
+    SCSICMD_READ_DEFECT_DATA_10 = 0x37,
+    SCSICMD_INITIALIZE_ELEMENT_STATUS_WITH_RANGE = 0x37,
+    SCSICMD_MEDIUM_SCAN = 0x38,
+    SCSICMD_COMPARE = 0x39,
+    SCSICMD_COPY_AND_VERIFY = 0x3A,
+    SCSICMD_WRITE_BUFFER = 0x3B,
+    SCSICMD_READ_BUFFER = 0x3C,
+    SCSICMD_UPDATE_BLOCK = 0x3D,
+    SCSICMD_READ_LONG_10 = 0x3E,
+    SCSICMD_WRITE_LONG_10 = 0x3F,
+    SCSICMD_CHANGE_DEFINITION = 0x40,
+    SCSICMD_WRITE_SAME_10 = 0x41,
+    SCSICMD_UNMAP = 0x42,
+    SCSICMD_READ_TOC_PMA_ATIP = 0x43,
+    SCSICMD_REPORT_DENSITY_SUPPORT = 0x44,
+    SCSICMD_PLAY_AUDIO_10 = 0x45,
+    SCSICMD_GET_CONFIGURATION = 0x46,
+    SCSICMD_PLAY_AUDIO_MSF = 0x47,
+    SCSICMD_SANITIZE = 0x48,
+    SCSICMD_GET_EVENT_STATUS_NOTIFICATION = 0x4A,
+    SCSICMD_PAUSE_RESUME = 0x4B,
+    SCSICMD_LOG_SELECT = 0x4C,
+    SCSICMD_LOG_SENSE = 0x4D,
+    SCSICMD_XDWRITE_10 = 0x50,
+    SCSICMD_XPWRITE_10 = 0x51,
+    SCSICMD_READ_DISC_INFORMATION = 0x51,
+    SCSICMD_XDREAD_10 = 0x52,
+    SCSICMD_XDWRITEREAD_10 = 0x53,
+    SCSICMD_SEND_OPC_INFORMATION = 0x54,
+    SCSICMD_MODE_SELECT_10 = 0x55,
+    SCSICMD_RESERVE_10 = 0x56,
+    SCSICMD_RELEASE_10 = 0x57,
+    SCSICMD_REPAIR_TRACK = 0x58,
+    SCSICMD_MODE_SENSE_10 = 0x5A,
+    SCSICMD_CLOSE_TRACK_SESSION = 0x5B,
+    SCSICMD_READ_BUFFER_CAPACITY = 0x5C,
+    SCSICMD_SEND_CUE_SHEET = 0x5D,
+    SCSICMD_PERSISTENT_RESERVE_IN = 0x5E,
+    SCSICMD_PERSISTENT_RESERVE_OUT = 0x5F,
+    SCSICMD_EXTENDED_CDB = 0x7E,
+    SCSICMD_VARIABLELENGTH_CDB = 0x7F,
+    SCSICMD_XDWRITE_EXTENDED_16 = 0x80,
+    SCSICMD_WRITE_FILEMARKS_16 = 0x80,
+    SCSICMD_READ_REVERSE_16 = 0x81,
+    SCSICMD_3RDPARTY_COPY_OUT_CMDS = 0x83,
+    SCSICMD_3RDPARTY_COPY_IN_CMDS = 0x84,
+    SCSICMD_ATA_PASSTHROUGH_16 = 0x85,
+    SCSICMD_ACCESS_CONTROL_IN = 0x86,
+    SCSICMD_ACCESS_CONTROL_OUT = 0x87,
+    SCSICMD_READ_16 = 0x88,
+    SCSICMD_COMPARE_AND_WRITE = 0x89,
+    SCSICMD_WRITE_16 = 0x8A,
+    SCSICMD_ORWRITE = 0x8B,
+    SCSICMD_READ_ATTRIBUTE = 0x8C,
+    SCSICMD_WRITE_ATTRIBUTE = 0x8D,
+    SCSICMD_WRITE_AND_VERIFY_16 = 0x8E,
+    SCSICMD_VERIFY_16 = 0x8F,
+    SCSICMD_PREFETCH_16 = 0x90,
+    SCSICMD_SYNCHRONIZE_CACHE_16 = 0x91,
+    SCSICMD_SPACE_16 = 0x91,
+    SCSICMD_LOCK_UNLOCK_CACHE_16 = 0x92,
+    SCSICMD_LOCATE_16 = 0x92,
+    SCSICMD_WRITE_SAME_16 = 0x93,
+    SCSICMD_ERASE_16 = 0x93,
+    SCSICMD_SERVICE_ACTION_BIDIRECTIONAL = 0x9D,
+    SCSICMD_SERVICE_ACTION_IN_16 = 0x9E,
+    SCSICMD_SERVICE_ACTION_OUT_16 = 0x9F,
+    SCSICMD_REPORT_LUNS = 0xA0,
+    SCSICMD_ATA_PASSTHROUGH_12 = 0xA1,
+    SCSICMD_SECURITY_PROTOCOL_IN = 0xA2,
+    SCSICMD_MAINTENANCE_IN = 0xA3,
+    SCSICMD_MAINTENANCE_OUT = 0xA4,
+    SCSICMD_REPORT_KEY = 0xA4,
+    SCSICMD_MOVE_MEDIUM = 0xA5,
+    SCSICMD_PLAY_AUDIO_12 = 0xA5,
+    SCSICMD_EXCHANGE_MEDIUM = 0xA6,
+    SCSICMD_MOVE_MEDIUM_ATTACHED = 0xA7,
+    SCSICMD_READ_12 = 0xA8,
+    SCSICMD_SERVICE_ACTION_OUT_12 = 0xA9,
+    SCSICMD_WRITE_12 = 0xAA,
+    SCSICMD_SERVICE_ACTION_IN_12 = 0xAB,
+    SCSICMD_ERASE_12 = 0xAC,
+    SCSICMD_READ_DVD_STRUCTURE = 0xAD,
+    SCSICMD_WRITE_AND_VERIFY_12 = 0xAE,
+    SCSICMD_VERIFY_12 = 0xAF,
+    SCSICMD_SEARCH_DATA_HIGH_12 = 0xB0,
+    SCSICMD_SEARCH_DATA_EQUAL_12 = 0xB1,
+    SCSICMD_SEARCH_DATA_LOW_12 = 0xB2,
+    SCSICMD_SET_LIMITS_12 = 0xB3,
+    SCSICMD_READ_ELEMENT_STATUS_ATTACHED = 0xB4,
+    SCSICMD_SECURITY_PROTOCOL_OUT = 0xB5,
+    SCSICMD_SEND_VOLUME_TAG = 0xB6,
+    SCSICMD_READ_DEFECT_DATA_12 = 0xB7,
+    SCSICMD_READ_ELEMENT_STATUS = 0xB8,
+    SCSICMD_READ_CD_MSF = 0xB9,
+    SCSICMD_REDUNDANCY_GROUP_IN = 0xBA,
+    SCSICMD_REDUNDANCY_GROUP_OUT = 0xBB,
+    SCSICMD_SPARE_IN = 0xBC,
+    SCSICMD_SPARE_OUT = 0xBD,
+    SCSICMD_VOLUME_SET_IN = 0xBE,
+    SCSICMD_VOLUME_SET_OUT = 0xBF,
 };
 
 #define TD_READ64           24
 };
 
 #define TD_READ64           24
index 497b6ede71dc5dd613b2ab99cf629e738328515d..2cec2f6d548669854014391fb174612e69ba100e 100644 (file)
@@ -5,16 +5,20 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <endian.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <endian.h>
+#include "../hunk-reloc.h"
 #include "piscsi.h"
 #include "piscsi-enums.h"
 #include "piscsi.h"
 #include "piscsi-enums.h"
-#include "../hunk-reloc.h"
 #include "../../../config_file/config_file.h"
 #include "../../../gpio/ps_protocol.h"
 
 #define BE(val) be32toh(val)
 #include "../../../config_file/config_file.h"
 #include "../../../gpio/ps_protocol.h"
 
 #define BE(val) be32toh(val)
+#define BE16(val) be16toh(val)
 
 // Comment these lines to restore debug output:
 
 // Comment these lines to restore debug output:
-#define printf(...)
+#define DEBUG(...)
+//#define DEBUG printf
+#define DEBUG_TRIVIAL(...)
+//#define DEBUG_TRIVIAL printf
 #define stop_cpu_emulation(...)
 
 #ifdef FAKESTORM
 #define stop_cpu_emulation(...)
 
 #ifdef FAKESTORM
@@ -25,6 +29,10 @@ extern struct emulator_config *cfg;
 extern void stop_cpu_emulation(uint8_t disasm_cur);
 
 struct piscsi_dev devs[8];
 extern void stop_cpu_emulation(uint8_t disasm_cur);
 
 struct piscsi_dev devs[8];
+struct piscsi_fs filesystems[NUM_FILESYSTEMS];
+
+uint8_t piscsi_num_fs = 0;
+
 uint8_t piscsi_cur_drive = 0;
 uint32_t piscsi_u32[4];
 uint32_t piscsi_dbg[8];
 uint8_t piscsi_cur_drive = 0;
 uint32_t piscsi_u32[4];
 uint32_t piscsi_dbg[8];
@@ -33,7 +41,10 @@ uint8_t *piscsi_rom_ptr;
 
 uint32_t rom_partitions[128];
 uint32_t rom_partition_prio[128];
 
 uint32_t rom_partitions[128];
 uint32_t rom_partition_prio[128];
-uint32_t rom_cur_partition = 0;
+uint32_t rom_partition_dostype[128];
+uint32_t rom_cur_partition = 0, rom_cur_fs = 0;
+
+
 
 extern unsigned char ac_piscsi_rom[];
 
 
 extern unsigned char ac_piscsi_rom[];
 
@@ -58,7 +69,7 @@ void piscsi_init() {
 
     FILE *in = fopen("./platforms/amiga/piscsi/piscsi.rom", "rb");
     if (in == NULL) {
 
     FILE *in = fopen("./platforms/amiga/piscsi/piscsi.rom", "rb");
     if (in == NULL) {
-        printf("[PISCSI] Could not open PISCSI Boot ROM file for reading.\n");
+        printf("[PISCSI] Could not open PISCSI Boot ROM file for reading!\n");
         // Zero out the boot ROM offset from the autoconfig ROM.
         ac_piscsi_rom[20] = 0;
         ac_piscsi_rom[21] = 0;
         // Zero out the boot ROM offset from the autoconfig ROM.
         ac_piscsi_rom[20] = 0;
         ac_piscsi_rom[21] = 0;
@@ -71,12 +82,9 @@ void piscsi_init() {
     fseek(in, 0, SEEK_SET);
     piscsi_rom_ptr = malloc(piscsi_rom_size);
     fread(piscsi_rom_ptr, piscsi_rom_size, 1, in);
     fseek(in, 0, SEEK_SET);
     piscsi_rom_ptr = malloc(piscsi_rom_size);
     fread(piscsi_rom_ptr, piscsi_rom_size, 1, in);
-    fclose(in);
 
 
-    // Parse the hunks in the device driver to find relocation offsets
-    in = fopen("./platforms/amiga/piscsi/device_driver_amiga/pi-scsi.device", "rb");
-    fseek(in, 0x0, SEEK_SET);
-    process_hunks(in, &piscsi_hinfo, piscsi_hreloc);
+    fseek(in, PISCSI_DRIVER_OFFSET, SEEK_SET);
+    process_hunks(in, &piscsi_hinfo, piscsi_hreloc, PISCSI_DRIVER_OFFSET);
 
     fclose(in);
     printf("[PISCSI] Loaded Boot ROM.\n");
 
     fclose(in);
     printf("[PISCSI] Loaded Boot ROM.\n");
@@ -95,22 +103,28 @@ void piscsi_find_partitions(struct piscsi_dev *d) {
     }
 
     if (!d->rdb || d->rdb->rdb_PartitionList == 0) {
     }
 
     if (!d->rdb || d->rdb->rdb_PartitionList == 0) {
-        printf("[PISCSI] No partitions on disk.\n");
+        DEBUG("[PISCSI] No partitions on disk.\n");
         return;
     }
 
     char *block = malloc(512);
 
         return;
     }
 
     char *block = malloc(512);
 
-    lseek(fd, be32toh(d->rdb->rdb_PartitionList) * 512, SEEK_SET);
+    lseek(fd, BE(d->rdb->rdb_PartitionList) * 512, SEEK_SET);
 next_partition:;
     read(fd, block, 512);
 
 next_partition:;
     read(fd, block, 512);
 
+    uint32_t first = be32toh(*((uint32_t *)&block[0]));
+    if (first != PART_IDENTIFIER) {
+        DEBUG("Entry at block %d is not a valid partition. Aborting.\n", BE(d->rdb->rdb_PartitionList));
+        return;
+    }
+
     struct PartitionBlock *pb = (struct PartitionBlock *)block;
     tmp = pb->pb_DriveName[0];
     pb->pb_DriveName[tmp + 1] = 0x00;
     struct PartitionBlock *pb = (struct PartitionBlock *)block;
     tmp = pb->pb_DriveName[0];
     pb->pb_DriveName[tmp + 1] = 0x00;
-    printf("[PISCSI] Partition %d: %s\n", cur_partition, pb->pb_DriveName + 1);
-    printf("Checksum: %.8X HostID: %d\n", BE(pb->pb_ChkSum), BE(pb->pb_HostID));
-    printf("Flags: %d (%.8X) Devflags: %d (%.8X)\n", BE(pb->pb_Flags), BE(pb->pb_Flags), BE(pb->pb_DevFlags), BE(pb->pb_DevFlags));
+    DEBUG("[PISCSI] Partition %d: %s\n", cur_partition, pb->pb_DriveName + 1);
+    DEBUG("Checksum: %.8X HostID: %d\n", BE(pb->pb_ChkSum), BE(pb->pb_HostID));
+    DEBUG("Flags: %d (%.8X) Devflags: %d (%.8X)\n", BE(pb->pb_Flags), BE(pb->pb_Flags), BE(pb->pb_DevFlags), BE(pb->pb_DevFlags));
     d->pb[cur_partition] = pb;
 
     if (d->pb[cur_partition]->pb_Next != 0xFFFFFFFF) {
     d->pb[cur_partition] = pb;
 
     if (d->pb[cur_partition]->pb_Next != 0xFFFFFFFF) {
@@ -118,11 +132,12 @@ next_partition:;
         block = malloc(512);
         lseek64(fd, next * 512, SEEK_SET);
         cur_partition++;
         block = malloc(512);
         lseek64(fd, next * 512, SEEK_SET);
         cur_partition++;
-        printf("[PISCSI] Next partition at block %d.\n", be32toh(pb->pb_Next));
+        DEBUG("[PISCSI] Next partition at block %d.\n", be32toh(pb->pb_Next));
         goto next_partition;
     }
         goto next_partition;
     }
-    printf("[PISCSI] No more partitions on disk.\n");
+    DEBUG("[PISCSI] No more partitions on disk.\n");
     d->num_partitions = cur_partition + 1;
     d->num_partitions = cur_partition + 1;
+    d->fshd_offs = lseek64(fd, 0, SEEK_CUR);
 
     return;
 }
 
     return;
 }
@@ -142,11 +157,14 @@ int piscsi_parse_rdb(struct piscsi_dev *d) {
     goto no_rdb_found;
 rdb_found:;
     struct RigidDiskBlock *rdb = (struct RigidDiskBlock *)block;
     goto no_rdb_found;
 rdb_found:;
     struct RigidDiskBlock *rdb = (struct RigidDiskBlock *)block;
-    printf("[PISCSI] RDB found at block %d.\n", i);
+    DEBUG("[PISCSI] RDB found at block %d.\n", i);
     d->c = be32toh(rdb->rdb_Cylinders);
     d->h = be32toh(rdb->rdb_Heads);
     d->s = be32toh(rdb->rdb_Sectors);
     d->c = be32toh(rdb->rdb_Cylinders);
     d->h = be32toh(rdb->rdb_Heads);
     d->s = be32toh(rdb->rdb_Sectors);
-    printf("[PISCSI] RDB - first partition at block %d.\n", be32toh(rdb->rdb_PartitionList));
+    d->num_partitions = 0;
+    DEBUG("[PISCSI] RDB - first partition at block %d.\n", be32toh(rdb->rdb_PartitionList));
+    if (d->rdb)
+        free(d->rdb);
     d->rdb = rdb;
     sprintf(d->rdb->rdb_DriveInitName, "pi-scsi.device");
     return 0;
     d->rdb = rdb;
     sprintf(d->rdb->rdb_DriveInitName, "pi-scsi.device");
     return 0;
@@ -158,6 +176,96 @@ no_rdb_found:;
     return -1;
 }
 
     return -1;
 }
 
+void piscsi_refresh_drives() {
+    piscsi_num_fs = 0;
+
+    for (int i = 0; i < NUM_FILESYSTEMS; i++) {
+        if (filesystems[i].binary_data) {
+            free(filesystems[i].binary_data);
+            filesystems[i].binary_data = NULL;
+        }
+        if (filesystems[i].fhb) {
+            free(filesystems[i].fhb);
+            filesystems[i].fhb = NULL;
+        }
+        filesystems[i].h_info.current_hunk = 0;
+        filesystems[i].h_info.reloc_hunks = 0;
+        filesystems[i].FS_ID = 0;
+        filesystems[i].handler = 0;
+    }
+
+    rom_cur_fs = 0;
+
+    for (int i = 0; i < NUM_UNITS; i++) {
+        if (devs[i].fd != -1) {
+            piscsi_parse_rdb(&devs[i]);
+            piscsi_find_partitions(&devs[i]);
+            piscsi_find_filesystems(&devs[i]);
+        }
+    }
+}
+
+void piscsi_find_filesystems(struct piscsi_dev *d) {
+    if (!d->num_partitions)
+        return;
+    
+    uint8_t fs_found = 0;
+    
+    uint8_t *fhb_block = malloc(512);
+
+    lseek64(d->fd, d->fshd_offs, SEEK_SET);
+
+    struct FileSysHeaderBlock *fhb = (struct FileSysHeaderBlock *)fhb_block;
+    read(d->fd, fhb_block, 512);
+    
+    while (BE(fhb->fhb_ID) == FS_IDENTIFIER) {
+        char *dosID = (char *)&fhb->fhb_DosType;
+        uint16_t *fsVer = (uint16_t *)&fhb->fhb_Version;
+
+        DEBUG("[FSHD] FSHD Block found.\n");
+        DEBUG("[FSHD] HostID: %d Next: %d Size: %d\n", BE(fhb->fhb_HostID), BE(fhb->fhb_Next), BE(fhb->fhb_SummedLongs));
+        DEBUG("[FSHD] Flags: %.8X DOSType: %c%c%c/%d\n", BE(fhb->fhb_Flags), dosID[0], dosID[1], dosID[2], dosID[3]);
+        DEBUG("[FSHD] Version: %d.%d\n", BE16(fsVer[0]), BE16(fsVer[1]));
+        DEBUG("[FSHD] Patchflags: %d Type: %d\n", BE(fhb->fhb_PatchFlags), BE(fhb->fhb_Type));
+        DEBUG("[FSHD] Task: %d Lock: %d\n", BE(fhb->fhb_Task), BE(fhb->fhb_Lock));
+        DEBUG("[FSHD] Handler: %d StackSize: %d\n", BE(fhb->fhb_Handler), BE(fhb->fhb_StackSize));
+        DEBUG("[FSHD] Prio: %d Startup: %d\n", BE(fhb->fhb_Priority), BE(fhb->fhb_Startup));
+        DEBUG("[FSHD] SegListBlocks: %d GlobalVec: %d\n", BE(fhb->fhb_Priority), BE(fhb->fhb_Startup));
+        DEBUG("[FSHD] FileSysName: %s\n", fhb->fhb_FileSysName + 1);
+
+        for (int i = 0; i < NUM_FILESYSTEMS; i++) {
+            if (filesystems[i].FS_ID == fhb->fhb_DosType) {
+                DEBUG("[FSHD] File system %c%c%c/%d already loaded. Skipping.\n", dosID[0], dosID[1], dosID[2], dosID[3]);
+                if (BE(fhb->fhb_Next) == 0xFFFFFFFF)
+                    goto fs_done;
+                
+                goto skip_fs_load_lseg;
+            }
+        }
+
+        if (load_lseg(d->fd, &filesystems[piscsi_num_fs].binary_data, &filesystems[piscsi_num_fs].h_info, filesystems[piscsi_num_fs].relocs) != -1) {
+            filesystems[piscsi_num_fs].FS_ID = fhb->fhb_DosType;
+            filesystems[piscsi_num_fs].fhb = fhb;
+            printf("[FSHD] Loaded and set up file system %d: %c%c%c/%d\n", piscsi_num_fs + 1, dosID[0], dosID[1], dosID[2], dosID[3]);
+            piscsi_num_fs++;
+        }
+
+skip_fs_load_lseg:;
+        fs_found++;
+        lseek64(d->fd, BE(fhb->fhb_Next) * 512, SEEK_SET);
+        fhb_block = malloc(512);
+        fhb = (struct FileSysHeaderBlock *)fhb_block;
+        read(d->fd, fhb_block, 512);
+    }
+
+    if (!fs_found)
+        DEBUG("[!!!FSHD] No file systems found on hard drive!\n");
+
+fs_done:;
+    if (fhb_block)
+        free(fhb_block);
+}
+
 void piscsi_map_drive(char *filename, uint8_t index) {
     if (index > 7) {
         printf("[PISCSI] Drive index %d out of range.\nUnable to map file %s to drive.\n", index, filename);
 void piscsi_map_drive(char *filename, uint8_t index) {
     if (index > 7) {
         printf("[PISCSI] Drive index %d out of range.\nUnable to map file %s to drive.\n", index, filename);
@@ -179,20 +287,20 @@ void piscsi_map_drive(char *filename, uint8_t index) {
     printf("[PISCSI] Map %d: [%s] - %llu bytes.\n", index, filename, file_size);
 
     if (piscsi_parse_rdb(d) == -1) {
     printf("[PISCSI] Map %d: [%s] - %llu bytes.\n", index, filename, file_size);
 
     if (piscsi_parse_rdb(d) == -1) {
-        printf("[PISCSI] No RDB found on disk, making up some CHS values.\n");
-        d->h = 64;
+        DEBUG("[PISCSI] No RDB found on disk, making up some CHS values.\n");
+        d->h = 16;
         d->s = 63;
         d->c = (file_size / 512) / (d->s * d->h);
     }
     printf("[PISCSI] CHS: %d %d %d\n", d->c, d->h, d->s);
 
     piscsi_find_partitions(d);
         d->s = 63;
         d->c = (file_size / 512) / (d->s * d->h);
     }
     printf("[PISCSI] CHS: %d %d %d\n", d->c, d->h, d->s);
 
     piscsi_find_partitions(d);
-    //stop_cpu_emulation(1);
+    piscsi_find_filesystems(d);
 }
 
 void piscsi_unmap_drive(uint8_t index) {
     if (devs[index].fd != -1) {
 }
 
 void piscsi_unmap_drive(uint8_t index) {
     if (devs[index].fd != -1) {
-        printf("[PISCSI] Unmapped drive %d.\n", index);
+        DEBUG("[PISCSI] Unmapped drive %d.\n", index);
         close (devs[index].fd);
         devs[index].fd = -1;
     }
         close (devs[index].fd);
         devs[index].fd = -1;
     }
@@ -233,66 +341,130 @@ char *io_cmd_name(int index) {
         case NSCMD_TD_FORMAT64: return "NSCMD_TD_FORMAT64";
 
         default:
         case NSCMD_TD_FORMAT64: return "NSCMD_TD_FORMAT64";
 
         default:
-            return "!!!Unhandled IO command";
+            return "[!!!PISCSI] Unhandled IO command";
     }
 }
 
     }
 }
 
+#define GETSCSINAME(a) case a: return ""#a"";
+#define SCSIUNHANDLED(a) return "[!!!PISCSI] Unhandled SCSI command "#a"";
+
 char *scsi_cmd_name(int index) {
     switch(index) {
 char *scsi_cmd_name(int index) {
     switch(index) {
-        case 0x00: return "TEST UNIT READY";
-        case 0x12: return "INQUIRY";
-        case 0x08: return "READ (6)";
-        case 0x0A: return "WRITE (6)";
-        case 0x28: return "READ (10)";
-        case 0x2A: return "WRITE (10)";
-        case 0x25: return "READ CAPACITY";
-        case 0x1A: return "MODE SENSE";
-        case 0x37: return "READ DEFECT DATA";
+        GETSCSINAME(SCSICMD_TEST_UNIT_READY);
+        GETSCSINAME(SCSICMD_INQUIRY);
+        GETSCSINAME(SCSICMD_READ_6);
+        GETSCSINAME(SCSICMD_WRITE_6);
+        GETSCSINAME(SCSICMD_READ_10);
+        GETSCSINAME(SCSICMD_WRITE_10);
+        GETSCSINAME(SCSICMD_READ_CAPACITY_10);
+        GETSCSINAME(SCSICMD_MODE_SENSE_6);
+        GETSCSINAME(SCSICMD_READ_DEFECT_DATA_10);
         default:
         default:
-            return "!!!Unhandled SCSI command";
+            return "[!!!PISCSI] Unhandled SCSI command";
     }
 }
 
 void print_piscsi_debug_message(int index) {
     }
 }
 
 void print_piscsi_debug_message(int index) {
+    int32_t r = 0;
+
     switch (index) {
         case DBG_INIT:
     switch (index) {
         case DBG_INIT:
-            printf("[PISCSI] Initializing devices.\n");
+            DEBUG("[PISCSI] Initializing devices.\n");
             break;
         case DBG_OPENDEV:
             break;
         case DBG_OPENDEV:
-            printf("[PISCSI] Opening device %d (%d). Flags: %d (%.2X)\n", piscsi_dbg[0], piscsi_dbg[1], piscsi_dbg[2], piscsi_dbg[2]);
+            if (piscsi_dbg[0] != 255)
+                DEBUG("[PISCSI] Opening device %d (%d). Flags: %d (%.2X)\n", piscsi_dbg[0], piscsi_dbg[2], piscsi_dbg[1], piscsi_dbg[1]);
             break;
         case DBG_CLEANUP:
             break;
         case DBG_CLEANUP:
-            printf("[PISCSI] Cleaning up.\n");
+            DEBUG("[PISCSI] Cleaning up.\n");
             break;
         case DBG_CHS:
             break;
         case DBG_CHS:
-            printf("[PISCSI] C/H/S: %d / %d / %d\n", piscsi_dbg[0], piscsi_dbg[1], piscsi_dbg[2]);
+            DEBUG("[PISCSI] C/H/S: %d / %d / %d\n", piscsi_dbg[0], piscsi_dbg[1], piscsi_dbg[2]);
             break;
         case DBG_BEGINIO:
             break;
         case DBG_BEGINIO:
-            printf("[PISCSI] BeginIO: io_Command: %d - io_Flags = %d - quick: %d\n", piscsi_dbg[0], piscsi_dbg[1], piscsi_dbg[2]);
+            DEBUG("[PISCSI] BeginIO: io_Command: %d (%s) - io_Flags = %d - quick: %d\n", piscsi_dbg[0], io_cmd_name(piscsi_dbg[0]), piscsi_dbg[1], piscsi_dbg[2]);
             break;
         case DBG_ABORTIO:
             break;
         case DBG_ABORTIO:
-            printf("[PISCSI] AbortIO!\n");
+            DEBUG("[PISCSI] AbortIO!\n");
             break;
         case DBG_SCSICMD:
             break;
         case DBG_SCSICMD:
-            printf("[PISCSI] SCSI Command %d (%s)\n", piscsi_dbg[1], scsi_cmd_name(piscsi_dbg[1]));
-            printf("Len: %d - %.2X %.2X %.2X - Command Length: %d\n", piscsi_dbg[0], piscsi_dbg[1], piscsi_dbg[2], piscsi_dbg[3], piscsi_dbg[4]);
+            DEBUG("[PISCSI] SCSI Command %d (%s)\n", piscsi_dbg[1], scsi_cmd_name(piscsi_dbg[1]));
+            DEBUG("Len: %d - %.2X %.2X %.2X - Command Length: %d\n", piscsi_dbg[0], piscsi_dbg[1], piscsi_dbg[2], piscsi_dbg[3], piscsi_dbg[4]);
             break;
         case DBG_SCSI_UNKNOWN_MODESENSE:
             break;
         case DBG_SCSI_UNKNOWN_MODESENSE:
-            printf("SCSI: Unknown modesense %.4X\n", piscsi_dbg[0]);
+            DEBUG("[!!!PISCSI] SCSI: Unknown modesense %.4X\n", piscsi_dbg[0]);
             break;
         case DBG_SCSI_UNKNOWN_COMMAND:
             break;
         case DBG_SCSI_UNKNOWN_COMMAND:
-            printf("SCSI: Unknown command %.4X\n", piscsi_dbg[0]);
+            DEBUG("[!!!PISCSI] SCSI: Unknown command %.4X\n", piscsi_dbg[0]);
             break;
         case DBG_SCSIERR:
             break;
         case DBG_SCSIERR:
-            printf("SCSI: An error occured: %.4X\n", piscsi_dbg[0]);
+            DEBUG("[!!!PISCSI] SCSI: An error occured: %.4X\n", piscsi_dbg[0]);
             break;
         case DBG_IOCMD:
             break;
         case DBG_IOCMD:
-            printf("[PISCSI] IO Command %d (%s)\n", piscsi_dbg[0], io_cmd_name(piscsi_dbg[0]));
+            DEBUG_TRIVIAL("[PISCSI] IO Command %d (%s)\n", piscsi_dbg[0], io_cmd_name(piscsi_dbg[0]));
             break;
         case DBG_IOCMD_UNHANDLED:
             break;
         case DBG_IOCMD_UNHANDLED:
-            printf("[PISCSI] WARN: IO command %.4X (%s) is unhandled by driver.\n", piscsi_dbg[0], io_cmd_name(piscsi_dbg[0]));
+            DEBUG("[!!!PISCSI] WARN: IO command %.4X (%s) is unhandled by driver.\n", piscsi_dbg[0], io_cmd_name(piscsi_dbg[0]));
+            break;
+        case DBG_SCSI_FORMATDEVICE:
+            DEBUG("[PISCSI] Get SCSI FormatDevice MODE SENSE.\n");
+            break;
+        case DBG_SCSI_RDG:
+            DEBUG("[PISCSI] Get SCSI RDG MODE SENSE.\n");
+            break;
+        case DBG_SCSI_DEBUG_MODESENSE_6:
+            DEBUG_TRIVIAL("[PISCSI] SCSI ModeSense debug. Data: %.8X\n", piscsi_dbg[0]);
+            r = get_mapped_item_by_address(cfg, piscsi_dbg[0]);
+            if (r != -1) {
+                uint32_t addr = piscsi_dbg[0] - cfg->map_offset[r];
+                struct SCSICmd_ModeSense6 *sense = (struct SCSICmd_ModeSense6 *)(&cfg->map_data[r][addr]);
+                DEBUG_TRIVIAL("[SenseData] CMD: %.2X\n", sense->opcode);
+                DEBUG_TRIVIAL("[SenseData] DBD: %d\n", sense->reserved_dbd & 0x04);
+                DEBUG_TRIVIAL("[SenseData] PC: %d\n", (sense->pc_pagecode & 0xC0 >> 6));
+                DEBUG_TRIVIAL("[SenseData] PageCodes: %.2X %.2X\n", (sense->pc_pagecode & 0x3F), sense->subpage_code);
+                DEBUG_TRIVIAL("[SenseData] AllocLen: %d\n", sense->alloc_len);
+                DEBUG_TRIVIAL("[SenseData] Control: %.2X (%d)\n", sense->control, sense->control);
+            }
+            else {
+                DEBUG("[!!!PISCSI] ModeSense data not immediately available.\n");
+            }
+            break;
+        default:
+            DEBUG("[!!!PISCSI] No debug message available for index %d.\n", index);
+            break;
+    }
+}
+
+#define DEBUGME_SIMPLE(i, s) case i: DEBUG(s); break;
+
+void piscsi_debugme(uint32_t index) {
+    switch (index) {
+        DEBUGME_SIMPLE(1, "[PISCSI-DEBUGME] Arrived at DiagEntry.\n");
+        DEBUGME_SIMPLE(3, "[PISCSI-DEBUGME] Init: Interrupt disable.\n");
+        DEBUGME_SIMPLE(4, "[PISCSI-DEBUGME] Init: Copy/reloc driver.\n");
+        DEBUGME_SIMPLE(5, "[PISCSI-DEBUGME] Init: InitResident.\n");
+        DEBUGME_SIMPLE(7, "[PISCSI-DEBUGME] Init: Begin partition loop.\n");
+        DEBUGME_SIMPLE(8, "[PISCSI-DEBUGME] Init: Partition loop done. Cleaning up and returning to Exec.\n");
+        DEBUGME_SIMPLE(9, "[PISCSI-DEBUGME] Init: Load file systems.\n");
+        DEBUGME_SIMPLE(10, "[PISCSI-DEBUGME] Init: AllocMem for resident.\n");
+        DEBUGME_SIMPLE(11, "[PISCSI-DEBUGME] Init: Checking if resident is loaded.\n");
+        DEBUGME_SIMPLE(22, "[PISCSI-DEBUGME] Arrived at BootEntry.\n");
+        DEBUGME_SIMPLE(30, "[PISCSI-DEBUGME] LoadFileSystems: Opening FileSystem.resource.\n");
+        DEBUGME_SIMPLE(33, "[PISCSI-DEBUGME] FileSystem.resource not available, creating.\n");
+        case 31:
+            DEBUG("[PISCSI-DEBUGME] OpenResource result: %d\n", piscsi_u32[0]);
+            break;
+        case 32:
+            DEBUG("AAAAHH!\n");
+            break;
+        default:
+            DEBUG("[!!!PISCSI-DEBUGME] No debugme message for index %d!\n", index);
             break;
     }
             break;
     }
+
+    if (index == 8) {
+        stop_cpu_emulation(1);
+    }
 }
 
 void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
 }
 
 void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
@@ -307,30 +479,30 @@ void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
         case PISCSI_CMD_READ:
             d = &devs[val];
             if (d->fd == -1) {
         case PISCSI_CMD_READ:
             d = &devs[val];
             if (d->fd == -1) {
-                printf ("[PISCSI] BUG: Attempted read from unmapped drive %d.\n", val);
+                DEBUG("[!!!PISCSI] BUG: Attempted read from unmapped drive %d.\n", val);
                 break;
             }
 
             if (cmd == PISCSI_CMD_READ) {
                 break;
             }
 
             if (cmd == PISCSI_CMD_READ) {
-                printf("[PISCSI] %d byte READ from block %d to address %.8X\n", piscsi_u32[1], piscsi_u32[0], piscsi_u32[2]);
+                DEBUG("[PISCSI-%d] %d byte READ from block %d to address %.8X\n", val, piscsi_u32[1], piscsi_u32[0], piscsi_u32[2]);
                 d->lba = piscsi_u32[0];
                 lseek(d->fd, (piscsi_u32[0] * 512), SEEK_SET);
             }
             else {
                 uint64_t src = piscsi_u32[3];
                 src = (src << 32) | piscsi_u32[0];
                 d->lba = piscsi_u32[0];
                 lseek(d->fd, (piscsi_u32[0] * 512), SEEK_SET);
             }
             else {
                 uint64_t src = piscsi_u32[3];
                 src = (src << 32) | piscsi_u32[0];
-                printf("[PISCSI] %d byte READ64 from block %lld to address %.8X\n", piscsi_u32[1], (src / 512), piscsi_u32[2]);
+                DEBUG("[PISCSI-%d] %d byte READ64 from block %lld to address %.8X\n", val, piscsi_u32[1], (src / 512), piscsi_u32[2]);
                 d->lba = (src / 512);
                 lseek64(d->fd, src, SEEK_SET);
             }
 
             r = get_mapped_item_by_address(cfg, piscsi_u32[2]);
             if (r != -1 && cfg->map_type[r] == MAPTYPE_RAM) {
                 d->lba = (src / 512);
                 lseek64(d->fd, src, SEEK_SET);
             }
 
             r = get_mapped_item_by_address(cfg, piscsi_u32[2]);
             if (r != -1 && cfg->map_type[r] == MAPTYPE_RAM) {
-                printf("[PISCSI] \"DMA\" Read goes to mapped range %d.\n", r);
+                DEBUG_TRIVIAL("[PISCSI-%d] \"DMA\" Read goes to mapped range %d.\n", val, r);
                 read(d->fd, cfg->map_data[r] + piscsi_u32[2] - cfg->map_offset[r], piscsi_u32[1]);
             }
             else {
                 read(d->fd, cfg->map_data[r] + piscsi_u32[2] - cfg->map_offset[r], piscsi_u32[1]);
             }
             else {
-                printf("[PISCSI] No mapped range found for read.\n");
+                DEBUG_TRIVIAL("[PISCSI-%d] No mapped range found for read.\n", val);
                 uint8_t c = 0;
                 for (uint32_t i = 0; i < piscsi_u32[1]; i++) {
                     read(d->fd, &c, 1);
                 uint8_t c = 0;
                 for (uint32_t i = 0; i < piscsi_u32[1]; i++) {
                     read(d->fd, &c, 1);
@@ -342,30 +514,30 @@ void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
         case PISCSI_CMD_WRITE:
             d = &devs[val];
             if (d->fd == -1) {
         case PISCSI_CMD_WRITE:
             d = &devs[val];
             if (d->fd == -1) {
-                printf ("[PISCSI] BUG: Attempted write to unmapped drive %d.\n", val);
+                DEBUG ("[PISCSI] BUG: Attempted write to unmapped drive %d.\n", val);
                 break;
             }
 
             if (cmd == PISCSI_CMD_WRITE) {
                 break;
             }
 
             if (cmd == PISCSI_CMD_WRITE) {
-                printf("[PISCSI] %d byte WRITE to block %d from address %.8X\n", piscsi_u32[1], piscsi_u32[0], piscsi_u32[2]);
+                DEBUG("[PISCSI-%d] %d byte WRITE to block %d from address %.8X\n", val, piscsi_u32[1], piscsi_u32[0], piscsi_u32[2]);
                 d->lba = piscsi_u32[0];
                 lseek(d->fd, (piscsi_u32[0] * 512), SEEK_SET);
             }
             else {
                 uint64_t src = piscsi_u32[3];
                 src = (src << 32) | piscsi_u32[0];
                 d->lba = piscsi_u32[0];
                 lseek(d->fd, (piscsi_u32[0] * 512), SEEK_SET);
             }
             else {
                 uint64_t src = piscsi_u32[3];
                 src = (src << 32) | piscsi_u32[0];
-                printf("[PISCSI] %d byte WRITE64 to block %lld from address %.8X\n", piscsi_u32[1], (src / 512), piscsi_u32[2]);
+                DEBUG("[PISCSI-%d] %d byte WRITE64 to block %lld from address %.8X\n", val, piscsi_u32[1], (src / 512), piscsi_u32[2]);
                 d->lba = (src / 512);
                 lseek64(d->fd, src, SEEK_SET);
             }
 
             r = get_mapped_item_by_address(cfg, piscsi_u32[2]);
             if (r != -1) {
                 d->lba = (src / 512);
                 lseek64(d->fd, src, SEEK_SET);
             }
 
             r = get_mapped_item_by_address(cfg, piscsi_u32[2]);
             if (r != -1) {
-                printf("[PISCSI] \"DMA\" Write comes from mapped range %d.\n", r);
+                DEBUG_TRIVIAL("[PISCSI-%d] \"DMA\" Write comes from mapped range %d.\n", val, r);
                 write(d->fd, cfg->map_data[r] + piscsi_u32[2] - cfg->map_offset[r], piscsi_u32[1]);
             }
             else {
                 write(d->fd, cfg->map_data[r] + piscsi_u32[2] - cfg->map_offset[r], piscsi_u32[1]);
             }
             else {
-                printf("[PISCSI] No mapped range found for write.\n");
+                DEBUG_TRIVIAL("[PISCSI-%d] No mapped range found for write.\n", val);
                 uint8_t c = 0;
                 for (uint32_t i = 0; i < piscsi_u32[1]; i++) {
                     c = read8(piscsi_u32[2] + i);
                 uint8_t c = 0;
                 for (uint32_t i = 0; i < piscsi_u32[1]; i++) {
                     c = read8(piscsi_u32[2] + i);
@@ -379,29 +551,32 @@ void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
             break;
         }
         case PISCSI_CMD_DRVNUM:
             break;
         }
         case PISCSI_CMD_DRVNUM:
+            //printf("%d ", val);
             if (val % 10 != 0)
                 piscsi_cur_drive = 255;
             else
                 piscsi_cur_drive = val / 10;
             if (val % 10 != 0)
                 piscsi_cur_drive = 255;
             else
                 piscsi_cur_drive = val / 10;
-            printf("[PISCSI] (%s) Drive number set to %d (%d)\n", op_type_names[type], piscsi_cur_drive, val);
+            if (piscsi_cur_drive > NUM_UNITS)
+                piscsi_cur_drive = 255;
+
+            if (piscsi_cur_drive != 255)
+                DEBUG("[PISCSI] (%s) Drive number set to %d (%d)\n", op_type_names[type], piscsi_cur_drive, val);
             break;
         case PISCSI_CMD_DEBUGME:
             break;
         case PISCSI_CMD_DEBUGME:
-            printf("[PISCSI] DebugMe triggered (%d).\n", val);
-            stop_cpu_emulation(1);
+            piscsi_debugme(val);
             break;
         case PISCSI_CMD_DRIVER: {
             break;
         case PISCSI_CMD_DRIVER: {
-            printf("[PISCSI] Driver copy/patch called, destination address %.8X.\n", val);
+            DEBUG("[PISCSI] Driver copy/patch called, destination address %.8X.\n", val);
             int r = get_mapped_item_by_address(cfg, val);
             if (r != -1) {
                 uint32_t addr = val - cfg->map_offset[r];
                 uint8_t *dst_data = cfg->map_data[r];
                 uint8_t cur_partition = 0;
             int r = get_mapped_item_by_address(cfg, val);
             if (r != -1) {
                 uint32_t addr = val - cfg->map_offset[r];
                 uint8_t *dst_data = cfg->map_data[r];
                 uint8_t cur_partition = 0;
-                memcpy(dst_data + addr, piscsi_rom_ptr + 0x400, 0x3C00);
+                memcpy(dst_data + addr, piscsi_rom_ptr + PISCSI_DRIVER_OFFSET, 0x4000 - PISCSI_DRIVER_OFFSET);
 
                 piscsi_hinfo.base_offset = val;
                 
                 reloc_hunks(piscsi_hreloc, dst_data + addr, &piscsi_hinfo);
 
                 piscsi_hinfo.base_offset = val;
                 
                 reloc_hunks(piscsi_hreloc, dst_data + addr, &piscsi_hinfo);
-                stop_cpu_emulation(1);
 
                 #define PUTNODELONG(val) *(uint32_t *)&dst_data[p_offs] = htobe32(val); p_offs += 4;
                 #define PUTNODELONGBE(val) *(uint32_t *)&dst_data[p_offs] = val; p_offs += 4;
 
                 #define PUTNODELONG(val) *(uint32_t *)&dst_data[p_offs] = htobe32(val); p_offs += 4;
                 #define PUTNODELONGBE(val) *(uint32_t *)&dst_data[p_offs] = val; p_offs += 4;
@@ -409,6 +584,7 @@ void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
                 for (int i = 0; i < 128; i++) {
                     rom_partitions[i] = 0;
                     rom_partition_prio[i] = 0;
                 for (int i = 0; i < 128; i++) {
                     rom_partitions[i] = 0;
                     rom_partition_prio[i] = 0;
+                    rom_partition_dostype[i] = 0;
                 }
                 rom_cur_partition = 0;
 
                 }
                 rom_cur_partition = 0;
 
@@ -416,12 +592,16 @@ void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
                 sprintf((char *)dst_data + data_addr, "pi-scsi.device");
                 uint32_t addr2 = addr + 0x4000;
                 for (int i = 0; i < NUM_UNITS; i++) {
                 sprintf((char *)dst_data + data_addr, "pi-scsi.device");
                 uint32_t addr2 = addr + 0x4000;
                 for (int i = 0; i < NUM_UNITS; i++) {
-                    piscsi_find_partitions(&devs[i]);
+                    if (devs[i].fd != -1)
+                        piscsi_find_partitions(&devs[i]);
+                    else
+                        goto skip_disk;
+
                     if (devs[i].num_partitions) {
                         uint32_t p_offs = addr2;
                     if (devs[i].num_partitions) {
                         uint32_t p_offs = addr2;
-                        printf("[PISCSI] Adding %d partitions for unit %d\n", devs[i].num_partitions, i);
+                        DEBUG("[PISCSI] Adding %d partitions for unit %d\n", devs[i].num_partitions, i);
                         for (uint32_t j = 0; j < devs[i].num_partitions; j++) {
                         for (uint32_t j = 0; j < devs[i].num_partitions; j++) {
-                            printf("Partition %d: %s\n", j, devs[i].pb[j]->pb_DriveName + 1);
+                            DEBUG("Partition %d: %s\n", j, devs[i].pb[j]->pb_DriveName + 1);
                             sprintf((char *)dst_data + p_offs, "%s", devs[i].pb[j]->pb_DriveName + 1);
                             p_offs += 0x20;
                             PUTNODELONG(addr2 + cfg->map_offset[r]);
                             sprintf((char *)dst_data + p_offs, "%s", devs[i].pb[j]->pb_DriveName + 1);
                             p_offs += 0x20;
                             PUTNODELONG(addr2 + cfg->map_offset[r]);
@@ -434,42 +614,86 @@ void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
                             struct pihd_dosnode_data *dat = (struct pihd_dosnode_data *)(&dst_data[addr2+0x20]);
 
                             if (BE(devs[i].pb[j]->pb_Flags) & 0x01) {
                             struct pihd_dosnode_data *dat = (struct pihd_dosnode_data *)(&dst_data[addr2+0x20]);
 
                             if (BE(devs[i].pb[j]->pb_Flags) & 0x01) {
-                                printf("Partition is bootable.\n");
+                                DEBUG("Partition is bootable.\n");
                                 rom_partition_prio[cur_partition] = 0;
                                 dat->priority = 0;
                             }
                             else {
                                 rom_partition_prio[cur_partition] = 0;
                                 dat->priority = 0;
                             }
                             else {
-                                printf("Partition is not bootable.\n");
+                                DEBUG("Partition is not bootable.\n");
                                 rom_partition_prio[cur_partition] = -128;
                                 dat->priority = htobe32(-128);
                             }
 
                                 rom_partition_prio[cur_partition] = -128;
                                 dat->priority = htobe32(-128);
                             }
 
-                            printf("DOSNode Data:\n");
-                            printf("Name: %s Device: %s\n", dst_data + addr2, dst_data + data_addr);
-                            printf("Unit: %d Flags: %d Pad1: %d\n", BE(dat->unit), BE(dat->flags), BE(dat->pad1));
-                            printf("Node len: %d Block len: %d\n", BE(dat->node_len) * 4, BE(dat->block_len) * 4);
-                            printf("H: %d SPB: %d BPS: %d\n", BE(dat->surf), BE(dat->secs_per_block), BE(dat->blocks_per_track));
-                            printf("Reserved: %d Prealloc: %d\n", BE(dat->reserved_blocks), BE(dat->pad2));
-                            printf("Interleaved: %d Buffers: %d Memtype: %d\n", BE(dat->interleave), BE(dat->buffers), BE(dat->mem_type));
-                            printf("Lowcyl: %d Highcyl: %d Prio: %d\n", BE(dat->lowcyl), BE(dat->highcyl), BE(dat->priority));
-                            printf("Maxtransfer: %.8X Mask: %.8X\n", BE(dat->maxtransfer), BE(dat->transfer_mask));
-                            printf("DOSType: %.8X\n", BE(dat->dostype));
+                            DEBUG("DOSNode Data:\n");
+                            DEBUG("Name: %s Device: %s\n", dst_data + addr2, dst_data + data_addr);
+                            DEBUG("Unit: %d Flags: %d Pad1: %d\n", BE(dat->unit), BE(dat->flags), BE(dat->pad1));
+                            DEBUG("Node len: %d Block len: %d\n", BE(dat->node_len) * 4, BE(dat->block_len) * 4);
+                            DEBUG("H: %d SPB: %d BPS: %d\n", BE(dat->surf), BE(dat->secs_per_block), BE(dat->blocks_per_track));
+                            DEBUG("Reserved: %d Prealloc: %d\n", BE(dat->reserved_blocks), BE(dat->pad2));
+                            DEBUG("Interleaved: %d Buffers: %d Memtype: %d\n", BE(dat->interleave), BE(dat->buffers), BE(dat->mem_type));
+                            DEBUG("Lowcyl: %d Highcyl: %d Prio: %d\n", BE(dat->lowcyl), BE(dat->highcyl), BE(dat->priority));
+                            DEBUG("Maxtransfer: %.8X Mask: %.8X\n", BE(dat->maxtransfer), BE(dat->transfer_mask));
+                            DEBUG("DOSType: %.8X\n", BE(dat->dostype));
 
                             rom_partitions[cur_partition] = addr2 + 0x20 + cfg->map_offset[r];
 
                             rom_partitions[cur_partition] = addr2 + 0x20 + cfg->map_offset[r];
+                            rom_partition_dostype[cur_partition] = dat->dostype;
                             cur_partition++;
                             addr2 += 0x100;
                             p_offs = addr2;
                         }
                     }
                             cur_partition++;
                             addr2 += 0x100;
                             p_offs = addr2;
                         }
                     }
+skip_disk:;
                 }
             }
            
             break;
         }
         case PISCSI_CMD_NEXTPART:
                 }
             }
            
             break;
         }
         case PISCSI_CMD_NEXTPART:
-            printf("[PISCSI] Switch partition %d -> %d\n", rom_cur_partition, rom_cur_partition + 1);
+            DEBUG("[PISCSI] Switch partition %d -> %d\n", rom_cur_partition, rom_cur_partition + 1);
             rom_cur_partition++;
             break;
             rom_cur_partition++;
             break;
+        case PISCSI_CMD_NEXTFS:
+            DEBUG("[PISCSI] Switch file file system %d -> %d\n", rom_cur_fs, rom_cur_fs + 1);
+            rom_cur_fs++;
+            break;
+        case PISCSI_CMD_COPYFS:
+            DEBUG("[PISCSI] Copy file system %d to %.8X and reloc.\n", rom_cur_fs, piscsi_u32[2]);
+            r = get_mapped_item_by_address(cfg, piscsi_u32[2]);
+            if (r != -1) {
+                uint32_t addr = piscsi_u32[2] - cfg->map_offset[r];
+                memset(cfg->map_data[r] + addr, 0x00, filesystems[rom_cur_fs].h_info.alloc_size);
+                memcpy(cfg->map_data[r] + addr, filesystems[rom_cur_fs].binary_data, filesystems[rom_cur_fs].h_info.byte_size);
+                filesystems[rom_cur_fs].h_info.base_offset = piscsi_u32[2];
+                reloc_hunks(filesystems[rom_cur_fs].relocs, cfg->map_data[r] + addr, &filesystems[rom_cur_fs].h_info);
+                filesystems[rom_cur_fs].handler = piscsi_u32[2];
+            }
+            break;
+        case PISCSI_CMD_SETFSH: {
+            int i = 0;
+            DEBUG("[PISCSI] Set handler for partition %d (DeviceNode: %.8X)\n", rom_cur_partition, val);
+            r = get_mapped_item_by_address(cfg, val);
+            if (r != -1) {
+                uint32_t addr = val - cfg->map_offset[r];
+                struct DeviceNode *node = (struct DeviceNode *)(cfg->map_data[r] + addr);
+                char *dosID = (char *)&rom_partition_dostype[rom_cur_partition];
+                DEBUG("[PISCSI] Partition DOSType is %c%c%c/%d\n", dosID[0], dosID[1], dosID[2], dosID[3]);
+                for (i = 0; i < piscsi_num_fs; i++) {
+                    if (rom_partition_dostype[rom_cur_partition] == filesystems[i].FS_ID) {
+                        node->dn_SegList = htobe32(filesystems[i].handler);
+                        goto fs_found;
+                    }
+                }
+                DEBUG("[!!!PISCSI] Found no handler for file system!\n");
+fs_found:;
+                DEBUG("[FS-HANDLER] Next: %d Type: %d\n", BE(node->dn_Next), BE(node->dn_Type));
+                DEBUG("[FS-HANDLER] Task: %d Lock: %d\n", BE(node->dn_Task), BE(node->dn_Lock));
+                DEBUG("[FS-HANDLER] Handler: %d Stacksize: %d\n", BE((uint32_t)node->dn_Handler), BE(node->dn_StackSize));
+                DEBUG("[FS-HANDLER] Priority: %d Startup: %d\n", BE((uint32_t)node->dn_Priority), BE(node->dn_Startup));
+                DEBUG("[FS-HANDLER] SegList: %d GlobalVec: %d\n", BE((uint32_t)node->dn_SegList), BE(node->dn_GlobalVec));
+                DEBUG("[PISCSI] Handler for partition %.8X set to %.8X (%.8X).\n", BE((uint32_t)node->dn_Name), filesystems[i].FS_ID, filesystems[i].handler);
+            }
+            break;
+        }
         case PISCSI_DBG_VAL1: case PISCSI_DBG_VAL2: case PISCSI_DBG_VAL3: case PISCSI_DBG_VAL4:
         case PISCSI_DBG_VAL5: case PISCSI_DBG_VAL6: case PISCSI_DBG_VAL7: case PISCSI_DBG_VAL8: {
             int i = ((addr & 0xFFFF) - PISCSI_DBG_VAL1) / 4;
         case PISCSI_DBG_VAL1: case PISCSI_DBG_VAL2: case PISCSI_DBG_VAL3: case PISCSI_DBG_VAL4:
         case PISCSI_DBG_VAL5: case PISCSI_DBG_VAL6: case PISCSI_DBG_VAL7: case PISCSI_DBG_VAL8: {
             int i = ((addr & 0xFFFF) - PISCSI_DBG_VAL1) / 4;
@@ -480,7 +704,7 @@ void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
             print_piscsi_debug_message(val);
             break;
         default:
             print_piscsi_debug_message(val);
             break;
         default:
-            printf("[PISCSI] WARN: Unhandled %s register write to %.8X: %d\n", op_type_names[type], addr, val);
+            DEBUG("[!!!PISCSI] WARN: Unhandled %s register write to %.8X: %d\n", op_type_names[type], addr, val);
             break;
     }
 }
             break;
     }
 }
@@ -493,20 +717,20 @@ uint32_t handle_piscsi_read(uint32_t addr, uint8_t type) {
     if ((addr & 0xFFFF) >= PISCSI_CMD_ROM) {
         uint32_t romoffs = (addr & 0xFFFF) - PISCSI_CMD_ROM;
         if (romoffs < (piscsi_rom_size + PIB)) {
     if ((addr & 0xFFFF) >= PISCSI_CMD_ROM) {
         uint32_t romoffs = (addr & 0xFFFF) - PISCSI_CMD_ROM;
         if (romoffs < (piscsi_rom_size + PIB)) {
-            //printf("[PISCSI] %s read from Boot ROM @$%.4X (%.8X): ", op_type_names[type], romoffs, addr);
+            //DEBUG("[PISCSI] %s read from Boot ROM @$%.4X (%.8X): ", op_type_names[type], romoffs, addr);
             uint32_t v = 0;
             switch (type) {
                 case OP_TYPE_BYTE:
                     v = piscsi_rom_ptr[romoffs - PIB];
             uint32_t v = 0;
             switch (type) {
                 case OP_TYPE_BYTE:
                     v = piscsi_rom_ptr[romoffs - PIB];
-                    //printf("%.2X\n", v);
+                    //DEBUG("%.2X\n", v);
                     break;
                 case OP_TYPE_WORD:
                     v = be16toh(*((uint16_t *)&piscsi_rom_ptr[romoffs - PIB]));
                     break;
                 case OP_TYPE_WORD:
                     v = be16toh(*((uint16_t *)&piscsi_rom_ptr[romoffs - PIB]));
-                    //printf("%.4X\n", v);
+                    //DEBUG("%.4X\n", v);
                     break;
                 case OP_TYPE_LONGWORD:
                     v = be32toh(*((uint32_t *)&piscsi_rom_ptr[romoffs - PIB]));
                     break;
                 case OP_TYPE_LONGWORD:
                     v = be32toh(*((uint32_t *)&piscsi_rom_ptr[romoffs - PIB]));
-                    //printf("%.8X\n", v);
+                    //DEBUG("%.8X\n", v);
                     break;
             }
             return v;
                     break;
             }
             return v;
@@ -522,45 +746,51 @@ uint32_t handle_piscsi_read(uint32_t addr, uint8_t type) {
         }
         case PISCSI_CMD_DRVTYPE:
             if (devs[piscsi_cur_drive].fd == -1) {
         }
         case PISCSI_CMD_DRVTYPE:
             if (devs[piscsi_cur_drive].fd == -1) {
-                printf("[PISCSI] %s Read from DRVTYPE %d, drive not attached.\n", op_type_names[type], piscsi_cur_drive);
+                DEBUG("[PISCSI] %s Read from DRVTYPE %d, drive not attached.\n", op_type_names[type], piscsi_cur_drive);
                 return 0;
             }
                 return 0;
             }
-            printf("[PISCSI] %s Read from DRVTYPE %d, drive attached.\n", op_type_names[type], piscsi_cur_drive);
+            DEBUG("[PISCSI] %s Read from DRVTYPE %d, drive attached.\n", op_type_names[type], piscsi_cur_drive);
             return 1;
             break;
         case PISCSI_CMD_DRVNUM:
             return piscsi_cur_drive;
             break;
         case PISCSI_CMD_CYLS:
             return 1;
             break;
         case PISCSI_CMD_DRVNUM:
             return piscsi_cur_drive;
             break;
         case PISCSI_CMD_CYLS:
-            printf("[PISCSI] %s Read from CYLS %d: %d\n", op_type_names[type], piscsi_cur_drive, devs[piscsi_cur_drive].c);
+            DEBUG("[PISCSI] %s Read from CYLS %d: %d\n", op_type_names[type], piscsi_cur_drive, devs[piscsi_cur_drive].c);
             return devs[piscsi_cur_drive].c;
             break;
         case PISCSI_CMD_HEADS:
             return devs[piscsi_cur_drive].c;
             break;
         case PISCSI_CMD_HEADS:
-            printf("[PISCSI] %s Read from HEADS %d: %d\n", op_type_names[type], piscsi_cur_drive, devs[piscsi_cur_drive].h);
+            DEBUG("[PISCSI] %s Read from HEADS %d: %d\n", op_type_names[type], piscsi_cur_drive, devs[piscsi_cur_drive].h);
             return devs[piscsi_cur_drive].h;
             break;
         case PISCSI_CMD_SECS:
             return devs[piscsi_cur_drive].h;
             break;
         case PISCSI_CMD_SECS:
-            printf("[PISCSI] %s Read from SECS %d: %d\n", op_type_names[type], piscsi_cur_drive, devs[piscsi_cur_drive].s);
+            DEBUG("[PISCSI] %s Read from SECS %d: %d\n", op_type_names[type], piscsi_cur_drive, devs[piscsi_cur_drive].s);
             return devs[piscsi_cur_drive].s;
             break;
         case PISCSI_CMD_BLOCKS: {
             uint32_t blox = devs[piscsi_cur_drive].fs / 512;
             return devs[piscsi_cur_drive].s;
             break;
         case PISCSI_CMD_BLOCKS: {
             uint32_t blox = devs[piscsi_cur_drive].fs / 512;
-            printf("[PISCSI] %s Read from BLOCKS %d: %d\n", op_type_names[type], piscsi_cur_drive, (uint32_t)(devs[piscsi_cur_drive].fs / 512));
-            printf("fs: %lld (%d)\n", devs[piscsi_cur_drive].fs, blox);
+            DEBUG("[PISCSI] %s Read from BLOCKS %d: %d\n", op_type_names[type], piscsi_cur_drive, (uint32_t)(devs[piscsi_cur_drive].fs / 512));
+            DEBUG("fs: %lld (%d)\n", devs[piscsi_cur_drive].fs, blox);
             return blox;
             break;
         }
         case PISCSI_CMD_GETPART: {
             return blox;
             break;
         }
         case PISCSI_CMD_GETPART: {
-            printf("[PISCSI] Get ROM partition %d offset: %.8X\n", rom_cur_partition, rom_partitions[rom_cur_partition]);
+            DEBUG("[PISCSI] Get ROM partition %d offset: %.8X\n", rom_cur_partition, rom_partitions[rom_cur_partition]);
             return rom_partitions[rom_cur_partition];
             break;
         }
         case PISCSI_CMD_GETPRIO:
             return rom_partitions[rom_cur_partition];
             break;
         }
         case PISCSI_CMD_GETPRIO:
-            printf("[PISCSI] Get partition %d boot priority: %d\n", rom_cur_partition, rom_partition_prio[rom_cur_partition]);
+            DEBUG("[PISCSI] Get partition %d boot priority: %d\n", rom_cur_partition, rom_partition_prio[rom_cur_partition]);
             return rom_partition_prio[rom_cur_partition];
             break;
             return rom_partition_prio[rom_cur_partition];
             break;
+        case PISCSI_CMD_CHECKFS:
+            DEBUG("[PISCSI] Get current loaded file system: %.8X\n", filesystems[rom_cur_fs].FS_ID);
+            return filesystems[rom_cur_fs].FS_ID;
+        case PISCSI_CMD_FSSIZE:
+            DEBUG("[PISCSI] Get alloc size of loaded file system: %d\n", filesystems[rom_cur_fs].h_info.alloc_size);
+            return filesystems[rom_cur_fs].h_info.alloc_size;
         default:
         default:
-            printf("[PISCSI] Unhandled %s register read from %.8X\n", op_type_names[type], addr);
+            DEBUG("[!!!PISCSI] WARN: Unhandled %s register read from %.8X\n", op_type_names[type], addr);
             break;
     }
 
             break;
     }
 
index 6fdf805c2aca52b2422129afbd86a6c5efc089bb..d3271255b8dc80fb74078ac8cc92f673f866b7d3 100644 (file)
 #define NSCMD_TD_FORMAT64 0xC003
 
 #define RDB_BLOCK_LIMIT 16
 #define NSCMD_TD_FORMAT64 0xC003
 
 #define RDB_BLOCK_LIMIT 16
-#define RDB_IDENTIFIER 0x5244534B
-
-void piscsi_init();
-void piscsi_map_drive(char *filename, uint8_t index);
 
 
-void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type);
-uint32_t handle_piscsi_read(uint32_t addr, uint8_t type);
+// RDSK
+#define RDB_IDENTIFIER 0x5244534B
+// PART
+#define PART_IDENTIFIER 0x50415254
+// FSHD
+#define        FS_IDENTIFIER 0x46534844
 
 
-void piscsi_block_op(uint8_t type, uint8_t num, uint32_t dest, uint32_t len);
+#define PISCSI_DRIVER_OFFSET 0x1000
+#define NUM_FILESYSTEMS 32
 
 struct piscsi_dev {
     uint32_t c;
 
 struct piscsi_dev {
     uint32_t c;
@@ -64,11 +65,21 @@ struct piscsi_dev {
     int32_t fd;
     uint32_t lba;
     uint32_t num_partitions;
     int32_t fd;
     uint32_t lba;
     uint32_t num_partitions;
+    uint32_t fshd_offs;
     // Will parse max eight partitions per disk
     struct PartitionBlock *pb[16];
     struct RigidDiskBlock *rdb;
 };
 
     // Will parse max eight partitions per disk
     struct PartitionBlock *pb[16];
     struct RigidDiskBlock *rdb;
 };
 
+struct piscsi_fs {
+   struct FileSysHeaderBlock * fhb;
+   uint32_t FS_ID;
+   uint32_t handler;
+   struct hunk_reloc relocs[512];
+   struct hunk_info h_info;
+   uint8_t *binary_data;
+};
+
 //  .long 0 /* dos disk name */
 //  .long 0 /* device file name */
 //  .long 0 /* unit */
 //  .long 0 /* dos disk name */
 //  .long 0 /* device file name */
 //  .long 0 /* unit */
@@ -166,6 +177,20 @@ struct RigidDiskBlock {
     char    rdb_DriveInitName[40];
 };
 
     char    rdb_DriveInitName[40];
 };
 
+struct DeviceNode {
+    uint32_t    dn_Next;
+    uint32_t    dn_Type;
+    uint32_t    dn_Task;
+    uint32_t    dn_Lock;
+    uint8_t        *dn_Handler;
+    uint32_t    dn_StackSize;
+    int32_t     dn_Priority;
+    uint32_t    dn_Startup;
+    uint32_t    dn_SegList;
+    uint32_t    dn_GlobalVec;
+    uint8_t     *dn_Name;
+};
+
 struct PartitionBlock {
     uint32_t   pb_ID;
     uint32_t   pb_SummedLongs;
 struct PartitionBlock {
     uint32_t   pb_ID;
     uint32_t   pb_SummedLongs;
@@ -180,3 +205,45 @@ struct PartitionBlock {
     uint32_t   pb_Environment[20];
     uint32_t   pb_EReserved[12];
 };
     uint32_t   pb_Environment[20];
     uint32_t   pb_EReserved[12];
 };
+
+struct SCSICmd_ModeSense6 {
+    uint8_t opcode;
+    uint8_t reserved_dbd;
+    uint8_t pc_pagecode;
+    uint8_t subpage_code;
+    uint8_t alloc_len;
+    uint8_t control;
+};
+
+struct FileSysHeaderBlock {
+    uint32_t   fhb_ID;
+    uint32_t   fhb_SummedLongs;
+    int32_t    fhb_ChkSum;
+    uint32_t   fhb_HostID;
+    uint32_t   fhb_Next;
+    uint32_t   fhb_Flags;
+    uint32_t   fhb_Reserved1[2];
+    uint32_t   fhb_DosType;
+    uint32_t   fhb_Version;
+    uint32_t   fhb_PatchFlags;
+    uint32_t   fhb_Type;
+    uint32_t   fhb_Task;
+    uint32_t   fhb_Lock;
+    uint32_t   fhb_Handler;
+    uint32_t   fhb_StackSize;
+    int32_t    fhb_Priority;
+    int32_t    fhb_Startup;
+    int32_t    fhb_SegListBlocks;
+    int32_t    fhb_GlobalVec;
+    uint32_t   fhb_Reserved2[23];
+    uint8_t    fhb_FileSysName[84];
+};
+
+void piscsi_init();
+void piscsi_map_drive(char *filename, uint8_t index);
+
+void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type);
+uint32_t handle_piscsi_read(uint32_t addr, uint8_t type);
+
+void piscsi_find_filesystems(struct piscsi_dev *d);
+void piscsi_refresh_drives();
index 408390940ec208983d18d2e2d69bd8201b2204bd..67af5f82e18b5fca07dbd56b536f7dcfcea5c6ca 100644 (file)
Binary files a/platforms/amiga/piscsi/piscsi.rom and b/platforms/amiga/piscsi/piscsi.rom differ
index 722b4f012f684d2a5acfd0805d6d3c1db34c5f8c..9e57c34e1642c0f2c8d3dff4d31825a098f3d3b5 100644 (file)
@@ -1,15 +1,23 @@
 # PiSCSI Interface/Device driver for Amiga
 
 # PiSCSI Interface/Device driver for Amiga
 
-Intended to be used as a high performance replacement for scsi.device, can currently be used for mounting raw RDB disk images (RDSK) for use in Workbench.
+A high performance replacement for scsi.device, allowing automatic booting and mounting of raw hard disk (RDB/RDSK) images.
 
 This driver and interface is work in progress, do not use it in conjunction with any critical data that you need to survive.
 
 
 This driver and interface is work in progress, do not use it in conjunction with any critical data that you need to survive.
 
+# Instructions
+
+To use the PiSCSI interface, simply enable it by uncommenting the `setvar piscsi` line in default.cfg, or add it to the config file you're currently using.
+
+Add disk images to the PiSCSI interface by uncommenting the `piscsi0` and `piscsi1` lines and editing them to point at the disk image(s) you want to use. 
+
+Physical drives can also be mounted using their mount point files on Linux, such as `/dev/sda` for a USB stick, but keep in mind that this is dangerous as it can destroy the contents of the disk.
+
+You can mount up to 7 disk images using setvar `piscsi0` through `piscsi6`.
+
 # Making changes to the driver
 
 If you make changes to the driver, you can always test these on the Amiga as a regular file in `DEVS:`, but the Z2 device has to be disabled for this to work properly.
 
 # Making changes to the driver
 
 If you make changes to the driver, you can always test these on the Amiga as a regular file in `DEVS:`, but the Z2 device has to be disabled for this to work properly.
 
-If you use the boot ROM, the separate `pi-scsi.device` driver file currently has to match the one in `piscsi.rom`. This is due to an oversight, and will probably be addressed at some point...
-
 Steps to create an updated boot ROM, all of these are done in the `device_driver_amiga` directory:
 
 * (Optional) If you've made changes to bootrom.s, first run `./build.sh`.
 Steps to create an updated boot ROM, all of these are done in the `device_driver_amiga` directory:
 
 * (Optional) If you've made changes to bootrom.s, first run `./build.sh`.
@@ -18,17 +26,8 @@ Steps to create an updated boot ROM, all of these are done in the `device_driver
 * (Optional) If you haven't previously compiled the `makerom` binary, or the code for it has been updated since last time, simply run `gcc makerom.c -o makerom`
 * Run `./makerom` to assemble the boot ROM file, it's automatically in the correct place for the emulator to find it.
 
 * (Optional) If you haven't previously compiled the `makerom` binary, or the code for it has been updated since last time, simply run `gcc makerom.c -o makerom`
 * Run `./makerom` to assemble the boot ROM file, it's automatically in the correct place for the emulator to find it.
 
-# Instructions
-
-In a perfect world, the PiSCSI boot ROM would automatically detect drives/partitions and add them as boot nodes to be available during early startup, but this is not yet possible.
-
-To enable the PiSCSI interface, uncomment the `setvar piscsi` line in default.cfg, or add it to the config file you're currently using.
-
-Add disk images to the PiSCSI interface by uncommenting the `piscsi0` and `piscsi1` lines and editing them to point at the disk image(s) you want to use. `piscsi0` through `piscsi6` are available for a total of seven mapped drives.
+# If you for instance want to mount a FAT32 disk with fat95, these old instructions may be of some use:
 
 
-To get a hard drive image mounted when WB starts, you need a few things:
-* Copy pi-scsi.device from the `device_driver_amiga` folder to `SYS:Devs` on your Amiga.
-  If you're super savvy, the driver is also available in "RAM" at the address `$80004400` because that's where the PiSCSI interface keeps the boot ROM, so you can technically just write it to a file on the Amiga from there.
 * Download giggledisk from http://www.geit.de/eng_giggledisk.html or https://aminet.net/package/disk/misc/giggledisk to make MountLists for attached devices.
   Place the giggledisk binary in `C:` or something so that it's available in the search path.
 * It might be a good idea to have fat95 installed on your Amiga, in case you want to use FAT32 images or other file systems that fat95 can handle: https://aminet.net/package/disk/misc/fat95
 * Download giggledisk from http://www.geit.de/eng_giggledisk.html or https://aminet.net/package/disk/misc/giggledisk to make MountLists for attached devices.
   Place the giggledisk binary in `C:` or something so that it's available in the search path.
 * It might be a good idea to have fat95 installed on your Amiga, in case you want to use FAT32 images or other file systems that fat95 can handle: https://aminet.net/package/disk/misc/fat95
index 9f440bbc4920eb9b30d349495a0698499dffa962..c4b7f561111dbbf7305adcc9273725c868d2dc29 100644 (file)
@@ -62,6 +62,9 @@ void rtg_update_screen();
 
 unsigned int rtg_read(uint32_t address, uint8_t mode) {
     //printf("%s read from RTG: %.8X\n", op_type_names[mode], address);
 
 unsigned int rtg_read(uint32_t address, uint8_t mode) {
     //printf("%s read from RTG: %.8X\n", op_type_names[mode], address);
+    if (address == RTG_COMMAND) {
+        return 0xFFCF;
+    }
     if (address >= PIGFX_REG_SIZE) {
         if (rtg_mem && (address - PIGFX_REG_SIZE) < PIGFX_UPPER) {
             switch (mode) {
     if (address >= PIGFX_REG_SIZE) {
         if (rtg_mem && (address - PIGFX_REG_SIZE) < PIGFX_UPPER) {
             switch (mode) {
index dda431c097d6f13054c07b3e561e7b6473ba1a6a..bd1546a8259c8344f5e30e0706c87ef9d1a6ed7c 100644 (file)
@@ -255,12 +255,19 @@ void rtg_p2c (int16_t sx, int16_t sy, int16_t dx, int16_t dy, int16_t w, int16_t
 #define DECODE_PLANAR_PIXEL(a) \
        switch (planes) { \
                case 8: if (layer_mask & 0x80 && bmp_data[(plane_size * 7) + cur_byte] & cur_bit) a |= 0x80; \
 #define DECODE_PLANAR_PIXEL(a) \
        switch (planes) { \
                case 8: if (layer_mask & 0x80 && bmp_data[(plane_size * 7) + cur_byte] & cur_bit) a |= 0x80; \
+        /* Fallthrough */ \
                case 7: if (layer_mask & 0x40 && bmp_data[(plane_size * 6) + cur_byte] & cur_bit) a |= 0x40; \
                case 7: if (layer_mask & 0x40 && bmp_data[(plane_size * 6) + cur_byte] & cur_bit) a |= 0x40; \
+        /* Fallthrough */ \
                case 6: if (layer_mask & 0x20 && bmp_data[(plane_size * 5) + cur_byte] & cur_bit) a |= 0x20; \
                case 6: if (layer_mask & 0x20 && bmp_data[(plane_size * 5) + cur_byte] & cur_bit) a |= 0x20; \
+        /* Fallthrough */ \
                case 5: if (layer_mask & 0x10 && bmp_data[(plane_size * 4) + cur_byte] & cur_bit) a |= 0x10; \
                case 5: if (layer_mask & 0x10 && bmp_data[(plane_size * 4) + cur_byte] & cur_bit) a |= 0x10; \
+        /* Fallthrough */ \
                case 4: if (layer_mask & 0x08 && bmp_data[(plane_size * 3) + cur_byte] & cur_bit) a |= 0x08; \
                case 4: if (layer_mask & 0x08 && bmp_data[(plane_size * 3) + cur_byte] & cur_bit) a |= 0x08; \
+        /* Fallthrough */ \
                case 3: if (layer_mask & 0x04 && bmp_data[(plane_size * 2) + cur_byte] & cur_bit) a |= 0x04; \
                case 3: if (layer_mask & 0x04 && bmp_data[(plane_size * 2) + cur_byte] & cur_bit) a |= 0x04; \
+        /* Fallthrough */ \
                case 2: if (layer_mask & 0x02 && bmp_data[plane_size + cur_byte] & cur_bit) a |= 0x02; \
                case 2: if (layer_mask & 0x02 && bmp_data[plane_size + cur_byte] & cur_bit) a |= 0x02; \
+        /* Fallthrough */ \
                case 1: if (layer_mask & 0x01 && bmp_data[cur_byte] & cur_bit) a |= 0x01; \
                        break; \
        }
                case 1: if (layer_mask & 0x01 && bmp_data[cur_byte] & cur_bit) a |= 0x01; \
                        break; \
        }
@@ -268,12 +275,19 @@ void rtg_p2c (int16_t sx, int16_t sy, int16_t dx, int16_t dy, int16_t w, int16_t
 #define DECODE_INVERTED_PLANAR_PIXEL(a) \
        switch (planes) { \
                case 8: if (layer_mask & 0x80 && (bmp_data[(plane_size * 7) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x80; \
 #define DECODE_INVERTED_PLANAR_PIXEL(a) \
        switch (planes) { \
                case 8: if (layer_mask & 0x80 && (bmp_data[(plane_size * 7) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x80; \
+        /* Fallthrough */ \
                case 7: if (layer_mask & 0x40 && (bmp_data[(plane_size * 6) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x40; \
                case 7: if (layer_mask & 0x40 && (bmp_data[(plane_size * 6) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x40; \
+        /* Fallthrough */ \
                case 6: if (layer_mask & 0x20 && (bmp_data[(plane_size * 5) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x20; \
                case 6: if (layer_mask & 0x20 && (bmp_data[(plane_size * 5) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x20; \
+        /* Fallthrough */ \
                case 5: if (layer_mask & 0x10 && (bmp_data[(plane_size * 4) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x10; \
                case 5: if (layer_mask & 0x10 && (bmp_data[(plane_size * 4) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x10; \
+        /* Fallthrough */ \
                case 4: if (layer_mask & 0x08 && (bmp_data[(plane_size * 3) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x08; \
                case 4: if (layer_mask & 0x08 && (bmp_data[(plane_size * 3) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x08; \
+        /* Fallthrough */ \
                case 3: if (layer_mask & 0x04 && (bmp_data[(plane_size * 2) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x04; \
                case 3: if (layer_mask & 0x04 && (bmp_data[(plane_size * 2) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x04; \
+        /* Fallthrough */ \
                case 2: if (layer_mask & 0x02 && (bmp_data[plane_size + cur_byte] ^ 0xFF) & cur_bit) a |= 0x02; \
                case 2: if (layer_mask & 0x02 && (bmp_data[plane_size + cur_byte] ^ 0xFF) & cur_bit) a |= 0x02; \
+        /* Fallthrough */ \
                case 1: if (layer_mask & 0x01 && (bmp_data[cur_byte] ^ 0xFF) & cur_bit) a |= 0x01; \
                        break; \
        }
                case 1: if (layer_mask & 0x01 && (bmp_data[cur_byte] ^ 0xFF) & cur_bit) a |= 0x01; \
                        break; \
        }
index c6111b4244b1f7e9a0feab246de9416574517d6e..c9d705106a793834402485349043ca58612613fa 100644 (file)
@@ -21,6 +21,8 @@
 #define WRITELONG(cmd, val) *(unsigned long *)((unsigned long)(b->RegisterBase)+cmd) = val;
 #define WRITEBYTE(cmd, val) *(unsigned char *)((unsigned long)(b->RegisterBase)+cmd) = val;
 
 #define WRITELONG(cmd, val) *(unsigned long *)((unsigned long)(b->RegisterBase)+cmd) = val;
 #define WRITEBYTE(cmd, val) *(unsigned char *)((unsigned long)(b->RegisterBase)+cmd) = val;
 
+#define CHECKRTG *((unsigned short *)(CARD_OFFSET))
+
 #define CARD_OFFSET   0x70000000
 #define CARD_REGSIZE  0x00010000
 #define CARD_MEMSIZE  0x02000000 // 32MB "VRAM"
 #define CARD_OFFSET   0x70000000
 #define CARD_REGSIZE  0x00010000
 #define CARD_MEMSIZE  0x02000000 // 32MB "VRAM"
@@ -225,6 +227,12 @@ static BYTE card_initialized;
 int FindCard(__REGA0(struct BoardInfo* b)) {
   //if (card_already_found)
 //    return 1;
 int FindCard(__REGA0(struct BoardInfo* b)) {
   //if (card_already_found)
 //    return 1;
+  uint16_t card_check = CHECKRTG;
+  if (card_check != 0xFFCF) {
+    // RTG not enabled
+    return 0;
+  }
+
   struct ConfigDev* cd = NULL;
   struct ExpansionBase *ExpansionBase = NULL;
   struct DOSBase *DOSBase = NULL;
   struct ConfigDev* cd = NULL;
   struct ExpansionBase *ExpansionBase = NULL;
   struct DOSBase *DOSBase = NULL;
index 0907cbeb70dbdbf764cd716b7ea35eeef48a0306..054dfe2ac678723b41fe93468caee4f5c1488208 100644 (file)
Binary files a/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card and b/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card differ
index 0907cbeb70dbdbf764cd716b7ea35eeef48a0306..054dfe2ac678723b41fe93468caee4f5c1488208 100644 (file)
Binary files a/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card and b/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card differ