+++ /dev/null
-// SPDX-License-Identifier: MIT
-
-/*
- * Based on:
- * Amiga ZZ9000 USB Storage Driver (ZZ9000USBStorage.device)
- * Copyright (C) 2016-2020, Lukas F. Hartmann <lukas@mntre.com>
- * Based on code Copyright (C) 2016, Jason S. McMullan <jason.mcmullan@gmail.com>
- * All rights reserved.
- *
- * Licensed under the MIT License:
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <exec/resident.h>
-#include <exec/errors.h>
-#include <exec/memory.h>
-#include <exec/lists.h>
-#include <exec/alerts.h>
-#include <exec/tasks.h>
-#include <exec/io.h>
-#include <exec/execbase.h>
-
-#include <libraries/expansion.h>
-
-#include <devices/trackdisk.h>
-#include <devices/timer.h>
-#include <devices/scsidisk.h>
-
-#include <dos/filehandler.h>
-
-#include <proto/exec.h>
-#include <proto/disk.h>
-#include <proto/expansion.h>
-
-#include <clib/debug_protos.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include "../piscsi-enums.h"
-
-#define WRITESHORT(cmd, val) *(unsigned short *)((unsigned long)(PISCSI_OFFSET+cmd)) = val;
-#define WRITELONG(cmd, val) *(unsigned long *)((unsigned long)(PISCSI_OFFSET+cmd)) = val;
-#define WRITEBYTE(cmd, val) *(unsigned char *)((unsigned long)(PISCSI_OFFSET+cmd)) = val;
-
-#define READSHORT(cmd, var) var = *(volatile unsigned short *)(PISCSI_OFFSET + cmd);
-#define READLONG(cmd, var) var = *(volatile unsigned long *)(PISCSI_OFFSET + cmd);
-
-#pragma pack(4)
-struct piscsi_base {
- struct Device* pi_dev;
- struct piscsi_unit {
- struct Unit unit;
- uint32_t regs_ptr;
-
- uint8_t enabled;
- uint8_t present;
- uint8_t valid;
- uint8_t read_only;
- uint8_t motor;
- uint8_t unit_num;
- uint16_t h, s;
- uint32_t c;
-
- uint32_t change_num;
- } units[NUM_UNITS];
-};
-
-struct ExecBase* SysBase = NULL;
-
-#ifdef _FSCSIDEV
-const char DevName[] = "scsi.device";
-#elif _FSCSI2ND
-const char DevName[] = "2nd.scsi.device";
-#else
-const char DevName[] = "pi-scsi.device";
-#endif
-const char DevIdString[] = "Pi-SCSI 0.1";
-
-const UWORD DevVersion = 43;
-const UWORD DevRevision = 10;
-
-#include "stabs.h"
-
-struct piscsi_base *dev_base = NULL;
-
-struct WBStartup *_WBenchMsg = NULL;
-
-//#define exit(...)
-//#define debug(...)
-#define KPrintF(...)
-#define debug(...)
-#define debugval(...)
-//#define debug(c, v) WRITESHORT(c, v)
-//#define debugval(c, v) WRITELONG(c, v)
-
-//#define bug(x,args...) KPrintF(x ,##args);
-//#define debug(x,args...) bug("%s:%ld " x "\n", __func__, (unsigned long)__LINE__ ,##args)
-
-uint8_t piscsi_perform_io(struct piscsi_unit *u, struct IORequest *io);
-uint8_t piscsi_rw(struct piscsi_unit *u, struct IORequest *io, uint32_t offset, uint8_t write);
-uint8_t piscsi_scsi(struct piscsi_unit *u, struct IORequest *io);
-
-extern void* DOSBase[2];
-
-uint32_t __UserDevInit(struct Device* dev) {
- //uint8_t* registers = NULL;
- SysBase = *(struct ExecBase **)4L;
-
- KPrintF("Initializing devices.\n");
- debug(PISCSI_DBG_MSG, DBG_INIT);
-
- dev_base = AllocMem(sizeof(struct piscsi_base), MEMF_PUBLIC | MEMF_CLEAR);
- dev_base->pi_dev = dev;
-
- for (int i = 0; i < NUM_UNITS; i++) {
- uint16_t r = 0;
- WRITESHORT(PISCSI_CMD_DRVNUM, i);
- dev_base->units[i].regs_ptr = PISCSI_OFFSET;
- READSHORT(PISCSI_CMD_DRVTYPE, r);
- dev_base->units[i].enabled = r;
- dev_base->units[i].present = r;
- dev_base->units[i].valid = r;
- dev_base->units[i].unit_num = i;
- if (dev_base->units[i].present) {
- READLONG(PISCSI_CMD_CYLS, dev_base->units[i].c);
- READSHORT(PISCSI_CMD_HEADS, dev_base->units[i].h);
- READSHORT(PISCSI_CMD_SECS, dev_base->units[i].s);
- KPrintF("C/H/S: %ld / %ld / %ld\n", dev_base->units[i].c, dev_base->units[i].h, dev_base->units[i].s);
-
- debugval(PISCSI_DBG_VAL1, dev_base->units[i].c);
- debugval(PISCSI_DBG_VAL2, dev_base->units[i].h);
- debugval(PISCSI_DBG_VAL3, dev_base->units[i].s);
- debug(PISCSI_DBG_MSG, DBG_CHS);
- }
- dev_base->units[i].change_num++;
- // Send any reset signal to the "SCSI" device here.
- }
-
- return 1;
-}
-
-uint32_t __UserDevCleanup(void) {
- KPrintF("Cleaning up.\n");
- debug(PISCSI_DBG_MSG, DBG_CLEANUP);
- FreeMem(dev_base, sizeof(struct piscsi_base));
- return 0;
-}
-
-uint32_t __UserDevOpen(struct IOExtTD *iotd, uint32_t num, uint32_t flags) {
- struct Node* node = (struct Node*)iotd;
- int io_err = IOERR_OPENFAIL;
-
- //WRITESHORT(PISCSI_CMD_DEBUGME, 1);
-
- int unit_num = 0;
- WRITELONG(PISCSI_CMD_DRVNUM, num);
- READLONG(PISCSI_CMD_DRVNUM, unit_num);
-
- debugval(PISCSI_DBG_VAL1, unit_num);
- debugval(PISCSI_DBG_VAL2, flags);
- debugval(PISCSI_DBG_VAL3, num);
- debug(PISCSI_DBG_MSG, DBG_OPENDEV);
- KPrintF("Opening device %ld Flags: %ld (%lx)\n", unit_num, flags, flags);
-
- if (iotd && unit_num < NUM_UNITS) {
- if (dev_base->units[unit_num].enabled && dev_base->units[unit_num].present) {
- io_err = 0;
- iotd->iotd_Req.io_Unit = (struct Unit*)&dev_base->units[unit_num].unit;
- iotd->iotd_Req.io_Unit->unit_flags = UNITF_ACTIVE;
- iotd->iotd_Req.io_Unit->unit_OpenCnt = 1;
- }
- }
-
-skip:;
- iotd->iotd_Req.io_Error = io_err;
-
- return io_err;
-}
-
-uint32_t __UserDevClose(struct IOExtTD *iotd) {
- return 0;
-}
-
-void exit(int status) { }
-
-ADDTABL_1(__BeginIO,a1);
-void __BeginIO(struct IORequest *io) {
- if (dev_base == NULL || io == NULL)
- return;
-
- struct piscsi_unit *u;
- struct Node* node = (struct Node*)io;
- u = (struct piscsi_unit *)io->io_Unit;
-
- if (node == NULL || u == NULL)
- return;
-
- debugval(PISCSI_DBG_VAL1, io->io_Command);
- debugval(PISCSI_DBG_VAL2, io->io_Flags);
- debugval(PISCSI_DBG_VAL3, (io->io_Flags & IOF_QUICK));
- debug(PISCSI_DBG_MSG, DBG_BEGINIO);
- KPrintF("io_Command = %ld, io_Flags = 0x%lx quick = %lx\n", io->io_Command, io->io_Flags, (io->io_Flags & IOF_QUICK));
- io->io_Error = piscsi_perform_io(u, io);
-
- if (!(io->io_Flags & IOF_QUICK)) {
- ReplyMsg(&io->io_Message);
- }
-}
-
-ADDTABL_1(__AbortIO,a1);
-void __AbortIO(struct IORequest* io) {
- debug(PISCSI_DBG_MSG, DBG_ABORTIO);
- KPrintF("AbortIO!\n");
- if (!io) return;
- io->io_Error = IOERR_ABORTED;
-}
-
-uint8_t piscsi_rw(struct piscsi_unit *u, struct IORequest *io, uint32_t offset, uint8_t write) {
- struct IOStdReq *iostd = (struct IOStdReq *)io;
- struct IOExtTD *iotd = (struct IOExtTD *)io;
-
- uint8_t* data;
- uint32_t len, num_blocks;
- uint32_t block, max_addr;
- uint8_t sderr;
-
- data = iotd->iotd_Req.io_Data;
- len = iotd->iotd_Req.io_Length;
- //uint32_t offset2 = iostd->io_Offset;
-
- max_addr = 0xffffffff;
-
- // well... if we had 64 bits this would make sense
- if ((offset > max_addr) || (offset+len > max_addr))
- return IOERR_BADADDRESS;
- if (data == 0)
- return IOERR_BADADDRESS;
- if (len < PISCSI_BLOCK_SIZE) {
- iostd->io_Actual = 0;
- return IOERR_BADLENGTH;
- }
-
- //block = offset;// >> SD_SECTOR_SHIFT;
- //num_blocks = len;// >> SD_SECTOR_SHIFT;
- sderr = 0;
-
- if (write) {
- //uint32_t retries = 10;
- //KPrintF("Write %lx -> %lx %lx\n", (uint32_t)data, offset, len);
- WRITELONG(PISCSI_CMD_ADDR1, (offset >> 9));
- WRITELONG(PISCSI_CMD_ADDR2, len);
- WRITELONG(PISCSI_CMD_ADDR3, (uint32_t)data);
- WRITESHORT(PISCSI_CMD_WRITE, u->unit_num);
- } else {
- //KPrintF("read %lx %lx -> %lx\n", offset, len, (uint32_t)data);
- WRITELONG(PISCSI_CMD_ADDR1, (offset >> 9));
- WRITELONG(PISCSI_CMD_ADDR2, len);
- WRITELONG(PISCSI_CMD_ADDR3, (uint32_t)data);
- WRITESHORT(PISCSI_CMD_READ, u->unit_num);
- }
-
- if (sderr) {
- iostd->io_Actual = 0;
-
- if (sderr & SCSIERR_TIMEOUT)
- return TDERR_DiskChanged;
- if (sderr & SCSIERR_PARAM)
- return TDERR_SeekError;
- if (sderr & SCSIERR_ADDRESS)
- return TDERR_SeekError;
- if (sderr & (SCSIERR_ERASESEQ | SCSIERR_ERASERES))
- return TDERR_BadSecPreamble;
- if (sderr & SCSIERR_CRC)
- return TDERR_BadSecSum;
- if (sderr & SCSIERR_ILLEGAL)
- return TDERR_TooFewSecs;
- if (sderr & SCSIERR_IDLE)
- return TDERR_PostReset;
-
- return TDERR_SeekError;
- } else {
- iostd->io_Actual = len;
- }
-
- return 0;
-}
-
-#define PISCSI_ID_STRING "PISTORM Fake SCSI Disk 0.1 1111111111111111"
-
-uint8_t piscsi_scsi(struct piscsi_unit *u, struct IORequest *io)
-{
- struct IOStdReq *iostd = (struct IOStdReq *)io;
- struct SCSICmd *scsi = iostd->io_Data;
- //uint8_t* registers = sdu->sdu_Registers;
- uint8_t *data = (uint8_t *)scsi->scsi_Data;
- uint32_t i, block, blocks, maxblocks;
- uint8_t err = 0;
-
- KPrintF("SCSI len=%ld, cmd = %02lx %02lx %02lx ... (%ld)\n",
- iostd->io_Length, scsi->scsi_Command[0],
- scsi->scsi_Command[1], scsi->scsi_Command[2],
- scsi->scsi_CmdLength);
-
- debugval(PISCSI_DBG_VAL1, iostd->io_Length);
- debugval(PISCSI_DBG_VAL2, scsi->scsi_Command[0]);
- debugval(PISCSI_DBG_VAL3, scsi->scsi_Command[1]);
- debugval(PISCSI_DBG_VAL4, scsi->scsi_Command[2]);
- debugval(PISCSI_DBG_VAL5, scsi->scsi_CmdLength);
- debug(PISCSI_DBG_MSG, DBG_SCSICMD);
-
- //maxblocks = u->s * u->c * u->h;
-
- if (scsi->scsi_CmdLength < 6) {
- //KPrintF("SCSICMD BADLENGTH2");
- return IOERR_BADLENGTH;
- }
-
- if (scsi->scsi_Command == NULL) {
- //KPrintF("SCSICMD IOERR_BADADDRESS1");
- return IOERR_BADADDRESS;
- }
-
- scsi->scsi_Actual = 0;
- //iostd->io_Actual = sizeof(*scsi);
-
- switch (scsi->scsi_Command[0]) {
- case 0x00: // TEST_UNIT_READY
- err = 0;
- break;
-
- case 0x12: // INQUIRY
- for (i = 0; i < scsi->scsi_Length; i++) {
- uint8_t val = 0;
-
- switch (i) {
- case 0: // SCSI device type: direct-access device
- val = (0 << 5) | 0;
- break;
- case 1: // RMB = 1
- val = (1 << 7);
- break;
- case 2: // VERSION = 0
- val = 0;
- break;
- case 3: // NORMACA=0, HISUP = 0, RESPONSE_DATA_FORMAT = 2
- val = (0 << 5) | (0 << 4) | 2;
- break;
- case 4: // ADDITIONAL_LENGTH = 44 - 4
- val = 44 - 4;
- break;
- default:
- if (i >= 8 && i < 44)
- val = PISCSI_ID_STRING[i - 8];
- else
- val = 0;
- break;
- }
- data[i] = val;
- }
- scsi->scsi_Actual = i;
- err = 0;
- break;
-
- case 0x08: // READ (6)
- case 0x0a: // WRITE (6)
- 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];
-
- READLONG(PISCSI_CMD_BLOCKS, maxblocks);
- if (block + blocks > maxblocks) {
- err = IOERR_BADADDRESS;
- break;
- }
- /*if (scsi->scsi_Length < (blocks << SD_SECTOR_SHIFT)) {
- err = IOERR_BADLENGTH;
- break;
- }*/
- if (data == NULL) {
- err = IOERR_BADADDRESS;
- break;
- }
-
- if (scsi->scsi_Command[0] == 0x08) {
- //KPrintF("scsi_read %lx %lx\n",block,blocks);
- //KPrintF("SCSI read %lx %lx -> %lx\n", block, blocks, (uint32_t)data);
- WRITELONG(PISCSI_CMD_ADDR2, block);
- WRITELONG(PISCSI_CMD_ADDR2, (blocks << 9));
- WRITELONG(PISCSI_CMD_ADDR3, (uint32_t)data);
- WRITESHORT(PISCSI_CMD_READ, u->unit_num);
- }
- else {
- //KPrintF("scsi_write %lx %lx\n",block,blocks);
- //KPrintF("SCSI write %lx -> %lx %lx\n", (uint32_t)data, block, blocks);
- WRITELONG(PISCSI_CMD_ADDR2, block);
- WRITELONG(PISCSI_CMD_ADDR2, (blocks << 9));
- WRITELONG(PISCSI_CMD_ADDR3, (uint32_t)data);
- WRITESHORT(PISCSI_CMD_WRITE, u->unit_num);
- }
-
- scsi->scsi_Actual = scsi->scsi_Length;
- err = 0;
- break;
-
- case 0x25: // READ CAPACITY (10)
- //KPrintF("SCSI command: Read Capacity.\n");
- if (scsi->scsi_CmdLength < 10) {
- err = HFERR_BadStatus;
- break;
- }
-
- block = *((uint32_t*)&scsi->scsi_Command[2]);
-
- /*if ((scsi->scsi_Command[8] & 1) || block != 0) {
- // PMI Not supported
- KPrintF("PMI not supported.\n");
- err = HFERR_BadStatus;
- break;
- }*/
-
- if (scsi->scsi_Length < 8) {
- err = IOERR_BADLENGTH;
- break;
- }
-
- READLONG(PISCSI_CMD_BLOCKS, blocks);
- ((uint32_t*)data)[0] = blocks - 1;
- ((uint32_t*)data)[1] = PISCSI_BLOCK_SIZE;
-
- scsi->scsi_Actual = 8;
- err = 0;
-
- break;
- case 0x1a: // MODE SENSE (6)
- //KPrintF("SCSI command: Mode Sense.\n");
- data[0] = 3 + 8 + 0x16;
- data[1] = 0; // MEDIUM TYPE
- data[2] = 0;
- data[3] = 8;
-
- READLONG(PISCSI_CMD_BLOCKS, maxblocks);
- (blocks = (maxblocks - 1) & 0xFFFFFF);
-
- *((uint32_t *)&data[4]) = blocks;
- *((uint32_t *)&data[8]) = PISCSI_BLOCK_SIZE;
-
- switch (((UWORD)scsi->scsi_Command[2] << 8) | scsi->scsi_Command[3]) {
- case 0x0300: { // Format Device Mode
- KPrintF("Grabbing SCSI format device mode data.\n");
- debug(PISCSI_DBG_MSG, DBG_SCSI_FORMATDEVICE);
- uint8_t *datext = data + 12;
- datext[0] = 0x03;
- datext[1] = 0x16;
- datext[2] = 0x00;
- datext[3] = 0x01;
- *((uint32_t *)&datext[4]) = 0;
- *((uint32_t *)&datext[8]) = 0;
- *((uint16_t *)&datext[10]) = u->s;
- *((uint16_t *)&datext[12]) = PISCSI_BLOCK_SIZE;
- datext[14] = 0x00;
- datext[15] = 0x01;
- *((uint32_t *)&datext[16]) = 0;
- datext[20] = 0x80;
-
- scsi->scsi_Actual = data[0] + 1;
- err = 0;
- break;
- }
- case 0x0400: // Rigid Drive Geometry
- KPrintF("Grabbing SCSI rigid drive geometry.\n");
- debug(PISCSI_DBG_MSG, DBG_SCSI_RDG);
- uint8_t *datext = data + 12;
- datext[0] = 0x04;
- *((uint32_t *)&datext[1]) = u->c;
- datext[1] = 0x16;
- datext[5] = u->h;
- datext[6] = 0x00;
- *((uint32_t *)&datext[6]) = 0;
- *((uint32_t *)&datext[10]) = 0;
- *((uint32_t *)&datext[13]) = u->c;
- datext[17] = 0;
- *((uint32_t *)&datext[18]) = 0;
- *((uint16_t *)&datext[20]) = 5400;
-
- scsi->scsi_Actual = data[0] + 1;
- err = 0;
- break;
-
- default:
- KPrintF("[WARN] Unhandled mode sense thing: %lx\n", ((UWORD)scsi->scsi_Command[2] << 8) | scsi->scsi_Command[3]);
- debugval(PISCSI_DBG_VAL1, (((UWORD)scsi->scsi_Command[2] << 8) | scsi->scsi_Command[3]));
- debug(PISCSI_DBG_MSG, DBG_SCSI_UNKNOWN_MODESENSE);
- err = HFERR_BadStatus;
- break;
- }
- break;
-
- case 0x37: // READ DEFECT DATA (10)
-
- break;
-
- default:
- debugval(PISCSI_DBG_VAL1, scsi->scsi_Command[0]);
- debug(PISCSI_DBG_MSG, DBG_SCSI_UNKNOWN_COMMAND);
- KPrintF("Unknown/unhandled SCSI command %lx.\n", scsi->scsi_Command[0]);
- err = HFERR_BadStatus;
- break;
- }
-
- if (err != 0) {
- debugval(PISCSI_DBG_VAL1, err);
- debug(PISCSI_DBG_MSG, DBG_SCSIERR);
- KPrintF("Some SCSI error occured: %ld\n", err);
- scsi->scsi_Actual = 0;
- }
-
- return err;
-}
-
-#define DUMMYCMD iostd->io_Actual = 0; break;
-uint8_t piscsi_perform_io(struct piscsi_unit *u, struct IORequest *io) {
- struct IOStdReq *iostd = (struct IOStdReq *)io;
- struct IOExtTD *iotd = (struct IOExtTD *)io;
-
- uint8_t *data;
- uint32_t len;
- uint32_t offset;
- //struct DriveGeometry *geom;
- uint8_t err = 0;
-
- if (!u->enabled) {
- return IOERR_OPENFAIL;
- }
-
- data = iotd->iotd_Req.io_Data;
- len = iotd->iotd_Req.io_Length;
-
- if (io->io_Error == IOERR_ABORTED) {
- return io->io_Error;
- }
-
- debugval(PISCSI_DBG_VAL1, io->io_Command);
- debugval(PISCSI_DBG_VAL2, io->io_Flags);
- debugval(PISCSI_DBG_VAL3, iostd->io_Length);
- debug(PISCSI_DBG_MSG, DBG_IOCMD);
- //KPrintF("cmd: %s\n",cmd_name(io->io_Command));
- //KPrintF("IO %lx Start, io_Flags = %ld, io_Command = %ld\n", io, io->io_Flags, io->io_Command);
-
- switch (io->io_Command) {
- case CMD_CLEAR:
- /* Invalidate read buffer */
- DUMMYCMD;
- case CMD_UPDATE:
- /* Flush write buffer */
- DUMMYCMD;
- case TD_PROTSTATUS:
- DUMMYCMD;
- case TD_CHANGENUM:
- iostd->io_Actual = u->change_num;
- break;
- case TD_REMOVE:
- DUMMYCMD;
- case TD_CHANGESTATE:
- DUMMYCMD;
- case TD_GETDRIVETYPE:
- iostd->io_Actual = DG_DIRECT_ACCESS;
- break;
- case TD_MOTOR:
- iostd->io_Actual = u->motor;
- u->motor = iostd->io_Length ? 1 : 0;
- break;
-
- case TD_FORMAT:
- offset = iotd->iotd_Req.io_Offset;
- //err = 0;
- err = piscsi_rw(u, io, offset, 1);
- break;
- case CMD_WRITE:
- offset = iotd->iotd_Req.io_Offset;
- //err = 0;
- err = piscsi_rw(u, io, offset, 1);
- break;
- case CMD_READ:
- offset = iotd->iotd_Req.io_Offset;
- //err = 0;
- err = piscsi_rw(u, io, offset, 0);
- break;
- case HD_SCSICMD:
- //err = 0;
- err = piscsi_scsi(u, io);
- break;
- default: {
- int cmd = io->io_Command;
- debug(PISCSI_DBG_MSG, DBG_IOCMD_UNHANDLED);
- err = IOERR_NOCMD;
- break;
- }
- }
-
- return err;
-}
-#undef DUMMYCMD
-
-ADDTABL_END();
#define SCSIERR_IDLE (1 << 0)
enum piscsi_stuff {
- PISCSI_BLOCK_SIZE = 512,
+ PISCSI_BLOCK_SIZE = 512, // Deprecated, do not use
+ PISCSI_MAX_BLOCK_SIZE = 65536,
PISCSI_TRACK_SECTORS = 2048,
};
enum piscsi_cmds {
- PISCSI_CMD_WRITE = 0x00,
- PISCSI_CMD_READ = 0x02,
- PISCSI_CMD_DRVNUM = 0x04,
- PISCSI_CMD_DRVTYPE = 0x06,
- PISCSI_CMD_BLOCKS = 0x08,
- PISCSI_CMD_CYLS = 0x0A,
- PISCSI_CMD_HEADS = 0x0C,
- PISCSI_CMD_SECS = 0x0E,
- PISCSI_CMD_ADDR1 = 0x10,
- PISCSI_CMD_ADDR2 = 0x14,
- PISCSI_CMD_ADDR3 = 0x18,
- PISCSI_CMD_ADDR4 = 0x1C,
- PISCSI_CMD_DEBUGME = 0x20,
- PISCSI_CMD_DRIVER = 0x40,
- PISCSI_CMD_NEXTPART = 0x44,
- PISCSI_CMD_GETPART = 0x48,
- PISCSI_CMD_GETPRIO = 0x4C,
- PISCSI_CMD_WRITE64 = 0x50,
- PISCSI_CMD_READ64 = 0x52,
- PISCSI_CMD_CHECKFS = 0x60,
- PISCSI_CMD_NEXTFS = 0x64,
- PISCSI_CMD_COPYFS = 0x68,
- PISCSI_CMD_FSSIZE = 0x6C,
- PISCSI_CMD_SETFSH = 0x70,
- PISCSI_DBG_MSG = 0x1000,
- PISCSI_DBG_VAL1 = 0x1010,
- PISCSI_DBG_VAL2 = 0x1014,
- PISCSI_DBG_VAL3 = 0x1018,
- PISCSI_DBG_VAL4 = 0x101C,
- PISCSI_DBG_VAL5 = 0x1020,
- PISCSI_DBG_VAL6 = 0x1024,
- PISCSI_DBG_VAL7 = 0x1028,
- PISCSI_DBG_VAL8 = 0x102C,
- PISCSI_CMD_ROM = 0x4000,
+ PISCSI_CMD_WRITE = 0x00,
+ PISCSI_CMD_READ = 0x02,
+ PISCSI_CMD_DRVNUM = 0x04,
+ PISCSI_CMD_DRVTYPE = 0x06,
+ PISCSI_CMD_BLOCKS = 0x08,
+ PISCSI_CMD_CYLS = 0x0A,
+ PISCSI_CMD_HEADS = 0x0C,
+ PISCSI_CMD_SECS = 0x0E,
+ PISCSI_CMD_ADDR1 = 0x10,
+ PISCSI_CMD_ADDR2 = 0x14,
+ PISCSI_CMD_ADDR3 = 0x18,
+ PISCSI_CMD_ADDR4 = 0x1C,
+ PISCSI_CMD_DEBUGME = 0x20,
+ PISCSI_CMD_DRIVER = 0x40,
+ PISCSI_CMD_NEXTPART = 0x44,
+ PISCSI_CMD_GETPART = 0x48,
+ 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_CMD_BLOCKSIZE = 0x74,
+ PISCSI_CMD_READBYTES = 0x78,
+ PISCSI_CMD_WRITEBYTES = 0x7C,
+ PISCSI_DBG_MSG = 0x1000,
+ PISCSI_DBG_VAL1 = 0x1010,
+ PISCSI_DBG_VAL2 = 0x1014,
+ PISCSI_DBG_VAL3 = 0x1018,
+ PISCSI_DBG_VAL4 = 0x101C,
+ PISCSI_DBG_VAL5 = 0x1020,
+ PISCSI_DBG_VAL6 = 0x1024,
+ PISCSI_DBG_VAL7 = 0x1028,
+ PISCSI_DBG_VAL8 = 0x102C,
+ PISCSI_CMD_ROM = 0x4000,
};
enum piscsi_dbg_msgs {
#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",
if (devs[i].fd != -1) {
close(devs[i].fd);
devs[i].fd = -1;
+ devs[i].block_size = 0;
}
}
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) {
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;
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;
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;
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;
}
}
- if (load_lseg(d->fd, &filesystems[piscsi_num_fs].binary_data, &filesystems[piscsi_num_fs].h_info, filesystems[piscsi_num_fs].relocs) != -1) {
+ printf ("Loadseg begins.\n");
+ 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]);
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) {
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);
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);
}
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);
}
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);
}
}
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;
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;