]> git.sesse.net Git - pistorm/blobdiff - platforms/amiga/piscsi/piscsi.c
Some more failed PiSCSI 1.3 autoboot ventures
[pistorm] / platforms / amiga / piscsi / piscsi.c
index cf9c696d006ad250d524d8a3e4585c3fb892ba4d..c6251c74c8787743111c1035cd908f056a3273f2 100644 (file)
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MIT
+
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
 #ifdef PISCSI_DEBUG
 #define DEBUG printf
 //#define DEBUG_TRIVIAL printf
-#define DEBUG_TRVIAL(...)
+#define DEBUG_TRIVIAL(...)
 
-extern void stop_cpu_emulation(uint8_t disasm_cur);
+//extern void stop_cpu_emulation(uint8_t disasm_cur);
+#define stop_cpu_emulation(...)
 
 static const char *op_type_names[4] = {
     "BYTE",
@@ -73,27 +76,59 @@ void piscsi_init() {
         devs[i].c = devs[i].h = devs[i].s = 0;
     }
 
-    FILE *in = fopen("./platforms/amiga/piscsi/piscsi.rom", "rb");
-    if (in == NULL) {
-        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;
-        ac_piscsi_rom[22] = 0;
-        ac_piscsi_rom[23] = 0;
-        return;
+    if (piscsi_rom_ptr == NULL) {
+        FILE *in = fopen("./platforms/amiga/piscsi/piscsi.rom", "rb");
+        if (in == NULL) {
+            printf("[PISCSI] Could not open PISCSI Boot ROM file for reading!\n");
+            // Zero out the boot ROM offset from the autoconfig ROM.
+            ac_piscsi_rom[20] = 0;
+            ac_piscsi_rom[21] = 0;
+            ac_piscsi_rom[22] = 0;
+            ac_piscsi_rom[23] = 0;
+            return;
+        }
+        fseek(in, 0, SEEK_END);
+        piscsi_rom_size = ftell(in);
+        fseek(in, 0, SEEK_SET);
+        piscsi_rom_ptr = malloc(piscsi_rom_size);
+        fread(piscsi_rom_ptr, piscsi_rom_size, 1, in);
+
+        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");
+    } else {
+        printf("[PISCSI] Boot ROM already loaded.\n");
     }
-    fseek(in, 0, SEEK_END);
-    piscsi_rom_size = ftell(in);
-    fseek(in, 0, SEEK_SET);
-    piscsi_rom_ptr = malloc(piscsi_rom_size);
-    fread(piscsi_rom_ptr, piscsi_rom_size, 1, in);
+    fflush(stdout);
+}
 
-    fseek(in, PISCSI_DRIVER_OFFSET, SEEK_SET);
-    process_hunks(in, &piscsi_hinfo, piscsi_hreloc, PISCSI_DRIVER_OFFSET);
+void piscsi_shutdown() {
+    printf("[PISCSI] Shutting down PiSCSI.\n");
+    for (int i = 0; i < 8; i++) {
+        if (devs[i].fd != -1) {
+            close(devs[i].fd);
+            devs[i].fd = -1;
+            devs[i].block_size = 0;
+        }
+    }
 
-    fclose(in);
-    printf("[PISCSI] Loaded Boot ROM.\n");
+    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;
+    }
 }
 
 void piscsi_find_partitions(struct piscsi_dev *d) {
@@ -113,11 +148,11 @@ void piscsi_find_partitions(struct piscsi_dev *d) {
         return;
     }
 
-    char *block = malloc(512);
+    char *block = malloc(d->block_size);
 
-    lseek(fd, BE(d->rdb->rdb_PartitionList) * 512, SEEK_SET);
+    lseek(fd, BE(d->rdb->rdb_PartitionList) * d->block_size, SEEK_SET);
 next_partition:;
-    read(fd, block, 512);
+    read(fd, block, d->block_size);
 
     uint32_t first = be32toh(*((uint32_t *)&block[0]));
     if (first != PART_IDENTIFIER) {
@@ -135,8 +170,8 @@ next_partition:;
 
     if (d->pb[cur_partition]->pb_Next != 0xFFFFFFFF) {
         uint64_t next = be32toh(pb->pb_Next);
-        block = malloc(512);
-        lseek64(fd, next * 512, SEEK_SET);
+        block = malloc(d->block_size);
+        lseek64(fd, next * d->block_size, SEEK_SET);
         cur_partition++;
         DEBUG("[PISCSI] Next partition at block %d.\n", be32toh(pb->pb_Next));
         goto next_partition;
@@ -151,11 +186,11 @@ next_partition:;
 int piscsi_parse_rdb(struct piscsi_dev *d) {
     int fd = d->fd;
     int i = 0;
-    uint8_t *block = malloc(512);
+    uint8_t *block = malloc(PISCSI_MAX_BLOCK_SIZE);
 
     lseek(fd, 0, SEEK_SET);
     for (i = 0; i < RDB_BLOCK_LIMIT; i++) {
-        read(fd, block, 512);
+        read(fd, block, PISCSI_MAX_BLOCK_SIZE);
         uint32_t first = be32toh(*((uint32_t *)&block[0]));
         if (first == RDB_IDENTIFIER)
             goto rdb_found;
@@ -169,6 +204,8 @@ rdb_found:;
     d->s = be32toh(rdb->rdb_Sectors);
     d->num_partitions = 0;
     DEBUG("[PISCSI] RDB - first partition at block %d.\n", be32toh(rdb->rdb_PartitionList));
+    d->block_size = be32toh(rdb->rdb_BlockBytes);
+    DEBUG("[PISCSI] Block size: %d. (%d)\n", be32toh(rdb->rdb_BlockBytes), d->block_size);
     if (d->rdb)
         free(d->rdb);
     d->rdb = rdb;
@@ -217,12 +254,12 @@ void piscsi_find_filesystems(struct piscsi_dev *d) {
 
     uint8_t fs_found = 0;
 
-    uint8_t *fhb_block = malloc(512);
+    uint8_t *fhb_block = malloc(d->block_size);
 
     lseek64(d->fd, d->fshd_offs, SEEK_SET);
 
     struct FileSysHeaderBlock *fhb = (struct FileSysHeaderBlock *)fhb_block;
-    read(d->fd, fhb_block, 512);
+    read(d->fd, fhb_block, d->block_size);
 
     while (BE(fhb->fhb_ID) == FS_IDENTIFIER) {
         char *dosID = (char *)&fhb->fhb_DosType;
@@ -251,7 +288,7 @@ void piscsi_find_filesystems(struct piscsi_dev *d) {
             }
         }
 
-        if (load_lseg(d->fd, &filesystems[piscsi_num_fs].binary_data, &filesystems[piscsi_num_fs].h_info, filesystems[piscsi_num_fs].relocs) != -1) {
+        if (load_lseg(d->fd, &filesystems[piscsi_num_fs].binary_data, &filesystems[piscsi_num_fs].h_info, filesystems[piscsi_num_fs].relocs, d->block_size) != -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]);
@@ -260,10 +297,10 @@ void piscsi_find_filesystems(struct piscsi_dev *d) {
 
 skip_fs_load_lseg:;
         fs_found++;
-        lseek64(d->fd, BE(fhb->fhb_Next) * 512, SEEK_SET);
-        fhb_block = malloc(512);
+        lseek64(d->fd, BE(fhb->fhb_Next) * d->block_size, SEEK_SET);
+        fhb_block = malloc(d->block_size);
         fhb = (struct FileSysHeaderBlock *)fhb_block;
-        read(d->fd, fhb_block, 512);
+        read(d->fd, fhb_block, d->block_size);
     }
 
     if (!fs_found) {
@@ -275,6 +312,10 @@ fs_done:;
         free(fhb_block);
 }
 
+struct piscsi_dev *piscsi_get_dev(uint8_t index) {
+    return &devs[index];
+}
+
 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);
@@ -300,11 +341,15 @@ void piscsi_map_drive(char *filename, uint8_t index) {
         d->h = 16;
         d->s = 63;
         d->c = (file_size / 512) / (d->s * d->h);
+        d->block_size = 512;
     }
     printf("[PISCSI] CHS: %d %d %d\n", d->c, d->h, d->s);
 
+    printf ("Finding partitions.\n");
     piscsi_find_partitions(d);
+    printf ("Finding file systems.\n");
     piscsi_find_filesystems(d);
+    printf ("Done.\n");
 }
 
 void piscsi_unmap_drive(uint8_t index) {
@@ -506,6 +551,7 @@ void piscsi_debugme(uint32_t index) {
 
 void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
     int32_t r;
+    uint8_t *map;
 #ifndef PISCSI_DEBUG
     if (type) {}
 #endif
@@ -517,70 +563,84 @@ void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
     switch (cmd) {
         case PISCSI_CMD_READ64:
         case PISCSI_CMD_READ:
+        case PISCSI_CMD_READBYTES:
             d = &devs[val];
             if (d->fd == -1) {
                 DEBUG("[!!!PISCSI] BUG: Attempted read from unmapped drive %d.\n", val);
                 break;
             }
 
-            if (cmd == PISCSI_CMD_READ) {
+            if (cmd == PISCSI_CMD_READBYTES) {
+                DEBUG("[PISCSI-%d] %d byte READBYTES from block %d to address %.8X\n", val, piscsi_u32[1], piscsi_u32[0] / d->block_size, piscsi_u32[2]);
+                uint32_t src = piscsi_u32[0];
+                d->lba = (src / d->block_size);
+                lseek(d->fd, src, SEEK_SET);
+            }
+            else if (cmd == PISCSI_CMD_READ) {
                 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);
+                lseek(d->fd, (piscsi_u32[0] * d->block_size), SEEK_SET);
             }
             else {
                 uint64_t src = piscsi_u32[3];
                 src = (src << 32) | piscsi_u32[0];
-                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);
+                DEBUG("[PISCSI-%d] %d byte READ64 from block %lld to address %.8X\n", val, piscsi_u32[1], (src / d->block_size), piscsi_u32[2]);
+                d->lba = (src / d->block_size);
                 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) {
+            map = get_mapped_data_pointer_by_address(cfg, piscsi_u32[2]);
+            if (map) {
                 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]);
+                read(d->fd, map, piscsi_u32[1]);
             }
             else {
                 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);
-                    write8(piscsi_u32[2] + i, (uint32_t)c);
+                    m68k_write_memory_8(piscsi_u32[2] + i, (uint32_t)c);
                 }
             }
             break;
         case PISCSI_CMD_WRITE64:
         case PISCSI_CMD_WRITE:
+        case PISCSI_CMD_WRITEBYTES:
             d = &devs[val];
             if (d->fd == -1) {
                 DEBUG ("[PISCSI] BUG: Attempted write to unmapped drive %d.\n", val);
                 break;
             }
 
-            if (cmd == PISCSI_CMD_WRITE) {
+            if (cmd == PISCSI_CMD_WRITEBYTES) {
+                DEBUG("[PISCSI-%d] %d byte WRITEBYTES to block %d from address %.8X\n", val, piscsi_u32[1], piscsi_u32[0] / d->block_size, piscsi_u32[2]);
+                uint32_t src = piscsi_u32[0];
+                d->lba = (src / d->block_size);
+                lseek(d->fd, src, SEEK_SET);
+            }
+            else if (cmd == PISCSI_CMD_WRITE) {
                 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);
+                lseek(d->fd, (piscsi_u32[0] * d->block_size), SEEK_SET);
             }
             else {
                 uint64_t src = piscsi_u32[3];
                 src = (src << 32) | piscsi_u32[0];
-                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);
+                DEBUG("[PISCSI-%d] %d byte WRITE64 to block %lld from address %.8X\n", val, piscsi_u32[1], (src / d->block_size), piscsi_u32[2]);
+                d->lba = (src / d->block_size);
                 lseek64(d->fd, src, SEEK_SET);
             }
 
-            r = get_mapped_item_by_address(cfg, piscsi_u32[2]);
-            if (r != -1) {
+            map = get_mapped_data_pointer_by_address(cfg, piscsi_u32[2]);
+            if (map) {
                 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]);
+                write(d->fd, map, piscsi_u32[1]);
             }
             else {
                 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);
+                    c = m68k_read_memory_8(piscsi_u32[2] + i);
                     write(d->fd, &c, 1);
                 }
             }
