From: beeanyew Date: Sun, 25 Apr 2021 05:48:24 +0000 (+0200) Subject: Add Pi->Amiga file transfer to PiStorm interaction device X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=852bfb6e64da97b3481c3e6f77799522f358e4a8;p=pistorm Add Pi->Amiga file transfer to PiStorm interaction device --- diff --git a/platforms/amiga/pistorm-dev/pistorm-dev-enums.h b/platforms/amiga/pistorm-dev/pistorm-dev-enums.h index 1778674..a67eda4 100644 --- a/platforms/amiga/pistorm-dev/pistorm-dev-enums.h +++ b/platforms/amiga/pistorm-dev/pistorm-dev-enums.h @@ -22,6 +22,10 @@ enum pistorm_dev_cmds { PI_CMD_HWREV = 0x10, // [R] Check the PiStorm hardware version/revision PI_CMD_SWREV = 0x12, // [R] Check the PiStorm software version/revision + PI_CMD_FILESIZE = 0x0100, // [R] Get the file size for file on the Pi side using the path + // at PI_STR1, if it exists. + PI_CMD_TRANSFERFILE = 0x0104, // [W] Transfer over a file from the Pi to Amiga RAM. + PI_CMD_QBASIC = 0x0FFC, // QBasic PI_CMD_NIBBLES = 0x0FFE, // Nibbles @@ -34,7 +38,7 @@ enum pistorm_dev_cmds { PI_DBG_VAL6 = 0x1024, // [RW] PI_DBG_VAL7 = 0x1028, // [RW] PI_DBG_VAL8 = 0x102C, // [RW] - PI_DBG_STR1 = 0x1030, // [W] Pointers to debug strings (typically in "Amiga RAM") + PI_DBG_STR1 = 0x1030, // [W] Pointers to debug strings (typically in Amiga RAM) PI_DBG_STR2 = 0x1034, // [W] PI_DBG_STR3 = 0x1038, // [W] PI_DBG_STR4 = 0x103C, // [W] @@ -58,10 +62,14 @@ enum pistorm_dev_cmds { PI_LONGWORD2 = 0x2014, // [RW] PI_LONGWORD3 = 0x2018, // [RW] PI_LONGWORD4 = 0x201C, // [RW] - PI_STR1 = 0x2020, // [W] Pointers to strings (typically in "Amiga RAM") + PI_STR1 = 0x2020, // [W] Pointers to strings (typically in Amiga RAM) PI_STR2 = 0x2024, // [W] PI_STR3 = 0x2028, // [W] PI_STR4 = 0x202C, // [W] + PI_PTR1 = 0x2030, // [W] Pointers to allocated memory in Amiga RAM. + PI_PTR2 = 0x2034, // [W] For instance for loading large files to Amiga RAM or + PI_PTR3 = 0x2038, // [W] transferring over files from the Pi side of things. + PI_PTR4 = 0x203C, // [W] PI_CMDRESULT = 0x2100, // [R] Check the result of any command that provides a "return value". }; diff --git a/platforms/amiga/pistorm-dev/pistorm-dev.c b/platforms/amiga/pistorm-dev/pistorm-dev.c index 5ca3488..7a16174 100644 --- a/platforms/amiga/pistorm-dev/pistorm-dev.c +++ b/platforms/amiga/pistorm-dev/pistorm-dev.c @@ -47,6 +47,7 @@ static uint8_t pi_byte[8]; static uint16_t pi_word[4]; static uint32_t pi_longword[4]; static uint32_t pi_string[4]; +static uint32_t pi_ptr[4]; static uint32_t pi_dbg_val[4]; static uint32_t pi_dbg_string[4]; @@ -79,6 +80,36 @@ int32_t grab_amiga_string(uint32_t addr, uint8_t *dest, uint32_t str_max_len) { return (int32_t)strlen((const char*)dest); } +int32_t amiga_transfer_file(uint32_t addr, char *filename) { + FILE *in = fopen(filename, "rb"); + if (in == NULL) { + DEBUG("[AMIGA_TRANSFER_FILE] Failed to open file %s for reading.\n", filename); + return -1; + } + fseek(in, 0, SEEK_END); + + int32_t r = get_mapped_item_by_address(cfg, addr); + uint32_t filesize = ftell(in); + + fseek(in, 0, SEEK_SET); + if (r == -1) { + DEBUG("[GRAB_AMIGA_STRING] No mapped range found for address $%.8X. Transferring file data over the bus.\n", addr); + uint8_t tmp_read = 0; + + for (uint32_t i = 0; i < filesize; i++) { + tmp_read = (uint8_t)fgetc(in); + write8(addr + i, tmp_read); + } + } else { + uint8_t *dst = cfg->map_data[r] + (addr - cfg->map_offset[r]); + fread(dst, filesize, 1, in); + } + fclose(in); + DEBUG("[AMIGA_TRANSFER_FILE] Copied %d bytes to address $%.8X.\n", filesize, addr); + + return 0; +} + char *get_pistorm_devcfg_filename() { return cfg_filename; } @@ -121,6 +152,29 @@ void handle_pistorm_dev_write(uint32_t addr_, uint32_t val, uint8_t type) { DEBUG("[PISTORM-DEV] Set STRING POINTER %d to $%.8X\n", (addr - PI_STR1) / 4, val); pi_string[(addr - PI_STR1) / 4] = val; break; + case PI_PTR1: case PI_PTR2: case PI_PTR3: case PI_PTR4: + DEBUG("[PISTORM-DEV] Set DATA POINTER %d to $%.8X\n", (addr - PI_PTR1) / 4, val); + pi_ptr[(addr - PI_PTR1) / 4] = val; + break; + + case PI_CMD_TRANSFERFILE: + DEBUG("[PISTORM-DEV] Write to TRANSFERFILE.\n"); + if (pi_string[0] == 0 || grab_amiga_string(pi_string[0], (uint8_t *)tmp_string, 255) == -1) { + printf("[PISTORM-DEV] No or invalid filename for TRANSFERFILE. Aborting.\n"); + pi_cmd_result = PI_RES_INVALIDVALUE; + } else if (pi_ptr[0] == 0) { + printf("[PISTORM-DEV] Null pointer specified for TRANSFERFILE destination. Aborting.\n"); + pi_cmd_result = PI_RES_INVALIDVALUE; + } else { + if (amiga_transfer_file(pi_ptr[0], tmp_string) == -1) { + pi_cmd_result = PI_RES_FAILED; + } else { + pi_cmd_result = PI_RES_OK; + } + } + pi_string[0] = 0; + pi_ptr[0] = 0; + break; case PI_CMD_RTGSTATUS: DEBUG("[PISTORM-DEV] Write to RTGSTATUS: %d\n", val); @@ -190,11 +244,11 @@ void handle_pistorm_dev_write(uint32_t addr_, uint32_t val, uint8_t type) { } else { FILE *tmp = fopen(tmp_string, "rb"); if (tmp == NULL) { - printf("[PISTORM-DEV] Failed to open file %s for PISCSI drive mapping. Aborting.\n", cfg_filename); + printf("[PISTORM-DEV] Failed to open file %s for PISCSI drive mapping. Aborting.\n", tmp_string); pi_cmd_result = PI_RES_FILENOTFOUND; } else { fclose(tmp); - printf("[PISTORM-DEV] Attempting to map file %s as PISCSI drive %d...\n", cfg_filename, pi_word[0]); + printf("[PISTORM-DEV] Attempting to map file %s as PISCSI drive %d...\n", tmp_string, pi_word[0]); piscsi_unmap_drive(pi_word[0]); piscsi_map_drive(tmp_string, pi_word[0]); pi_cmd_result = PI_RES_OK; @@ -240,7 +294,7 @@ void handle_pistorm_dev_write(uint32_t addr_, uint32_t val, uint8_t type) { } else { FILE *tmp = fopen(tmp_string, "rb"); if (tmp == NULL) { - printf("[PISTORM-DEV] Failed to open file %s for KICKROM mapping. Aborting.\n", cfg_filename); + printf("[PISTORM-DEV] Failed to open file %s for KICKROM mapping. Aborting.\n", tmp_string); pi_cmd_result = PI_RES_FILENOTFOUND; } else { fclose(tmp); @@ -270,7 +324,7 @@ void handle_pistorm_dev_write(uint32_t addr_, uint32_t val, uint8_t type) { } else { FILE *tmp = fopen(tmp_string, "rb"); if (tmp == NULL) { - printf("[PISTORM-DEV] Failed to open file %s for EXTROM mapping. Aborting.\n", cfg_filename); + printf("[PISTORM-DEV] Failed to open file %s for EXTROM mapping. Aborting.\n", tmp_string); pi_cmd_result = PI_RES_FILENOTFOUND; } else { fclose(tmp); @@ -363,6 +417,31 @@ uint32_t handle_pistorm_dev_read(uint32_t addr_, uint8_t type) { uint32_t addr = (addr_ & 0xFFFF); switch((addr)) { + case PI_CMD_FILESIZE: + DEBUG("[PISTORM-DEV] %s read from FILESIZE.\n", op_type_names[type]); + if (pi_string[0] == 0 || grab_amiga_string(pi_string[0], (uint8_t *)tmp_string, 255) == -1) { + DEBUG("[PISTORM-DEV] Failed to grab string for FILESIZE command. Aborting.\n"); + pi_cmd_result = PI_RES_FAILED; + pi_longword[0] = 0; + return 0; + } else { + FILE *tmp = fopen(tmp_string, "rb"); + if (tmp == NULL) { + DEBUG("[PISTORM-DEV] Failed to open file %s for FILESIZE command. Aborting.\n", tmp_string); + pi_longword[0] = 0; + pi_cmd_result = PI_RES_FILENOTFOUND; + } else { + fseek(tmp, 0, SEEK_END); + pi_longword[0] = ftell(tmp); + DEBUG("[PISTORM-DEV] Returning file size for file %s: %d bytes.\n", tmp_string, pi_longword[0]); + fclose(tmp); + pi_cmd_result = PI_RES_OK; + } + } + pi_string[0] = 0; + return pi_longword[0]; + break; + case PI_CMD_HWREV: // Probably replace this with some read from the CPLD to get a simple hardware revision. DEBUG("[PISTORM-DEV] %s Read from HWREV\n", op_type_names[type]); @@ -406,7 +485,7 @@ uint32_t handle_pistorm_dev_read(uint32_t addr_, uint8_t type) { break; case PI_CMDRESULT: - DEBUG("[PISTORM-DEV] %s Read from CMDRESULT\n", op_type_names[type]); + DEBUG("[PISTORM-DEV] %s Read from CMDRESULT: %d\n", op_type_names[type], pi_cmd_result); return pi_cmd_result; break; diff --git a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/PiSimple b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/PiSimple index b4f8d8b..9cc89dc 100644 Binary files a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/PiSimple and b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/PiSimple differ diff --git a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.c b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.c index c5b20f1..8bf004e 100644 --- a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.c +++ b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.c @@ -91,6 +91,22 @@ unsigned short pi_remap_extrom(char *filename) { RETURN_CMDRES; } +// File operation things +unsigned short pi_get_filesize(char *filename, unsigned int *file_size) { + WRITELONG(PI_STR1, (unsigned int)filename); + READLONG(PI_CMD_FILESIZE, *file_size); + + RETURN_CMDRES; +} + +unsigned short pi_transfer_file(char *filename, unsigned char *dest_ptr) { + WRITELONG(PI_STR1, (unsigned int)filename); + WRITELONG(PI_PTR1, (unsigned int)dest_ptr); + WRITESHORT(PI_CMD_TRANSFERFILE, 1); + + RETURN_CMDRES; +} + // PiSCSI stuff // TODO: There's currently no way to read back what drives are mounted at which SCSI index. unsigned short pi_piscsi_map_drive(char *filename, unsigned char index) { diff --git a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.h b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.h index feff2da..6de33b0 100644 --- a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.h +++ b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/pistorm_dev.h @@ -22,6 +22,9 @@ unsigned short pi_piscsi_unmap_drive(unsigned char index); unsigned short pi_piscsi_insert_media(char *filename, unsigned char index); unsigned short pi_piscsi_eject_media(unsigned char index); +unsigned short pi_get_filesize(char *filename, unsigned int *file_size); +unsigned short pi_transfer_file(char *filename, unsigned char *dest_ptr); + unsigned short pi_load_config(char *filename); void pi_reload_config(); void pi_load_default_config(); diff --git a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/simple_interact.c b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/simple_interact.c index eaf2903..b9ea1a9 100644 --- a/platforms/amiga/pistorm-dev/pistorm_dev_amiga/simple_interact.c +++ b/platforms/amiga/pistorm-dev/pistorm_dev_amiga/simple_interact.c @@ -3,6 +3,11 @@ #include "../pistorm-dev-enums.h" #include "pistorm_dev.h" +//#define SHUTUP_VSCODE + +#ifdef SHUTUP_VSCODE +#define __stdargs +#else #include #include #include @@ -23,6 +28,7 @@ #include #include #include +#endif #include #include @@ -31,7 +37,7 @@ #define LOADLIB(a, b) if ((a = (struct a*)OpenLibrary(b,0L))==NULL) { \ printf("Failed to load %s.\n", b); \ return 1; \ - } \ + } void print_usage(char *exe); int get_command(char *cmd); @@ -89,6 +95,37 @@ int __stdargs main (int argc, char *argv[]) { } pi_handle_config(cmd_arg, argv[2]); break; + case PI_CMD_TRANSFERFILE: + if (argc < 4) { + printf ("Please specify a source and destination filename in addition to the command.\n"); + printf ("Example: %s --transfer platforms/platform.h snakes.h\n", argv[0]); + } + if (pi_get_filesize(argv[2], &tmpvalue) == PI_RES_FILENOTFOUND) { + printf ("File %s not found on the Pi side.\n", argv[2]); + } else { + unsigned int filesize = tmpvalue; + unsigned char *dest = malloc(filesize); + + if (dest == NULL) { + printf ("Failed to allocate memory buffer for file. Aborting file transfer.\n"); + } else { + printf ("Found a %d byte file on the Pi side. Eating it.\n", filesize); + if (pi_transfer_file(argv[2], dest) != PI_RES_OK) { + printf ("Something went horribly wrong during the file transfer.\n"); + } else { + FILE *out = fopen(argv[3], "wb+"); + if (out == NULL) { + printf ("Failed to open output file %s for writing.\n", argv[3]); + } else { + fwrite(dest, filesize, 1, out); + fclose(out); + printf ("%d bytes transferred to file %s.\n", filesize, argv[3]); + } + } + free(dest); + } + } + break; default: printf ("Unhandled command %s.\n", argv[1]); return 1; @@ -117,6 +154,9 @@ int get_command(char *cmd) { cmd_arg = PICFG_DEFAULT; return PI_CMD_SWITCHCONFIG; } + if (strcmp(cmd, "--transfer-file") == 0 || strcmp(cmd, "--transfer") == 0 || strcmp(cmd, "--getfile") == 0) { + return PI_CMD_TRANSFERFILE; + } return -1; }