From: beeanyew Date: Tue, 16 Feb 2021 07:03:46 +0000 (+0100) Subject: [WIP] PiSCSI custom file system experiments X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=24d09251d52d81019dcc440b80c6b4ccdfbb8d22;p=pistorm [WIP] PiSCSI custom file system experiments Still not quite working, only FFS working for now. --- diff --git a/.gitignore b/.gitignore index aaf0ccc..8e3ac16 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,10 @@ *.img *.hdf *.rom +*.dll +*.bin +*.exe +*.stackdump !/platforms/amiga/piscsi/*.rom /m68kmake /m68kmake.exe diff --git a/default.cfg b/default.cfg index 5160d84..0cea4a0 100644 --- a/default.cfg +++ b/default.cfg @@ -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 diff --git a/emulator.c b/emulator.c index b13bbdc..b4ca6b0 100644 --- a/emulator.c +++ b/emulator.c @@ -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 { diff --git a/platforms/amiga/Gayle.c b/platforms/amiga/Gayle.c index 520ca9b..cf5729a 100644 --- a/platforms/amiga/Gayle.c +++ b/platforms/amiga/Gayle.c @@ -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) { diff --git a/platforms/amiga/amiga-platform.c b/platforms/amiga/amiga-platform.c index ed887ba..8230179 100644 --- a/platforms/amiga/amiga-platform.c +++ b/platforms/amiga/amiga-platform.c @@ -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); } diff --git a/platforms/amiga/hunk-reloc.c b/platforms/amiga/hunk-reloc.c index 6421c06..4869600 100644 --- a/platforms/amiga/hunk-reloc.c +++ b/platforms/amiga/hunk-reloc.c @@ -6,13 +6,21 @@ #include #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; +} diff --git a/platforms/amiga/hunk-reloc.h b/platforms/amiga/hunk-reloc.h index afd6c02..c153ac6 100644 --- a/platforms/amiga/hunk-reloc.h +++ b/platforms/amiga/hunk-reloc.h @@ -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); diff --git a/platforms/amiga/piscsi/device_driver_amiga/bootrom b/platforms/amiga/piscsi/device_driver_amiga/bootrom index 416c960..fe3d33a 100644 Binary files a/platforms/amiga/piscsi/device_driver_amiga/bootrom and b/platforms/amiga/piscsi/device_driver_amiga/bootrom differ diff --git a/platforms/amiga/piscsi/device_driver_amiga/bootrom.s b/platforms/amiga/piscsi/device_driver_amiga/bootrom.s index f27ac5f..0696d83 100644 --- a/platforms/amiga/piscsi/device_driver_amiga/bootrom.s +++ b/platforms/amiga/piscsi/device_driver_amiga/bootrom.s @@ -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 diff --git a/platforms/amiga/piscsi/device_driver_amiga/build.sh b/platforms/amiga/piscsi/device_driver_amiga/build.sh index a09dad8..3497372 100644 --- a/platforms/amiga/piscsi/device_driver_amiga/build.sh +++ b/platforms/amiga/piscsi/device_driver_amiga/build.sh @@ -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 diff --git a/platforms/amiga/piscsi/device_driver_amiga/makerom.c b/platforms/amiga/piscsi/device_driver_amiga/makerom.c index 0a5ccda..e63c777 100644 --- a/platforms/amiga/piscsi/device_driver_amiga/makerom.c +++ b/platforms/amiga/piscsi/device_driver_amiga/makerom.c @@ -3,7 +3,7 @@ #include #include -#define BOOTLDR_SIZE 0x400 +#define BOOTLDR_SIZE 0x1000 #define DIAG_TOTAL_SIZE 0x4000 char *rombuf, *zerobuf, *devicebuf; diff --git a/platforms/amiga/piscsi/device_driver_amiga/pi-scsi.device b/platforms/amiga/piscsi/device_driver_amiga/pi-scsi.device index 2e1e1e5..c57df2b 100644 Binary files a/platforms/amiga/piscsi/device_driver_amiga/pi-scsi.device and b/platforms/amiga/piscsi/device_driver_amiga/pi-scsi.device differ diff --git a/platforms/amiga/piscsi/device_driver_amiga/piscsi-amiga-2.c b/platforms/amiga/piscsi/device_driver_amiga/piscsi-amiga-2.c index 8a76d3f..fd0a0e2 100644 --- a/platforms/amiga/piscsi/device_driver_amiga/piscsi-amiga-2.c +++ b/platforms/amiga/piscsi/device_driver_amiga/piscsi-amiga-2.c @@ -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: diff --git a/platforms/amiga/piscsi/piscsi-enums.h b/platforms/amiga/piscsi/piscsi-enums.h index 235d7f2..5d4efa4 100644 --- a/platforms/amiga/piscsi/piscsi-enums.h +++ b/platforms/amiga/piscsi/piscsi-enums.h @@ -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 diff --git a/platforms/amiga/piscsi/piscsi.c b/platforms/amiga/piscsi/piscsi.c index 497b6ed..2cec2f6 100644 --- a/platforms/amiga/piscsi/piscsi.c +++ b/platforms/amiga/piscsi/piscsi.c @@ -5,16 +5,20 @@ #include #include #include +#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; } diff --git a/platforms/amiga/piscsi/piscsi.h b/platforms/amiga/piscsi/piscsi.h index 6fdf805..d327125 100644 --- a/platforms/amiga/piscsi/piscsi.h +++ b/platforms/amiga/piscsi/piscsi.h @@ -47,15 +47,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; @@ -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(); diff --git a/platforms/amiga/piscsi/piscsi.rom b/platforms/amiga/piscsi/piscsi.rom index 4083909..67af5f8 100644 Binary files a/platforms/amiga/piscsi/piscsi.rom and b/platforms/amiga/piscsi/piscsi.rom differ diff --git a/platforms/amiga/piscsi/readme.md b/platforms/amiga/piscsi/readme.md index 722b4f0..9e57c34 100644 --- a/platforms/amiga/piscsi/readme.md +++ b/platforms/amiga/piscsi/readme.md @@ -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 diff --git a/platforms/amiga/rtg/rtg.c b/platforms/amiga/rtg/rtg.c index 9f440bb..c4b7f56 100644 --- a/platforms/amiga/rtg/rtg.c +++ b/platforms/amiga/rtg/rtg.c @@ -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) { diff --git a/platforms/amiga/rtg/rtg.h b/platforms/amiga/rtg/rtg.h index dda431c..bd1546a 100644 --- a/platforms/amiga/rtg/rtg.h +++ b/platforms/amiga/rtg/rtg.h @@ -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; \ } diff --git a/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c b/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c index c6111b4..c9d7051 100644 --- a/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c +++ b/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c @@ -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; diff --git a/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card b/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card index 0907cbe..054dfe2 100644 Binary files a/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card and b/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card differ diff --git a/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card b/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card index 0907cbe..054dfe2 100644 Binary files a/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card and b/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card differ