@@ -591,24 +651,28 @@ 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)
+            if (val % 10 != 0) {
                 piscsi_cur_drive = 255;
+            }
             else
                 piscsi_cur_drive = val / 10;
-            if (piscsi_cur_drive > NUM_UNITS)
+            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_DRVNUMX:
+            piscsi_cur_drive = val;
+            DEBUG("[PISCSI] DRVNUMX: %d.\n", val);
+            break;
         case PISCSI_CMD_DEBUGME:
             piscsi_debugme(val);
             break;
-        case PISCSI_CMD_DRIVER: {
+        case PISCSI_CMD_DRIVER:
             DEBUG("[PISCSI] Driver copy/patch called, destination address %.8X.\n", val);
-            int r = get_mapped_item_by_address(cfg, val);
+            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];
@@ -688,7 +752,6 @@ skip_disk:;
             }
 
             break;
-        }
         case PISCSI_CMD_NEXTPART:
             DEBUG("[PISCSI] Switch partition %d -> %d\n", rom_cur_partition, rom_cur_partition + 1);
             rom_cur_partition++;
@@ -716,8 +779,8 @@ skip_disk:;
             if (r != -1) {
                 uint32_t addr = val - cfg->map_offset[r];
                 struct DeviceNode *node = (struct DeviceNode *)(cfg->map_data[r] + addr);
-#ifdef PISCSI_DEBUG
                 char *dosID = (char *)&rom_partition_dostype[rom_cur_partition];
+#ifdef PISCSI_DEBUG
 #endif
                 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++) {
@@ -727,7 +790,7 @@ skip_disk:;
                         goto fs_found;
                     }
                 }
