mirror of
https://github.com/captain-amygdala/pistorm.git
synced 2026-04-26 03:57:49 +00:00
[WIP] PiSCSI autoboot working
This commit is contained in:
@@ -341,8 +341,8 @@ void setvar_amiga(struct emulator_config *cfg, char *var, char *val) {
|
||||
printf("[AMIGA] PISCSI Interface Enabled.\n");
|
||||
piscsi_enabled = 1;
|
||||
piscsi_init();
|
||||
//ac_z2_type[ac_z2_pic_count] = ACTYPE_PISCSI;
|
||||
//ac_z2_pic_count++;
|
||||
ac_z2_type[ac_z2_pic_count] = ACTYPE_PISCSI;
|
||||
ac_z2_pic_count++;
|
||||
adjust_ranges_amiga(cfg);
|
||||
}
|
||||
if (piscsi_enabled) {
|
||||
|
||||
Binary file not shown.
@@ -40,23 +40,41 @@ ROMOFFS EQU $4000
|
||||
* structures which require absolute pointers to ROM code or data.
|
||||
|
||||
*----- We'll store Version and Revision in serial number
|
||||
VERSION EQU 37 ; also the high word of serial number
|
||||
REVISION EQU 1 ; also the low word of serial number
|
||||
VERSION EQU 37 ; also the high word of serial number
|
||||
REVISION EQU 1 ; also the low word of serial number
|
||||
|
||||
* See the Addison-Wesley Amiga Hardware Manual for more info.
|
||||
|
||||
MANUF_ID EQU 2011 ; CBM assigned (2011 for hackers only)
|
||||
PRODUCT_ID EQU 1 ; Manufacturer picks product ID
|
||||
|
||||
MANUF_ID EQU 2011 ; CBM assigned (2011 for hackers only)
|
||||
PRODUCT_ID EQU 1 ; Manufacturer picks product ID
|
||||
BOARDSIZE EQU $10000 ; How much address space board decodes
|
||||
SIZE_FLAG EQU 3 ; Autoconfig 3-bit flag for BOARDSIZE
|
||||
; 0=$800000(8meg) 4=$80000(512K)
|
||||
; 1=$10000(64K) 5=$100000(1meg)
|
||||
; 2=$20000(128K) 6=$200000(2meg)
|
||||
; 3=$40000(256K) 7=$400000(4meg)
|
||||
CODE
|
||||
|
||||
BOARDSIZE EQU $10000 ; How much address space board decodes
|
||||
SIZE_FLAG EQU 3 ; Autoconfig 3-bit flag for BOARDSIZE
|
||||
; 0=$800000(8meg) 4=$80000(512K)
|
||||
; 1=$10000(64K) 5=$100000(1meg)
|
||||
; 2=$20000(128K) 6=$200000(2meg)
|
||||
; 3=$40000(256K) 7=$400000(4meg)
|
||||
CODE
|
||||
; Exec stuff
|
||||
AllocMem EQU -198
|
||||
InitResident EQU -102
|
||||
FindResident EQU -96
|
||||
OpenLibrary EQU -552
|
||||
CloseLibrary EQU -414
|
||||
|
||||
AllocMem EQU -198
|
||||
; Expansion stuff
|
||||
MakeDosNode EQU -144
|
||||
AddDosNode EQU -150
|
||||
AddBootNode EQU -36
|
||||
|
||||
; PiSCSI stuff
|
||||
PiSCSIAddr1 EQU $80000010
|
||||
PiSCSIDebugMe EQU $80000020
|
||||
PiSCSIDriver EQU $80000040
|
||||
PiSCSINextPart EQU $80000044
|
||||
PiSCSIGetPart EQU $80000048
|
||||
PiSCSIGetPrio EQU $8000004C
|
||||
|
||||
******* RomStart ***************************************************
|
||||
**********************************************************************
|
||||
@@ -92,10 +110,12 @@ rt_Init: dc.l Init-RomStart ; APTR RT_INIT
|
||||
|
||||
|
||||
******* Strings referenced in Diag Copy area ************************
|
||||
DevName: dc.b 'PiSCSI Snake Controller',0 ; Name string
|
||||
IdString dc.b 'PISCSI v0.1',0 ; Id string
|
||||
DevName: dc.b 'pi-scsi.device',0,0 ; Name string
|
||||
IdString dc.b 'PISCSI v0.8',0 ; Id string
|
||||
|
||||
DosName: dc.b 'dos.library',0 ; DOS library name
|
||||
DosName: dc.b 'dos.library',0 ; DOS library name
|
||||
ExpansionName: dc.b "expansion.library",0
|
||||
LibName: dc.b "pi-scsi.device",0,0
|
||||
|
||||
DosDevName: dc.b 'ABC',0 ; dos device name for MakeDosNode()
|
||||
; (dos device will be ABC:)
|
||||
@@ -121,7 +141,8 @@ DiagEntry:
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
move.l #1,$80000020
|
||||
move.l #1,PiSCSIDebugMe
|
||||
move.l a3,PiSCSIAddr1
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
@@ -167,7 +188,7 @@ endpatches:
|
||||
|
||||
BootEntry:
|
||||
align 2
|
||||
move.l #2,$80000020
|
||||
move.l #2,PiSCSIDebugMe
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
@@ -175,7 +196,7 @@ BootEntry:
|
||||
nop
|
||||
|
||||
lea DosName(PC),a1 ; 'dos.library',0
|
||||
jsr _LVOFindResident(a6) ; find the DOS resident tag
|
||||
jsr FindResident(a6) ; find the DOS resident tag
|
||||
move.l d0,a0 ; in order to bootstrap
|
||||
move.l RT_INIT(A0),a0 ; set vector to DOS INIT
|
||||
jsr (a0) ; and initialize DOS
|
||||
@@ -216,37 +237,65 @@ Init: ; After Diag patching, our romtag will point to this
|
||||
; BootNode, and Enqueue() on eb_MountList.
|
||||
;
|
||||
align 2
|
||||
move.w #$00B8,$dff09a
|
||||
move.l #3,$80000020
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
move.l a6,-(a7) ; Push A6 to stack
|
||||
;move.w #$00B8,$dff09a ; Disable interrupts during init
|
||||
move.l #3,PiSCSIDebugMe
|
||||
|
||||
move.l #4,$80000020
|
||||
move.l #11,PiSCSIDebugMe
|
||||
movea.l 4,a6
|
||||
lea LibName(pc),a1
|
||||
jsr FindResident(a6)
|
||||
move.l #10,PiSCSIDebugMe
|
||||
cmp.l #0,d0
|
||||
bne.s SkipDriverLoad ; Library is already loaded, jump straight to partitions
|
||||
|
||||
move.l #4,PiSCSIDebugMe
|
||||
movea.l 4,a6
|
||||
move.l #$40000,d0
|
||||
moveq #0,d1
|
||||
jsr AllocMem(a6)
|
||||
jsr AllocMem(a6) ; Allocate memory for the PiStorm to copy the driver to
|
||||
|
||||
move.l d0,$80000040
|
||||
nop
|
||||
nop
|
||||
move.l d0,PiSCSIDriver ; Copy the PiSCSI driver to allocated memory and patch offsets
|
||||
|
||||
move.l #5,$80000020
|
||||
move.l #5,PiSCSIDebugMe
|
||||
move.l d0,a1
|
||||
move.l #0,d1
|
||||
movea.l 4,a6
|
||||
add.l #$02c,a1
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
jsr -102(a6)
|
||||
nop
|
||||
nop
|
||||
jsr InitResident(a6) ; Initialize the PiSCSI driver
|
||||
|
||||
moveq.l #1,d0 ; indicate "success"
|
||||
SkipDriverLoad:
|
||||
lea ExpansionName(pc),a1
|
||||
moveq #0,d0
|
||||
jsr OpenLibrary(a6) ; Open expansion.library to make this work, somehow
|
||||
move.l d0,a6
|
||||
|
||||
move.w #$80B8,$dff09a
|
||||
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,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 a6,a1
|
||||
movea.l 4,a6
|
||||
jsr CloseLibrary(a6)
|
||||
move.l #6,PiSCSIDebugMe
|
||||
|
||||
move.l (a7)+,a6 ; Pop A6 from stack
|
||||
|
||||
;move.w #$80B8,$dff09a ; Re-enable interrupts
|
||||
moveq.l #1,d0 ; indicate "success"
|
||||
rts
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -30,8 +30,8 @@
|
||||
#define DEVICE_NAME "pi-scsi.device"
|
||||
#define DEVICE_DATE "(3 Feb 2021)"
|
||||
#define DEVICE_ID_STRING "PiSCSI " XSTR(DEVICE_VERSION) "." XSTR(DEVICE_REVISION) " " DEVICE_DATE
|
||||
#define DEVICE_VERSION 1
|
||||
#define DEVICE_REVISION 0
|
||||
#define DEVICE_VERSION 43
|
||||
#define DEVICE_REVISION 20
|
||||
#define DEVICE_PRIORITY 0
|
||||
|
||||
#pragma pack(4)
|
||||
@@ -108,7 +108,7 @@ static struct Library __attribute__((used)) *init_device(uint8_t *seg_list asm("
|
||||
|
||||
for (int i = 0; i < NUM_UNITS; i++) {
|
||||
uint16_t r = 0;
|
||||
WRITESHORT(PISCSI_CMD_DRVNUM, i);
|
||||
WRITESHORT(PISCSI_CMD_DRVNUM, (i * 10));
|
||||
dev_base->units[i].regs_ptr = PISCSI_OFFSET;
|
||||
READSHORT(PISCSI_CMD_DRVTYPE, r);
|
||||
dev_base->units[i].enabled = r;
|
||||
@@ -166,12 +166,12 @@ static void __attribute__((used)) open(struct Library *dev asm("a6"), struct IOE
|
||||
}
|
||||
|
||||
iotd->iotd_Req.io_Error = io_err;
|
||||
//dev_base->open_count++;
|
||||
((struct Library *)dev_base->pi_dev)->lib_OpenCnt++;
|
||||
}
|
||||
|
||||
static uint8_t* __attribute__((used)) close(struct Library *dev asm("a6"), struct IOExtTD *iotd asm("a1"))
|
||||
{
|
||||
//dev_base->open_count--;
|
||||
((struct Library *)dev_base->pi_dev)->lib_OpenCnt--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -383,6 +383,7 @@ uint8_t piscsi_scsi(struct piscsi_unit *u, struct IORequest *io)
|
||||
break;
|
||||
}
|
||||
|
||||
WRITESHORT(PISCSI_CMD_DRVNUM, u->unit_num);
|
||||
READLONG(PISCSI_CMD_BLOCKS, maxblocks);
|
||||
if (block + blocks > maxblocks || blocks == 0) {
|
||||
err = IOERR_BADADDRESS;
|
||||
@@ -426,7 +427,8 @@ uint8_t piscsi_scsi(struct piscsi_unit *u, struct IORequest *io)
|
||||
err = IOERR_BADLENGTH;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
WRITESHORT(PISCSI_CMD_DRVNUM, u->unit_num);
|
||||
READLONG(PISCSI_CMD_BLOCKS, blocks);
|
||||
((uint32_t*)data)[0] = blocks - 1;
|
||||
((uint32_t*)data)[1] = PISCSI_BLOCK_SIZE;
|
||||
@@ -441,6 +443,7 @@ uint8_t piscsi_scsi(struct piscsi_unit *u, struct IORequest *io)
|
||||
data[2] = 0;
|
||||
data[3] = 8;
|
||||
|
||||
WRITESHORT(PISCSI_CMD_DRVNUM, u->unit_num);
|
||||
READLONG(PISCSI_CMD_BLOCKS, maxblocks);
|
||||
(blocks = (maxblocks - 1) & 0xFFFFFF);
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ enum piscsi_cmds {
|
||||
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_DBG_MSG = 0x1000,
|
||||
|
||||
@@ -11,8 +11,11 @@
|
||||
#include "../../../config_file/config_file.h"
|
||||
#include "../../../gpio/ps_protocol.h"
|
||||
|
||||
// Comment this line to restore debug output:
|
||||
//#define printf(...)
|
||||
#define BE(val) be32toh(val)
|
||||
|
||||
// Comment these lines to restore debug output:
|
||||
#define printf(...)
|
||||
#define stop_cpu_emulation(...)
|
||||
|
||||
#ifdef FAKESTORM
|
||||
#define lseek64 lseek
|
||||
@@ -28,6 +31,10 @@ uint32_t piscsi_dbg[8];
|
||||
uint32_t piscsi_rom_size = 0;
|
||||
uint8_t *piscsi_rom_ptr;
|
||||
|
||||
uint32_t rom_partitions[128];
|
||||
uint32_t rom_partition_prio[128];
|
||||
uint32_t rom_cur_partition = 0;
|
||||
|
||||
extern unsigned char ac_piscsi_rom[];
|
||||
|
||||
static const char *op_type_names[4] = {
|
||||
@@ -77,15 +84,23 @@ void piscsi_init() {
|
||||
|
||||
void piscsi_find_partitions(struct piscsi_dev *d) {
|
||||
int fd = d->fd;
|
||||
char *block = malloc(512);
|
||||
int cur_partition = 0;
|
||||
uint8_t tmp;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (d->pb[i]) {
|
||||
free(d->pb[i]);
|
||||
d->pb[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!d->rdb || d->rdb->rdb_PartitionList == 0) {
|
||||
printf("[PISCSI] No partitions on disk.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
char *block = malloc(512);
|
||||
|
||||
lseek(fd, be32toh(d->rdb->rdb_PartitionList) * 512, SEEK_SET);
|
||||
next_partition:;
|
||||
read(fd, block, 512);
|
||||
@@ -93,7 +108,9 @@ next_partition:;
|
||||
struct PartitionBlock *pb = (struct PartitionBlock *)block;
|
||||
tmp = pb->pb_DriveName[0];
|
||||
pb->pb_DriveName[tmp + 1] = 0x00;
|
||||
printf("Partition %d: %s\n", cur_partition, pb->pb_DriveName + 1);
|
||||
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));
|
||||
d->pb[cur_partition] = pb;
|
||||
|
||||
if (d->pb[cur_partition]->pb_Next != 0xFFFFFFFF) {
|
||||
@@ -101,10 +118,11 @@ next_partition:;
|
||||
block = malloc(512);
|
||||
lseek64(fd, next * 512, SEEK_SET);
|
||||
cur_partition++;
|
||||
printf("Next partition at block %d.\n", be32toh(pb->pb_Next));
|
||||
printf("[PISCSI] Next partition at block %d.\n", be32toh(pb->pb_Next));
|
||||
goto next_partition;
|
||||
}
|
||||
printf("No more partitions on disk.\n");
|
||||
printf("[PISCSI] No more partitions on disk.\n");
|
||||
d->num_partitions = cur_partition + 1;
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -120,9 +138,6 @@ int piscsi_parse_rdb(struct piscsi_dev *d) {
|
||||
uint32_t first = be32toh(*((uint32_t *)&block[0]));
|
||||
if (first == RDB_IDENTIFIER)
|
||||
goto rdb_found;
|
||||
else {
|
||||
printf("Block %d is not RDB, looking for %.8X, found %.8X\n", i, RDB_IDENTIFIER, first);
|
||||
}
|
||||
}
|
||||
goto no_rdb_found;
|
||||
rdb_found:;
|
||||
@@ -276,6 +291,7 @@ void print_piscsi_debug_message(int index) {
|
||||
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]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,7 +307,7 @@ 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", piscsi_cur_drive);
|
||||
printf ("[PISCSI] BUG: Attempted read from unmapped drive %d.\n", val);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -326,7 +342,7 @@ 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", piscsi_cur_drive);
|
||||
printf ("[PISCSI] BUG: Attempted write to unmapped drive %d.\n", val);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -363,16 +379,10 @@ void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
|
||||
break;
|
||||
}
|
||||
case PISCSI_CMD_DRVNUM:
|
||||
if (val != 0) {
|
||||
if (val < 10) // Kludge for GiggleDisk
|
||||
piscsi_cur_drive = val;
|
||||
else if (val >= 10 && val % 10 != 0)
|
||||
piscsi_cur_drive = 255;
|
||||
else
|
||||
piscsi_cur_drive = val / 10;
|
||||
}
|
||||
if (val % 10 != 0)
|
||||
piscsi_cur_drive = 255;
|
||||
else
|
||||
piscsi_cur_drive = val;
|
||||
piscsi_cur_drive = val / 10;
|
||||
printf("[PISCSI] (%s) Drive number set to %d (%d)\n", op_type_names[type], piscsi_cur_drive, val);
|
||||
break;
|
||||
case PISCSI_CMD_DEBUGME:
|
||||
@@ -385,21 +395,81 @@ void handle_piscsi_write(uint32_t addr, uint32_t val, uint8_t type) {
|
||||
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);
|
||||
|
||||
piscsi_hinfo.base_offset = val;
|
||||
|
||||
reloc_hunks(piscsi_hreloc, dst_data + addr, &piscsi_hinfo);
|
||||
stop_cpu_emulation(1);
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < 0x3C00; i++) {
|
||||
uint8_t src = piscsi_rom_ptr[0x400 + i];
|
||||
write8(addr + i, src);
|
||||
|
||||
#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;
|
||||
|
||||
for (int i = 0; i < 128; i++) {
|
||||
rom_partitions[i] = 0;
|
||||
rom_partition_prio[i] = 0;
|
||||
}
|
||||
rom_cur_partition = 0;
|
||||
|
||||
uint32_t data_addr = addr + 0x3F00;
|
||||
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].num_partitions) {
|
||||
uint32_t p_offs = addr2;
|
||||
printf("[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);
|
||||
sprintf((char *)dst_data + p_offs, "%s", devs[i].pb[j]->pb_DriveName + 1);
|
||||
p_offs += 0x20;
|
||||
PUTNODELONG(addr2 + cfg->map_offset[r]);
|
||||
PUTNODELONG(data_addr + cfg->map_offset[r]);
|
||||
PUTNODELONG((i * 10));
|
||||
PUTNODELONG(0);
|
||||
uint32_t nodesize = (be32toh(devs[i].pb[j]->pb_Environment[0]) + 1) * 4;
|
||||
memcpy(dst_data + p_offs, devs[i].pb[j]->pb_Environment, nodesize);
|
||||
|
||||
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");
|
||||
rom_partition_prio[cur_partition] = 0;
|
||||
dat->priority = 0;
|
||||
}
|
||||
else {
|
||||
printf("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));
|
||||
|
||||
rom_partitions[cur_partition] = addr2 + 0x20 + cfg->map_offset[r];
|
||||
cur_partition++;
|
||||
addr2 += 0x100;
|
||||
p_offs = addr2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PISCSI_CMD_NEXTPART:
|
||||
printf("[PISCSI] Switch partition %d -> %d\n", rom_cur_partition, rom_cur_partition + 1);
|
||||
rom_cur_partition++;
|
||||
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;
|
||||
@@ -445,6 +515,11 @@ uint32_t handle_piscsi_read(uint32_t addr, uint8_t type) {
|
||||
}
|
||||
|
||||
switch (addr & 0xFFFF) {
|
||||
case PISCSI_CMD_ADDR1: case PISCSI_CMD_ADDR2: case PISCSI_CMD_ADDR3: case PISCSI_CMD_ADDR4: {
|
||||
int i = ((addr & 0xFFFF) - PISCSI_CMD_ADDR1) / 4;
|
||||
return piscsi_u32[i];
|
||||
break;
|
||||
}
|
||||
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);
|
||||
@@ -475,6 +550,15 @@ uint32_t handle_piscsi_read(uint32_t addr, uint8_t type) {
|
||||
return blox;
|
||||
break;
|
||||
}
|
||||
case PISCSI_CMD_GETPART: {
|
||||
printf("[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]);
|
||||
return rom_partition_prio[rom_cur_partition];
|
||||
break;
|
||||
default:
|
||||
printf("[PISCSI] Unhandled %s register read from %.8X\n", op_type_names[type], addr);
|
||||
break;
|
||||
|
||||
@@ -63,34 +63,41 @@ struct piscsi_dev {
|
||||
uint64_t fs;
|
||||
int32_t fd;
|
||||
uint32_t lba;
|
||||
uint32_t num_partitions;
|
||||
// Will parse max eight partitions per disk
|
||||
struct PartitionBlock *pb[16];
|
||||
struct RigidDiskBlock *rdb;
|
||||
};
|
||||
|
||||
/*
|
||||
dosnode: \
|
||||
// .long 0 /* dos disk name */
|
||||
// .long 0 /* device file name */
|
||||
// .long 0 /* unit */
|
||||
// .long 0 /* flags */
|
||||
// .long 16 /* length of node? */
|
||||
// .long 128 /* longs in a block */
|
||||
// .long 0
|
||||
// .long 4 /* surfaces */
|
||||
// .long 1 /* sectors per block */
|
||||
// .long 256 /* blocks per track */
|
||||
// .long 2 /* reserved bootblocks 256 = 128KB */
|
||||
// .long 0
|
||||
// .long 0
|
||||
// .long 2 /* lowcyl FIXME */
|
||||
// /*.long 2047*/ /* hicyl */
|
||||
// .long 10 /* buffers */
|
||||
// .long 0 /* MEMF_ANY */
|
||||
// .long 0x0001fe00 /* MAXTRANS */
|
||||
// .long 0x7ffffffe /* Mask */
|
||||
// .long -1 /* boot prio */
|
||||
// .long 0x444f5303 /* dostype: DOS3 */1
|
||||
struct DosEnvec {
|
||||
uint32_t de_TableSize; /* Size of Environment vector */
|
||||
uint32_t de_SizeBlock; /* in longwords: standard value is 128 */
|
||||
uint32_t de_SecOrg; /* not used; must be 0 */
|
||||
uint32_t de_Surfaces; /* # of heads (surfaces). drive specific */
|
||||
uint32_t de_SectorPerBlock; /* not used; must be 1 */
|
||||
uint32_t de_BlocksPerTrack; /* blocks per track. drive specific */
|
||||
uint32_t de_Reserved; /* DOS reserved blocks at start of partition. */
|
||||
uint32_t de_PreAlloc; /* DOS reserved blocks at end of partition */
|
||||
uint32_t de_Interleave; /* usually 0 */
|
||||
uint32_t de_LowCyl; /* starting cylinder. typically 0 */
|
||||
uint32_t de_HighCyl; /* max cylinder. drive specific */
|
||||
uint32_t de_NumBuffers; /* Initial # DOS of buffers. */
|
||||
uint32_t de_BufMemType; /* type of mem to allocate for buffers */
|
||||
uint32_t de_MaxTransfer; /* Max number of bytes to transfer at a time */
|
||||
uint32_t de_Mask; /* Address Mask to block out certain memory */
|
||||
int32_t de_BootPri; /* Boot priority for autoboot */
|
||||
uint32_t de_DosType; /* ASCII (HEX) string showing filesystem type;
|
||||
* 0X444F5300 is old filesystem,
|
||||
* 0X444F5301 is fast file system */
|
||||
uint32_t de_Baud; /* Baud rate for serial handler */
|
||||
uint32_t de_Control; /* Control word for handler/filesystem */
|
||||
uint32_t de_BootBlocks; /* Number of blocks containing boot code */
|
||||
|
||||
};
|
||||
|
||||
struct pihd_dosnode_data {
|
||||
uint32_t name_ptr;
|
||||
@@ -105,7 +112,7 @@ struct pihd_dosnode_data {
|
||||
uint32_t blocks_per_track;
|
||||
uint32_t reserved_blocks;
|
||||
uint32_t pad2;
|
||||
uint32_t pad3;
|
||||
uint32_t interleave;
|
||||
uint32_t lowcyl;
|
||||
uint32_t highcyl;
|
||||
uint32_t buffers;
|
||||
|
||||
Binary file not shown.
@@ -4,6 +4,20 @@ Intended to be used as a high performance replacement for scsi.device, can curre
|
||||
|
||||
This driver and interface is work in progress, do not use it in conjunction with any critical data that you need to survive.
|
||||
|
||||
# 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`.
|
||||
* (Optional) If you've had build.sh create a new `bootrom` file, you need to chop off the first few bytes of it, since VASM adds a single hunk to the beginning of it. Simply delete all bytes up until you bump into the value `0x90`, this is the first value in the boot ROM identifier.
|
||||
* Compile the new `pi-scsi.device` using `./build2.sh`.
|
||||
* (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.
|
||||
@@ -34,7 +48,7 @@ Thus, an edited line would look something like `FileSystem = L:FastFileSys
|
||||
|
||||
If the MountList has several partitions listed in it, it must be split up into separate files for all partitions to be mounted.
|
||||
|
||||
Once you've edited a MountList file, simply copy/move it to `SYS:Devs:DOSDrivers`, and the drive will be mounted automatically the next time you boot into Workbench.
|
||||
Once you've edited a MountList file, simply copy/move it to `SYS:Devs/DOSDrivers`, and the drive will be mounted automatically the next time you boot into Workbench.
|
||||
|
||||
If you don't want it to be mounted automatically, simply use the `Mount` command from CLI.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user