mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 01:25:33 -07:00
Merge pull request #6801 from jriwanek-forks/ls120
Bring jriwanek LS-120 work
This commit is contained in:
@@ -91,6 +91,7 @@
|
||||
#include <86box/cdrom.h>
|
||||
#include <86box/cdrom_interface.h>
|
||||
#include <86box/rdisk.h>
|
||||
#include <86box/superdisk.h>
|
||||
#include <86box/mo.h>
|
||||
#include <86box/scsi_disk.h>
|
||||
#include <86box/cdrom_image.h>
|
||||
@@ -1292,6 +1293,7 @@ usage:
|
||||
mouse_init();
|
||||
cdrom_global_init();
|
||||
rdisk_global_init();
|
||||
superdisk_global_init();
|
||||
mo_global_init();
|
||||
|
||||
/* Initialize the keyboard accelerator list with default values */
|
||||
@@ -1651,6 +1653,8 @@ pc_reset_hard_close(void)
|
||||
|
||||
rdisk_close();
|
||||
|
||||
superdisk_close();
|
||||
|
||||
mo_close();
|
||||
|
||||
scsi_disk_close();
|
||||
@@ -1767,7 +1771,7 @@ pc_reset_hard_init(void)
|
||||
mo_hard_reset();
|
||||
|
||||
rdisk_hard_reset();
|
||||
|
||||
superdisk_hard_reset();
|
||||
|
||||
/* Reset any ISA ROM cards. */
|
||||
isarom_reset();
|
||||
@@ -1937,6 +1941,8 @@ pc_close(UNUSED(thread_t *ptr))
|
||||
|
||||
rdisk_close();
|
||||
|
||||
superdisk_close();
|
||||
|
||||
mo_close();
|
||||
|
||||
scsi_disk_close();
|
||||
|
||||
@@ -127,6 +127,7 @@ target_link_libraries(86Box
|
||||
game
|
||||
cdrom
|
||||
rdisk
|
||||
superdisk
|
||||
mo
|
||||
hdd
|
||||
net
|
||||
|
||||
157
src/config.c
157
src/config.c
@@ -74,6 +74,7 @@
|
||||
#include <86box/cdrom.h>
|
||||
#include <86box/cdrom_interface.h>
|
||||
#include <86box/rdisk.h>
|
||||
#include <86box/superdisk.h>
|
||||
#include <86box/mo.h>
|
||||
#include <86box/sound.h>
|
||||
#include <86box/midi.h>
|
||||
@@ -1956,6 +1957,118 @@ load_other_removable_devices(void)
|
||||
}
|
||||
|
||||
go_to_mo:
|
||||
memset(temp, 0x00, sizeof(temp));
|
||||
for (c = 0; c < SUPERDISK_NUM; c++) {
|
||||
sprintf(temp, "superdisk_%02i_parameters", c + 1);
|
||||
p = ini_section_get_string(cat, temp, NULL);
|
||||
if (p != NULL)
|
||||
sscanf(p, "%01u, %s", &superdisk_drives[c].is_240, s);
|
||||
else
|
||||
sscanf("0, none", "%01u, %s", &superdisk_drives[c].is_240, s);
|
||||
superdisk_drives[c].bus_type = hdd_string_to_bus(s, 1);
|
||||
|
||||
/* Default values, needed for proper operation of the Settings dialog. */
|
||||
superdisk_drives[c].ide_channel = superdisk_drives[c].scsi_device_id = c + 2;
|
||||
|
||||
if (superdisk_drives[c].bus_type == SUPERDISK_BUS_ATAPI) {
|
||||
sprintf(temp, "superdisk_%02i_ide_channel", c + 1);
|
||||
sprintf(tmp2, "%01u:%01u", (c + 2) >> 1, (c + 2) & 1);
|
||||
p = ini_section_get_string(cat, temp, tmp2);
|
||||
sscanf(p, "%01u:%01u", &board, &dev);
|
||||
board &= 3;
|
||||
dev &= 1;
|
||||
superdisk_drives[c].ide_channel = (board << 1) + dev;
|
||||
|
||||
if (superdisk_drives[c].ide_channel > 7)
|
||||
superdisk_drives[c].ide_channel = 7;
|
||||
} else if (superdisk_drives[c].bus_type == SUPERDISK_BUS_SCSI) {
|
||||
sprintf(temp, "superdisk_%02i_scsi_location", c + 1);
|
||||
sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c + 2);
|
||||
p = ini_section_get_string(cat, temp, tmp2);
|
||||
sscanf(p, "%01u:%02u", &board, &dev);
|
||||
if (board >= SCSI_BUS_MAX) {
|
||||
/* Invalid bus - check legacy ID */
|
||||
sprintf(temp, "superdisk_%02i_scsi_id", c + 1);
|
||||
superdisk_drives[c].scsi_device_id = ini_section_get_int(cat, temp, c + 2);
|
||||
|
||||
if (superdisk_drives[c].scsi_device_id > 15)
|
||||
superdisk_drives[c].scsi_device_id = 15;
|
||||
} else {
|
||||
board %= SCSI_BUS_MAX;
|
||||
dev &= 15;
|
||||
superdisk_drives[c].scsi_device_id = (board << 4) + dev;
|
||||
}
|
||||
}
|
||||
|
||||
if (superdisk_drives[c].bus_type != SUPERDISK_BUS_ATAPI) {
|
||||
sprintf(temp, "superdisk_%02i_ide_channel", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
}
|
||||
|
||||
if (superdisk_drives[c].bus_type != SUPERDISK_BUS_SCSI) {
|
||||
sprintf(temp, "superdisk_%02i_scsi_location", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
}
|
||||
|
||||
sprintf(temp, "superdisk_%02i_scsi_id", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
|
||||
sprintf(temp, "superdisk_%02i_image_path", c + 1);
|
||||
p = ini_section_get_string(cat, temp, "");
|
||||
|
||||
if (!strcmp(p, usr_path))
|
||||
p[0] = 0x00;
|
||||
|
||||
if (p[0] != 0x00) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 511)
|
||||
fatal("Configuration: Length of superdisk_%02i_image_path is more than 511\n", c + 1);
|
||||
else
|
||||
strncpy(superdisk_drives[c].image_path, p, 511);
|
||||
} else
|
||||
path_append_filename(superdisk_drives[c].image_path, usr_path, p);
|
||||
path_normalize(superdisk_drives[c].image_path);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
|
||||
superdisk_drives[c].image_history[i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char));
|
||||
sprintf(temp, "superdisk_%02i_image_history_%02i", c + 1, i + 1);
|
||||
p = ini_section_get_string(cat, temp, NULL);
|
||||
if (p) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
|
||||
fatal("Configuration: Length of superdisk_%02i_image_history_%02i is more than %i\n",
|
||||
c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1);
|
||||
else
|
||||
snprintf(superdisk_drives[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s", p);
|
||||
} else
|
||||
snprintf(superdisk_drives[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s%s%s", usr_path,
|
||||
path_get_slash(usr_path), p);
|
||||
path_normalize(superdisk_drives[c].image_history[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the SuperDisk drive is disabled, delete all its variables. */
|
||||
if (superdisk_drives[c].bus_type == SUPERDISK_BUS_DISABLED) {
|
||||
sprintf(temp, "superdisk_%02i_parameters", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
|
||||
sprintf(temp, "superdisk_%02i_ide_channel", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
|
||||
sprintf(temp, "superdisk_%02i_scsi_location", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
|
||||
sprintf(temp, "superdisk_%02i_image_path", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
|
||||
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
|
||||
sprintf(temp, "superdisk_%02i_image_history_%02i", c + 1, i + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset(temp, 0x00, sizeof(temp));
|
||||
for (c = 0; c < MO_NUM; c++) {
|
||||
sprintf(temp, "mo_%02i_parameters", c + 1);
|
||||
@@ -2231,6 +2344,7 @@ config_load(void)
|
||||
memset(cdrom_ioctl, 0, sizeof(cdrom_ioctl_t) * CDROM_NUM);
|
||||
#endif
|
||||
memset(rdisk_drives, 0, sizeof(rdisk_drive_t));
|
||||
memset(superdisk_drives, 0, sizeof(superdisk_drive_t));
|
||||
|
||||
for (int i = 0; i < 768; i++)
|
||||
scancode_config_map[i] = i;
|
||||
@@ -3720,6 +3834,49 @@ save_other_removable_devices(void)
|
||||
}
|
||||
}
|
||||
|
||||
for (c = 0; c < SUPERDISK_NUM; c++) {
|
||||
sprintf(temp, "superdisk_%02i_parameters", c + 1);
|
||||
if (superdisk_drives[c].bus_type == 0) {
|
||||
ini_section_delete_var(cat, temp);
|
||||
} else {
|
||||
sprintf(tmp2, "%u, %s", superdisk_drives[c].is_240,
|
||||
hdd_bus_to_string(superdisk_drives[c].bus_type, 1));
|
||||
ini_section_set_string(cat, temp, tmp2);
|
||||
}
|
||||
|
||||
sprintf(temp, "superdisk_%02i_ide_channel", c + 1);
|
||||
if (superdisk_drives[c].bus_type != SUPERDISK_BUS_ATAPI)
|
||||
ini_section_delete_var(cat, temp);
|
||||
else {
|
||||
sprintf(tmp2, "%01u:%01u", superdisk_drives[c].ide_channel >> 1,
|
||||
superdisk_drives[c].ide_channel & 1);
|
||||
ini_section_set_string(cat, temp, tmp2);
|
||||
}
|
||||
|
||||
sprintf(temp, "superdisk_%02i_scsi_id", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
|
||||
sprintf(temp, "superdisk_%02i_scsi_location", c + 1);
|
||||
if (superdisk_drives[c].bus_type != SUPERDISK_BUS_SCSI)
|
||||
ini_section_delete_var(cat, temp);
|
||||
else {
|
||||
sprintf(tmp2, "%01u:%02u", superdisk_drives[c].scsi_device_id >> 4,
|
||||
superdisk_drives[c].scsi_device_id & 15);
|
||||
ini_section_set_string(cat, temp, tmp2);
|
||||
}
|
||||
|
||||
sprintf(temp, "superdisk_%02i_image_path", c + 1);
|
||||
if ((superdisk_drives[c].bus_type == 0) || (strlen(superdisk_drives[c].image_path) == 0))
|
||||
ini_section_delete_var(cat, temp);
|
||||
else {
|
||||
path_normalize(superdisk_drives[c].image_path);
|
||||
if (!strnicmp(superdisk_drives[c].image_path, usr_path, strlen(usr_path)))
|
||||
ini_section_set_string(cat, temp, &superdisk_drives[c].image_path[strlen(usr_path)]);
|
||||
else
|
||||
ini_section_set_string(cat, temp, superdisk_drives[c].image_path);
|
||||
}
|
||||
}
|
||||
|
||||
for (c = 0; c < MO_NUM; c++) {
|
||||
sprintf(temp, "mo_%02i_parameters", c + 1);
|
||||
if (mo_drives[c].bus_type == 0) {
|
||||
|
||||
@@ -43,5 +43,7 @@ add_library(rdisk OBJECT rdisk.c)
|
||||
|
||||
add_library(mo OBJECT mo.c)
|
||||
|
||||
add_library(superdisk OBJECT superdisk.c)
|
||||
|
||||
add_subdirectory(minivhd)
|
||||
target_link_libraries(86Box minivhd)
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/rdisk.h>
|
||||
#include <86box/superdisk.h>
|
||||
#include <86box/mo.h>
|
||||
|
||||
typedef struct cmd640_t {
|
||||
@@ -418,11 +419,19 @@ cmd640_reset(void *priv)
|
||||
(cdrom[i].ide_channel <= max_channel) && cdrom[i].priv)
|
||||
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
|
||||
}
|
||||
|
||||
for (i = 0; i < RDISK_NUM; i++) {
|
||||
if ((rdisk_drives[i].bus_type == RDISK_BUS_ATAPI) && (rdisk_drives[i].ide_channel >= min_channel) &&
|
||||
(rdisk_drives[i].ide_channel <= max_channel) && rdisk_drives[i].priv)
|
||||
rdisk_reset((scsi_common_t *) rdisk_drives[i].priv);
|
||||
}
|
||||
|
||||
for (i = 0; i < SUPERDISK_NUM; i++) {
|
||||
if ((superdisk_drives[i].bus_type == SUPERDISK_BUS_ATAPI) && (superdisk_drives[i].ide_channel >= min_channel) &&
|
||||
(superdisk_drives[i].ide_channel <= max_channel) && superdisk_drives[i].priv)
|
||||
superdisk_reset((scsi_common_t *) superdisk_drives[i].priv);
|
||||
}
|
||||
|
||||
for (i = 0; i < MO_NUM; i++) {
|
||||
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel >= min_channel) &&
|
||||
(mo_drives[i].ide_channel <= max_channel) && mo_drives[i].priv)
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/rdisk.h>
|
||||
#include <86box/superdisk.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/scsi_disk.h>
|
||||
@@ -542,10 +543,17 @@ cmd646_reset(void *priv)
|
||||
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && check_ch(dev, cdrom[i].ide_channel) && cdrom[i].priv)
|
||||
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
|
||||
}
|
||||
|
||||
for (i = 0; i < RDISK_NUM; i++) {
|
||||
if ((rdisk_drives[i].bus_type == RDISK_BUS_ATAPI) && check_ch(dev, rdisk_drives[i].ide_channel) && rdisk_drives[i].priv)
|
||||
rdisk_reset((scsi_common_t *) rdisk_drives[i].priv);
|
||||
}
|
||||
|
||||
for (i = 0; i < SUPERDISK_NUM; i++) {
|
||||
if ((superdisk_drives[i].bus_type == SUPERDISK_BUS_ATAPI) && (superdisk_drives[i].ide_channel < 4) && superdisk_drives[i].priv)
|
||||
superdisk_reset((scsi_common_t *) superdisk_drives[i].priv);
|
||||
}
|
||||
|
||||
for (i = 0; i < MO_NUM; i++) {
|
||||
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && check_ch(dev, mo_drives[i].ide_channel) && mo_drives[i].priv)
|
||||
mo_reset((scsi_common_t *) mo_drives[i].priv);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/rdisk.h>
|
||||
#include <86box/superdisk.h>
|
||||
#include <86box/mo.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
@@ -488,6 +489,7 @@ sff_reset(void *priv)
|
||||
if ((hdd[i].bus_type == HDD_BUS_ATAPI) && (hdd[i].ide_channel < 4) && hdd[i].priv)
|
||||
scsi_disk_reset((scsi_common_t *) hdd[i].priv);
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < CDROM_NUM; i++) {
|
||||
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) &&
|
||||
cdrom[i].priv)
|
||||
@@ -498,6 +500,12 @@ sff_reset(void *priv)
|
||||
rdisk_drives[i].priv)
|
||||
rdisk_reset((scsi_common_t *) rdisk_drives[i].priv);
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < SUPERDISK_NUM; i++) {
|
||||
if ((superdisk_drives[i].bus_type == SUPERDISK_BUS_ATAPI) && (superdisk_drives[i].ide_channel < 4) && superdisk_drives[i].priv)
|
||||
superdisk_reset((scsi_common_t *) superdisk_drives[i].priv);
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < MO_NUM; i++) {
|
||||
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) &&
|
||||
mo_drives[i].priv)
|
||||
|
||||
@@ -172,7 +172,7 @@ rdisk_load_abort(const rdisk_t *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
image_is_zdi(const char *s)
|
||||
{
|
||||
return !strcasecmp(path_get_extension((char *) s), "ZDI");
|
||||
|
||||
2334
src/disk/superdisk.c
Normal file
2334
src/disk/superdisk.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -35,7 +35,7 @@ typedef struct disk_size_t {
|
||||
int root_dir_entries;
|
||||
} disk_size_t;
|
||||
|
||||
static const disk_size_t disk_sizes[14] = {
|
||||
static const disk_size_t disk_sizes[16] = {
|
||||
// clang-format off
|
||||
#if 0
|
||||
{ 1, 1, 2, 1, 1, 77, 26, 0, 0, 4, 2, 6, 68 }, /* 250k 8" */
|
||||
@@ -57,10 +57,8 @@ static const disk_size_t disk_sizes[14] = {
|
||||
{ 2, 2, 3, 1, 0, 80, 36, 2, 0xf0, 2, 2, 9, 240 }, /* 2.88M */
|
||||
{ 0, 64, 0, 0, 0, 96, 32, 2, 0, 0, 0, 0, 0 }, /* ZIP 100 */
|
||||
{ 0, 64, 0, 0, 0, 239, 32, 2, 0, 0, 0, 0, 0 }, /* ZIP 250 */
|
||||
#if 0
|
||||
{ 0, 8, 0, 0, 0, 963, 32, 2, 0, 0, 0, 0, 0 }, /* LS-120 */
|
||||
{ 0, 32, 0, 0, 0, 262, 56, 2, 0, 0, 0, 0, 0 } /* LS-240 */
|
||||
#endif
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ typedef struct machine_status_t {
|
||||
dev_status_empty_active_t fdd[FDD_NUM];
|
||||
dev_status_empty_active_t cdrom[CDROM_NUM];
|
||||
dev_status_empty_active_t rdisk[RDISK_NUM];
|
||||
dev_status_empty_active_t superdisk[SUPERDISK_NUM];
|
||||
dev_status_empty_active_t mo[MO_NUM];
|
||||
dev_status_empty_active_t cassette;
|
||||
dev_status_active_t hdd[HDD_BUS_USB];
|
||||
|
||||
@@ -183,6 +183,9 @@ extern void rdisk_reload(uint8_t id);
|
||||
extern void mo_eject(uint8_t id);
|
||||
extern void mo_mount(uint8_t id, char *fn, uint8_t wp);
|
||||
extern void mo_reload(uint8_t id);
|
||||
extern void superdisk_eject(uint8_t id);
|
||||
extern void superdisk_mount(uint8_t id, char *fn, uint8_t wp);
|
||||
extern void superdisk_reload(uint8_t id);
|
||||
|
||||
/* Other stuff. */
|
||||
extern void startblit(void);
|
||||
|
||||
@@ -46,11 +46,14 @@
|
||||
#define GPCMD_REQUEST_SENSE 0x03
|
||||
#define GPCMD_FORMAT_UNIT 0x04
|
||||
#define GPCMD_IOMEGA_SENSE 0x06
|
||||
#define GPCMD_IMATION_SENSE 0x06
|
||||
#define GPCMD_READ_6 0x08
|
||||
#define GPCMD_WRITE_6 0x0a
|
||||
#define GPCMD_SEEK_6 0x0b
|
||||
#define GPCMD_IOMEGA_SET_PROTECTION_MODE 0x0c
|
||||
#define GPCMD_IMATION_SET_PROTECTION_MODE 0x0c
|
||||
#define GPCMD_IOMEGA_EJECT 0x0d /* ATAPI only? */
|
||||
#define GPCMD_IMATION_EJECT 0x0d /* ATAPI only? */
|
||||
#define GPCMD_NO_OPERATION_TOSHIBA 0x0d /* Toshiba Vendor Unique command. */
|
||||
#define GPCMD_NO_OPERATION_NEC 0x0d /* NEC Vendor Unique command. */
|
||||
#define GPCMD_INQUIRY 0x12
|
||||
@@ -160,21 +163,23 @@
|
||||
#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA 0xe9 /* Matsushita Vendor Unique command */
|
||||
|
||||
/* Mode page codes for mode sense/set */
|
||||
#define GPMODE_UNIT_ATN_PAGE 0x00
|
||||
#define GPMODE_R_W_ERROR_PAGE 0x01
|
||||
#define GPMODE_UNIT_ATN_PAGE 0x00 /* Unit Attention page */
|
||||
#define GPMODE_R_W_ERROR_PAGE 0x01 /* Read-Write Error Recovery page */
|
||||
#define GPMODE_DISCONNECT_PAGE 0x02 /* Disconnect/reconnect page */
|
||||
#define GPMODE_FORMAT_DEVICE_PAGE 0x03
|
||||
#define GPMODE_FORMAT_DEVICE_PAGE 0x03 /* Format device page */
|
||||
#define GPMODE_RIGID_DISK_PAGE 0x04 /* Rigid disk geometry page */
|
||||
#define GPMODE_FLEXIBLE_DISK_PAGE 0x05
|
||||
#define GPMODE_CACHING_PAGE 0x08
|
||||
#define GPMODE_CDROM_PAGE_SONY 0x08
|
||||
#define GPMODE_CDROM_AUDIO_PAGE_SONY 0x09
|
||||
#define GPMODE_CDROM_PAGE 0x0d
|
||||
#define GPMODE_CDROM_AUDIO_PAGE 0x0e
|
||||
#define GPMODE_CAPABILITIES_PAGE 0x2a
|
||||
#define GPMODE_IOMEGA_PAGE 0x2f
|
||||
#define GPMODE_UNK_VENDOR_PAGE 0x30
|
||||
#define GPMODE_ALL_PAGES 0x3f
|
||||
#define GPMODE_FLEXIBLE_DISK_PAGE 0x05 /* Flexible disk page */
|
||||
#define GPMODE_CACHING_PAGE 0x08 /* Caching page */
|
||||
#define GPMODE_CDROM_PAGE_SONY 0x08 /* Sony-specific CD-ROM page */
|
||||
#define GPMODE_CDROM_AUDIO_PAGE_SONY 0x09 /* Sony-specific CD-ROM audio page */
|
||||
#define GPMODE_MEDIUM_TYPES_PAGE 0x0b /* Medium types supported page */
|
||||
#define GPMODE_CDROM_PAGE 0x0d /* General CD-ROM page */
|
||||
#define GPMODE_CDROM_AUDIO_PAGE 0x0e /* General CD-ROM audio page */
|
||||
#define GPMODE_REMOVABLE_BLOCK_ACCESS_PAGE 0x1b /* Removable block access capabilities page */
|
||||
#define GPMODE_CAPABILITIES_PAGE 0x2a /* Capabilities page */
|
||||
#define GPMODE_IOMEGA_PAGE 0x2f /* Iomega-specific page */
|
||||
#define GPMODE_UNK_VENDOR_PAGE 0x30 /* Unknown vendor-specific page */
|
||||
#define GPMODE_ALL_PAGES 0x3f /* All pages supported */
|
||||
|
||||
/* Mode page codes for presence */
|
||||
#define GPMODEP_UNIT_ATN_PAGE 0x0000000000000001LL
|
||||
|
||||
148
src/include/86box/superdisk.h
Normal file
148
src/include/86box/superdisk.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the Imation SuperDisk drive with SCSI(-like)
|
||||
* commands, for both ATAPI and SCSI usage.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Jasmine Iwanek, <jriwanek@gmail.com>
|
||||
*
|
||||
* Copyright 2018-2025 Miran Grca.
|
||||
* Copyright 2022-2025 Jasmine Iwanek.
|
||||
*/
|
||||
|
||||
#ifndef EMU_SUPERDISK_H
|
||||
#define EMU_SUPERDISK_H
|
||||
|
||||
#define SUPERDISK_NUM 4
|
||||
|
||||
#define BUF_SIZE 32768
|
||||
|
||||
#define SUPERDISK_TIME 10.0
|
||||
|
||||
#define SUPERDISK_SECTORS (963 * 256)
|
||||
|
||||
#define SUPERDISK_240_SECTORS (469504)
|
||||
|
||||
#define SUPERDISK_IMAGE_HISTORY 10
|
||||
|
||||
enum {
|
||||
SUPERDISK_BUS_DISABLED = 0,
|
||||
SUPERDISK_BUS_ATAPI = 5,
|
||||
SUPERDISK_BUS_SCSI = 6,
|
||||
SUPERDISK_BUS_USB = 7
|
||||
};
|
||||
|
||||
typedef struct superdisk_drive_t {
|
||||
uint8_t id;
|
||||
|
||||
union {
|
||||
uint8_t res;
|
||||
/* Reserved for other ID's. */
|
||||
uint8_t res0;
|
||||
uint8_t res1;
|
||||
uint8_t ide_channel;
|
||||
uint8_t scsi_device_id;
|
||||
};
|
||||
|
||||
uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */
|
||||
uint8_t bus_mode; /* Bit 0 = PIO suported;
|
||||
Bit 1 = DMA supportd. */
|
||||
uint8_t read_only; /* Struct variable reserved for
|
||||
media status. */
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
|
||||
FILE *fp;
|
||||
void *priv;
|
||||
|
||||
char image_path[1024];
|
||||
char prev_image_path[1024];
|
||||
|
||||
char *image_history[SUPERDISK_IMAGE_HISTORY];
|
||||
|
||||
uint32_t is_240;
|
||||
uint32_t medium_size;
|
||||
uint32_t base;
|
||||
} superdisk_drive_t;
|
||||
|
||||
typedef struct superdisk_t {
|
||||
mode_sense_pages_t ms_pages_saved;
|
||||
|
||||
superdisk_drive_t *drv;
|
||||
#ifdef EMU_IDE_H
|
||||
ide_tf_t *tf;
|
||||
#else
|
||||
void *tf;
|
||||
#endif
|
||||
|
||||
uint8_t *buffer;
|
||||
uint8_t atapi_cdb[16];
|
||||
uint8_t current_cdb[16];
|
||||
uint8_t sense[256];
|
||||
|
||||
uint8_t id;
|
||||
uint8_t cur_lun;
|
||||
uint8_t pad0;
|
||||
uint8_t pad1;
|
||||
|
||||
uint16_t max_transfer_len;
|
||||
uint16_t pad2;
|
||||
|
||||
int requested_blocks;
|
||||
int packet_status;
|
||||
int total_length;
|
||||
int do_page_save;
|
||||
int unit_attention;
|
||||
int request_pos;
|
||||
int old_len;
|
||||
int transition;
|
||||
|
||||
uint32_t sector_pos;
|
||||
uint32_t sector_len;
|
||||
uint32_t packet_len;
|
||||
|
||||
double callback;
|
||||
|
||||
uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen);
|
||||
} superdisk_t;
|
||||
|
||||
extern superdisk_t *superdisk[SUPERDISK_NUM];
|
||||
extern superdisk_drive_t superdisk_drives[SUPERDISK_NUM];
|
||||
extern uint8_t atapi_superdisk_drives[8];
|
||||
extern uint8_t scsi_superdisk_drives[16];
|
||||
|
||||
#define superdisk_sense_error dev->sense[0]
|
||||
#define superdisk_sense_key dev->sense[2]
|
||||
#define superdisk_info *(uint32_t *) &(dev->sense[3])
|
||||
#define superdisk_asc dev->sense[12]
|
||||
#define superdisk_ascq dev->sense[13]
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void superdisk_disk_close(const superdisk_t *dev);
|
||||
extern void superdisk_disk_reload(const superdisk_t *dev);
|
||||
extern void superdisk_insert(superdisk_t *dev);
|
||||
|
||||
extern void superdisk_global_init(void);
|
||||
extern void superdisk_hard_reset(void);
|
||||
|
||||
extern void superdisk_reset(scsi_common_t *sc);
|
||||
extern int superdisk_is_empty(const uint8_t id);
|
||||
extern void superdisk_load(const superdisk_t *dev, const char *fn, const int skip_insert);
|
||||
extern void superdisk_close(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*EMU_SUPERDISK_H*/
|
||||
@@ -49,10 +49,11 @@ extern int ui_msgbox_header(int flags, void *header, void *message);
|
||||
#define SB_CDROM 0x30
|
||||
#define SB_RDISK 0x40
|
||||
#define SB_MO 0x50
|
||||
#define SB_HDD 0x60
|
||||
#define SB_NETWORK 0x70
|
||||
#define SB_SOUND 0x80
|
||||
#define SB_TEXT 0x90
|
||||
#define SB_SUPERDISK 0x60
|
||||
#define SB_HDD 0x70
|
||||
#define SB_NETWORK 0x80
|
||||
#define SB_SOUND 0x90
|
||||
#define SB_TEXT 0x100
|
||||
|
||||
extern wchar_t *ui_window_title(wchar_t *s);
|
||||
extern void ui_hard_reset_completed(void);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <86box/cassette.h>
|
||||
#include <86box/cdrom.h>
|
||||
#include <86box/rdisk.h>
|
||||
#include <86box/superdisk.h>
|
||||
#include <86box/mo.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/thread.h>
|
||||
@@ -32,14 +33,22 @@ machine_status_init(void)
|
||||
machine_status.fdd[i].empty = (strlen(floppyfns[i]) == 0);
|
||||
machine_status.fdd[i].active = false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < CDROM_NUM; ++i) {
|
||||
machine_status.cdrom[i].empty = (strlen(cdrom[i].image_path) == 0);
|
||||
machine_status.cdrom[i].active = false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < RDISK_NUM; i++) {
|
||||
machine_status.rdisk[i].empty = (strlen(rdisk_drives[i].image_path) == 0);
|
||||
machine_status.rdisk[i].active = false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < SUPERDISK_NUM; i++) {
|
||||
machine_status.superdisk[i].empty = (strlen(superdisk_drives[i].image_path) == 0);
|
||||
machine_status.superdisk[i].active = false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < MO_NUM; i++) {
|
||||
machine_status.mo[i].empty = (strlen(mo_drives[i].image_path) == 0);
|
||||
machine_status.mo[i].active = false;
|
||||
|
||||
BIN
src/qt/icons/superdisk_active.ico
Normal file
BIN
src/qt/icons/superdisk_active.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
BIN
src/qt/icons/superdisk_empty.ico
Normal file
BIN
src/qt/icons/superdisk_empty.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
BIN
src/qt/icons/superdisk_empty_active.ico
Normal file
BIN
src/qt/icons/superdisk_empty_active.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
@@ -648,6 +648,12 @@ msgstr "Unitats de disc extraïble:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "ISA RTC:"
|
||||
|
||||
|
||||
@@ -648,6 +648,12 @@ msgstr "Mechaniky vyměnitelných disků:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "ISA hodiny:"
|
||||
|
||||
|
||||
@@ -648,6 +648,12 @@ msgstr "Wechseldatenträger:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "ISA-Echtzeituhr:"
|
||||
|
||||
|
||||
@@ -648,6 +648,12 @@ msgstr "Unidades de disco removible:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "ISA RTC:"
|
||||
|
||||
|
||||
@@ -648,6 +648,12 @@ msgstr "Irrotettavat levyasemat:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "ISA-RTC (kello):"
|
||||
|
||||
|
||||
@@ -648,6 +648,12 @@ msgstr "Lecteurs de disques amovibles :"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "Horloge temps réel ISA :"
|
||||
|
||||
|
||||
@@ -650,6 +650,12 @@ msgstr "Pogoni izmjenjivih diskova:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "Sat stvarnog vremena (RTC):"
|
||||
|
||||
|
||||
@@ -648,6 +648,12 @@ msgstr "Unità disco rimovibili:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "RTC ISA:"
|
||||
|
||||
|
||||
@@ -649,6 +649,12 @@ msgstr "取り外し可能なディスクドライブ:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "ISA RTCカード:"
|
||||
|
||||
|
||||
@@ -648,6 +648,12 @@ msgstr "제거 가능한 디스크 드라이브:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "ISA RTC 카드:"
|
||||
|
||||
|
||||
@@ -649,6 +649,12 @@ msgstr "Stacje dysków wymiennych:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "ISA RTC:"
|
||||
|
||||
|
||||
@@ -642,6 +642,12 @@ msgstr "Unidades de disco removível:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "RTC ISA:"
|
||||
|
||||
|
||||
@@ -649,6 +649,12 @@ msgstr "Unidades de disco amovível:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "ISA RTC:"
|
||||
|
||||
|
||||
@@ -649,6 +649,12 @@ msgstr "Дисководы съёмных дисков:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "ISA RTC:"
|
||||
|
||||
|
||||
@@ -648,6 +648,12 @@ msgstr "Mechaniky vymeniteľných diskov:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "ISA hodiny:"
|
||||
|
||||
|
||||
@@ -650,6 +650,12 @@ msgstr "Odstranljivi diskovni pogoni:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "Ura realnega časa ISA:"
|
||||
|
||||
|
||||
@@ -648,6 +648,12 @@ msgstr "Çıkarılabilir disk sürücüleri:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "ISA RTC:"
|
||||
|
||||
|
||||
@@ -650,6 +650,12 @@ msgstr "Дисководи знімних дисків:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "ISA RTC:"
|
||||
|
||||
|
||||
@@ -649,6 +649,12 @@ msgstr "可移动磁盘 (ZIP) 驱动器:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "ISA 实时时钟:"
|
||||
|
||||
|
||||
@@ -649,6 +649,12 @@ msgstr "抽取式磁碟機:"
|
||||
msgid "ZIP 250"
|
||||
msgstr "ZIP 250"
|
||||
|
||||
msgid "Superdrives:"
|
||||
msgstr "Superdrives:"
|
||||
|
||||
msgid "LS-240"
|
||||
msgstr "LS-240"
|
||||
|
||||
msgid "ISA RTC:"
|
||||
msgstr "ISA 實時時鐘:"
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ extern "C" {
|
||||
#include <86box/scsi.h>
|
||||
#include <86box/scsi_device.h>
|
||||
#include <86box/rdisk.h>
|
||||
#include <86box/superdisk.h>
|
||||
#include <86box/mo.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/machine.h>
|
||||
@@ -107,6 +108,7 @@ struct Pixmaps {
|
||||
PixmapSetEmptyActive floppy_35;
|
||||
PixmapSetEmptyActive cdrom;
|
||||
PixmapSetEmptyActive rdisk;
|
||||
PixmapSetEmptyActive superdisk;
|
||||
PixmapSetEmptyActive mo;
|
||||
PixmapSetActive hd;
|
||||
PixmapSetEmptyActive net;
|
||||
@@ -328,6 +330,7 @@ struct MachineStatus::States {
|
||||
pixmaps.floppy_35.load(QIcon(":/settings/qt/icons/floppy_35.ico"));
|
||||
pixmaps.cdrom.load(QIcon(":/settings/qt/icons/cdrom.ico"));
|
||||
pixmaps.rdisk.load(QIcon(":/settings/qt/icons/rdisk.ico"));
|
||||
pixmaps.superdisk.load(QIcon(":/settings/qt/icons/superdisk.ico"));
|
||||
pixmaps.mo.load(QIcon(":/settings/qt/icons/mo.ico"));
|
||||
pixmaps.hd.load(QIcon(":/settings/qt/icons/hard_disk.ico"));
|
||||
pixmaps.net.load(QIcon(":/settings/qt/icons/network.ico"));
|
||||
@@ -345,6 +348,9 @@ struct MachineStatus::States {
|
||||
for (auto &z : rdisk) {
|
||||
z.pixmaps = &pixmaps.rdisk;
|
||||
}
|
||||
for (auto &z : superdisk) {
|
||||
z.pixmaps = &pixmaps.superdisk;
|
||||
}
|
||||
for (auto &m : mo) {
|
||||
m.pixmaps = &pixmaps.mo;
|
||||
}
|
||||
@@ -361,6 +367,7 @@ struct MachineStatus::States {
|
||||
std::array<StateEmptyActive, FDD_NUM> fdd;
|
||||
std::array<StateEmptyActive, CDROM_NUM> cdrom;
|
||||
std::array<StateEmptyActive, RDISK_NUM> rdisk;
|
||||
std::array<StateEmptyActive, SUPERDISK_NUM> superdisk;
|
||||
std::array<StateEmptyActive, MO_NUM> mo;
|
||||
std::array<StateActive, HDD_BUS_USB> hdds;
|
||||
std::array<StateEmptyActive, NET_CARD_MAX> net;
|
||||
@@ -461,6 +468,27 @@ MachineStatus::iterateRDisk(const std::function<void(int)> &cb)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MachineStatus::iterateSuperdisk(const std::function<void(int)> &cb)
|
||||
{
|
||||
auto hdc_name = QString(hdc_get_internal_name(hdc_current[0]));
|
||||
for (size_t i = 0; i < SUPERDISK_NUM; i++) {
|
||||
/* Could be Internal or External IDE.. */
|
||||
if ((superdisk_drives[i].bus_type == SUPERDISK_BUS_ATAPI) && !hasIDE() &&
|
||||
(hdc_name.left(3) != QStringLiteral("ide")) &&
|
||||
(hdc_name.left(5) != QStringLiteral("xtide")) &&
|
||||
(hdc_name.left(5) != QStringLiteral("mcide")))
|
||||
continue;
|
||||
if ((superdisk_drives[i].bus_type == SUPERDISK_BUS_SCSI) && !hasSCSI() &&
|
||||
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
|
||||
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
|
||||
continue;
|
||||
if (superdisk_drives[i].bus_type != 0) {
|
||||
cb(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MachineStatus::iterateMO(const std::function<void(int)> &cb)
|
||||
{
|
||||
@@ -580,6 +608,10 @@ MachineStatus::refreshIcons()
|
||||
if (machine_status.rdisk[i].write_active)
|
||||
ui_sb_update_icon_write(SB_RDISK | i, 0);
|
||||
}
|
||||
for (size_t i = 0; i < SUPERDISK_NUM; i++) {
|
||||
d->superdisk[i].setActive(machine_status.superdisk[i].active);
|
||||
d->superdisk[i].setEmpty(machine_status.superdisk[i].empty);
|
||||
}
|
||||
for (size_t i = 0; i < MO_NUM; i++) {
|
||||
d->mo[i].setActive(machine_status.mo[i].active);
|
||||
d->mo[i].setWriteActive(machine_status.mo[i].write_active);
|
||||
@@ -619,6 +651,10 @@ MachineStatus::clearActivity()
|
||||
rdisk.setActive(false);
|
||||
rdisk.setWriteActive(false);
|
||||
}
|
||||
for (auto &superdisk : d->superdisk) {
|
||||
superdisk.setActive(false);
|
||||
superdisk.setWriteActive(false);
|
||||
}
|
||||
for (auto &mo : d->mo) {
|
||||
mo.setActive(false);
|
||||
mo.setWriteActive(false);
|
||||
@@ -660,6 +696,9 @@ MachineStatus::refresh(QStatusBar *sbar)
|
||||
for (size_t i = 0; i < RDISK_NUM; i++) {
|
||||
sbar->removeWidget(d->rdisk[i].label.get());
|
||||
}
|
||||
for (size_t i = 0; i < SUPERDISK_NUM; i++) {
|
||||
sbar->removeWidget(d->superdisk[i].label.get());
|
||||
}
|
||||
for (size_t i = 0; i < MO_NUM; i++) {
|
||||
sbar->removeWidget(d->mo[i].label.get());
|
||||
}
|
||||
@@ -780,6 +819,22 @@ MachineStatus::refresh(QStatusBar *sbar)
|
||||
sbar->addWidget(d->rdisk[i].label.get());
|
||||
});
|
||||
|
||||
iterateSuperdisk([this, sbar](int i) {
|
||||
d->superdisk[i].label = std::make_unique<ClickableLabel>();
|
||||
d->superdisk[i].setEmpty(QString(superdisk_drives[i].image_path).isEmpty());
|
||||
d->superdisk[i].setActive(false);
|
||||
d->superdisk[i].refresh();
|
||||
connect((ClickableLabel *) d->superdisk[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) {
|
||||
MediaMenu::ptr->superdiskMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->superdiskMenus[i]->sizeHint().height()));
|
||||
});
|
||||
connect((ClickableLabel *) d->superdisk[i].label.get(), &ClickableLabel::dropped, [i](QString str) {
|
||||
MediaMenu::ptr->superdiskMount(i, str, false);
|
||||
});
|
||||
d->superdisk[i].label->setToolTip(MediaMenu::ptr->superdiskMenus[i]->title());
|
||||
d->superdisk[i].label->setAcceptDrops(true);
|
||||
sbar->addWidget(d->superdisk[i].label.get());
|
||||
});
|
||||
|
||||
iterateMO([this, sbar](int i) {
|
||||
d->mo[i].label = std::make_unique<ClickableLabel>();
|
||||
d->mo[i].setEmpty(QString(mo_drives[i].image_path).isEmpty());
|
||||
@@ -985,6 +1040,10 @@ MachineStatus::updateTip(int tag)
|
||||
if (d->rdisk[item].label && MediaMenu::ptr->rdiskMenus[item])
|
||||
d->rdisk[item].label->setToolTip(MediaMenu::ptr->rdiskMenus[item]->toolTip());
|
||||
break;
|
||||
case SB_SUPERDISK:
|
||||
if (d->superdisk[item].label && MediaMenu::ptr->superdiskMenus[item])
|
||||
d->superdisk[item].label->setToolTip(MediaMenu::ptr->superdiskMenus[item]->title());
|
||||
break;
|
||||
case SB_MO:
|
||||
if (d->mo[item].label && MediaMenu::ptr->moMenus[item])
|
||||
d->mo[item].label->setToolTip(MediaMenu::ptr->moMenus[item]->toolTip());
|
||||
|
||||
@@ -73,6 +73,7 @@ public:
|
||||
static void iterateFDD(const std::function<void(int i)> &cb);
|
||||
static void iterateCDROM(const std::function<void(int i)> &cb);
|
||||
static void iterateRDisk(const std::function<void(int i)> &cb);
|
||||
static void iterateSuperdisk(const std::function<void(int i)> &cb);
|
||||
static void iterateMO(const std::function<void(int i)> &cb);
|
||||
static void iterateNIC(const std::function<void(int i)> &cb);
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ enum class MediaType {
|
||||
Optical,
|
||||
RDisk,
|
||||
Mo,
|
||||
SuperDisk,
|
||||
Cassette,
|
||||
Cartridge
|
||||
};
|
||||
@@ -57,10 +58,10 @@ typedef QHash<ui::MediaType, device_media_history_t> master_list_t;
|
||||
// Used to iterate over all supported types when preparing data structures
|
||||
// Also useful to indicate which types support history
|
||||
static const MediaType AllSupportedMediaHistoryTypes[] = {
|
||||
MediaType::Optical,
|
||||
MediaType::Floppy,
|
||||
MediaType::RDisk,
|
||||
MediaType::Mo,
|
||||
MediaType::SuperDisk,
|
||||
MediaType::Cassette,
|
||||
MediaType::Cartridge
|
||||
};
|
||||
|
||||
@@ -54,6 +54,7 @@ extern "C" {
|
||||
#include <86box/cdrom.h>
|
||||
#include <86box/scsi_device.h>
|
||||
#include <86box/rdisk.h>
|
||||
#include <86box/superdisk.h>
|
||||
#include <86box/mo.h>
|
||||
#include <86box/sound.h>
|
||||
#include <86box/ui.h>
|
||||
@@ -1136,6 +1137,141 @@ MediaMenu::moReload(int index, int slot)
|
||||
ui_sb_update_tip(SB_MO | index);
|
||||
}
|
||||
|
||||
void
|
||||
MediaMenu::superdiskNewImage(int i)
|
||||
{
|
||||
NewFloppyDialog dialog(NewFloppyDialog::MediaType::SuperDisk, parentWidget);
|
||||
switch (dialog.exec()) {
|
||||
default:
|
||||
break;
|
||||
case QDialog::Accepted:
|
||||
QByteArray filename = dialog.fileName().toUtf8();
|
||||
superdiskMount(i, filename, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaMenu::superdiskSelectImage(int i, bool wp)
|
||||
{
|
||||
const auto filename = QFileDialog::getOpenFileName(
|
||||
parentWidget,
|
||||
QString(),
|
||||
QString(),
|
||||
tr("SuperDisk images") % util::DlgFilter({ "im?", "sdi" }) % tr("All files") % util::DlgFilter({ "*" }, true));
|
||||
|
||||
if (!filename.isEmpty())
|
||||
superdiskMount(i, filename, wp);
|
||||
}
|
||||
|
||||
void
|
||||
MediaMenu::superdiskMount(int i, const QString &filename, bool wp)
|
||||
{
|
||||
const auto dev = static_cast<superdisk_t *>(superdisk_drives[i].priv);
|
||||
int was_empty = superdisk_is_empty(i);
|
||||
|
||||
superdisk_disk_close(dev);
|
||||
superdisk_drives[i].read_only = wp;
|
||||
if (!filename.isEmpty()) {
|
||||
QByteArray filenameBytes = filename.toUtf8();
|
||||
superdisk_load(dev, filenameBytes.data(), 1);
|
||||
|
||||
/* Signal media change to the emulated machine. */
|
||||
superdisk_insert(dev);
|
||||
|
||||
/* The drive was previously empty, transition directly to UNIT ATTENTION. */
|
||||
if (was_empty)
|
||||
superdisk_insert(dev);
|
||||
}
|
||||
mhm.addImageToHistory(i, ui::MediaType::SuperDisk, superdisk_drives[i].prev_image_path, superdisk_drives[i].image_path);
|
||||
|
||||
ui_sb_update_icon_state(SB_SUPERDISK | i, filename.isEmpty() ? 1 : 0);
|
||||
superdiskUpdateMenu(i);
|
||||
ui_sb_update_tip(SB_SUPERDISK | i);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
void
|
||||
MediaMenu::superdiskEject(int i)
|
||||
{
|
||||
const auto dev = static_cast<superdisk_t *>(superdisk_drives[i].priv);
|
||||
|
||||
mhm.addImageToHistory(i, ui::MediaType::SuperDisk, superdisk_drives[i].image_path, QString());
|
||||
superdisk_disk_close(dev);
|
||||
superdisk_drives[i].image_path[0] = 0;
|
||||
if (superdisk_drives[i].bus_type) {
|
||||
/* Signal disk change to the emulated machine. */
|
||||
superdisk_insert(dev);
|
||||
}
|
||||
|
||||
ui_sb_update_icon_state(SB_SUPERDISK | i, 1);
|
||||
superdiskUpdateMenu(i);
|
||||
ui_sb_update_tip(SB_SUPERDISK | i);
|
||||
config_save();
|
||||
}
|
||||
|
||||
void
|
||||
MediaMenu::superdiskReloadPrev(int i)
|
||||
{
|
||||
const auto dev = static_cast<superdisk_t *>(superdisk_drives[i].priv);
|
||||
|
||||
superdisk_disk_reload(dev);
|
||||
if (strlen(superdisk_drives[i].image_path) == 0) {
|
||||
ui_sb_update_icon_state(SB_SUPERDISK | i, 1);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_SUPERDISK | i, 0);
|
||||
}
|
||||
|
||||
superdiskUpdateMenu(i);
|
||||
ui_sb_update_tip(SB_SUPERDISK | i);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
void
|
||||
MediaMenu::superdiskReload(int index, int slot)
|
||||
{
|
||||
const QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::SuperDisk);
|
||||
superdiskMount(index, filename, false);
|
||||
superdiskUpdateMenu(index);
|
||||
ui_sb_update_tip(SB_SUPERDISK | index);
|
||||
}
|
||||
|
||||
void
|
||||
MediaMenu::superdiskUpdateMenu(int i)
|
||||
{
|
||||
const QString name = superdisk_drives[i].image_path;
|
||||
const QString prev_name = superdisk_drives[i].prev_image_path;
|
||||
if (!superdiskMenus.contains(i))
|
||||
return;
|
||||
auto *menu = superdiskMenus[i];
|
||||
auto childs = menu->children();
|
||||
|
||||
auto *ejectMenu = dynamic_cast<QAction *>(childs[superdiskEjectPos]);
|
||||
ejectMenu->setEnabled(!name.isEmpty());
|
||||
|
||||
QString busName = tr("Unknown Bus");
|
||||
switch (superdisk_drives[i].bus_type) {
|
||||
default:
|
||||
break;
|
||||
case SUPERDISK_BUS_ATAPI:
|
||||
busName = "ATAPI";
|
||||
break;
|
||||
case SUPERDISK_BUS_SCSI:
|
||||
busName = "SCSI";
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
menu->setTitle(tr("SuperDisk %1 %2 (%3): %4").arg((superdisk_drives[i].is_240 > 0) ? "240" : "120", QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name));
|
||||
#endif
|
||||
menu->setTitle(QString::asprintf(tr("SuperDisk %03i %i (%s): %ls").toUtf8().constData(), (superdisk_drives[i].is_240 > 0) ? 240 : 120, i + 1, busName.toUtf8().data(), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data()));
|
||||
|
||||
for (int slot = 0; slot < MAX_PREV_IMAGES; slot++)
|
||||
updateImageHistory(i, slot, ui::MediaType::SuperDisk);
|
||||
}
|
||||
|
||||
void
|
||||
MediaMenu::nicConnect(int i)
|
||||
{
|
||||
@@ -1295,4 +1431,23 @@ mo_reload(uint8_t id)
|
||||
{
|
||||
MediaMenu::ptr->moReloadPrev(id);
|
||||
}
|
||||
|
||||
void
|
||||
superdisk_eject(uint8_t id)
|
||||
{
|
||||
MediaMenu::ptr->superdiskEject(id);
|
||||
}
|
||||
|
||||
void
|
||||
superdisk_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
{
|
||||
MediaMenu::ptr->superdiskMount(id, QString(fn), wp);
|
||||
}
|
||||
|
||||
void
|
||||
superdisk_reload(uint8_t id)
|
||||
{
|
||||
MediaMenu::ptr->superdiskReloadPrev(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -67,6 +67,14 @@ public:
|
||||
void moReload(int index, int slot);
|
||||
void moUpdateMenu(int i);
|
||||
|
||||
void superdiskNewImage(int i);
|
||||
void superdiskSelectImage(int i, bool wp);
|
||||
void superdiskMount(int i, const QString &filename, bool wp);
|
||||
void superdiskEject(int i);
|
||||
void superdiskReloadPrev(int i);
|
||||
void superdiskReload(int index, int slot);
|
||||
void superdiskUpdateMenu(int i);
|
||||
|
||||
void nicConnect(int i);
|
||||
void nicDisconnect(int i);
|
||||
void nicUpdateMenu(int i);
|
||||
@@ -86,6 +94,7 @@ private:
|
||||
QMap<int, QMenu *> cdromMenus;
|
||||
QMap<int, QMenu *> rdiskMenus;
|
||||
QMap<int, QMenu *> moMenus;
|
||||
QMap<int, QMenu *> superdiskMenus;
|
||||
QMap<int, QMenu *> netMenus;
|
||||
|
||||
QString getMediaOpenDirectory();
|
||||
@@ -117,6 +126,9 @@ private:
|
||||
int moEjectPos;
|
||||
int moImageHistoryPos[MAX_PREV_IMAGES];
|
||||
|
||||
int superdiskEjectPos;
|
||||
int superdiskReloadPos;
|
||||
|
||||
int netDisconnPos;
|
||||
|
||||
friend class MachineStatus;
|
||||
|
||||
@@ -28,6 +28,7 @@ extern "C" {
|
||||
#include <86box/random.h>
|
||||
#include <86box/scsi_device.h>
|
||||
#include <86box/rdisk.h>
|
||||
#include <86box/superdisk.h>
|
||||
#include <86box/mo.h>
|
||||
}
|
||||
|
||||
@@ -57,7 +58,7 @@ struct disk_size_t {
|
||||
int root_dir_entries;
|
||||
};
|
||||
|
||||
static const disk_size_t disk_sizes[14] = {
|
||||
static const disk_size_t disk_sizes[16] = {
|
||||
// clang-format off
|
||||
#if 0
|
||||
{ 1, 1, 2, 1, 1, 77, 26, 0, 0, 4, 2, 6, 68 }, /* 250k 8" */
|
||||
@@ -79,11 +80,9 @@ static const disk_size_t disk_sizes[14] = {
|
||||
{ 2, 2, 3, 1, 0, 80, 36, 2, 0xf0, 2, 2, 9, 240 }, /* 2.88M */
|
||||
{ 0, 64, 0, 0, 0, 96, 32, 2, 0, 0, 0, 0, 0 }, /* ZIP 100 */
|
||||
{ 0, 64, 0, 0, 0, 239, 32, 2, 0, 0, 0, 0, 0 }, /* ZIP 250 */
|
||||
#if 0
|
||||
{ 0, 8, 0, 0, 0, 963, 32, 2, 0, 0, 0, 0, 0 }, /* LS-120 */
|
||||
{ 0, 32, 0, 0, 0, 262, 56, 2, 0, 0, 0, 0, 0 } /* LS-240 */
|
||||
#endif
|
||||
// clang-format on
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static const QStringList rpmModes = {
|
||||
@@ -126,6 +125,11 @@ static const QStringList moTypes = {
|
||||
"5.25\" 1.3 GB",
|
||||
};
|
||||
|
||||
static const QStringList superDiskTypes = {
|
||||
"LS-120",
|
||||
"LS-240",
|
||||
};
|
||||
|
||||
NewFloppyDialog::NewFloppyDialog(MediaType type, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::NewFloppyDialog)
|
||||
@@ -150,6 +154,12 @@ NewFloppyDialog::NewFloppyDialog(MediaType type, QWidget *parent)
|
||||
}
|
||||
ui->fileField->setFilter(tr("Removable disk images") % util::DlgFilter({ "im?", "img", "rdi", "zdi" }, true));
|
||||
break;
|
||||
case MediaType::SuperDisk:
|
||||
for (int i = 0; i < superDiskTypes.size(); ++i) {
|
||||
Models::AddEntry(model, tr(superDiskTypes[i].toUtf8().data()), i);
|
||||
}
|
||||
ui->fileField->setFilter(tr("SuperDisk images") % util::DlgFilter({ "im?", "img", "sdi" }, true));
|
||||
break;
|
||||
case MediaType::Mo:
|
||||
for (int i = 0; i < moTypes.size(); ++i) {
|
||||
Models::AddEntry(model, tr(moTypes[i].toUtf8().data()), i);
|
||||
@@ -232,6 +242,22 @@ NewFloppyDialog::onCreate()
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MediaType::SuperDisk:
|
||||
{
|
||||
fileType = fi.suffix().toLower() == QStringLiteral("sdi") ? FileType::Sdi: FileType::Img;
|
||||
|
||||
std::atomic_bool res;
|
||||
std::thread t([this, &res, filename, fileType, &progress] {
|
||||
res = createSuperDiskSectorImage(filename, disk_sizes[ui->comboBoxSize->currentIndex() + 12], fileType, progress);
|
||||
});
|
||||
progress.exec();
|
||||
t.join();
|
||||
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MediaType::Mo:
|
||||
{
|
||||
fileType = fi.suffix().toLower() == QStringLiteral("mdi") ? FileType::Mdi : FileType::Img;
|
||||
@@ -708,3 +734,186 @@ NewFloppyDialog::createMoSectorImage(const QString &filename, int8_t disk_size,
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
NewFloppyDialog::createSuperDiskSectorImage(const QString &filename, const disk_size_t& disk_size, FileType type, QProgressDialog& pbar)
|
||||
{
|
||||
uint32_t total_size = 0;
|
||||
uint32_t total_sectors = 0;
|
||||
uint32_t sector_bytes = 0;
|
||||
uint16_t base = 0x1000;
|
||||
uint32_t pbar_max = 0;
|
||||
|
||||
QFile file(filename);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
return false;
|
||||
}
|
||||
QDataStream stream(&file);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
|
||||
sector_bytes = (128 << disk_size.sector_len);
|
||||
total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors;
|
||||
if (total_sectors > SUPERDISK_SECTORS)
|
||||
total_sectors = SUPERDISK_240_SECTORS;
|
||||
total_size = total_sectors * sector_bytes;
|
||||
|
||||
pbar_max = total_size;
|
||||
if (type == FileType::Zdi) {
|
||||
pbar_max += base;
|
||||
}
|
||||
pbar_max >>= 11;
|
||||
|
||||
if (type == FileType::Zdi) {
|
||||
QByteArray data(base, 0);
|
||||
auto empty = data.data();
|
||||
|
||||
*(uint32_t *) &(empty[0x08]) = (uint32_t) base;
|
||||
*(uint32_t *) &(empty[0x0C]) = total_size;
|
||||
*(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes;
|
||||
*(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors;
|
||||
*(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides;
|
||||
*(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks;
|
||||
|
||||
stream.writeRawData(empty, base);
|
||||
pbar_max -= 2;
|
||||
}
|
||||
|
||||
QByteArray bytes(total_size, 0);
|
||||
auto empty = bytes.data();
|
||||
|
||||
if (total_sectors == SUPERDISK_SECTORS) {
|
||||
/* LS-120 */
|
||||
/* MBR */
|
||||
*(uint64_t *) &(empty[0x0000]) = 0x2054524150492EEBLL;
|
||||
*(uint64_t *) &(empty[0x0008]) = 0x3930302065646F63LL;
|
||||
*(uint64_t *) &(empty[0x0010]) = 0x67656D6F49202D20LL;
|
||||
*(uint64_t *) &(empty[0x0018]) = 0x726F70726F432061LL;
|
||||
*(uint64_t *) &(empty[0x0020]) = 0x202D206E6F697461LL;
|
||||
*(uint64_t *) &(empty[0x0028]) = 0x30392F33322F3131LL;
|
||||
|
||||
*(uint64_t *) &(empty[0x01AE]) = 0x0116010100E90644LL;
|
||||
*(uint64_t *) &(empty[0x01B6]) = 0xED08BBE5014E0135LL;
|
||||
*(uint64_t *) &(empty[0x01BE]) = 0xFFFFFE06FFFFFE80LL;
|
||||
*(uint64_t *) &(empty[0x01C6]) = 0x0002FFE000000020LL;
|
||||
|
||||
*(uint16_t *) &(empty[0x01FE]) = 0xAA55;
|
||||
|
||||
/* 31 sectors filled with 0x48 */
|
||||
memset(&(empty[0x0200]), 0x48, 0x3E00);
|
||||
|
||||
/* Boot sector */
|
||||
*(uint64_t *) &(empty[0x4000]) = 0x584F4236389058EBLL;
|
||||
*(uint64_t *) &(empty[0x4008]) = 0x0008040200302E35LL;
|
||||
*(uint64_t *) &(empty[0x4010]) = 0x00C0F80000020002LL;
|
||||
*(uint64_t *) &(empty[0x4018]) = 0x0000002000FF003FLL;
|
||||
*(uint32_t *) &(empty[0x4020]) = 0x0002FFE0;
|
||||
*(uint16_t *) &(empty[0x4024]) = 0x0080;
|
||||
|
||||
empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */
|
||||
empty[0x4027] = random_generate();
|
||||
empty[0x4028] = random_generate();
|
||||
empty[0x4029] = random_generate();
|
||||
empty[0x402A] = random_generate();
|
||||
|
||||
memset(&(empty[0x402B]), 0x00, 0x000B);
|
||||
memset(&(empty[0x4036]), 0x20, 0x0008);
|
||||
|
||||
empty[0x4036] = 'F';
|
||||
empty[0x4037] = 'A';
|
||||
empty[0x4038] = 'T';
|
||||
empty[0x4039] = '1';
|
||||
empty[0x403A] = '6';
|
||||
memset(&(empty[0x403B]), 0x20, 0x0003);
|
||||
|
||||
empty[0x41FE] = 0x55;
|
||||
empty[0x41FF] = 0xAA;
|
||||
|
||||
empty[0x5000] = empty[0x1D000] = empty[0x4015];
|
||||
empty[0x5001] = empty[0x1D001] = 0xFF;
|
||||
empty[0x5002] = empty[0x1D002] = 0xFF;
|
||||
empty[0x5003] = empty[0x1D003] = 0xFF;
|
||||
|
||||
/* Root directory = 0x35000
|
||||
Data = 0x39000 */
|
||||
} else {
|
||||
/* LS-240 */
|
||||
/* MBR */
|
||||
*(uint64_t *) &(empty[0x0000]) = 0x2054524150492EEBLL;
|
||||
*(uint64_t *) &(empty[0x0008]) = 0x3930302065646F63LL;
|
||||
*(uint64_t *) &(empty[0x0010]) = 0x67656D6F49202D20LL;
|
||||
*(uint64_t *) &(empty[0x0018]) = 0x726F70726F432061LL;
|
||||
*(uint64_t *) &(empty[0x0020]) = 0x202D206E6F697461LL;
|
||||
*(uint64_t *) &(empty[0x0028]) = 0x30392F33322F3131LL;
|
||||
|
||||
*(uint64_t *) &(empty[0x01AE]) = 0x0116010100E900E9LL;
|
||||
*(uint64_t *) &(empty[0x01B6]) = 0x2E32A7AC014E0135LL;
|
||||
|
||||
*(uint64_t *) &(empty[0x01EE]) = 0xEE203F0600010180LL;
|
||||
*(uint64_t *) &(empty[0x01F6]) = 0x000777E000000020LL;
|
||||
*(uint16_t *) &(empty[0x01FE]) = 0xAA55;
|
||||
|
||||
/* 31 sectors filled with 0x48 */
|
||||
memset(&(empty[0x0200]), 0x48, 0x3E00);
|
||||
|
||||
/* The second sector begins with some strange data
|
||||
in my reference image. */
|
||||
*(uint64_t *) &(empty[0x0200]) = 0x3831393230334409LL;
|
||||
*(uint64_t *) &(empty[0x0208]) = 0x6A57766964483130LL;
|
||||
*(uint64_t *) &(empty[0x0210]) = 0x3C3A34676063653FLL;
|
||||
*(uint64_t *) &(empty[0x0218]) = 0x586A56A8502C4161LL;
|
||||
*(uint64_t *) &(empty[0x0220]) = 0x6F2D702535673D6CLL;
|
||||
*(uint64_t *) &(empty[0x0228]) = 0x255421B8602D3456LL;
|
||||
*(uint64_t *) &(empty[0x0230]) = 0x577B22447B52603ELL;
|
||||
*(uint64_t *) &(empty[0x0238]) = 0x46412CC871396170LL;
|
||||
*(uint64_t *) &(empty[0x0240]) = 0x704F55237C5E2626LL;
|
||||
*(uint64_t *) &(empty[0x0248]) = 0x6C7932C87D5C3C20LL;
|
||||
*(uint64_t *) &(empty[0x0250]) = 0x2C50503E47543D6ELL;
|
||||
*(uint64_t *) &(empty[0x0258]) = 0x46394E807721536ALL;
|
||||
*(uint64_t *) &(empty[0x0260]) = 0x505823223F245325LL;
|
||||
*(uint64_t *) &(empty[0x0268]) = 0x365C79B0393B5B6ELL;
|
||||
|
||||
/* Boot sector */
|
||||
*(uint64_t *) &(empty[0x4000]) = 0x584F4236389058EBLL;
|
||||
*(uint64_t *) &(empty[0x4008]) = 0x0001080200302E35LL;
|
||||
*(uint64_t *) &(empty[0x4010]) = 0x00EFF80000020002LL;
|
||||
*(uint64_t *) &(empty[0x4018]) = 0x0000002000400020LL;
|
||||
*(uint32_t *) &(empty[0x4020]) = 0x000777E0;
|
||||
*(uint16_t *) &(empty[0x4024]) = 0x0080;
|
||||
|
||||
empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */
|
||||
empty[0x4027] = random_generate();
|
||||
empty[0x4028] = random_generate();
|
||||
empty[0x4029] = random_generate();
|
||||
empty[0x402A] = random_generate();
|
||||
|
||||
memset(&(empty[0x402B]), 0x00, 0x000B);
|
||||
memset(&(empty[0x4036]), 0x20, 0x0008);
|
||||
|
||||
empty[0x4036] = 'F';
|
||||
empty[0x4037] = 'A';
|
||||
empty[0x4038] = 'T';
|
||||
empty[0x4039] = '1';
|
||||
empty[0x403A] = '6';
|
||||
memset(&(empty[0x403B]), 0x20, 0x0003);
|
||||
|
||||
empty[0x41FE] = 0x55;
|
||||
empty[0x41FF] = 0xAA;
|
||||
|
||||
empty[0x4200] = empty[0x22000] = empty[0x4015];
|
||||
empty[0x4201] = empty[0x22001] = 0xFF;
|
||||
empty[0x4202] = empty[0x22002] = 0xFF;
|
||||
empty[0x4203] = empty[0x22003] = 0xFF;
|
||||
|
||||
/* Root directory = 0x3FE00
|
||||
Data = 0x38200 */
|
||||
}
|
||||
|
||||
pbar.setMaximum(pbar_max);
|
||||
for (uint32_t i = 0; i < pbar_max; i++) {
|
||||
stream.writeRawData(&empty[i << 11], 2048);
|
||||
fileProgress(i);
|
||||
}
|
||||
fileProgress(pbar_max);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18,11 +18,13 @@ public:
|
||||
Floppy,
|
||||
RDisk,
|
||||
Mo,
|
||||
SuperDisk,
|
||||
};
|
||||
enum class FileType {
|
||||
Img,
|
||||
Fdi,
|
||||
Zdi,
|
||||
Sdi,
|
||||
Mdi,
|
||||
};
|
||||
explicit NewFloppyDialog(MediaType type, QWidget *parent = nullptr);
|
||||
@@ -44,6 +46,7 @@ private:
|
||||
bool createSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type);
|
||||
bool createRDiskSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type, QProgressDialog &pbar);
|
||||
bool createMoSectorImage(const QString &filename, int8_t disk_size, FileType type, QProgressDialog &pbar);
|
||||
bool createSuperDiskSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type, QProgressDialog &pbar);
|
||||
};
|
||||
|
||||
#endif // QT_NEWFLOPPYDIALOG_HPP
|
||||
|
||||
@@ -23,6 +23,7 @@ extern "C" {
|
||||
#include <86box/scsi_device.h>
|
||||
#include <86box/mo.h>
|
||||
#include <86box/rdisk.h>
|
||||
#include <86box/superdisk.h>
|
||||
}
|
||||
|
||||
#include "qt_models_common.hpp"
|
||||
|
||||
@@ -35,6 +35,9 @@ private slots:
|
||||
void on_comboBoxRDiskBus_activated(int index);
|
||||
void on_comboBoxRDiskChannel_activated(int index);
|
||||
void on_comboBoxRDiskType_activated(int index);
|
||||
#if 0
|
||||
void onSuperDiskRowChanged(const QModelIndex ¤t);
|
||||
#endif
|
||||
|
||||
private:
|
||||
Ui::SettingsOtherRemovable *ui;
|
||||
|
||||
@@ -49,6 +49,7 @@ extern "C" {
|
||||
#include <86box/cassette.h>
|
||||
#include <86box/cdrom.h>
|
||||
#include <86box/rdisk.h>
|
||||
#include <86box/superdisk.h>
|
||||
#include <86box/mo.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/thread.h>
|
||||
@@ -307,6 +308,9 @@ ui_sb_update_icon_state(int tag, int state)
|
||||
case SB_RDISK:
|
||||
machine_status.rdisk[item].empty = state > 0 ? true : false;
|
||||
break;
|
||||
case SB_SUPERDISK:
|
||||
machine_status.superdisk[item].empty = state > 0 ? true : false;
|
||||
break;
|
||||
case SB_MO:
|
||||
machine_status.mo[item].empty = state > 0 ? true : false;
|
||||
break;
|
||||
@@ -345,6 +349,9 @@ ui_sb_update_icon(int tag, int active)
|
||||
case SB_RDISK:
|
||||
machine_status.rdisk[item].active = active > 0 ? true : false;
|
||||
break;
|
||||
case SB_SUPERDISK:
|
||||
machine_status.superdisk[item].active = active > 0 ? true : false;
|
||||
break;
|
||||
case SB_MO:
|
||||
machine_status.mo[item].active = active > 0 ? true : false;
|
||||
break;
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
<file>qt/icons/record.ico</file>
|
||||
<file>qt/icons/rewind.ico</file>
|
||||
<file>qt/icons/sound.ico</file>
|
||||
<file>qt/icons/superdisk.ico</file>
|
||||
<file>qt/icons/superdisk_active.ico</file>
|
||||
<file>qt/icons/superdisk_disabled.ico</file>
|
||||
<file>qt/icons/superdisk_empty.ico</file>
|
||||
<file>qt/icons/superdisk_empty_active.ico</file>
|
||||
<file>qt/icons/storage_controllers.ico</file>
|
||||
<file>qt/icons/superdisk.ico</file>
|
||||
<file>qt/icons/superdisk_image.ico</file>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Handle the platform-side of CDROM/RDisk/MO drives.
|
||||
* Handle the platform-side of CDROM/RDisk/MO/SuperDisk drives.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <86box/scsi_device.h>
|
||||
#include <86box/cdrom.h>
|
||||
#include <86box/cdrom_image.h>
|
||||
#include <86box/superdisk.h>
|
||||
#include <86box/mo.h>
|
||||
#include <86box/rdisk.h>
|
||||
#include <86box/scsi_disk.h>
|
||||
@@ -142,6 +143,63 @@ cdrom_mount(uint8_t id, char *fn)
|
||||
config_save();
|
||||
}
|
||||
|
||||
void
|
||||
superdisk_eject(uint8_t id)
|
||||
{
|
||||
superdisk_t *dev = (superdisk_t *) superdisk_drives[id].priv;
|
||||
|
||||
superdisk_disk_close(dev);
|
||||
if (superdisk_drives[id].bus_type) {
|
||||
/* Signal disk change to the emulated machine. */
|
||||
superdisk_insert(dev);
|
||||
}
|
||||
|
||||
ui_sb_update_icon_state(SB_SUPERDISK | id, 1);
|
||||
#if 0
|
||||
media_menu_update_superdisk(id);
|
||||
#endif
|
||||
ui_sb_update_tip(SB_SUPERDISK | id);
|
||||
config_save();
|
||||
}
|
||||
|
||||
void
|
||||
superdisk_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
{
|
||||
superdisk_t *dev = (superdisk_t *) superdisk_drives[id].priv;
|
||||
|
||||
superdisk_disk_close(dev);
|
||||
superdisk_drives[id].read_only = wp;
|
||||
superdisk_load(dev, fn, 0);
|
||||
|
||||
ui_sb_update_icon_state(SB_SUPERDISK | id, strlen(superdisk_drives[id].image_path) ? 0 : 1);
|
||||
#if 0
|
||||
media_menu_update_superdisk(id);
|
||||
#endif
|
||||
ui_sb_update_tip(SB_SUPERDISK | id);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
void
|
||||
superdisk_reload(uint8_t id)
|
||||
{
|
||||
superdisk_t *dev = (superdisk_t *) superdisk_drives[id].priv;
|
||||
|
||||
superdisk_disk_reload(dev);
|
||||
if (strlen(superdisk_drives[id].image_path) == 0) {
|
||||
ui_sb_update_icon_state(SB_SUPERDISK | id, 1);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_SUPERDISK | id, 0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
media_menu_update_superdisk(id);
|
||||
#endif
|
||||
ui_sb_update_tip(SB_SUPERDISK | id);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
void
|
||||
mo_eject(uint8_t id)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user