-                DEBUG("[!!!PISCSI] Found no handler for file system!\n");
+                printf("[!!!PISCSI] Found no handler for file system %c%c%c/%d\n", dosID[0], dosID[1], dosID[2], dosID[3]);
 fs_found:;
                 DEBUG("[FS-HANDLER] Next: %d Type: %.8X\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));
@@ -812,8 +875,8 @@ uint32_t handle_piscsi_read(uint32_t addr, uint8_t type) {
             return devs[piscsi_cur_drive].s;
             break;
         case PISCSI_CMD_BLOCKS: {
-            uint32_t blox = devs[piscsi_cur_drive].fs / 512;
-            DEBUG("[PISCSI] %s Read from BLOCKS %d: %d\n", op_type_names[type], piscsi_cur_drive, (uint32_t)(devs[piscsi_cur_drive].fs / 512));
+            uint32_t blox = devs[piscsi_cur_drive].fs / devs[piscsi_cur_drive].block_size;
+            DEBUG("[PISCSI] %s Read from BLOCKS %d: %d\n", op_type_names[type], piscsi_cur_drive, (uint32_t)(devs[piscsi_cur_drive].fs / devs[piscsi_cur_drive].block_size));
             DEBUG("fs: %lld (%d)\n", devs[piscsi_cur_drive].fs, blox);
             return blox;
             break;
@@ -833,6 +896,9 @@ uint32_t handle_piscsi_read(uint32_t addr, uint8_t type) {
         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;
+        case PISCSI_CMD_BLOCKSIZE:
+            DEBUG("[PISCSI] Get block size of drive %d: %d\n", piscsi_cur_drive, devs[piscsi_cur_drive].block_size);
+            return devs[piscsi_cur_drive].block_size;
         default:
             DEBUG("[!!!PISCSI] WARN: Unhandled %s register read from %.8X\n", op_type_names[type], addr);
             break;