diff --git a/src/86box.h b/src/86box.h index 9b3ed2a63..2a7f52999 100644 --- a/src/86box.h +++ b/src/86box.h @@ -8,13 +8,13 @@ * * Main include file for the application. * - * Version: @(#)86box.h 1.0.16 2017/12/09 + * Version: @(#)86box.h 1.0.17 2018/01/18 * * Authors: Miran Grca, * Fred N. van Kempen, * - * Copyright 2016-2017 Miran Grca. - * Copyright 2017 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #ifndef EMU_86BOX_H # define EMU_86BOX_H @@ -68,6 +68,11 @@ extern int force_debug; /* (O) force debug output */ #ifdef USE_WX extern int video_fps; /* (O) render speed in fps */ #endif +extern int settings_only; /* (O) show only the settings dialog */ +#ifdef _WIN32 +extern uint64_t unique_id; +extern uint64_t source_hwnd; +#endif extern wchar_t log_path[1024]; /* (O) full path of logfile */ diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 85975efdc..95cee85b5 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -8,7 +8,7 @@ * * Implementation of the floppy drive emulation. * - * Version: @(#)fdd.c 1.0.6 2018/01/16 + * Version: @(#)fdd.c 1.0.7 2018/01/18 * * Authors: Sarah Walker, * Miran Grca, @@ -232,8 +232,9 @@ int fdd_get_from_internal_name(char *s) /* This is needed for the dump as 86F feature. */ void fdd_do_seek(int drive, int track) { - if (drives[drive].seek) - drives[drive].seek(drive, fdd[drive].track); + if (drives[drive].seek) { + drives[drive].seek(drive, track); + } } void fdd_forced_seek(int drive, int track_diff) diff --git a/src/floppy/fdd.h b/src/floppy/fdd.h index 6ca86ed16..8b05881ef 100644 --- a/src/floppy/fdd.h +++ b/src/floppy/fdd.h @@ -8,7 +8,7 @@ * * Implementation of the floppy drive emulation. * - * Version: @(#)fdd.h 1.0.4 2018/01/16 + * Version: @(#)fdd.h 1.0.5 2018/01/18 * * Authors: Sarah Walker, * Miran Grca, @@ -274,6 +274,8 @@ void img_set_fdc(void *fdc); extern void d86f_set_cur_track(int drive, int track); extern void d86f_zero_track(int drive); +extern int d86f_export(int drive, wchar_t *fn); + #ifdef __cplusplus } #endif diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 4804f9bcf..c0350d6fc 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -10,7 +10,7 @@ * data in the form of FM/MFM-encoded transitions) which also * forms the core of the emulator's floppy disk emulation. * - * Version: @(#)fdd_86f.c 1.0.13 2018/01/16 + * Version: @(#)fdd_86f.c 1.0.14 2018/01/18 * * Author: Miran Grca, * Copyright 2016-2018 Miran Grca. @@ -23,6 +23,7 @@ #include #include #include "../lzf/lzf.h" +#define HAVE_STDARG_H #include "../86box.h" #include "../config.h" #include "../dma.h" @@ -239,7 +240,7 @@ struct uint32_t dma_over; int turbo_pos; uint16_t sector_id_bit_field[2][256][256][256]; -} d86f[FDD_NUM]; +} d86f[FDD_NUM + 1]; #pragma pack(pop) @@ -257,7 +258,7 @@ d86f_log(const char *format, ...) if (d86f_do_log) { va_start(ap, format); - pclog(format, ap); + pclog_ex(format, ap); va_end(ap); } #endif @@ -705,7 +706,7 @@ uint32_t d86f_get_data_len(int drive) uint32_t d86f_has_extra_bit_cells(int drive) { - return (d86f_disk_flags(drive) >> 7) & 1; + return (d86f_handler[drive].disk_flags(drive) >> 7) & 1; } uint32_t d86f_header_size(int drive) @@ -1316,7 +1317,7 @@ void d86f_read_sector_id(int drive, int side, int match) if (d86f[drive].calc_crc.word != d86f[drive].track_crc.word) { d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = 0; - pclog("86F: ID CRC error: %04X != %04X (%08X)\n", d86f[drive].track_crc.word, d86f[drive].calc_crc.word, d86f[drive].last_sector.dword); + d86f_log("86F: ID CRC error: %04X != %04X (%08X)\n", d86f[drive].track_crc.word, d86f[drive].calc_crc.word, d86f[drive].last_sector.dword); if ((d86f[drive].state != STATE_02_READ_ID) && (d86f[drive].state != STATE_0A_READ_ID)) { d86f[drive].error_condition = 0; @@ -1508,7 +1509,7 @@ void d86f_read_sector_data(int drive, int side) if ((d86f[drive].calc_crc.word != d86f[drive].track_crc.word) && (d86f[drive].state != STATE_02_READ_DATA)) { - pclog("86F: Data CRC error: %04X != %04X (%08X)\n", d86f[drive].track_crc.word, d86f[drive].calc_crc.word, d86f[drive].last_sector.dword); + d86f_log("86F: Data CRC error: %04X != %04X (%08X)\n", d86f[drive].track_crc.word, d86f[drive].calc_crc.word, d86f[drive].last_sector.dword); d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0; d86f[drive].error_condition = 0; d86f[drive].state = STATE_IDLE; @@ -2966,14 +2967,18 @@ void d86f_seek(int drive, int track) void d86f_write_track(int drive, FILE **f, int side, uint16_t *da0, uint16_t *sa0) { - fwrite(&(d86f[drive].side_flags[side]), 1, 2, *f); + uint16_t side_flags = d86f_handler[drive].side_flags(drive); + uint32_t extra_bit_cells = d86f_handler[drive].extra_bit_cells(drive, side); + uint32_t index_hole_pos = d86f_handler[drive].index_hole_pos(drive, side); + + fwrite(&side_flags, 1, 2, *f); if (d86f_has_extra_bit_cells(drive)) { - fwrite(&(d86f[drive].extra_bit_cells[side]), 1, 4, *f); + fwrite(&extra_bit_cells, 1, 4, *f); } - fwrite(&(d86f[drive].index_hole_pos[side]), 1, 4, *f); + fwrite(&index_hole_pos, 1, 4, *f); if (d86f_has_surface_desc(drive)) { @@ -3000,22 +3005,27 @@ void d86f_set_cur_track(int drive, int track) d86f[drive].cur_track = track; } -void d86f_write_tracks(int drive, FILE **f) +void d86f_write_tracks(int drive, FILE **f, uint32_t *track_table) { int sides; int side, thin_track; int logical_track = 0; sides = d86f_get_sides(drive); + uint32_t *tbl = d86f[drive].track_offset; + if (track_table) + tbl = track_table; + int fdd_side = fdd_get_head(drive); if (!fdd_doublestep_40(drive)) { for (side = 0; side < sides; side++) { + fdd_set_head(drive, side); d86f_decompose_encoded_buffer(drive, side); for (thin_track = 0; thin_track < 2; thin_track++) { - if (d86f_get_sides(drive) == 2) + if (sides == 2) { logical_track = ((d86f[drive].cur_track + thin_track) << 1) + side; } @@ -3023,9 +3033,14 @@ void d86f_write_tracks(int drive, FILE **f) { logical_track = d86f[drive].cur_track + thin_track; } - if (d86f[drive].track_offset[logical_track]) + if (track_table && !tbl[logical_track]) { - fseek(*f, d86f[drive].track_offset[logical_track], SEEK_SET); + fseek(*f, 0, SEEK_END); + track_table[logical_track] = ftell(*f); + } + if (tbl[logical_track]) + { + fseek(*f, tbl[logical_track], SEEK_SET); d86f_write_track(drive, f, side, d86f[drive].thin_track_encoded_data[thin_track][side], d86f[drive].thin_track_surface_data[thin_track][side]); } } @@ -3035,7 +3050,8 @@ void d86f_write_tracks(int drive, FILE **f) { for (side = 0; side < sides; side++) { - if (d86f_get_sides(drive) == 2) + fdd_set_head(drive, side); + if (sides == 2) { logical_track = (d86f[drive].cur_track << 1) + side; } @@ -3043,13 +3059,20 @@ void d86f_write_tracks(int drive, FILE **f) { logical_track = d86f[drive].cur_track; } - if (d86f[drive].track_offset[logical_track]) + if (track_table && !tbl[logical_track]) { - fseek(*f, d86f[drive].track_offset[logical_track], SEEK_SET); + fseek(*f, 0, SEEK_END); + track_table[logical_track] = ftell(*f); + } + if (tbl[logical_track]) + { + fseek(*f, tbl[logical_track], SEEK_SET); d86f_write_track(drive, f, side, d86f[drive].track_encoded_data[side], d86f[drive].track_surface_data[side]); } } } + + fdd_set_head(drive, fdd_side); } void d86f_writeback(int drive) @@ -3073,7 +3096,7 @@ void d86f_writeback(int drive) fseek(d86f[drive].f, 8, SEEK_SET); fwrite(d86f[drive].track_offset, 1, d86f_get_track_table_size(drive), d86f[drive].f); - d86f_write_tracks(drive, &d86f[drive].f); + d86f_write_tracks(drive, &d86f[drive].f, NULL); if (d86f[drive].is_compressed) { @@ -3359,6 +3382,61 @@ void d86f_common_handlers(int drive) drives[drive].stop = d86f_stop; } +int d86f_export(int drive, wchar_t *fn) +{ + FILE *f; + uint32_t tt[512]; + + int tracks = 86; + int i; + + uint32_t magic = 0x46423638; + uint16_t version = 0x020B; + + uint16_t disk_flags = d86f_handler[drive].disk_flags(drive); + + uint32_t struct_size = sizeof(d86f) / (FDD_NUM + 1); + + memset(tt, 0, 512 * sizeof(uint32_t)); + + memcpy(&(d86f[4]), &(d86f[drive]), struct_size); + + f = plat_fopen(fn, L"wb"); + if (!f) + return 0; + + fwrite(&magic, 4, 1, f); + fwrite(&version, 2, 1, f); + fwrite(&disk_flags, 2, 1, f); + + fwrite(tt, 1, ((d86f_get_sides(drive) == 2) ? 2048 : 1024), f); + + /* Do this do teremine how many tracks to actually output. */ + fdd_do_seek(drive, 2); + if (d86f[drive].cur_track == 1) + tracks >>= 1; + + for (i = 0; i < tracks; i++) { + fdd_do_seek(drive, i); + d86f_write_tracks(drive, &f, tt); + } + + fclose(f); + + f = plat_fopen(fn, L"rb+"); + + fseek(f, 8, SEEK_SET); + fwrite(tt, 1, ((d86f_get_sides(drive) == 2) ? 2048 : 1024), f); + + fclose(f); + + fdd_do_seek(drive, fdd_current_track(drive)); + + memcpy(&(d86f[drive]), &(d86f[4]), struct_size); + + return 1; +} + void d86f_load(int drive, wchar_t *fn) { uint32_t magic = 0; @@ -3664,7 +3742,7 @@ void d86f_load(int drive, wchar_t *fn) void d86f_init() { - memset(d86f, 0, sizeof(d86f)); + memset(d86f, 0, sizeof(d86f)); d86f_setupcrc(0x1021); d86f[0].state = d86f[1].state = STATE_IDLE; diff --git a/src/floppy/fdd_86f.h b/src/floppy/fdd_86f.h index a04ddb2fa..983915fcb 100644 --- a/src/floppy/fdd_86f.h +++ b/src/floppy/fdd_86f.h @@ -10,7 +10,7 @@ * data in the form of FM/MFM-encoded transitions) which also * forms the core of the emulator's floppy disk emulation. * - * Version: @(#)floppy_86f.h 1.0.3 2018/01/17 + * Version: @(#)floppy_86f.h 1.0.4 2018/01/18 * * Author: Miran Grca, * Copyright 2016-2018 Miran Grca. @@ -39,7 +39,6 @@ extern void d86f_prepare_track_layout(int drive, int side); extern void d86f_set_version(int drive, uint16_t version); extern uint16_t d86f_side_flags(int drive); extern uint16_t d86f_track_flags(int drive); -extern void d86f_write_tracks(int drive, FILE **f); #define length_gap0 80 #define length_gap1 50 diff --git a/src/keyboard_at.c b/src/keyboard_at.c index cf9861ea8..180882887 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -8,7 +8,7 @@ * * Intel 8042 (AT keyboard controller) emulation. * - * Version: @(#)keyboard_at.c 1.0.24 2018/01/17 + * Version: @(#)keyboard_at.c 1.0.25 2018/01/18 * * Authors: Sarah Walker, * Miran Grca, @@ -1472,10 +1472,9 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0xd4: /*Write to mouse*/ kbdlog("ATkbd: write to mouse (%02X)\n", val); kbd_mouse_set(kbd, 1); - if (mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) { - pclog("Mouse write\n"); + if (mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) mouse_write(val, mouse_p); - } else if (!mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) { + else if (!mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) { pclog("Adding 0xFF to queue\n"); keyboard_at_adddata_mouse(0xff); } @@ -1786,7 +1785,6 @@ kbd_read(uint16_t port, void *priv) switch (port) { case 0x60: ret = kbd->out; - pclog("Reading: %02X\n", ret); kbd->status &= ~(STAT_OFULL); picintc(kbd->last_irq); kbd->last_irq = 0; @@ -2038,7 +2036,6 @@ keyboard_at_adddata_keyboard_raw(uint8_t val) void keyboard_at_adddata_mouse(uint8_t val) { - pclog("Adding mouse data: %02X\n", val); mouse_queue[mouse_queue_end] = val; mouse_queue_end = (mouse_queue_end + 1) & 0xf; } diff --git a/src/lang/language.h b/src/lang/language.h index 910bf1e0a..20af9142e 100644 --- a/src/lang/language.h +++ b/src/lang/language.h @@ -10,11 +10,11 @@ * * NOTE: FIXME: Strings 2176 and 2193 are same. * - * Version: @(#)language.h 1.0.4 2017/11/25 + * Version: @(#)language.h 1.0.5 2018/01/18 * - * Author: Fred N. van Kempem, + * Author: Fred N. van Kempen, * - * Copyright 2017 Fred N. van Kempen. + * Copyright 2017,2018 Fred N. van Kempen. */ #ifndef LANG_UAGE_H # define LANG_UAGE_H @@ -135,7 +135,7 @@ #define IDS_2159 2159 // "All floppy images (*.0??;*.." #define IDS_2160 2160 // "Configuration files (*.CF.." #define IDS_2161 2161 // "&New image..." -#define IDS_2162 2162 // "Existing image..." +#define IDS_2162 2162 // "&Existing image..." #define IDS_2163 2163 // "Existing image (&Write-pr..." #define IDS_2164 2164 // "E&ject" #define IDS_2165 2165 // "&Mute" @@ -145,6 +145,9 @@ #define IDS_2169 2169 // "Image (&Write-protected)..." #define IDS_2170 2170 // "Check BPB" #define IDS_2171 2171 // "Unable to initialize Flui.." +#define IDS_2172 2172 // "E&xport to 86F..." +#define IDS_2173 2173 // "Surface-based images (*.8.." +#define IDS_2174 2174 // "All floppy images (*.DSK..." #define IDS_4096 4096 // "Hard disk (%s)" #define IDS_4097 4097 // "%01i:%01i" @@ -201,11 +204,29 @@ #define IDS_5637 5637 // "ATAPI (PIO and DMA) (%01i:%01i)" #define IDS_5638 5638 // "SCSI (%02i:%02i)" -#define IDS_6144 6144 // "English (United States)" +#define IDS_5888 5888 // "160 kB" +#define IDS_5889 5889 // "180 kB" +#define IDS_5890 5890 // "320 kB" +#define IDS_5891 5891 // "360 kB" +#define IDS_5892 5892 // "640 kB" +#define IDS_5893 5893 // "720 kB" +#define IDS_5894 5894 // "1.2 MB" +#define IDS_5895 5895 // "1.25 MB" +#define IDS_5896 5896 // "1.44 MB" +#define IDS_5897 5897 // "DMF (cluster 1024)" +#define IDS_5898 5898 // "DMF (cluster 2048)" +#define IDS_5899 5899 // "2.88 MB" -#define IDS_LANG_ENUS IDS_6144 +#define IDS_6144 6144 // "Perfect RPM" +#define IDS_6145 6145 // "1%% below perfect RPM" +#define IDS_6146 6146 // "1.5%% below perfect RPM" +#define IDS_6147 6147 // "2%% below perfect RPM" -#define STR_NUM_2048 124 +#define IDS_7168 7168 // "English (United States)" + +#define IDS_LANG_ENUS IDS_7168 + +#define STR_NUM_2048 127 #define STR_NUM_3072 11 #define STR_NUM_4096 20 #define STR_NUM_4352 7 @@ -213,7 +234,9 @@ #define STR_NUM_5120 1 #define STR_NUM_5376 7 #define STR_NUM_5632 7 -#define STR_NUM_6144 1 +#define STR_NUM_5888 12 +#define STR_NUM_6144 4 +#define STR_NUM_7168 1 #endif /*LANG_UAGE_H*/ diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index 8d4d77d2b..98c28180a 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -50,6 +50,7 @@ static struct uint32_t split_addr, split_size; uint8_t mem_pos_regs[8]; + uint8_t mem_2mb_pos_regs[8]; } ps2; @@ -527,6 +528,24 @@ static void ps2_mca_board_common_init() lpt1_init(0x3bc); } +static uint8_t ps2_mem_expansion_read(int port, void *p) +{ + return ps2.mem_pos_regs[port & 7]; +} + +static void ps2_mem_expansion_write(int port, uint8_t val, void *p) +{ + if (port < 0x102 || port == 0x104) + return; + + ps2.mem_pos_regs[port & 7] = val; + + if (ps2.mem_pos_regs[2] & 1) + mem_mapping_enable(&ps2.expansion_mapping); + else + mem_mapping_disable(&ps2.expansion_mapping); +} + static void ps2_mca_board_model_50_init() { ps2_mca_board_common_init(); @@ -537,6 +556,58 @@ static void ps2_mca_board_model_50_init() ps2.planar_read = model_50_read; ps2.planar_write = model_50_write; + if (mem_size > 2048) + { + /* Only 2 MB supported on planar, create a memory expansion card for the rest */ + mem_mapping_set_addr(&ram_high_mapping, 0x100000, 0x160000); + + ps2.mem_pos_regs[0] = 0xff; + ps2.mem_pos_regs[1] = 0xfc; + + switch (mem_size/1024) + { + case 3: + ps2.mem_pos_regs[4] = 0xfc; /* 11 11 11 00 = 0 0 0 1 */ + break; + case 4: + ps2.mem_pos_regs[4] = 0xfe; /* 11 11 11 10 = 0 0 0 2 */ + break; + case 5: + ps2.mem_pos_regs[4] = 0xf2; /* 11 11 00 10 = 0 0 1 2 */ + break; + case 6: + ps2.mem_pos_regs[4] = 0xfa; /* 11 11 10 10 = 0 0 2 2 */ + break; + case 7: + ps2.mem_pos_regs[4] = 0xca; /* 11 00 10 10 = 0 1 2 2 */ + break; + case 8: + ps2.mem_pos_regs[4] = 0xea; /* 11 10 10 10 = 0 2 2 2 */ + break; + case 9: + ps2.mem_pos_regs[4] = 0x2a; /* 00 10 10 10 = 1 2 2 2 */ + break; + case 10: + ps2.mem_pos_regs[4] = 0xaa; /* 10 10 10 10 = 2 2 2 2 */ + break; + } + + mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL); + mem_mapping_add(&ps2.expansion_mapping, + 0x260000, + (mem_size - 2048)*1024, + mem_read_ram, + mem_read_ramw, + mem_read_raml, + mem_write_ram, + mem_write_ramw, + mem_write_raml, + &ram[0x260000], + MEM_MAPPING_INTERNAL, + NULL); + mem_mapping_disable(&ps2.expansion_mapping); + } + device_add(&ps1vga_device); } @@ -666,24 +737,6 @@ static void mem_encoding_write(uint16_t addr, uint8_t val, void *p) mem_encoding_update(); } -static uint8_t ps2_mem_expansion_read(int port, void *p) -{ - return ps2.mem_pos_regs[port & 7]; -} - -static void ps2_mem_expansion_write(int port, uint8_t val, void *p) -{ - if (port < 0x102 || port == 0x104) - return; - - ps2.mem_pos_regs[port & 7] = val; - - if (ps2.mem_pos_regs[2] & 1) - mem_mapping_enable(&ps2.expansion_mapping); - else - mem_mapping_disable(&ps2.expansion_mapping); -} - static void ps2_mca_board_model_80_type2_init(int is486) { ps2_mca_board_common_init(); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index b950d44fe..b92ff5392 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11,15 +11,15 @@ * NOTES: OpenAT wip for 286-class machine with open BIOS. * PS2_M80-486 wip, pending receipt of TRM's for machine. * - * Version: @(#)machine_table.c 1.0.12 2018/01/05 + * Version: @(#)machine_table.c 1.0.13 2018/01/19 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * * Copyright 2008-2018 Sarah Walker. - * Copyright 2016,2018 Miran Grca. - * Copyright 2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #include #include @@ -78,7 +78,7 @@ machine_t machines[] = { #endif { "[286 ISA] Toshiba 3100e", ROM_T3100E, "t3100e", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1024, 5120, 256, 63, machine_at_t3100e_init, NULL, nvr_at_close }, - { "[286 MCA] IBM PS/2 model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 16, 1, 63, machine_ps2_model_50_init, NULL, nvr_at_close }, + { "[286 MCA] IBM PS/2 model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 10, 1, 63, machine_ps2_model_50_init, NULL, nvr_at_close }, { "[386SX ISA] AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL, nvr_at_close }, { "[386SX ISA] Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 16, 1, 127, machine_at_wd76c10_init, NULL, nvr_at_close }, diff --git a/src/pc.c b/src/pc.c index 4dd5769ce..04e18d051 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Main emulator module where most things are controlled. * - * Version: @(#)pc.c 1.0.52 2018/01/16 + * Version: @(#)pc.c 1.0.53 2018/01/18 * * Authors: Sarah Walker, * Miran Grca, @@ -18,6 +18,7 @@ * Copyright 2016-2018 Miran Grca. * Copyright 2017,2018 Fred N. van Kempen. */ +#include #include #include #include @@ -88,6 +89,11 @@ int force_debug = 0; /* (O) force debug output */ #ifdef USE_WX int video_fps = RENDER_FPS; /* (O) render speed in fps */ #endif +int settings_only = 0; /* (O) show only the settings dialog */ +#ifdef _WIN32 +uint64_t unique_id = 0; +uint64_t source_hwnd = 0; +#endif wchar_t log_path[1024] = { L'\0'}; /* (O) full path of logfile */ /* Configuration values. */ @@ -315,6 +321,10 @@ usage: printf("-P or --vmpath path - set 'path' to be root for vm\n"); #ifdef USE_WX printf("-R or --fps num - set render speed to 'num' fps\n"); +#endif + printf("-S or --settings - show only the settings dialog\n"); +#ifdef _WIN32 + printf("-H or --hwnd id,hwnd - sends back the main dialog's hwnd\n"); #endif printf("\nA config file can be specified. If none is, the default file will be used.\n"); return(0); @@ -347,6 +357,18 @@ usage: if ((c+1) == argc) goto usage; video_fps = wcstol(argv[++c], NULL, 10); +#endif + } else if (!wcscasecmp(argv[c], L"--settings") || + !wcscasecmp(argv[c], L"-S")) { + settings_only = 1; +#ifdef _WIN32 + } else if (!wcscasecmp(argv[c], L"--hwnd") || + !wcscasecmp(argv[c], L"-H")) { + + if ((c+1) == argc) goto usage; + + wcstombs(temp, argv[++c], 128); + sscanf(temp, "%016" PRIX64 ",%016" PRIX64, &unique_id, &source_hwnd); #endif } else if (!wcscasecmp(argv[c], L"--test")) { /* some (undocumented) test function here.. */ diff --git a/src/ui.h b/src/ui.h index 794b2995a..75d869c7f 100644 --- a/src/ui.h +++ b/src/ui.h @@ -8,13 +8,13 @@ * * Define the various UI functions. * - * Version: @(#)ui.h 1.0.10 2017/11/18 + * Version: @(#)ui.h 1.0.11 2018/01/18 * * Authors: Miran Grca, * Fred N. van Kempen, * - * Copyright 2016,2017 Miran Grca. - * Copyright 2017 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #ifndef EMU_UI_H # define EMU_UI_H @@ -61,6 +61,7 @@ extern void ui_sb_update_icon_state(int tag, int active); extern void ui_sb_set_text_w(wchar_t *wstr); extern void ui_sb_set_text(char *str); extern void ui_sb_bugui(char *str); +extern void ui_sb_mount_floppy_img(uint8_t id, int part, uint8_t wp, wchar_t *file_name); #ifdef __cplusplus } diff --git a/src/win/86Box.rc b/src/win/86Box.rc index fc81764d5..9a860661e 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -8,7 +8,7 @@ * * Application resource script for Windows. * - * Version: @(#)86Box.rc 1.0.22 2018/01/17 + * Version: @(#)86Box.rc 1.0.23 2018/01/18 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -256,19 +256,22 @@ BEGIN CTEXT "MIDI",IDT_1748,70,7,32,9,SS_CENTERIMAGE END -DLG_NEW_FLOPPY DIALOG DISCARDABLE 0, 0, 186, 65 +DLG_NEW_FLOPPY DIALOG DISCARDABLE 0, 0, 226, 86 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "New Floppy Image" FONT 8, "MS Sans Serif" BEGIN - DEFPUSHBUTTON "OK",IDOK,74,44,50,14 - PUSHBUTTON "Cancel",IDCANCEL,129,44,50,14 - LTEXT "File name:",IDT_1749,7,6,34,12,SS_CENTERIMAGE - LTEXT "Disk size:",IDT_1750,7,25,34,12,SS_CENTERIMAGE - EDITTEXT IDC_EDIT_FILE_NAME,43,7,124,12,ES_AUTOHSCROLL | ES_READONLY - COMBOBOX IDC_COMBO_DISK_SIZE,43,25,136,14,CBS_DROPDOWN | CBS_SORT | + DEFPUSHBUTTON "OK",IDOK,74,65,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,65,50,14 + LTEXT "File name:",IDT_1749,7,6,44,12,SS_CENTERIMAGE + LTEXT "Disk size:",IDT_1750,7,25,44,12,SS_CENTERIMAGE + LTEXT "RPM mode:",IDT_1751,7,45,44,12,SS_CENTERIMAGE + EDITTEXT IDC_EDIT_FILE_NAME,53,5,154,14,ES_AUTOHSCROLL | ES_READONLY + COMBOBOX IDC_COMBO_DISK_SIZE,53,25,166,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "...",IDC_CFILE,166,7,13,12 + COMBOBOX IDC_COMBO_RPM_MODE,53,45,166,14,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "...",IDC_CFILE,206,5,13,14 END DLG_CONFIG DIALOG DISCARDABLE 0, 0, 366, 241 @@ -650,9 +653,9 @@ BEGIN DLG_NEW_FLOPPY, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 179 + RIGHTMARGIN, 219 TOPMARGIN, 7 - BOTTOMMARGIN, 58 + BOTTOMMARGIN, 79 END DLG_CFG_MAIN, DIALOG @@ -888,7 +891,7 @@ BEGIN IDS_2159"All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.JSON;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.JSON;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.JSON;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.JSON;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.JSON;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" IDS_2160 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" IDS_2161 "&New image..." - IDS_2162 "Existing image..." + IDS_2162 "&Existing image..." IDS_2163 "Existing image (&Write-protected)..." IDS_2164 "E&ject" IDS_2165 "&Mute" @@ -898,6 +901,9 @@ BEGIN IDS_2169 "Image (&Write-protected)..." IDS_2170 "Check BPB" IDS_2171 "Unable to initialize FluidSynth, make sure you have the following libraries\nin your 86Box folder:\n\nlibfluidsynth.dll\nlibglib-2.0-0.dll\nlibiconv-2.dll\nlibintl-8.dll\nlibpcre-1.dll" + IDS_2172 "E&xport to 86F..." + IDS_2173 "Surface-based images (*.86F)\0*.86F\0" + IDS_2174 "All floppy images (*.86F;*.DSK;*.FDI;*.FLP;*.IMA;*.IMG;*.VFD)\0*.86F;*.DSK;*.FDI;*.FLP;*.IMA;*.IMG;*.VFD\0Basic sector-based images (*.DSK;*.FDI;*.FLP;*.IMA;*.IMG;*.VFD)\0*.DSK;*.FDI;*.FLP;*.IMA;*.IMG;*.VFD\0Surface-based images (*.86F)\0*.86F\0" IDS_4096 "Hard disk (%s)" IDS_4097 "%01i:%01i" @@ -954,9 +960,27 @@ BEGIN IDS_5637 "ATAPI (PIO and DMA) (%01i:%01i)" IDS_5638 "SCSI (%02i:%02i)" - IDS_6144 "English (United States)" + IDS_5888 "160 kB" + IDS_5889 "180 kB" + IDS_5890 "320 kB" + IDS_5891 "360 kB" + IDS_5892 "640 kB" + IDS_5893 "720 kB" + IDS_5894 "1.2 MB" + IDS_5895 "1.25 MB" + IDS_5896 "1.44 MB" + IDS_5897 "DMF (cluster 1024)" + IDS_5898 "DMF (cluster 2048)" + IDS_5899 "2.88 MB" + + IDS_6144 "Perfect RPM" + IDS_6145 "1%% below perfect RPM" + IDS_6146 "1.5%% below perfect RPM" + IDS_6147 "2%% below perfect RPM" + + IDS_7168 "English (United States)" END -#define IDS_LANG_ENUS IDS_6144 +#define IDS_LANG_ENUS IDS_7168 #ifndef _MAC diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 00fcaa527..9e5e73873 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -255,8 +255,8 @@ ifneq ($(WX), n) else UIOBJ := win_ui.o win_ddraw.o win_d3d.o win_png.o \ win_dialog.o win_about.o win_status.o win_stbar.o \ - win_settings.o win_devconf.o \ - win_snd_gain.o win_jsconf.o + win_settings.o win_devconf.o win_snd_gain.o \ + win_new_floppy.o win_jsconf.o endif ifeq ($(OPENAL), y) diff --git a/src/win/resource.h b/src/win/resource.h index c02acb69a..1bfd88785 100644 --- a/src/win/resource.h +++ b/src/win/resource.h @@ -8,7 +8,7 @@ * * Windows resource defines. * - * Version: @(#)resource.h 1.0.16 2018/01/17 + * Version: @(#)resource.h 1.0.17 2018/01/18 * * Authors: Sarah Walker, * Miran Grca, @@ -84,6 +84,7 @@ #define IDT_1748 1748 /* MIDI */ #define IDT_1749 1749 /* File name: */ #define IDT_1750 1750 /* Disk size: */ +#define IDT_1751 1751 /* RPM mode: */ /* @@ -193,6 +194,7 @@ #define IDC_EDIT_FILE_NAME 1190 /* new floppy image dialog */ #define IDC_COMBO_DISK_SIZE 1191 +#define IDC_COMBO_RPM_MODE 1192 /* For the DeviceConfig code, re-do later. */ @@ -276,7 +278,7 @@ #define IDM_FLOPPY_IMAGE_NEW 0x1200 #define IDM_FLOPPY_IMAGE_EXISTING 0x1300 #define IDM_FLOPPY_IMAGE_EXISTING_WP 0x1400 -#define IDM_FLOPPY_DUMP_86F 0x1500 +#define IDM_FLOPPY_EXPORT_TO_86F 0x1500 #define IDM_FLOPPY_EJECT 0x1600 #define IDM_CDROM_MUTE 0x2200 diff --git a/src/win/win.c b/src/win/win.c index 5b307566c..0a6d71a19 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -8,15 +8,15 @@ * * Platform main support module for Windows. * - * Version: @(#)win.c 1.0.43 2017/12/28 + * Version: @(#)win.c 1.0.44 2018/01/18 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - * Copyright 2017 Fred N. van Kempen. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #define UNICODE #include @@ -72,7 +72,9 @@ static rc_str_t *lpRCstr2048, *lpRCstr5120, *lpRCstr5376, *lpRCstr5632, - *lpRCstr6144; + *lpRCstr5888, + *lpRCstr6144, + *lpRCstr7168; static struct { @@ -136,7 +138,9 @@ LoadCommonStrings(void) lpRCstr5120 = (rc_str_t *)malloc(STR_NUM_5120*sizeof(rc_str_t)); lpRCstr5376 = (rc_str_t *)malloc(STR_NUM_5376*sizeof(rc_str_t)); lpRCstr5632 = (rc_str_t *)malloc(STR_NUM_5632*sizeof(rc_str_t)); + lpRCstr5888 = (rc_str_t *)malloc(STR_NUM_5888*sizeof(rc_str_t)); lpRCstr6144 = (rc_str_t *)malloc(STR_NUM_6144*sizeof(rc_str_t)); + lpRCstr7168 = (rc_str_t *)malloc(STR_NUM_7168*sizeof(rc_str_t)); for (i=0; i= 5376) && (i <= 5631)) { str = lpRCstr5376[i-5376].str; - } else if ((i >= 5632) && (i <= 6143)) { + } else if ((i >= 5632) && (i <= 5887)) { str = lpRCstr5632[i-5632].str; - } else { + } else if ((i >= 5888) && (i <= 6143)) { + str = lpRCstr5888[i-5888].str; + } else if ((i >= 6144) && (i <= 7167)) { str = lpRCstr6144[i-6144].str; + } else { + str = lpRCstr7168[i-7168].str; } return((wchar_t *)str); diff --git a/src/win/win.h b/src/win/win.h index 3c2fedf0b..1b716c724 100644 --- a/src/win/win.h +++ b/src/win/win.h @@ -46,6 +46,9 @@ #define WM_RESETD3D WM_USER #define WM_LEAVEFULLSCREEN WM_USER+1 #define WM_SAVESETTINGS 0x8888 +#define WM_SHOWSETTINGS 0x8889 +#define WM_PAUSE 0x8890 +#define WM_SENDHWND 0x8891 extern HINSTANCE hinstance; @@ -114,6 +117,10 @@ extern void AboutDialogCreate(HWND hwnd); extern void SoundGainDialogCreate(HWND hwnd); +/* Functions in win_new_floppy.c: */ +extern void NewFloppyDialogCreate(HWND hwnd, int id, int part); + + /* Functions in win_status.c: */ extern HWND hwndStatus; extern void StatusWindowCreate(HWND hwnd); diff --git a/src/win/win_new_floppy.c b/src/win/win_new_floppy.c new file mode 100644 index 000000000..e2cc70da5 --- /dev/null +++ b/src/win/win_new_floppy.c @@ -0,0 +1,413 @@ +/* + * 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. + * + * Handle the New Floppy Image dialog. + * + * Version: @(#)win_new_floppy.c 1.0.0 2018/01/18 + * + * Authors: Miran Grca, + * + * Copyright 2016-2018 Miran Grca. + */ +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP +#include +#include +#include +#include +#include +#include "../86box.h" +#include "../plat.h" +#include "../random.h" +#include "../ui.h" +#include "win.h" + + +typedef struct { + int hole; + int sides; + int data_rate; + int encoding; + int rpm; + int tracks; + int sectors; /* For IMG and Japanese FDI only. */ + int sector_len; /* For IMG and Japanese FDI only. */ + int media_desc; + int spc; + int num_fats; + int spfat; + int root_dir_entries; +} disk_size_t; + + +disk_size_t disk_sizes[12] = { { 0, 1, 2, 1, 0, 40, 8, 2, 0xFE, 2, 2, 1, 112 }, /* 160k */ + { 0, 1, 2, 1, 0, 40, 9, 2, 0xFC, 2, 2, 1, 112 }, /* 180k */ + { 0, 2, 2, 1, 0, 40, 8, 2, 0xFF, 2, 2, 1, 112 }, /* 320k */ + { 0, 2, 2, 1, 0, 40, 9, 2, 0xFD, 2, 2, 2, 112 }, /* 360k */ + { 0, 2, 2, 1, 0, 80, 8, 2, 0xFB, 2, 2, 2, 112 }, /* 640k */ + { 0, 2, 2, 1, 0, 80, 9, 2, 0xF9, 2, 2, 3, 112 }, /* 720k */ + { 1, 2, 0, 1, 1, 80, 15, 2, 0xF9, 1, 2, 7, 224 }, /* 1.2M */ + { 1, 2, 0, 1, 1, 77, 8, 3, 0xFE, 1, 2, 2, 192 }, /* 1.25M */ + { 1, 2, 0, 1, 0, 80, 18, 2, 0xF0, 1, 2, 9, 224 }, /* 1.44M */ + { 1, 2, 0, 1, 0, 80, 21, 2, 0xF0, 2, 2, 5, 16 }, /* DMF cluster 1024 */ + { 1, 2, 0, 1, 0, 80, 21, 2, 0xF0, 4, 2, 3, 16 }, /* DMF cluster 2048 */ + { 2, 2, 3, 1, 0, 80, 36, 2, 0xF0, 2, 2, 9, 240 } }; /* 2.88M */ + +static char *empty; + + +static int +create_86f(WCHAR *file_name, disk_size_t disk_size, uint8_t rpm_mode) +{ + FILE *f; + + uint32_t magic = 0x46423638; + uint16_t version = 0x020B; + uint16_t dflags = 0; + uint16_t tflags = 0; + uint16_t index_hole_pos = 0; + uint32_t tarray[512]; + uint32_t array_size, array_size2; + uint32_t track_base, track_size; + int i; + + dflags = 0; /* Has surface data? - Assume no for now. */ + dflags |= (disk_size.hole << 1); /* Hole */ + dflags |= ((disk_size.sides - 1) << 3); /* Sides. */ + dflags |= (0 << 4); /* Write protect? - Assume no for now. */ + dflags |= (rpm_mode << 5); /* RPM mode. */ + dflags |= (0 << 7); /* Has extra bit cells? - Assume no for now. */ + + tflags = disk_size.data_rate; /* Data rate. */ + tflags |= (disk_size.encoding << 3); /* Encoding. */ + tflags |= (disk_size.rpm << 5); /* RPM. */ + + switch (disk_size.hole) { + case 0: + case 1: + default: + switch(rpm_mode) { + case 1: + array_size = 25250; + break; + case 2: + array_size = 25374; + break; + case 3: + array_size = 25750; + break; + default: + array_size = 25000; + break; + } + break; + case 2: + switch(rpm_mode) { + case 1: + array_size = 50500; + break; + case 2: + array_size = 50750; + break; + case 3: + array_size = 51000; + break; + default: + array_size = 50000; + break; + } + break; + } + + array_size2 = (array_size << 3); + array_size = (array_size2 >> 4) << 1; + if (array_size2 & 15) + array_size += 2; + + empty = (char *) malloc(array_size); + + memset(tarray, 0, 2048); + memset(empty, 0, array_size); + + f = plat_fopen(file_name, L"wb"); + if (!f) + return 0; + + fwrite(&magic, 4, 1, f); + fwrite(&version, 2, 1, f); + fwrite(&dflags, 2, 1, f); + + track_size = array_size + 6; + + track_base = 8 + ((disk_size.sides == 2) ? 2048 : 1024); + + for (i = 0; i < disk_size.tracks * disk_size.sides; i++) + tarray[i] = track_base + (i * track_size); + + fwrite(tarray, 1, (disk_size.sides == 2) ? 2048 : 1024, f); + + for (i = 0; i < disk_size.tracks * disk_size.sides; i++) { + fwrite(&tflags, 2, 1, f); + fwrite(&index_hole_pos, 4, 1, f); + fwrite(empty, 1, array_size, f); + } + + free(empty); + + fclose(f); + + return 1; +} + + +static int +create_sector_image(WCHAR *file_name, disk_size_t disk_size, uint8_t is_fdi) +{ + FILE *f; + uint32_t total_size = 0; + uint32_t total_sectors = 0; + uint32_t sector_bytes = 0; + uint32_t root_dir_bytes = 0; + uint32_t fat_size = 0; + uint32_t fat1_offs = 0; + uint32_t fat2_offs = 0; + uint32_t zero_bytes = 0; + uint16_t base = 0x1000; + + f = plat_fopen(file_name, L"wb"); + if (!f) + return 0; + + sector_bytes = (128 << disk_size.sector_len); + total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors; + total_size = total_sectors * sector_bytes; + root_dir_bytes = (disk_size.root_dir_entries << 5); + fat_size = (disk_size.spfat * sector_bytes); + fat1_offs = sector_bytes; + fat2_offs = fat1_offs + fat_size; + zero_bytes = fat2_offs + fat_size + root_dir_bytes; + + if (is_fdi) { + empty = (char *) malloc(base); + memset(empty, 0, base); + + *(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; + + fwrite(empty, 1, base, f); + free(empty); + } + + empty = (char *) malloc(total_size); + memset(empty, 0x00, zero_bytes); + memset(empty + zero_bytes, 0xF6, total_size - zero_bytes); + + empty[0x00] = 0xEB; /* Jump to make MS-DOS happy. */ + empty[0x01] = 0x58; + empty[0x02] = 0x90; + + empty[0x03] = 0x38; /* '86BOX5.0' OEM ID. */ + empty[0x04] = 0x36; + empty[0x05] = 0x42; + empty[0x06] = 0x4F; + empty[0x07] = 0x58; + empty[0x08] = 0x35; + empty[0x09] = 0x2E; + empty[0x0A] = 0x30; + + *(uint16_t *) &(empty[0x0B]) = (uint16_t) sector_bytes; + *(uint8_t *) &(empty[0x0D]) = (uint8_t) disk_size.spc; + *(uint16_t *) &(empty[0x0E]) = (uint16_t) 1; + *(uint8_t *) &(empty[0x10]) = (uint8_t) disk_size.num_fats; + *(uint16_t *) &(empty[0x11]) = (uint16_t) disk_size.root_dir_entries; + *(uint16_t *) &(empty[0x13]) = (uint16_t) total_sectors; + *(uint8_t *) &(empty[0x15]) = (uint8_t) disk_size.media_desc; + *(uint16_t *) &(empty[0x16]) = (uint16_t) disk_size.spfat; + *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sectors; + *(uint8_t *) &(empty[0x1A]) = (uint8_t) disk_size.sides; + + empty[0x26] = 0x29; /* ')' followed by randomly-generated volume serial number. */ + empty[0x27] = random_generate(); + empty[0x28] = random_generate(); + empty[0x29] = random_generate(); + empty[0x2A] = random_generate(); + + memset(&(empty[0x2B]), 0x20, 11); + + empty[0x36] = 'F'; + empty[0x37] = 'A'; + empty[0x38] = 'T'; + empty[0x39] = '1'; + empty[0x3A] = '2'; + + empty[0x1FE] = 0x55; + empty[0x1FF] = 0xAA; + + empty[fat1_offs + 0x00] = empty[fat2_offs + 0x00] = empty[0x15]; + empty[fat1_offs + 0x01] = empty[fat2_offs + 0x01] = empty[0xFF]; + empty[fat1_offs + 0x02] = empty[fat2_offs + 0x02] = empty[0xFF]; + + fwrite(empty, 1, total_size, f); + free(empty); + + fclose(f); + + return 1; +} + + +static int fdd_id, sb_part; + +static int file_type = 0; /* 0 = IMG, 1 = Japanese FDI, 2 = 86F */ +static wchar_t fd_file_name[512]; + + +/* Show a MessageBox dialog. This is nasty, I know. --FvK */ +static int +new_floppy_msgbox(HWND hwnd, int type, void *arg) +{ + HWND h; + int i; + + h = hwndMain; + hwndMain = hwnd; + + i = ui_msgbox(type, arg); + + hwndMain = h; + + return(i); +} + + +#ifdef __amd64__ +static LRESULT CALLBACK +#else +static BOOL CALLBACK +#endif +NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int i = 0; + int wcs_len, ext_offs; + wchar_t *ext; + uint8_t disk_size, rpm_mode; + int ret; + FILE *f; + + switch (message) { + case WM_INITDIALOG: + plat_pause(1); + memset(fd_file_name, 0, 512 * sizeof(wchar_t)); + h = GetDlgItem(hdlg, IDC_COMBO_DISK_SIZE); + for (i = 0; i < 12; i++) + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) plat_get_string(IDS_5888 + i)); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_COMBO_RPM_MODE); + for (i = 0; i < 4; i++) + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) plat_get_string(IDS_6144 + i)); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + h = GetDlgItem(hdlg, IDT_1751); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + h = GetDlgItem(hdlg, IDOK); + EnableWindow(h, FALSE); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + h = GetDlgItem(hdlg, IDC_COMBO_DISK_SIZE); + disk_size = SendMessage(h, CB_GETCURSEL, 0, 0); + if (file_type == 2) { + h = GetDlgItem(hdlg, IDC_COMBO_RPM_MODE); + rpm_mode = SendMessage(h, CB_GETCURSEL, 0, 0); + ret = create_86f(fd_file_name, disk_sizes[disk_size], rpm_mode); + } else + ret = create_sector_image(fd_file_name, disk_sizes[disk_size], file_type); + if (ret) + ui_sb_mount_floppy_img(fdd_id, sb_part, 0, fd_file_name); + else { + new_floppy_msgbox(hdlg, MBX_ERROR, (wchar_t *)IDS_4108); + return TRUE; + } + case IDCANCEL: + EndDialog(hdlg, 0); + plat_pause(0); + return TRUE; + + case IDC_CFILE: + if (!file_dlg_w(hdlg, plat_get_string(IDS_2174), L"", 1)) { + h = GetDlgItem(hdlg, IDC_EDIT_FILE_NAME); + f = _wfopen(wopenfilestring, L"rb"); + if (f != NULL) { + fclose(f); + if (new_floppy_msgbox(hdlg, MBX_QUESTION, (wchar_t *)IDS_4111) != 0) /* yes */ + return FALSE; + } + SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); + memset(fd_file_name, 0, sizeof(fd_file_name)); + wcscpy(fd_file_name, wopenfilestring); + h = GetDlgItem(hdlg, IDC_COMBO_DISK_SIZE); + EnableWindow(h, TRUE); + wcs_len = wcslen(wopenfilestring); + ext_offs = wcs_len - 4; + ext = &(wopenfilestring[ext_offs]); + if ((wcs_len >= 4) && !wcsicmp(ext, L".FDI")) + file_type = 1; + else if ((wcs_len >= 4) && !wcsicmp(ext, L".86F")) + file_type = 2; + else + file_type = 0; + h = GetDlgItem(hdlg, IDT_1751); + if (file_type == 2) { + EnableWindow(h, TRUE); + ShowWindow(h, SW_SHOW); + } else { + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + } + h = GetDlgItem(hdlg, IDC_COMBO_RPM_MODE); + if (file_type == 2) { + EnableWindow(h, TRUE); + ShowWindow(h, SW_SHOW); + } else { + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + } + h = GetDlgItem(hdlg, IDOK); + EnableWindow(h, TRUE); + return TRUE; + } else + return FALSE; + + default: + break; + } + break; + } + + return(FALSE); +} + + +void +NewFloppyDialogCreate(HWND hwnd, int id, int part) +{ + fdd_id = id; + sb_part = part; + DialogBox(hinstance, (LPCTSTR)DLG_NEW_FLOPPY, hwnd, NewFloppyDialogProcedure); +} diff --git a/src/win/win_settings.c b/src/win/win_settings.c index c52c8c9bc..ff3a5c0b3 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.28 2018/01/16 + * Version: @(#)win_settings.c 1.0.29 2018/01/19 * * Author: Miran Grca, * @@ -108,6 +108,8 @@ static int settings_mouse_to_list[20], settings_list_to_mouse[20]; static int settings_scsi_to_list[20], settings_list_to_scsi[20]; static int settings_network_to_list[20], settings_list_to_network[20]; +static uint8_t mfm_tracking, esdi_tracking, xtide_tracking, ide_tracking, scsi_tracking[16]; + /* Show a MessageBox dialog. This is nasty, I know. --FvK */ @@ -185,8 +187,29 @@ static void win_settings_init(void) temp_ide_qua_irq = ide_irq[3]; temp_bugger = bugger_enabled; + mfm_tracking = xtide_tracking = esdi_tracking = ide_tracking = 0; + for (i = 0; i < 16; i++) + scsi_tracking[i] = 0; + /* Hard disks category */ memcpy(temp_hdd, hdd, HDD_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDD_NUM; i++) + { + if (hdd[i].bus == HDD_BUS_MFM) + mfm_tracking |= (1 << hdd[i].mfm_channel); + else if (hdd[i].bus == HDD_BUS_XTIDE) + xtide_tracking |= (1 << hdd[i].xtide_channel); + else if (hdd[i].bus == HDD_BUS_ESDI) + esdi_tracking |= (1 << hdd[i].esdi_channel); + else if (hdd[i].bus == HDD_BUS_IDE_PIO_ONLY) + ide_tracking |= (1 << hdd[i].ide_channel); + else if (hdd[i].bus == HDD_BUS_IDE_PIO_AND_DMA) + ide_tracking |= (1 << hdd[i].ide_channel); + else if (hdd[i].bus == HDD_BUS_SCSI) + scsi_tracking[hdd[i].scsi_id] |= (1 << hdd[i].scsi_lun); + else if (hdd[i].bus == HDD_BUS_SCSI_REMOVABLE) + scsi_tracking[hdd[i].scsi_id] |= (1 << hdd[i].scsi_lun); + } /* Removable devices category */ for (i = 0; i < FDD_NUM; i++) @@ -196,6 +219,15 @@ static void win_settings_init(void) temp_fdd_check_bpb[i] = fdd_get_check_bpb(i); } memcpy(temp_cdrom_drives, cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); + for (i = 0; i < CDROM_NUM; i++) + { + if (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) + ide_tracking |= (1 << cdrom_drives[i].ide_channel); + else if (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA) + ide_tracking |= (1 << cdrom_drives[i].ide_channel); + else if (cdrom_drives[i].bus_type == CDROM_BUS_SCSI) + scsi_tracking[cdrom_drives[i].scsi_device_id] |= (1 << cdrom_drives[i].scsi_device_lun); + } temp_deviceconfig = 0; } @@ -2028,7 +2060,49 @@ static void add_locations(HWND hdlg) free(lptsTemp); } -static void recalc_location_controls(HWND hdlg, int is_add_dlg) +static uint8_t next_free_binary_channel(uint8_t *tracking) +{ + int i; + + for (i = 0; i < 2; i++) { + if (!(*tracking & (1 << i))) + return i; + } + + return 2; +} + +static uint8_t next_free_ide_channel(void) +{ + int i; + + for (i = 0; i < 8; i++) { + if (!(ide_tracking & (1 << i))) + return i; + } + + return 7; +} + +static void next_free_scsi_id_and_lun(uint8_t *id, uint8_t *lun) +{ + uint8_t i, j; + + for (j = 0; j < 8; j++) { + for (i = 0; i < 16; i++) { + if (!(scsi_tracking[i] & (1 << j))) { + *id = i; + *lun = j; + return; + } + } + } + + *id = 6; + *lun = 7; +} + +static void recalc_location_controls(HWND hdlg, int is_add_dlg, int assign_id) { int i = 0; HWND h; @@ -2074,6 +2148,8 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); + if (assign_id & !is_add_dlg) + temp_hdd[hdlv_current_sel].mfm_channel = next_free_binary_channel(&mfm_tracking); SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.mfm_channel : temp_hdd[hdlv_current_sel].mfm_channel, 0); break; case HDD_BUS_XTIDE: /* XT IDE */ @@ -2084,6 +2160,8 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); + if (assign_id & !is_add_dlg) + temp_hdd[hdlv_current_sel].xtide_channel = next_free_binary_channel(&xtide_tracking); SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.xtide_channel : temp_hdd[hdlv_current_sel].xtide_channel, 0); break; case HDD_BUS_ESDI: /* ESDI */ @@ -2094,6 +2172,8 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); + if (assign_id & !is_add_dlg) + temp_hdd[hdlv_current_sel].esdi_channel = next_free_binary_channel(&esdi_tracking); SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.esdi_channel : temp_hdd[hdlv_current_sel].esdi_channel, 0); break; case HDD_BUS_IDE_PIO_ONLY: /* IDE (PIO-only) */ @@ -2105,6 +2185,8 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); + if (assign_id & !is_add_dlg) + temp_hdd[hdlv_current_sel].ide_channel = next_free_ide_channel(); SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.ide_channel : temp_hdd[hdlv_current_sel].ide_channel, 0); break; case HDD_BUS_SCSI: /* SCSI */ @@ -2116,6 +2198,9 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); + if (assign_id & !is_add_dlg) + next_free_scsi_id_and_lun((uint8_t *) &temp_hdd[hdlv_current_sel].scsi_id, (uint8_t *) &temp_hdd[hdlv_current_sel].scsi_lun); + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -2162,6 +2247,7 @@ static void recalc_next_free_id(HWND hdlg) int c_ide_dma = 0; int c_scsi = 0; int enable_add = 0; + int scsi_tracking_total = 0xff; next_free_id = -1; @@ -2212,6 +2298,10 @@ static void recalc_next_free_id(HWND hdlg) /* pclog("Enable add: %i\n", enable_add); */ enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_esdi < ESDI_NUM) || (c_xtide < XTIDE_NUM) || (c_ide_pio < IDE_NUM) || (c_ide_dma < IDE_NUM) || (c_scsi < SCSI_NUM)); /* pclog("Enable add: %i\n", enable_add); */ + enable_add = enable_add && (mfm_tracking < 0x03) && (esdi_tracking < 0x03) && (xtide_tracking < 0x03) && (ide_tracking < 0xff); + for (i = 0; i < 16; i++) + scsi_tracking_total &= scsi_tracking[i]; + enable_add = enable_add && (scsi_tracking_total != 0xff); h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD_NEW); @@ -2609,6 +2699,8 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM char *big_buf; int b = 0; uint64_t r = 0; + uint8_t channel = 0; + uint8_t id = 0, lun = 0; switch (message) { @@ -2671,7 +2763,7 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM } SendMessage(h, CB_SETCURSEL, hdd_ptr->bus, 0); max_tracks = 266305; - recalc_location_controls(hdlg, 1); + recalc_location_controls(hdlg, 1, 0); if (existing & 2) { /* We're functioning as a load image dialog for a removable SCSI hard disk, @@ -2698,14 +2790,23 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM } else { + channel = next_free_ide_channel(); + next_free_scsi_id_and_lun(&id, &lun); h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); SendMessage(h, CB_SETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - SendMessage(h, CB_SETCURSEL, 0, 0); + SendMessage(h, CB_SETCURSEL, 0, id); h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - SendMessage(h, CB_SETCURSEL, 0, 0); + SendMessage(h, CB_SETCURSEL, 0, lun); h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - SendMessage(h, CB_SETCURSEL, 0, 0); + SendMessage(h, CB_SETCURSEL, 0, channel); + + new_hdd.mfm_channel = next_free_binary_channel(&mfm_tracking); + new_hdd.esdi_channel = next_free_binary_channel(&esdi_tracking); + new_hdd.xtide_channel = next_free_binary_channel(&xtide_tracking); + new_hdd.ide_channel = channel; + new_hdd.scsi_id = id; + new_hdd.scsi_lun = lun; } h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); EnableWindow(h, FALSE); @@ -3183,7 +3284,7 @@ hdd_add_file_open_error: } no_update = 1; - recalc_location_controls(hdlg, 1); + recalc_location_controls(hdlg, 1, 0); h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); b = SendMessage(h,CB_GETCURSEL,0,0) + 1; if (b == hdd_ptr->bus) @@ -3324,6 +3425,52 @@ void hard_disk_add_open(HWND hwnd, int is_existing) int ignore_change = 0; +static void hard_disk_track(uint8_t id) +{ + switch(temp_hdd[id].bus) { + case HDD_BUS_MFM: + mfm_tracking |= (1 << temp_hdd[id].mfm_channel); + break; + case HDD_BUS_ESDI: + esdi_tracking |= (1 << temp_hdd[id].esdi_channel); + break; + case HDD_BUS_XTIDE: + xtide_tracking |= (1 << temp_hdd[id].xtide_channel); + break; + case HDD_BUS_IDE_PIO_ONLY: + case HDD_BUS_IDE_PIO_AND_DMA: + ide_tracking |= (1 << temp_hdd[id].ide_channel); + break; + case HDD_BUS_SCSI: + case HDD_BUS_SCSI_REMOVABLE: + scsi_tracking[temp_hdd[id].scsi_id] |= (1 << temp_hdd[id].scsi_lun); + break; + } +} + +static void hard_disk_untrack(uint8_t id) +{ + switch(temp_hdd[id].bus) { + case HDD_BUS_MFM: + mfm_tracking &= ~(1 << temp_hdd[id].mfm_channel); + break; + case HDD_BUS_ESDI: + esdi_tracking &= ~(1 << temp_hdd[id].esdi_channel); + break; + case HDD_BUS_XTIDE: + xtide_tracking &= ~(1 << temp_hdd[id].xtide_channel); + break; + case HDD_BUS_IDE_PIO_ONLY: + case HDD_BUS_IDE_PIO_AND_DMA: + ide_tracking &= ~(1 << temp_hdd[id].ide_channel); + break; + case HDD_BUS_SCSI: + case HDD_BUS_SCSI_REMOVABLE: + scsi_tracking[temp_hdd[id].scsi_id] &= ~(1 << temp_hdd[id].scsi_lun); + break; + } +} + #ifdef __amd64__ static LRESULT CALLBACK #else @@ -3333,13 +3480,16 @@ win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPar { HWND h; int old_sel = 0; - int b = 0; + int b = 0, i = 0; switch (message) { case WM_INITDIALOG: ignore_change = 1; + for (i = 0; i < HDD_NUM; i++) + hard_disk_track(i); + normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. This will cause an emulator reset prompt on the first opening of this category with a messy hard disk list (which can only happen by manually editing the configuration file). */ @@ -3360,7 +3510,7 @@ win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPar { hdlv_current_sel = -1; } - recalc_location_controls(hdlg, 0); + recalc_location_controls(hdlg, 0, 0); ignore_change = 0; return TRUE; @@ -3390,7 +3540,7 @@ win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPar ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); SendMessage(h, CB_SETCURSEL, temp_hdd[hdlv_current_sel].bus - 1, 0); - recalc_location_controls(hdlg, 0); + recalc_location_controls(hdlg, 0, 0); ignore_change = 0; } break; @@ -3412,7 +3562,8 @@ win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPar goto hd_bus_skip; } temp_hdd[hdlv_current_sel].bus = b; - recalc_location_controls(hdlg, 0); + hard_disk_untrack(hdlv_current_sel); + recalc_location_controls(hdlg, 0, 1); h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); hd_bus_skip: @@ -3427,6 +3578,7 @@ hd_bus_skip: ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + hard_disk_untrack(hdlv_current_sel); if (temp_hdd[hdlv_current_sel].bus == HDD_BUS_MFM) { temp_hdd[hdlv_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); @@ -3439,6 +3591,7 @@ hd_bus_skip: { temp_hdd[hdlv_current_sel].xtide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); } + hard_disk_track(hdlv_current_sel); h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); ignore_change = 0; @@ -3452,7 +3605,9 @@ hd_bus_skip: ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + hard_disk_untrack(hdlv_current_sel); temp_hdd[hdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + hard_disk_track(hdlv_current_sel); h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); ignore_change = 0; @@ -3466,7 +3621,9 @@ hd_bus_skip: ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + hard_disk_untrack(hdlv_current_sel); temp_hdd[hdlv_current_sel].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + hard_disk_track(hdlv_current_sel); h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); ignore_change = 0; @@ -3480,7 +3637,9 @@ hd_bus_skip: ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + hard_disk_untrack(hdlv_current_sel); temp_hdd[hdlv_current_sel].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + hard_disk_track(hdlv_current_sel); h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); ignore_change = 0; @@ -3512,6 +3671,7 @@ hd_bus_skip: case IDC_BUTTON_HDD_REMOVE: memcpy(temp_hdd[hdlv_current_sel].fn, L"", 4); + hard_disk_untrack(hdlv_current_sel); temp_hdd[hdlv_current_sel].bus = HDD_BUS_DISABLED; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ ignore_change = 1; @@ -3529,7 +3689,7 @@ hd_bus_skip: { hdlv_current_sel = -1; } - recalc_location_controls(hdlg, 0); + recalc_location_controls(hdlg, 0, 1); ignore_change = 0; return FALSE; } @@ -3932,7 +4092,7 @@ static void cdrom_add_locations(HWND hdlg) free(lptsTemp); } -static void cdrom_recalc_location_controls(HWND hdlg) +static void cdrom_recalc_location_controls(HWND hdlg, int assign_id) { int i = 0; HWND h; @@ -3966,6 +4126,9 @@ static void cdrom_recalc_location_controls(HWND hdlg) ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); + if (assign_id) + temp_cdrom_drives[cdlv_current_sel].ide_channel = next_free_ide_channel(); + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -3979,6 +4142,9 @@ static void cdrom_recalc_location_controls(HWND hdlg) ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); + if (assign_id) + next_free_scsi_id_and_lun((uint8_t *) &temp_cdrom_drives[cdlv_current_sel].scsi_device_id, (uint8_t *) &temp_cdrom_drives[cdlv_current_sel].scsi_device_lun); + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -3993,6 +4159,23 @@ static void cdrom_recalc_location_controls(HWND hdlg) } +static void cdrom_track(uint8_t id) +{ + if ((temp_cdrom_drives[id].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) || (temp_cdrom_drives[id].bus_type == CDROM_BUS_ATAPI_PIO_ONLY)) + ide_tracking |= (1 << temp_cdrom_drives[id].ide_channel); + else if (temp_cdrom_drives[id].bus_type == CDROM_BUS_SCSI) + scsi_tracking[temp_cdrom_drives[id].scsi_device_id] |= (1 << temp_cdrom_drives[id].scsi_device_lun); +} + +static void cdrom_untrack(uint8_t id) +{ + if ((temp_cdrom_drives[id].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) || (temp_cdrom_drives[id].bus_type == CDROM_BUS_ATAPI_PIO_ONLY)) + ide_tracking &= ~(1 << temp_cdrom_drives[id].ide_channel); + else if (temp_cdrom_drives[id].bus_type == CDROM_BUS_SCSI) + scsi_tracking[temp_cdrom_drives[id].scsi_device_id] &= ~(1 << temp_cdrom_drives[id].scsi_device_lun); +} + + int rd_ignore_change = 0; #ifdef __amd64__ @@ -4014,6 +4197,9 @@ win_settings_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPAR case WM_INITDIALOG: rd_ignore_change = 1; + for (i = 0; i < CDROM_NUM; i++) + cdrom_track(i); + fdlv_current_sel = 0; h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); win_settings_floppy_drives_init_columns(h); @@ -4070,7 +4256,7 @@ win_settings_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPAR SendMessage(h, CB_SETCURSEL, b, 0); - cdrom_recalc_location_controls(hdlg); + cdrom_recalc_location_controls(hdlg, 0); rd_ignore_change = 0; return TRUE; @@ -4145,7 +4331,7 @@ win_settings_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPAR SendMessage(h, CB_SETCURSEL, b, 0); - cdrom_recalc_location_controls(hdlg); + cdrom_recalc_location_controls(hdlg, 0); rd_ignore_change = 0; } break; @@ -4223,8 +4409,10 @@ win_settings_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPAR { goto cdrom_bus_skip; } + cdrom_untrack(cdlv_current_sel); temp_cdrom_drives[cdlv_current_sel].bus_type = b2; - cdrom_recalc_location_controls(hdlg); + cdrom_recalc_location_controls(hdlg, 1); + cdrom_track(cdlv_current_sel); h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); win_settings_cdrom_drives_update_item(h, cdlv_current_sel); cdrom_bus_skip: @@ -4253,7 +4441,9 @@ cdrom_bus_skip: rd_ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); + cdrom_untrack(cdlv_current_sel); temp_cdrom_drives[cdlv_current_sel].scsi_device_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + cdrom_track(cdlv_current_sel); h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); win_settings_cdrom_drives_update_item(h, cdlv_current_sel); rd_ignore_change = 0; @@ -4267,7 +4457,9 @@ cdrom_bus_skip: rd_ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + cdrom_untrack(cdlv_current_sel); temp_cdrom_drives[cdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + cdrom_track(cdlv_current_sel); h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); win_settings_cdrom_drives_update_item(h, cdlv_current_sel); rd_ignore_change = 0; diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index 96e58aa28..46acbabdb 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -8,7 +8,7 @@ * * Implement the application's Status Bar. * - * Version: @(#)win_stbar.c 1.0.8 2018/01/16 + * Version: @(#)win_stbar.c 1.0.9 2018/01/18 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -134,6 +134,14 @@ StatusBarCreateFloppySubmenu(HMENU m, int id) AppendMenu(m, MF_SEPARATOR, 0, 0); AppendMenu(m, MF_STRING, IDM_FLOPPY_EJECT | id, plat_get_string(IDS_2164)); + AppendMenu(m, MF_SEPARATOR, 0, 0); + AppendMenu(m, MF_STRING, IDM_FLOPPY_EXPORT_TO_86F | id, + plat_get_string(IDS_2172)); + + if (floppyfns[id][0] == 0x0000) { + EnableMenuItem(m, IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(m, IDM_FLOPPY_EXPORT_TO_86F | id, MF_BYCOMMAND | MF_GRAYED); + } } @@ -791,6 +799,20 @@ StatusBarPopupMenu(HWND hwnd, POINT pt, int id) } +void +ui_sb_mount_floppy_img(uint8_t id, int part, uint8_t wp, wchar_t *file_name) +{ + fdd_close(id); + ui_writeprot[id] = wp; + fdd_load(id, file_name); + ui_sb_update_icon_state(SB_FLOPPY | id, wcslen(floppyfns[id]) ? 0 : 1); + EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | (wcslen(floppyfns[id]) ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EXPORT_TO_86F | id, MF_BYCOMMAND | (wcslen(floppyfns[id]) ? MF_ENABLED : MF_GRAYED)); + ui_sb_update_tip(SB_FLOPPY | id); + config_save(); +} + + /* Handle messages for the Status Bar window. */ #ifdef __amd64__ static LRESULT CALLBACK @@ -816,6 +838,12 @@ StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) item_params = LOWORD(wParam) & 0x00ff; /* high 8 bits */ switch (item_id) { + case IDM_FLOPPY_IMAGE_NEW: + id = item_params & 0x0003; + part = ui_sb_find_part(SB_FLOPPY | id); + NewFloppyDialogCreate(hwnd, id, part); + break; + case IDM_FLOPPY_IMAGE_EXISTING: case IDM_FLOPPY_IMAGE_EXISTING_WP: id = item_params & 0x0003; @@ -824,15 +852,8 @@ StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; ret = file_dlg_w_st(hwnd, IDS_2159, floppyfns[id], 0); - if (! ret) { - fdd_close(id); - ui_writeprot[id] = (item_id == IDM_FLOPPY_IMAGE_EXISTING_WP) ? 1 : 0; - fdd_load(id, wopenfilestring); - ui_sb_update_icon_state(SB_FLOPPY | id, wcslen(floppyfns[id]) ? 0 : 1); - EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | (wcslen(floppyfns[id]) ? MF_ENABLED : MF_GRAYED)); - ui_sb_update_tip(SB_FLOPPY | id); - config_save(); - } + if (! ret) + ui_sb_mount_floppy_img(id, part, (item_id == IDM_FLOPPY_IMAGE_EXISTING_WP) ? 1 : 0, wopenfilestring); break; case IDM_FLOPPY_EJECT: @@ -844,10 +865,27 @@ StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) fdd_close(id); ui_sb_update_icon_state(SB_FLOPPY | id, 1); EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EXPORT_TO_86F | id, MF_BYCOMMAND | MF_GRAYED); ui_sb_update_tip(SB_FLOPPY | id); config_save(); break; + case IDM_FLOPPY_EXPORT_TO_86F: + id = item_params & 0x0003; + part = ui_sb_find_part(SB_FLOPPY | id); + if ((part == -1) || (sb_menu_handles == NULL)) + break; + + ret = file_dlg_w_st(hwnd, IDS_2173, floppyfns[id], 1); + if (! ret) { + plat_pause(1); + ret = d86f_export(id, wopenfilestring); + if (!ret) + ui_msgbox(MBX_ERROR, (wchar_t *)IDS_4108); + plat_pause(0); + } + break; + case IDM_CDROM_MUTE: id = item_params & 0x0007; part = ui_sb_find_part(SB_CDROM | id); diff --git a/src/win/win_ui.c b/src/win/win_ui.c index d43ff8664..2f162dab5 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -8,7 +8,7 @@ * * user Interface module for WinAPI on Windows. * - * Version: @(#)win_ui.c 1.0.12 2018/01/15 + * Version: @(#)win_ui.c 1.0.13 2018/01/18 * * Authors: Sarah Walker, * Miran Grca, @@ -304,6 +304,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_ACTION_PAUSE: plat_pause(dopause ^ 1); + CheckMenuItem(menuMain, IDM_ACTION_PAUSE, dopause ? MF_CHECKED : MF_UNCHECKED); break; case IDM_CONFIG: @@ -641,6 +642,15 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) PostQuitMessage(0); break; + case WM_SHOWSETTINGS: + win_settings_open(hwnd); + break; + + case WM_PAUSE: + plat_pause(dopause ^ 1); + CheckMenuItem(menuMain, IDM_ACTION_PAUSE, dopause ? MF_CHECKED : MF_UNCHECKED); + break; + case WM_SYSCOMMAND: /* * Disable ALT key *ALWAYS*, @@ -681,6 +691,20 @@ ui_init(int nCmdShow) atexit(plat_mouse_capture); #endif + if (settings_only) { + if (! pc_init_modules()) { + /* Dang, no ROMs found at all! */ + MessageBox(hwnd, + plat_get_string(IDS_2056), + plat_get_string(IDS_2050), + MB_OK | MB_ICONERROR); + return(6); + } + + win_settings_open(NULL); + return(0); + } + /* Create our main window's class and register it. */ wincl.hInstance = hinstance; wincl.lpszClassName = CLASS_NAME; @@ -814,6 +838,13 @@ ui_init(int nCmdShow) /* Set the PAUSE mode depending on the renderer. */ plat_pause(0); + /* If so requested via the command line, inform the + * application that started us of our HWND, using the + * the hWnd and unique ID the application has given + * us. */ + if (source_hwnd) + SendMessage((HWND) (uintptr_t) source_hwnd, WM_SENDHWND, (WPARAM) unique_id, (LPARAM) hwndMain); + /* * Everything has been configured, and all seems to work, * so now it is time to start the main thread to do some