mirror of
https://github.com/ogoguel/activegs-ios.git
synced 2024-12-22 15:30:36 +00:00
719 lines
18 KiB
C++
719 lines
18 KiB
C++
/*
|
|
ActiveGS, Copyright 2004-2016 Olivier Goguel, https://github.com/ogoguel/ActiveGS
|
|
Based on Kegs, Copyright 2004 Kent Dickey, https://kegs.sourceforge.net
|
|
This code is covered by the GNU GPL licence
|
|
*/
|
|
|
|
#include "defc.h"
|
|
#include "moremem.h"
|
|
#include "sim65816.h"
|
|
#include "iwm.h"
|
|
#include "config.h"
|
|
#include "driver.h"
|
|
|
|
#ifdef _MSC_VER
|
|
#define snprintf _snprintf
|
|
#endif
|
|
|
|
//extern int g_rom_version;
|
|
//extern word32 g_mem_size_base;
|
|
extern byte *g_rom_fc_ff_ptr;
|
|
extern byte *g_rom_cards_ptr;
|
|
//extern word32 g_mem_size_exp;
|
|
//extern Iwm iwm;
|
|
///extern int Verbose;
|
|
|
|
//extern int g_highest_smartport_unit;
|
|
|
|
// was in config.cpp
|
|
|
|
int g_config_control_panel = 0;
|
|
int g_config_kegs_update_needed = 0;
|
|
word32 g_cfg_vbl_count = 0;
|
|
int g_user_page2_shadow = 1;
|
|
int g_save_cur_a2_stat = 0;
|
|
|
|
const byte g_rom_c600_rom01_diffs[256] = {
|
|
0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xe2, 0x00,
|
|
0xd0, 0x50, 0x0f, 0x77, 0x5b, 0xb9, 0xc3, 0xb1,
|
|
0xb1, 0xf8, 0xcb, 0x4e, 0xb8, 0x60, 0xc7, 0x2e,
|
|
0xfc, 0xe0, 0xbf, 0x1f, 0x66, 0x37, 0x4a, 0x70,
|
|
0x55, 0x2c, 0x3c, 0xfc, 0xc2, 0xa5, 0x08, 0x29,
|
|
0xac, 0x21, 0xcc, 0x09, 0x55, 0x03, 0x17, 0x35,
|
|
0x4e, 0xe2, 0x0c, 0xe9, 0x3f, 0x9d, 0xc2, 0x06,
|
|
0x18, 0x88, 0x0d, 0x58, 0x57, 0x6d, 0x83, 0x8c,
|
|
0x22, 0xd3, 0x4f, 0x0a, 0xe5, 0xb7, 0x9f, 0x7d,
|
|
0x2c, 0x3e, 0xae, 0x7f, 0x24, 0x78, 0xfd, 0xd0,
|
|
0xb5, 0xd6, 0xe5, 0x26, 0x85, 0x3d, 0x8d, 0xc9,
|
|
0x79, 0x0c, 0x75, 0xec, 0x98, 0xcc, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x39, 0x00, 0x35, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00,
|
|
0x6c, 0x44, 0xce, 0x4c, 0x01, 0x08, 0x00, 0x00
|
|
};
|
|
|
|
extern void x_config_load_roms();
|
|
extern void x_config_load_additional_roms();
|
|
|
|
|
|
|
|
void
|
|
config_load_roms()
|
|
{
|
|
int more_than_8mb;
|
|
int changed_rom;
|
|
int i;
|
|
|
|
// OG load roms
|
|
if (g_driver.x_config_load_roms==NULL)
|
|
x_fatal_exit("missing rom");
|
|
|
|
g_driver.x_config_load_roms();
|
|
|
|
memset(&g_rom_cards_ptr[0], 0, 256*16);
|
|
|
|
if (g_sim65816.g_rom_version < 0)
|
|
{
|
|
// No need to
|
|
return ;
|
|
}
|
|
|
|
/* initialize c600 rom to be diffs from the real ROM, to build-in */
|
|
/* Apple II compatibility without distributing ROMs */
|
|
for(i = 0; i < 256; i++) {
|
|
g_rom_cards_ptr[0x600 + i] = g_rom_fc_ff_ptr[0x3c600 + i] ^
|
|
g_rom_c600_rom01_diffs[i];
|
|
}
|
|
|
|
if(g_sim65816.g_rom_version >= 3) {
|
|
/* some patches */
|
|
g_rom_cards_ptr[0x61b] ^= 0x40;
|
|
g_rom_cards_ptr[0x61c] ^= 0x33;
|
|
g_rom_cards_ptr[0x632] ^= 0xc0;
|
|
g_rom_cards_ptr[0x633] ^= 0x33;
|
|
}
|
|
|
|
|
|
x_config_load_additional_roms();
|
|
|
|
more_than_8mb = (g_sim65816.g_mem_size_exp > 0x800000);
|
|
/* Only do the patch if users wants more than 8MB of expansion mem */
|
|
|
|
changed_rom = 0;
|
|
if(g_sim65816.g_rom_version == 1) {
|
|
/* make some patches to ROM 01 */
|
|
#if 0
|
|
/* 1: Patch ROM selftest to not do speed test */
|
|
printf("Patching out speed test failures from ROM 01\n");
|
|
g_rom_fc_ff_ptr[0x3785a] = 0x18;
|
|
changed_rom = 1;
|
|
#endif
|
|
|
|
#if 0
|
|
/* 2: Patch ROM selftests not to do tests 2,4 */
|
|
/* 0 = skip, 1 = do it, test 1 is bit 0 of LSByte */
|
|
g_rom_fc_ff_ptr[0x371e9] = 0xf5;
|
|
g_rom_fc_ff_ptr[0x371ea] = 0xff;
|
|
changed_rom = 1;
|
|
#endif
|
|
|
|
|
|
if(more_than_8mb) {
|
|
/* Geoff Weiss patch to use up to 14MB of RAM */
|
|
g_rom_fc_ff_ptr[0x30302] = 0xdf;
|
|
g_rom_fc_ff_ptr[0x30314] = 0xdf;
|
|
g_rom_fc_ff_ptr[0x3031c] = 0x00;
|
|
changed_rom = 1;
|
|
}
|
|
|
|
/* Patch ROM selftest to not do ROM cksum if any changes*/
|
|
if(changed_rom) {
|
|
g_rom_fc_ff_ptr[0x37a06] = 0x18;
|
|
g_rom_fc_ff_ptr[0x37a07] = 0x18;
|
|
}
|
|
} else if(g_sim65816.g_rom_version == 3) {
|
|
/* patch ROM 03 */
|
|
printf("Patching ROM 03 smartport bug\n");
|
|
/* 1: Patch Smartport code to fix a stupid bug */
|
|
/* that causes it to write the IWM status reg into c036, */
|
|
/* which is the system speed reg...it's "safe" since */
|
|
/* IWM status reg bit 4 must be 0 (7MHz)..., otherwise */
|
|
/* it might have turned on shadowing in all banks! */
|
|
g_rom_fc_ff_ptr[0x357c9] = 0x00;
|
|
changed_rom = 1;
|
|
|
|
#if 0
|
|
/* patch ROM 03 to not to speed test */
|
|
/* skip fast speed test */
|
|
g_rom_fc_ff_ptr[0x36ad7] = 0x18;
|
|
g_rom_fc_ff_ptr[0x36ad8] = 0x18;
|
|
changed_rom = 1;
|
|
#endif
|
|
|
|
#if 0
|
|
/* skip slow speed test */
|
|
g_rom_fc_ff_ptr[0x36ae7] = 0x18;
|
|
g_rom_fc_ff_ptr[0x36ae8] = 0x6b;
|
|
changed_rom = 1;
|
|
#endif
|
|
|
|
#if 0
|
|
/* 4: Patch ROM 03 selftests not to do tests 1-4 */
|
|
g_rom_fc_ff_ptr[0x364a9] = 0xf0;
|
|
g_rom_fc_ff_ptr[0x364aa] = 0xff;
|
|
changed_rom = 1;
|
|
#endif
|
|
|
|
/* ROM tests are in ff/6403-642x, where 6403 = addr of */
|
|
/* test 1, etc. */
|
|
|
|
if(more_than_8mb) {
|
|
/* Geoff Weiss patch to use up to 14MB of RAM */
|
|
g_rom_fc_ff_ptr[0x30b] = 0xdf;
|
|
g_rom_fc_ff_ptr[0x31d] = 0xdf;
|
|
g_rom_fc_ff_ptr[0x325] = 0x00;
|
|
changed_rom = 1;
|
|
}
|
|
|
|
if(changed_rom) {
|
|
/* patch ROM 03 selftest to not do ROM cksum */
|
|
g_rom_fc_ff_ptr[0x36cb0] = 0x18;
|
|
g_rom_fc_ff_ptr[0x36cb1] = 0x18;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Disk *
|
|
cfg_get_dsk_from_slot_drive(int slot, int drive)
|
|
{
|
|
Disk *dsk;
|
|
int max_drive;
|
|
|
|
/* Get dsk */
|
|
max_drive = 2;
|
|
switch(slot) {
|
|
case 5:
|
|
dsk = &(g_iwm.iwm.drive35[drive]);
|
|
break;
|
|
case 6:
|
|
dsk = &(g_iwm.iwm.drive525[drive]);
|
|
break;
|
|
default:
|
|
max_drive = MAX_C7_DISKS;
|
|
dsk = &(g_iwm.iwm.smartport[drive]);
|
|
break;
|
|
}
|
|
|
|
if(drive >= max_drive) {
|
|
dsk -= drive; /* move back to drive 0 effectively */
|
|
}
|
|
dsk->slot = slot;
|
|
dsk->disk = drive+1;
|
|
return dsk;
|
|
}
|
|
|
|
|
|
void
|
|
insert_disk(int slot, int drive, const char *name, int ejected, int force_size,
|
|
const char *partition_name, int part_num)
|
|
{
|
|
byte buf_2img[512];
|
|
Disk *dsk;
|
|
|
|
|
|
// char *part_ptr;
|
|
int size;
|
|
#if 0
|
|
// char *name_ptr;
|
|
char *uncomp_ptr, *system_str;
|
|
int system_len;
|
|
#endif
|
|
// int part_len;
|
|
int cmp_o, cmp_p, cmp_dot;
|
|
int cmp_b, cmp_i, cmp_n;
|
|
int can_write;
|
|
int len;
|
|
int nibs;
|
|
int unix_pos;
|
|
size_t name_len;
|
|
int image_identified;
|
|
int exp_size;
|
|
int save_track;
|
|
int ret;
|
|
int tmp;
|
|
int i;
|
|
|
|
|
|
g_config_kegs_update_needed = 1;
|
|
|
|
if((slot < 5) || (slot > 7)) {
|
|
fatal_printf("Invalid slot for inserting disk: %d\n", slot);
|
|
return;
|
|
}
|
|
if(drive < 0 || ((slot == 7) && (drive >= MAX_C7_DISKS)) ||
|
|
((slot < 7) && (drive > 1))) {
|
|
fatal_printf("Invalid drive for inserting disk: %d\n", drive);
|
|
return;
|
|
}
|
|
|
|
dsk = cfg_get_dsk_from_slot_drive(slot, drive);
|
|
|
|
// OG Do not insert same disk at same place
|
|
if (( dsk->name_ptr && name) && !strcmp(dsk->name_ptr,name)) return ;
|
|
|
|
#if 0
|
|
printf("Inserting disk %s (%s or %d) in slot %d, drive: %d\n", name,
|
|
partition_name, part_num, slot, drive);
|
|
#endif
|
|
|
|
dsk->just_ejected = 0;
|
|
dsk->force_size = force_size;
|
|
|
|
if(dsk->fd >= 0) {
|
|
eject_disk(dsk);
|
|
}
|
|
|
|
// OG check for valid name first
|
|
if (!name) return ;
|
|
|
|
/* Before opening, make sure no other mounted disk has this name */
|
|
/* If so, unmount it */
|
|
if(!ejected) {
|
|
for(i = 0; i < 2; i++) {
|
|
eject_named_disk(&g_iwm.iwm.drive525[i], name,partition_name);
|
|
eject_named_disk(&g_iwm.iwm.drive35[i], name, partition_name);
|
|
}
|
|
for(i = 0; i < MAX_C7_DISKS; i++) {
|
|
eject_named_disk(&g_iwm.iwm.smartport[i],name,partition_name);
|
|
}
|
|
}
|
|
|
|
/*
|
|
if(dsk->name_ptr != 0) {
|
|
// free old name_ptr
|
|
free(dsk->name_ptr);
|
|
}
|
|
*/
|
|
|
|
name_len = strlen(name);
|
|
strncpy(dsk->name_ptr,name,MAX_DISK_NAME);
|
|
/*
|
|
name_len = strlen(name);
|
|
name_ptr = (char *)malloc(name_len + 1);
|
|
strncpy(name_ptr, name, name_len + 1);
|
|
dsk->name_ptr = name_ptr;
|
|
*/
|
|
|
|
// dsk->partition_name = 0;
|
|
dsk->partition_name[0] = 0;
|
|
|
|
if(partition_name != 0) {
|
|
/*
|
|
part_len = strlen(partition_name) + 1;
|
|
part_ptr = (char *)malloc(part_len);
|
|
strncpy(part_ptr, partition_name, part_len);
|
|
dsk->partition_name = part_ptr;
|
|
*/
|
|
strncpy(dsk->partition_name,partition_name,MAX_DISK_NAME);
|
|
}
|
|
dsk->partition_num = part_num;
|
|
|
|
iwm_printf("Opening up disk image named: %s\n", dsk->name_ptr);
|
|
|
|
if(ejected) {
|
|
/* just get out of here */
|
|
dsk->fd = -1;
|
|
return;
|
|
}
|
|
|
|
dsk->fd = -1;
|
|
|
|
#ifdef ACTIVEGSKARATEKA
|
|
can_write = 0;
|
|
#else
|
|
can_write = 1;
|
|
#endif
|
|
|
|
//OG discard .GZ support
|
|
#if 0
|
|
if((name_len > 3) && (strcmp(&name_ptr[name_len - 3], ".gz") == 0)) {
|
|
|
|
/* it's gzip'ed, try to gunzip it, then unlink the */
|
|
/* uncompressed file */
|
|
|
|
can_write = 0;
|
|
|
|
uncomp_ptr = (char *)malloc(name_len + 1);
|
|
strncpy(uncomp_ptr, name_ptr, name_len + 1);
|
|
uncomp_ptr[name_len - 3] = 0;
|
|
|
|
system_len = 2*name_len + 100;
|
|
system_str = (char *)malloc(system_len + 1);
|
|
snprintf(system_str, system_len,
|
|
"set -o noclobber;gunzip -c %c%s%c > %c%s%c",
|
|
0x22, name_ptr, 0x22,
|
|
0x22, uncomp_ptr, 0x22);
|
|
/* 0x22 are " to allow spaces in filenames */
|
|
printf("I am uncompressing %s into %s for mounting\n",
|
|
name_ptr, uncomp_ptr);
|
|
ret = system(system_str);
|
|
if(ret == 0) {
|
|
/* successfully ran */
|
|
dsk->fd = open(uncomp_ptr, O_RDONLY | O_BINARY, 0x1b6);
|
|
iwm_printf("Opening .gz file %s is fd: %d\n",
|
|
uncomp_ptr, dsk->fd);
|
|
|
|
/* and, unlink the temporary file */
|
|
(void)unlink(uncomp_ptr);
|
|
}
|
|
free(system_str);
|
|
free(uncomp_ptr);
|
|
/* Reduce name_len by 3 so that subsequent compares for .po */
|
|
/* look at the correct chars */
|
|
name_len -= 3;
|
|
}
|
|
#endif // OG
|
|
|
|
if(dsk->fd < 0 && can_write) {
|
|
dsk->fd = open(dsk->name_ptr, O_RDWR | O_BINARY, 0x1b6);
|
|
}
|
|
|
|
if(dsk->fd < 0 /*&& can_write*/) {
|
|
printf("Trying to open %s read-only, errno: %d\n", dsk->name_ptr,
|
|
errno);
|
|
dsk->fd = open(dsk->name_ptr, O_RDONLY | O_BINARY, 0x1b6);
|
|
can_write = 0;
|
|
}
|
|
|
|
iwm_printf("open returned: %d\n", dsk->fd);
|
|
|
|
if(dsk->fd < 0) {
|
|
fatal_printf("Disk image %s does not exist!\n", dsk->name_ptr);
|
|
return;
|
|
}
|
|
|
|
if(can_write != 0) {
|
|
dsk->write_prot = 0;
|
|
dsk->write_through_to_unix = 1;
|
|
} else {
|
|
dsk->write_prot = 1;
|
|
dsk->write_through_to_unix = 0;
|
|
}
|
|
|
|
save_track = dsk->cur_qtr_track; /* save arm position */
|
|
dsk->image_type = DSK_TYPE_PRODOS;
|
|
dsk->image_start = 0;
|
|
|
|
/* See if it is in 2IMG format */
|
|
ret = read(dsk->fd, (char *)&buf_2img[0], 512);
|
|
size = force_size;
|
|
if(size <= 0) {
|
|
size = cfg_get_fd_size(dsk->fd) ;
|
|
}
|
|
|
|
/* Try to guess that there is a Mac Binary header of 128 bytes */
|
|
/* See if image size & 0xfff = 0x080 which indicates extra 128 bytes */
|
|
if((size & 0xfff) == 0x080) {
|
|
printf("Assuming Mac Binary header on %s\n", dsk->name_ptr);
|
|
dsk->image_start += 0x80;
|
|
}
|
|
image_identified = 0;
|
|
if(buf_2img[0] == '2' && buf_2img[1] == 'I' && buf_2img[2] == 'M' &&
|
|
buf_2img[3] == 'G') {
|
|
|
|
// OG Put back Gilles Tschopp hack to deal with corrupted 2IMG files
|
|
size -= 64;
|
|
size = size & -0x1000;
|
|
|
|
/* It's a 2IMG disk */
|
|
#ifdef _DEBUG
|
|
printf("Image named %s is in 2IMG format\n", dsk->name_ptr);
|
|
#endif
|
|
image_identified = 1;
|
|
|
|
if(buf_2img[12] == 0) {
|
|
printf("2IMG is in DOS 3.3 sector order\n");
|
|
dsk->image_type = DSK_TYPE_DOS33;
|
|
}
|
|
if(buf_2img[19] & 0x80) {
|
|
/* disk is locked */
|
|
printf("2IMG is write protected\n");
|
|
dsk->write_prot = 1;
|
|
dsk->write_through_to_unix = 0;
|
|
}
|
|
if((buf_2img[17] & 1) && (dsk->image_type == DSK_TYPE_DOS33)) {
|
|
dsk->vol_num = buf_2img[16];
|
|
printf("Setting DOS 3.3 vol num to %d\n", dsk->vol_num);
|
|
}
|
|
|
|
// OG do not overwrite when 2mg size = 0
|
|
int size2img = (buf_2img[31] << 24) + (buf_2img[30] << 16) + (buf_2img[29] << 8) + buf_2img[28];
|
|
if (size2img) size = size2img;
|
|
else printf(".2MG has corrupted size - fixed.\n");
|
|
|
|
unix_pos = (buf_2img[27] << 24) + (buf_2img[26] << 16) +
|
|
(buf_2img[25] << 8) + buf_2img[24];
|
|
// Some 2IMG archives have the size byte reversed
|
|
if(size == 0x800c00) {
|
|
// Byte reversed 0x0c8000
|
|
size = 0x0c8000;
|
|
}
|
|
dsk->image_start = unix_pos;
|
|
dsk->image_size = size;
|
|
}
|
|
exp_size = 800*1024;
|
|
if(dsk->disk_525) {
|
|
exp_size = 140*1024;
|
|
}
|
|
if(!image_identified) {
|
|
/* See if it might be the Mac diskcopy format */
|
|
tmp = (buf_2img[0x40] << 24) + (buf_2img[0x41] << 16) +
|
|
(buf_2img[0x42] << 8) + buf_2img[0x43];
|
|
if((size >= (exp_size + 0x54)) && (tmp == exp_size)) {
|
|
/* It's diskcopy since data size field matches */
|
|
printf("Image named %s is in Mac diskcopy format\n",
|
|
dsk->name_ptr);
|
|
image_identified = 1;
|
|
dsk->image_start += 0x54;
|
|
dsk->image_size = exp_size;
|
|
dsk->image_type = DSK_TYPE_PRODOS; /* ProDOS */
|
|
}
|
|
}
|
|
if(!image_identified) {
|
|
/* Assume raw image */
|
|
dsk->image_size = size;
|
|
dsk->image_type = DSK_TYPE_PRODOS;
|
|
if(dsk->disk_525) {
|
|
dsk->image_type = DSK_TYPE_DOS33;
|
|
|
|
if(name_len >= 4) {
|
|
cmp_o = dsk->name_ptr[name_len-1];
|
|
cmp_p = dsk->name_ptr[name_len-2];
|
|
cmp_dot = dsk->name_ptr[name_len-3];
|
|
if(cmp_dot == '.' &&
|
|
(cmp_p == 'p' || cmp_p == 'P') &&
|
|
(cmp_o == 'o' || cmp_o == 'O')) {
|
|
dsk->image_type = DSK_TYPE_PRODOS;
|
|
}
|
|
|
|
cmp_b = dsk->name_ptr[name_len-1];
|
|
cmp_i = dsk->name_ptr[name_len-2];
|
|
cmp_n = dsk->name_ptr[name_len-3];
|
|
cmp_dot = dsk->name_ptr[name_len-4];
|
|
if(cmp_dot == '.' &&
|
|
(cmp_n == 'n' || cmp_n == 'N') &&
|
|
(cmp_i == 'i' || cmp_i == 'I') &&
|
|
(cmp_b == 'b' || cmp_b == 'B')) {
|
|
dsk->image_type = DSK_TYPE_NIB;
|
|
dsk->write_prot = 0; // OG : Remove WriteProtect on .nib !!!! TO REACTIVATE !!
|
|
dsk->write_through_to_unix = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
dsk->disk_dirty = 0;
|
|
dsk->nib_pos = 0;
|
|
dsk->trks = 0;
|
|
|
|
if(dsk->smartport) {
|
|
g_iwm.g_highest_smartport_unit = MAX(dsk->drive,g_iwm.g_highest_smartport_unit);
|
|
|
|
// OG Disabled partition support
|
|
#ifndef ACTIVEGS
|
|
if( (partition_name != NULL && *partition_name ) || part_num >= 0) {
|
|
ret = cfg_partition_find_by_name_or_num(dsk->fd,
|
|
partition_name, part_num, dsk);
|
|
printf("partition %s (num %d) mounted, wr_prot: %d\n",
|
|
partition_name, part_num, dsk->write_prot);
|
|
|
|
if(ret < 0) {
|
|
close(dsk->fd);
|
|
dsk->fd = -1;
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
iwm_printf("adding smartport device[%d], size:%08x, "
|
|
"img_sz:%08x\n", dsk->drive, dsk->trks[0].unix_len,
|
|
dsk->image_size);
|
|
} else if(dsk->disk_525) {
|
|
unix_pos = dsk->image_start;
|
|
size = dsk->image_size;
|
|
disk_set_num_tracks(dsk, 4*35);
|
|
len = 0x1000;
|
|
nibs = NIB_LEN_525;
|
|
if(dsk->image_type == DSK_TYPE_NIB) {
|
|
len = dsk->image_size / 35;;
|
|
nibs = len;
|
|
}
|
|
if(size != 35*len) {
|
|
fatal_printf("Disk 5.25 error: size is %d, not 140K. "
|
|
"Will try to mount anyway\n", size, 35*len);
|
|
}
|
|
for(i = 0; i < 35; i++) {
|
|
iwm_move_to_track(dsk, 4*i);
|
|
disk_unix_to_nib(dsk, 4*i, unix_pos, len, nibs);
|
|
unix_pos += len;
|
|
}
|
|
} else {
|
|
/* disk_35 */
|
|
unix_pos = dsk->image_start;
|
|
size = dsk->image_size;
|
|
if(size != 800*1024) {
|
|
fatal_printf("Disk 3.5 error: size is %d, not 800K. "
|
|
"Will try to mount anyway\n", size);
|
|
}
|
|
disk_set_num_tracks(dsk, 2*80);
|
|
for(i = 0; i < 2*80; i++) {
|
|
iwm_move_to_track(dsk, i);
|
|
len = g_track_bytes_35[i >> 5];
|
|
nibs = g_track_nibs_35[i >> 5];
|
|
iwm_printf("Trk: %d.%d = unix: %08x, %04x, %04x\n",
|
|
i>>1, i & 1, unix_pos, len, nibs);
|
|
disk_unix_to_nib(dsk, i, unix_pos, len, nibs);
|
|
unix_pos += len;
|
|
|
|
iwm_printf(" trk_len:%05x\n", dsk->trks[i].track_len);
|
|
}
|
|
}
|
|
|
|
iwm_move_to_track(dsk, save_track);
|
|
|
|
x_notify_disk_insertion(dsk->image_size,dsk->image_start,(dsk->image_type == DSK_TYPE_PRODOS),slot,drive);
|
|
|
|
}
|
|
|
|
void
|
|
eject_named_disk(Disk *dsk, const char *name, const char *partition_name)
|
|
{
|
|
|
|
if(dsk->fd < 0) {
|
|
return;
|
|
}
|
|
|
|
/* If name matches, eject the disk! */
|
|
if(!strcmp(dsk->name_ptr, name)) {
|
|
/* It matches, eject it */
|
|
if((partition_name != 0) && (dsk->partition_name != 0)) {
|
|
/* If both have partitions, and they differ, then */
|
|
/* don't eject. Otherwise, eject */
|
|
if(strcmp(dsk->partition_name, partition_name) != 0) {
|
|
/* Don't eject */
|
|
return;
|
|
}
|
|
}
|
|
eject_disk(dsk);
|
|
}
|
|
}
|
|
|
|
void
|
|
eject_disk_by_num(int slot, int drive)
|
|
{
|
|
Disk *dsk;
|
|
|
|
dsk = cfg_get_dsk_from_slot_drive(slot, drive);
|
|
|
|
eject_disk(dsk);
|
|
}
|
|
|
|
void
|
|
eject_disk(Disk *dsk)
|
|
{
|
|
int motor_on;
|
|
int i;
|
|
|
|
if(dsk->fd < 0) {
|
|
return;
|
|
}
|
|
|
|
g_config_kegs_update_needed = 1;
|
|
|
|
motor_on = g_iwm.iwm.motor_on;
|
|
if(g_moremem.g_c031_disk35 & 0x40) {
|
|
motor_on = g_iwm.iwm.motor_on35;
|
|
}
|
|
if(motor_on) {
|
|
halt_printf("Try eject dsk:%s, but motor_on!\n", dsk->name_ptr);
|
|
}
|
|
|
|
iwm_flush_disk_to_unix(dsk);
|
|
|
|
printf("Ejecting disk: %s\n", dsk->name_ptr);
|
|
|
|
/* Free all memory, close file */
|
|
|
|
/* free the tracks first */
|
|
if(dsk->trks != 0) {
|
|
for(i = 0; i < dsk->num_tracks; i++) {
|
|
if(dsk->trks[i].nib_area) {
|
|
free(dsk->trks[i].nib_area);
|
|
}
|
|
dsk->trks[i].nib_area = 0;
|
|
dsk->trks[i].track_len = 0;
|
|
}
|
|
free(dsk->trks);
|
|
}
|
|
dsk->num_tracks = 0;
|
|
dsk->trks = 0;
|
|
|
|
/* close file, clean up dsk struct */
|
|
close(dsk->fd);
|
|
|
|
dsk->image_start = 0;
|
|
dsk->image_size = 0;
|
|
dsk->nib_pos = 0;
|
|
dsk->disk_dirty = 0;
|
|
dsk->write_through_to_unix = 0;
|
|
dsk->write_prot = 1;
|
|
dsk->fd = -1;
|
|
dsk->just_ejected = 1;
|
|
|
|
/* Leave name_ptr valid */ // OG WHY?
|
|
|
|
/*
|
|
if (dsk->name_ptr)
|
|
{
|
|
free(dsk->name_ptr);
|
|
dsk->name_ptr = NULL;
|
|
}
|
|
*/
|
|
dsk->name_ptr[0]=0;
|
|
}
|
|
|
|
|
|
int
|
|
cfg_get_fd_size(int fd)
|
|
{
|
|
struct stat stat_buf;
|
|
int ret;
|
|
|
|
ret = fstat(fd, &stat_buf);
|
|
if(ret != 0) {
|
|
fprintf(stderr,"fstat returned %d on fd %d, errno: %d\n",
|
|
ret, fd, errno);
|
|
stat_buf.st_size = 0;
|
|
}
|
|
|
|
return (int)stat_buf.st_size;
|
|
}
|