mirror of
https://github.com/captain-amygdala/pistorm.git
synced 2026-01-24 19:21:41 +00:00
[WIP] PiSCSI custom file system experiments
Still not quite working, only FFS working for now.
This commit is contained in:
parent
1baedcea07
commit
24d09251d5
4
.gitignore
vendored
4
.gitignore
vendored
@ -2,6 +2,10 @@
|
||||
*.img
|
||||
*.hdf
|
||||
*.rom
|
||||
*.dll
|
||||
*.bin
|
||||
*.exe
|
||||
*.stackdump
|
||||
!/platforms/amiga/piscsi/*.rom
|
||||
/m68kmake
|
||||
/m68kmake.exe
|
||||
|
||||
@ -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
|
||||
|
||||
13
emulator.c
13
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 {
|
||||
|
||||
@ -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 (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;
|
||||
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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -6,13 +6,21 @@
|
||||
#include <endian.h>
|
||||
#include "hunk-reloc.h"
|
||||
|
||||
#ifdef FAKESTORM
|
||||
#define lseek64 lseek
|
||||
#endif
|
||||
|
||||
#define DEBUG(...)
|
||||
//#define DEBUG printf
|
||||
|
||||
#define BE(val) be32toh(val)
|
||||
#define BE16(val) be16toh(val)
|
||||
|
||||
#define READLW(a, b) fread(&a, 4, 1, b); a = be32toh(a);
|
||||
#define READW(a, b) fread(&a, 2, 1, b); a = be16toh(a);
|
||||
|
||||
uint32_t lw;
|
||||
uint32_t lw = 0;
|
||||
static uint32_t file_offset = 0, add_size = 0;
|
||||
|
||||
char *hunk_id_name(uint32_t index) {
|
||||
switch (index) {
|
||||
@ -70,7 +78,7 @@ int process_hunk(uint32_t index, struct hunk_info *info, FILE *f, struct hunk_re
|
||||
case HUNKTYPE_CODE:
|
||||
DEBUG("Hunk %d: CODE.\n", info->current_hunk);
|
||||
READLW(discard, f);
|
||||
info->hunk_offsets[info->current_hunk] = ftell(f);
|
||||
info->hunk_offsets[info->current_hunk] = ftell(f) - file_offset;
|
||||
DEBUG("Code hunk size: %d (%.8X)\n", discard * 4, discard * 4);
|
||||
fseek(f, discard * 4, SEEK_CUR);
|
||||
return 0;
|
||||
@ -80,7 +88,7 @@ int process_hunk(uint32_t index, struct hunk_info *info, FILE *f, struct hunk_re
|
||||
DEBUG("Processing Reloc32 hunk.\n");
|
||||
do {
|
||||
READLW(discard, f);
|
||||
if (discard) {
|
||||
if (discard && discard != 0xFFFFFFFF) {
|
||||
READLW(cur_hunk, f);
|
||||
DEBUG("Relocating %d offsets pointing to hunk %d.\n", discard, cur_hunk);
|
||||
for(uint32_t i = 0; i < discard; i++) {
|
||||
@ -114,13 +122,14 @@ int process_hunk(uint32_t index, struct hunk_info *info, FILE *f, struct hunk_re
|
||||
case HUNKTYPE_BSS:
|
||||
DEBUG("Hunk %d: BSS.\n", info->current_hunk);
|
||||
READLW(discard, f);
|
||||
info->hunk_offsets[info->current_hunk] = ftell(f);
|
||||
info->hunk_offsets[info->current_hunk] = ftell(f) - file_offset;
|
||||
DEBUG("Skipping BSS hunk. Size: %d\n", discard * 4);
|
||||
add_size += (discard * 4);
|
||||
return 0;
|
||||
case HUNKTYPE_DATA:
|
||||
DEBUG("Hunk %d: DATA.\n", info->current_hunk);
|
||||
READLW(discard, f);
|
||||
info->hunk_offsets[info->current_hunk] = ftell(f);
|
||||
info->hunk_offsets[info->current_hunk] = ftell(f) - file_offset;
|
||||
DEBUG("Skipping data hunk. Size: %d.\n", discard * 4);
|
||||
fseek(f, discard * 4, SEEK_CUR);
|
||||
return 0;
|
||||
@ -148,24 +157,87 @@ void reloc_hunk(struct hunk_reloc *h, uint8_t *buf, struct hunk_info *i) {
|
||||
*src_ptr = htobe32(dst);
|
||||
}
|
||||
|
||||
void process_hunks(FILE *in, struct hunk_info *h_info, struct hunk_reloc *r) {
|
||||
void process_hunks(FILE *in, struct hunk_info *h_info, struct hunk_reloc *r, uint32_t offset) {
|
||||
READLW(lw, in);
|
||||
DEBUG("Hunk ID: %.8X (%s)\n", lw, hunk_id_name(lw));
|
||||
|
||||
while(!feof(in) && process_hunk(lw, h_info, in, r) != -1) {
|
||||
file_offset = offset;
|
||||
add_size = 0;
|
||||
|
||||
while (!feof(in) && process_hunk(lw, h_info, in, r) != -1) {
|
||||
READLW(lw, in);
|
||||
if (feof(in)) goto end_parse;
|
||||
DEBUG("Hunk ID: %.8X (%s)\n", lw, hunk_id_name(lw));
|
||||
DEBUG("File pos: %.8lX\n", ftell(in));
|
||||
DEBUG("File pos: %.8lX\n", ftell(in) - file_offset);
|
||||
}
|
||||
end_parse:;
|
||||
DEBUG("Done processing hunks.\n");
|
||||
}
|
||||
|
||||
void reloc_hunks(struct hunk_reloc *r, uint8_t *buf, struct hunk_info *h_info) {
|
||||
for(uint32_t i = 0; i < h_info->reloc_hunks; i++) {
|
||||
reloc_hunk(&r[i], buf, h_info);
|
||||
DEBUG("Relocating %d offsets.\n", h_info->reloc_hunks);
|
||||
for (uint32_t i = 0; i < h_info->reloc_hunks; i++) {
|
||||
DEBUG("Relocating offset %d.\n", i);
|
||||
reloc_hunk(&r[i], buf, h_info);
|
||||
}
|
||||
DEBUG("Done relocating offsets.\n");
|
||||
}
|
||||
|
||||
struct LoadSegBlock {
|
||||
uint32_t lsb_ID;
|
||||
uint32_t lsb_SummedLongs;
|
||||
int32_t lsb_ChkSum;
|
||||
uint32_t lsb_HostID;
|
||||
uint32_t lsb_Next;
|
||||
uint32_t lsb_LoadData[123]; // Assumes 512 byte blocks
|
||||
};
|
||||
#define LOADSEG_IDENTIFIER 0x4C534547
|
||||
|
||||
int load_lseg(int fd, uint8_t **buf_p, struct hunk_info *i, struct hunk_reloc *relocs) {
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
uint8_t *block = malloc(512);
|
||||
uint32_t next_blk = 0;
|
||||
struct LoadSegBlock *lsb = (struct LoadSegBlock *)block;
|
||||
|
||||
read(fd, block, 512);
|
||||
if (BE(lsb->lsb_ID) != LOADSEG_IDENTIFIER) {
|
||||
DEBUG("[LOAD_LSEG] Attempted to load a non LSEG-block: %.8X", BE(lsb->lsb_ID));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
char *filename = "data/lsegout.bin";
|
||||
FILE *out = fopen(filename, "wb+");
|
||||
|
||||
DEBUG("[LOAD_LSEG] LSEG data:\n");
|
||||
DEBUG("[LOAD_LSEG] Longs: %d HostID: %d\n", BE(lsb->lsb_SummedLongs), BE(lsb->lsb_HostID));
|
||||
DEBUG("[LOAD_LSEG] Next: %d LoadData: %p\n", BE(lsb->lsb_Next), (void *)lsb->lsb_LoadData);
|
||||
next_blk = BE(lsb->lsb_Next);
|
||||
do {
|
||||
next_blk = BE(lsb->lsb_Next);
|
||||
fwrite(lsb->lsb_LoadData, 4, 123, out);
|
||||
lseek64(fd, next_blk * 512, SEEK_SET);
|
||||
read(fd, block, 512);
|
||||
} while (next_blk != 0xFFFFFFFF);
|
||||
|
||||
uint32_t file_size = ftell(out);
|
||||
fseek(out, 0, SEEK_SET);
|
||||
uint8_t *buf = malloc(file_size + 1024);
|
||||
fread(buf, file_size, 1, out);
|
||||
fseek(out, 0, SEEK_SET);
|
||||
process_hunks(out, i, relocs, 0x0);
|
||||
|
||||
fclose(out);
|
||||
*buf_p = buf;
|
||||
i->byte_size = file_size;
|
||||
i->alloc_size = file_size + add_size;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:;
|
||||
if (block)
|
||||
free(block);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
Binary file not shown.
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define BOOTLDR_SIZE 0x400
|
||||
#define BOOTLDR_SIZE 0x1000
|
||||
#define DIAG_TOTAL_SIZE 0x4000
|
||||
|
||||
char *rombuf, *zerobuf, *devicebuf;
|
||||
|
||||
Binary file not shown.
@ -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];
|
||||
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 = scsi->scsi_Command[7];
|
||||
blocks = (blocks << 8) | scsi->scsi_Command[8];
|
||||
break;
|
||||
}
|
||||
blocks = *(uint16_t *)(&scsi->scsi_Command[7]);
|
||||
/*blocks = scsi->scsi_Command[7];
|
||||
blocks = (blocks << 8) | scsi->scsi_Command[8];*/
|
||||
|
||||
WRITESHORT(PISCSI_CMD_DRVNUM, u->unit_num);
|
||||
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:
|
||||
|
||||
@ -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
|
||||
|
||||
@ -5,16 +5,20 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <endian.h>
|
||||
#include "../hunk-reloc.h"
|
||||
#include "piscsi.h"
|
||||
#include "piscsi-enums.h"
|
||||
#include "../hunk-reloc.h"
|
||||
#include "../../../config_file/config_file.h"
|
||||
#include "../../../gpio/ps_protocol.h"
|
||||
|
||||
#define BE(val) be32toh(val)
|
||||
#define BE16(val) be16toh(val)
|
||||
|
||||
// Comment these lines to restore debug output:
|
||||
#define printf(...)
|
||||
#define DEBUG(...)
|
||||
//#define DEBUG printf
|
||||
#define DEBUG_TRIVIAL(...)
|
||||
//#define DEBUG_TRIVIAL printf
|
||||
#define stop_cpu_emulation(...)
|
||||
|
||||
#ifdef FAKESTORM
|
||||
@ -25,6 +29,10 @@ extern struct emulator_config *cfg;
|
||||
extern void stop_cpu_emulation(uint8_t disasm_cur);
|
||||
|
||||
struct piscsi_dev devs[8];
|
||||
struct piscsi_fs filesystems[NUM_FILESYSTEMS];
|
||||
|
||||
uint8_t piscsi_num_fs = 0;
|
||||
|
||||
uint8_t piscsi_cur_drive = 0;
|
||||
uint32_t piscsi_u32[4];
|
||||
uint32_t piscsi_dbg[8];
|
||||
@ -33,7 +41,10 @@ uint8_t *piscsi_rom_ptr;
|
||||
|
||||
uint32_t rom_partitions[128];
|
||||
uint32_t rom_partition_prio[128];
|
||||
uint32_t rom_cur_partition = 0;
|
||||
uint32_t rom_partition_dostype[128];
|
||||
uint32_t rom_cur_partition = 0, rom_cur_fs = 0;
|
||||
|
||||
|
||||
|
||||
extern unsigned char ac_piscsi_rom[];
|
||||
|
||||
@ -58,7 +69,7 @@ void piscsi_init() {
|
||||
|
||||
FILE *in = fopen("./platforms/amiga/piscsi/piscsi.rom", "rb");
|
||||
if (in == NULL) {
|
||||
printf("[PISCSI] Could not open PISCSI Boot ROM file for reading.\n");
|
||||
printf("[PISCSI] Could not open PISCSI Boot ROM file for reading!\n");
|
||||
// Zero out the boot ROM offset from the autoconfig ROM.
|
||||
ac_piscsi_rom[20] = 0;
|
||||
ac_piscsi_rom[21] = 0;
|
||||
@ -71,12 +82,9 @@ void piscsi_init() {
|
||||
fseek(in, 0, SEEK_SET);
|
||||
piscsi_rom_ptr = malloc(piscsi_rom_size);
|
||||
fread(piscsi_rom_ptr, piscsi_rom_size, 1, in);
|
||||
fclose(in);
|
||||
|
||||
// Parse the hunks in the device driver to find relocation offsets
|
||||
in = fopen("./platforms/amiga/piscsi/device_driver_amiga/pi-scsi.device", "rb");
|
||||
fseek(in, 0x0, SEEK_SET);
|
||||
process_hunks(in, &piscsi_hinfo, piscsi_hreloc);
|
||||
fseek(in, PISCSI_DRIVER_OFFSET, SEEK_SET);
|
||||
process_hunks(in, &piscsi_hinfo, piscsi_hreloc, PISCSI_DRIVER_OFFSET);
|
||||
|
||||
fclose(in);
|
||||
printf("[PISCSI] Loaded Boot ROM.\n");
|
||||
@ -95,22 +103,28 @@ void piscsi_find_partitions(struct piscsi_dev *d) {
|
||||
}
|
||||
|
||||
if (!d->rdb || d->rdb->rdb_PartitionList == 0) {
|
||||
printf("[PISCSI] No partitions on disk.\n");
|
||||
DEBUG("[PISCSI] No partitions on disk.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
char *block = malloc(512);
|
||||
|
||||
lseek(fd, be32toh(d->rdb->rdb_PartitionList) * 512, SEEK_SET);
|
||||
lseek(fd, BE(d->rdb->rdb_PartitionList) * 512, SEEK_SET);
|
||||
next_partition:;
|
||||
read(fd, block, 512);
|
||||
|
||||
uint32_t first = be32toh(*((uint32_t *)&block[0]));
|
||||
if (first != PART_IDENTIFIER) {
|
||||
DEBUG("Entry at block %d is not a valid partition. Aborting.\n", BE(d->rdb->rdb_PartitionList));
|
||||
return;
|
||||
}
|
||||
|
||||
struct PartitionBlock *pb = (struct PartitionBlock *)block;
|
||||
tmp = pb->pb_DriveName[0];
|
||||
pb->pb_DriveName[tmp + 1] = 0x00;
|
||||
printf("[PISCSI] Partition %d: %s\n", cur_partition, pb->pb_DriveName + 1);
|
||||
printf("Checksum: %.8X HostID: %d\n", BE(pb->pb_ChkSum), BE(pb->pb_HostID));
|
||||
printf("Flags: %d (%.8X) Devflags: %d (%.8X)\n", BE(pb->pb_Flags), BE(pb->pb_Flags), BE(pb->pb_DevFlags), BE(pb->pb_DevFlags));
|
||||
DEBUG("[PISCSI] Partition %d: %s\n", cur_partition, pb->pb_DriveName + 1);
|
||||
DEBUG("Checksum: %.8X HostID: %d\n", BE(pb->pb_ChkSum), BE(pb->pb_HostID));
|
||||
DEBUG("Flags: %d (%.8X) Devflags: %d (%.8X)\n", BE(pb->pb_Flags), BE(pb->pb_Flags), BE(pb->pb_DevFlags), BE(pb->pb_DevFlags));
|
||||
d->pb[cur_partition] = pb;
|
||||
|
||||
if (d->pb[cur_partition]->pb_Next != 0xFFFFFFFF) {
|
||||
@ -118,11 +132,12 @@ next_partition:;
|
||||
block = malloc(512);
|
||||
lseek64(fd, next * 512, SEEK_SET);
|
||||
cur_partition++;
|
||||
printf("[PISCSI] Next partition at block %d.\n", be32toh(pb->pb_Next));
|
||||
DEBUG("[PISCSI] Next partition at block %d.\n", be32toh(pb->pb_Next));
|
||||
goto next_partition;
|
||||
}
|
||||
printf("[PISCSI] No more partitions on disk.\n");
|
||||
DEBUG("[PISCSI] No more partitions on disk.\n");
|
||||
d->num_partitions = cur_partition + 1;
|
||||
d->fshd_offs = lseek64(fd, 0, SEEK_CUR);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -142,11 +157,14 @@ int piscsi_parse_rdb(struct piscsi_dev *d) {
|
||||
goto no_rdb_found;
|
||||
rdb_found:;
|
||||
struct RigidDiskBlock *rdb = (struct RigidDiskBlock *)block;
|
||||
printf("[PISCSI] RDB found at block %d.\n", i);
|
||||
DEBUG("[PISCSI] RDB found at block %d.\n", i);
|
||||
d->c = be32toh(rdb->rdb_Cylinders);
|
||||
d->h = be32toh(rdb->rdb_Heads);
|
||||
d->s = be32toh(rdb->rdb_Sectors);
|
||||
printf("[PISCSI] RDB - first partition at block %d.\n", be32toh(rdb->rdb_PartitionList));
|
||||
d->num_partitions = 0;
|
||||
DEBUG("[PISCSI] RDB - first partition at block %d.\n", be32toh(rdb->rdb_PartitionList));
|
||||
if (d->rdb)
|
||||
free(d->rdb);
|
||||
d->rdb = rdb;
|
||||
sprintf(d->rdb->rdb_DriveInitName, "pi-scsi.device");
|
||||
return 0;
|
||||
@ -158,6 +176,96 @@ no_rdb_found:;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void piscsi_refresh_drives() {
|
||||
piscsi_num_fs = 0;
|
||||
|
||||
for (int i = 0; i < NUM_FILESYSTEMS; i++) {
|
||||
if (filesystems[i].binary_data) {
|
||||
free(filesystems[i].binary_data);
|
||||
filesystems[i].binary_data = NULL;
|
||||
}
|
||||
if (filesystems[i].fhb) {
|
||||
free(filesystems[i].fhb);
|
||||
filesystems[i].fhb = NULL;
|
||||
}
|
||||
filesystems[i].h_info.current_hunk = 0;
|
||||
filesystems[i].h_info.reloc_hunks = 0;
|
||||
filesystems[i].FS_ID = 0;
|
||||
filesystems[i].handler = 0;
|
||||
}
|
||||
|
||||
rom_cur_fs = 0;
|
||||
|
||||
for (int i = 0; i < NUM_UNITS; i++) {
|
||||
if (devs[i].fd != -1) {
|
||||
piscsi_parse_rdb(&devs[i]);
|
||||
piscsi_find_partitions(&devs[i]);
|
||||
piscsi_find_filesystems(&devs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void piscsi_find_filesystems(struct piscsi_dev *d) {
|
||||
if (!d->num_partitions)
|
||||
return;
|
||||
|
||||
uint8_t fs_found = 0;
|
||||
|
||||
uint8_t *fhb_block = malloc(512);
|
||||
|
||||
lseek64(d->fd, d->fshd_offs, SEEK_SET);
|
||||
|
||||
struct FileSysHeaderBlock *fhb = (struct FileSysHeaderBlock *)fhb_block;
|
||||
read(d->fd, fhb_block, 512);
|
||||
|
||||
while (BE(fhb->fhb_ID) == FS_IDENTIFIER) {
|
||||
char *dosID = (char *)&fhb->fhb_DosType;
|
||||
uint16_t *fsVer = (uint16_t *)&fhb->fhb_Version;
|
||||
|
||||
DEBUG("[FSHD] FSHD Block found.\n");
|
||||
DEBUG("[FSHD] HostID: %d Next: %d Size: %d\n", BE(fhb->fhb_HostID), BE(fhb->fhb_Next), BE(fhb->fhb_SummedLongs));
|
||||
DEBUG("[FSHD] Flags: %.8X DOSType: %c%c%c/%d\n", BE(fhb->fhb_Flags), dosID[0], dosID[1], dosID[2], dosID[3]);
|
||||
DEBUG("[FSHD] Version: %d.%d\n", BE16(fsVer[0]), BE16(fsVer[1]));
|
||||
DEBUG("[FSHD] Patchflags: %d Type: %d\n", BE(fhb->fhb_PatchFlags), BE(fhb->fhb_Type));
|
||||
DEBUG("[FSHD] Task: %d Lock: %d\n", BE(fhb->fhb_Task), BE(fhb->fhb_Lock));
|
||||
DEBUG("[FSHD] Handler: %d StackSize: %d\n", BE(fhb->fhb_Handler), BE(fhb->fhb_StackSize));
|
||||
DEBUG("[FSHD] Prio: %d Startup: %d\n", BE(fhb->fhb_Priority), BE(fhb->fhb_Startup));
|
||||
DEBUG("[FSHD] SegListBlocks: %d GlobalVec: %d\n", BE(fhb->fhb_Priority), BE(fhb->fhb_Startup));
|
||||
DEBUG("[FSHD] FileSysName: %s\n", fhb->fhb_FileSysName + 1);
|
||||
|
||||
for (int i = 0; i < NUM_FILESYSTEMS; i++) {
|
||||
if (filesystems[i].FS_ID == fhb->fhb_DosType) {
|
||||
DEBUG("[FSHD] File system %c%c%c/%d already loaded. Skipping.\n", dosID[0], dosID[1], dosID[2], dosID[3]);
|
||||
if (BE(fhb->fhb_Next) == 0xFFFFFFFF)
|
||||
goto fs_done;
|
||||
|
||||
goto skip_fs_load_lseg;
|
||||
}
|
||||
}
|
||||
|
||||
if (load_lseg(d->fd, &filesystems[piscsi_num_fs].binary_data, &filesystems[piscsi_num_fs].h_info, filesystems[piscsi_num_fs].relocs) != -1) {
|
||||
filesystems[piscsi_num_fs].FS_ID = fhb->fhb_DosType;
|
||||
filesystems[piscsi_num_fs].fhb = fhb;
|
||||
printf("[FSHD] Loaded and set up file system %d: %c%c%c/%d\n", piscsi_num_fs + 1, dosID[0], dosID[1], dosID[2], dosID[3]);
|
||||
piscsi_num_fs++;
|
||||
}
|
||||
|
||||
skip_fs_load_lseg:;
|
||||
fs_found++;
|
||||
lseek64(d->fd, BE(fhb->fhb_Next) * 512, SEEK_SET);
|
||||
fhb_block = malloc(512);
|
||||
fhb = (struct FileSysHeaderBlock *)fhb_block;
|
||||
read(d->fd, fhb_block, 512);
|
||||
}
|
||||
|
||||
if (!fs_found)
|
||||
DEBUG("[!!!FSHD] No file systems found on hard drive!\n");
|
||||
|
||||
fs_done:;
|
||||
if (fhb_block)
|
||||
free(fhb_block);
|
||||
}
|
||||
|
||||
void piscsi_map_drive(char *filename, uint8_t index) {
|
||||
if (index > 7) {
|
||||
printf("[PISCSI] Drive index %d out of range.\nUnable to map file %s to drive.\n", index, filename);
|
||||
@ -179,20 +287,20 @@ void piscsi_map_drive(char *filename, uint8_t index) {
|
||||
printf("[PISCSI] Map %d: [%s] - %llu bytes.\n", index, filename, file_size);
|
||||
|
||||
if (piscsi_parse_rdb(d) == -1) {
|
||||
printf("[PISCSI] No RDB found on disk, making up some CHS values.\n");
|
||||
d->h = 64;
|
||||
DEBUG("[PISCSI] No RDB found on disk, making up some CHS values.\n");
|
||||
d->h = 16;
|
||||
d->s = 63;
|
||||
d->c = (file_size / 512) / (d->s * d->h);
|
||||
}
|
||||
printf("[PISCSI] CHS: %d %d %d\n", d->c, d->h, d->s);
|
||||
|
||||
piscsi_find_partitions(d);
|
||||
//stop_cpu_emulation(1);
|
||||
piscsi_find_filesystems(d);
|
||||
}
|
||||
|
||||
void piscsi_unmap_drive(uint8_t index) {
|
||||
if (devs[index].fd != -1) {
|
||||
printf("[PISCSI] Unmapped drive %d.\n", index);
|
||||
DEBUG("[PISCSI] Unmapped drive %d.\n", index);
|
||||
close (devs[index].fd);
|
||||
devs[index].fd = -1;
|
||||
}
|
||||
@ -233,65 +341,129 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -47,15 +47,16 @@
|
||||
#define NSCMD_TD_FORMAT64 0xC003
|
||||
|
||||
#define RDB_BLOCK_LIMIT 16
|
||||
|
||||
// RDSK
|
||||
#define RDB_IDENTIFIER 0x5244534B
|
||||
// PART
|
||||
#define PART_IDENTIFIER 0x50415254
|
||||
// FSHD
|
||||
#define FS_IDENTIFIER 0x46534844
|
||||
|
||||
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_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();
|
||||
|
||||
Binary file not shown.
@ -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
|
||||
# If you for instance want to mount a FAT32 disk with fat95, these old instructions may be of some use:
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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; \
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user