]> 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
+*.dll
+*.bin
+*.exe
+*.stackdump
 !/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
-# 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
-# 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
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/hunk-reloc.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;
+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;
@@ -60,7 +63,6 @@ char disasm_buf[4096];
 
 int mem_fd, mouse_fd = -1, keyboard_fd = -1;
 int mem_fd_gpclk;
-int gayle_emulation_enabled = 1;
 int irq;
 int gayleirq;
 
@@ -81,7 +83,7 @@ void *iplThread(void *args) {
     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;
@@ -111,8 +113,6 @@ void stop_cpu_emulation(uint8_t disasm_cur) {
   do_disasm = 0;
 }
 
-//unsigned char g_kick[524288];
-//unsigned char g_ram[FASTSIZE + 1]; /* RAM */
 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++) {
-    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 {
index 520ca9bdfab867a737f3fb3888af314a8c57cd62..cf5729ad7406782c6db8a3ae6a1f1e4562a5fb80 100644 (file)
@@ -25,6 +25,9 @@
 #include "gayle-ide/ide.h"
 #include "amiga-registers.h"
 
+//#define DEBUG(...)
+#define DEBUG printf
+
 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;
-static struct ide_controller *ide0;
+static struct ide_controller *ide0 = NULL;
 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;
+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) {
-  //if (index) {}
+  if (index) {}
   return ide0;
 }
 
@@ -74,16 +79,16 @@ void set_hard_drive_image_file_amiga(uint8_t index, char *filename) {
 }
 
 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);
+      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 {
@@ -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);
+          num_ide_drives++;
         }
         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]);
       }
     }
   }
-  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) {
@@ -118,47 +132,49 @@ uint8_t CheckIrq(void) {
 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:;
-    ide_write8(ide0, ide_action, value);
-    return;
+      ide_write8(ide0, ide_action, value);
+      return;
 skip_idewrite8:;
+    }
   }
 
   switch (address) {
@@ -206,14 +222,16 @@ skip_idewrite8:;
 }
 
 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) {
@@ -254,100 +272,100 @@ void writeGayleL(unsigned int address, unsigned int value) {
 }
 
 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:;
-    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:;
-  }
+    }
 
-  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) {
@@ -367,16 +385,18 @@ skip_ideread8:;
 }
 
 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) {
index ed887baf4ff1083e76b2f25ba971f282617896e7..82301791bfd9714dc01bd44d10f1580151474c93 100644 (file)
@@ -6,6 +6,7 @@
 #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"
@@ -398,6 +399,9 @@ void handle_reset_amiga(struct emulator_config *cfg) {
     ac_z2_current_pic = 0;
     ac_z3_current_pic = 0;
 
+    if (piscsi_enabled)
+        piscsi_refresh_drives();
+
     adjust_ranges_amiga(cfg);
 }
 
index 6421c06d3f67b7f45b26ce0f1da1d5799aab5f2c..4869600f95571b6515a4dae8580fc20afd6db0dc 100644 (file)
@@ -6,13 +6,21 @@
 #include <endian.h>
 #include "hunk-reloc.h"
 
+#ifdef FAKESTORM
+#define lseek64 lseek
+#endif
+
 #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);
 
-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) {
@@ -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);
-            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;
@@ -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);
-                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++) {
@@ -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);
-            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);
+            add_size += (discard * 4);
             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;
@@ -148,24 +157,87 @@ void reloc_hunk(struct hunk_reloc *h, uint8_t *buf, struct hunk_info *i) {
     *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));
 
-    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));
-        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) {
-    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);
+        reloc_hunk(&r[i], buf, h_info);
     }
     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];
-    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;
@@ -27,6 +27,8 @@ enum hunk_types {
 };
 
 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 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);
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
+OpenResource    EQU -$1F2
+AddResource     EQU -$1E6
 
 ; Expansion stuff
 MakeDosNode     EQU -144
@@ -70,11 +72,28 @@ AddBootNode     EQU -36
 
 ; 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
+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  ***************************************************
 **********************************************************************
@@ -238,7 +257,7 @@ Init:       ; After Diag patching, our romtag will point to this
             ;
             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
@@ -265,37 +284,138 @@ Init:       ; After Diag patching, our romtag will point to this
             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
 
+            move.l  #7,PiSCSIDebugMe
 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  #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  #8,PiSCSIDebugMe
             move.l #1,PiSCSINextPart    ; Switch to the next partition
             bra.w PartitionLoop
 
 
 EndPartitions:
+            move.l  #8,PiSCSIDebugMe
             move.l a6,a1
+            move.l  #800,PiSCSIDebugMe
             movea.l 4,a6
+            move.l  #801,PiSCSIDebugMe
             jsr CloseLibrary(a6)
-            move.l  #6,PiSCSIDebugMe
+            move.l  #802,PiSCSIDebugMe
 
             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"
+            move.l  #805,PiSCSIDebugMe
             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
-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-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>
 
-#define BOOTLDR_SIZE 0x400
+#define BOOTLDR_SIZE 0x1000
 #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;
+        uint16_t scsi_num;
         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].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);
@@ -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]) {
-        case 0x00:      // TEST_UNIT_READY
+        case SCSICMD_TEST_UNIT_READY:
             err = 0;
             break;
         
-        case 0x12:      // INQUIRY
+        case SCSICMD_INQUIRY:
             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;
         
-        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;
             }
-            /*if (scsi->scsi_Length < (blocks << SD_SECTOR_SHIFT)) {
-                err = IOERR_BADLENGTH;
-                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;
         
-        case 0x25: // READ CAPACITY (10)
+        case SCSICMD_READ_CAPACITY_10:
             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;
             }
             
-            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;
@@ -437,13 +430,16 @@ uint8_t piscsi_scsi(struct piscsi_unit *u, struct IORequest *io)
             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;
 
-            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);
 
@@ -498,9 +494,9 @@ uint8_t piscsi_scsi(struct piscsi_unit *u, struct IORequest *io)
             }
             break;
         
-        case 0x37: // READ DEFECT DATA (10)
+        case SCSICMD_READ_DEFECT_DATA_10:
             break;
-        case 0x40: // CHANGE DEFINITION
+        case SCSICMD_CHANGE_DEFINITION:
             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_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,
@@ -65,6 +70,155 @@ enum piscsi_dbg_msgs {
     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
index 497b6ede71dc5dd613b2ab99cf629e738328515d..2cec2f6d548669854014391fb174612e69ba100e 100644 (file)
@@ -5,16 +5,20 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <endian.h>
+#include "../hunk-reloc.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)
+#define BE16(val) be16toh(val)
 
 // 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
@@ -25,6 +29,10 @@ extern struct emulator_config *cfg;
 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];
@@ -33,7 +41,10 @@ uint8_t *piscsi_rom_ptr;
 
 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[];
 
@@ -58,7 +69,7 @@ void piscsi_init() {
 
     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;
@@ -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);
-    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");
@@ -95,22 +103,28 @@ void piscsi_find_partitions(struct piscsi_dev *d) {
     }
 
     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);
 
-    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);
 
+    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;
-    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) {
@@ -118,11 +132,12 @@ next_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;
     }
-    printf("[PISCSI] No more partitions on disk.\n");
+    DEBUG("[PISCSI] No more partitions on disk.\n");
     d->num_partitions = cur_partition + 1;
+    d->fshd_offs = lseek64(fd, 0, SEEK_CUR);
 
     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;
-    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);
-    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;
@@ -158,6 +176,96 @@ no_rdb_found:;
     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);
@@ -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] 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);
-    //stop_cpu_emulation(1);
+    piscsi_find_filesystems(d);
 }
 
 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;
     }
@@ -233,66 +341,130 @@ char *io_cmd_name(int index) {
         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) {
-        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:
-            return "!!!Unhandled SCSI command";
+            return "[!!!PISCSI] Unhandled SCSI command";
     }
 }
 
 void print_piscsi_debug_message(int index) {
+    int32_t r = 0;
+
     switch (index) {
         case DBG_INIT:
-            printf("[PISCSI] Initializing devices.\n");
+            DEBUG("[PISCSI] Initializing devices.\n");
             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:
-            printf("[PISCSI] Cleaning up.\n");
+            DEBUG("[PISCSI] Cleaning up.\n");
             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:
-            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:
-            printf("[PISCSI] AbortIO!\n");
+            DEBUG("[PISCSI] AbortIO!\n");
             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:
-            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:
-            printf("SCSI: Unknown command %.4X\n", piscsi_dbg[0]);
+            DEBUG("[!!!PISCSI] SCSI: Unknown command %.4X\n", piscsi_dbg[0]);
             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:
-            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:
-            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;
     }
+
+    if (index == 8) {
+        stop_cpu_emulation(1);
+    }
 }
 
 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) {
-                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) {
-                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];
-                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) {
-                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 {
-                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);
@@ -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) {
-                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) {
-                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];
-                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) {
-                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 {
-                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);
@@ -379,29 +551,32 @@ void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
             break;
         }
         case PISCSI_CMD_DRVNUM:
+            //printf("%d ", val);
             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:
-            printf("[PISCSI] DebugMe triggered (%d).\n", val);
-            stop_cpu_emulation(1);
+            piscsi_debugme(val);
             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;
-                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);
-                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;
@@ -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;
+                    rom_partition_dostype[i] = 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++) {
-                    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;
-                        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++) {
-                            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]);
@@ -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) {
-                                printf("Partition is bootable.\n");
+                                DEBUG("Partition is bootable.\n");
                                 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);
                             }
 
-                            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_partition_dostype[cur_partition] = dat->dostype;
                             cur_partition++;
                             addr2 += 0x100;
                             p_offs = addr2;
                         }
                     }
+skip_disk:;
                 }
             }
            
             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;
+        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;
@@ -480,7 +704,7 @@ void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
             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;
     }
 }
@@ -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)) {
-            //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];
-                    //printf("%.2X\n", v);
+                    //DEBUG("%.2X\n", v);
                     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]));
-                    //printf("%.8X\n", v);
+                    //DEBUG("%.8X\n", 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) {
-                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;
             }
-            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:
-            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:
-            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:
-            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;
-            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: {
-            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:
-            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;
+        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:
-            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;
     }
 
index 6fdf805c2aca52b2422129afbd86a6c5efc089bb..d3271255b8dc80fb74078ac8cc92f673f866b7d3 100644 (file)
 #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;
@@ -64,11 +65,21 @@ struct piscsi_dev {
     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;
 };
 
+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 */
@@ -166,6 +177,20 @@ struct RigidDiskBlock {
     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;
@@ -180,3 +205,45 @@ struct PartitionBlock {
     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
 
-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.
 
+# 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.
 
-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`.
@@ -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.
 
-# 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
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);
+    if (address == RTG_COMMAND) {
+        return 0xFFCF;
+    }
     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; \
+        /* Fallthrough */ \
                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; \
+        /* Fallthrough */ \
                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; \
+        /* Fallthrough */ \
                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; \
+        /* Fallthrough */ \
                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; \
+        /* Fallthrough */ \
                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; \
+        /* Fallthrough */ \
                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; \
+        /* Fallthrough */ \
                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; \
+        /* Fallthrough */ \
                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 CHECKRTG *((unsigned short *)(CARD_OFFSET))
+
 #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;
+  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;
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