From 949dea352417a37b098a1d85a553956572b02c32 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 29 Jul 2021 20:34:55 +0200 Subject: [PATCH] Added IBM PCjr cartridge support. --- src/config.c | 36 ++++++ src/device/CMakeLists.txt | 2 +- src/device/cartridge.c | 208 ++++++++++++++++++++++++++++++++++ src/floppy/fdd.c | 34 +++--- src/include/86box/cartridge.h | 40 +++++++ src/include/86box/language.h | 8 +- src/include/86box/machine.h | 1 + src/include/86box/plat.h | 2 + src/include/86box/resource.h | 43 +++---- src/include/86box/ui.h | 17 +-- src/include/86box/win.h | 3 + src/machine/machine.c | 3 + src/machine/machine_table.c | 2 +- src/win/86Box.rc | 14 +++ src/win/Makefile.mingw | 3 +- src/win/win_cdrom.c | 24 ++++ src/win/win_media_menu.c | 80 ++++++++++++- src/win/win_stbar.c | 57 +++++++++- 18 files changed, 523 insertions(+), 54 deletions(-) create mode 100644 src/device/cartridge.c create mode 100644 src/include/86box/cartridge.h diff --git a/src/config.c b/src/config.c index 299bd8dd5..08969bc3f 100644 --- a/src/config.c +++ b/src/config.c @@ -38,6 +38,7 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/cassette.h> +#include <86box/cartridge.h> #include <86box/nvr.h> #include <86box/config.h> #include <86box/isamem.h> @@ -1115,6 +1116,33 @@ load_storage_controllers(void) cassette_append = !!config_get_int(cat, "cassette_append", 0); cassette_pcm = config_get_int(cat, "cassette_pcm", 0); cassette_ui_writeprot = !!config_get_int(cat, "cassette_writeprot", 0); + + for (c=0; c<2; c++) { + sprintf(temp, "cartridge_%02i_fn", c + 1); + p = config_get_string(cat, temp, ""); + +#if 0 + /* + * NOTE: + * Temporary hack to remove the absolute + * path currently saved in most config + * files. We should remove this before + * finalizing this release! --FvK + */ + if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { + /* + * Yep, its absolute and prefixed + * with the EXE path. Just strip + * that off for now... + */ + wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(cart_fns[c])); + } else +#endif + if (strlen(p) > 511) + fatal("load_storage_controllers(): strlen(p) > 511\n"); + else + strncpy(cart_fns[c], p, strlen(p) + 1); + } } @@ -2547,6 +2575,14 @@ save_storage_controllers(void) config_delete_var(cat, "cassette_writeprot"); else config_set_int(cat, "cassette_writeprot", cassette_ui_writeprot); + + for (c=0; c<2; c++) { + sprintf(temp, "cartridge_%02i_fn", c+1); + if (strlen(cart_fns[c]) == 0) + config_delete_var(cat, temp); + else + config_set_string(cat, temp, cart_fns[c]); + } } diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index cecb241a5..7e78d752f 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -13,7 +13,7 @@ # Copyright 2020,2021 David Hrdlička. # -add_library(dev OBJECT bugger.c cassette.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c +add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c postcard.c serial.c vpc2007.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c smbus_piix4.c keyboard.c keyboard_xt.c keyboard_at.c mouse.c mouse_bus.c diff --git a/src/device/cartridge.c b/src/device/cartridge.c new file mode 100644 index 000000000..894262aa3 --- /dev/null +++ b/src/device/cartridge.c @@ -0,0 +1,208 @@ +/* + * 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 PCjr cartridge emulation. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2021 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/timer.h> +#include <86box/plat.h> +#include <86box/ui.h> +#include <86box/mem.h> +#include <86box/machine.h> +#include <86box/cartridge.h> + + +typedef struct +{ + uint8_t * buf; + uint32_t base; +} cart_t; + + +char cart_fns[2][512]; + + +static cart_t carts[2]; + +static mem_mapping_t cart_mappings[2]; + + +#ifdef ENABLE_CARTRIDGE_LOG +int cartridge_do_log = ENABLE_CARTRIDGE_LOG; + + +static void +cartridge_log(const char *fmt, ...) +{ + va_list ap; + + if (cartridge_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define cartridge_log(fmt, ...) +#endif + + +static uint8_t +cart_read(uint32_t addr, void *priv) +{ + cart_t *dev = (cart_t *) priv; + + return dev->buf[addr - dev->base]; +} + + +static void +cart_load_error(int drive, char *fn) +{ + cartridge_log("Cartridge: could not load '%s'\n",fn); + memset(cart_fns[drive], 0, sizeof(cart_fns[drive])); + ui_sb_update_icon_state(SB_CARTRIDGE | drive, 1); +} + + +static void +cart_image_close(int drive) +{ + if (carts[drive].buf != NULL) { + free(carts[drive].buf); + carts[drive].buf = NULL; + } + + carts[drive].base = 0x00000000; + + mem_mapping_disable(&cart_mappings[drive]); +} + + +static void +cart_image_load(int drive, char *fn) +{ + FILE *f; + uint32_t size; + uint32_t base = 0x00000000; + + cart_image_close(drive); + + f = fopen(fn, "rb"); + if (fseek(f, 0, SEEK_END) == -1) + fatal("cart_image_load(): Error seeking to the end of the file\n"); + size = ftell(f); + if (size < 0x1200) { + cartridge_log("cart_image_load(): File size %i is too small\n", size); + cart_load_error(drive, fn); + return; + } + if (size & 0x00000fff) { + size -= 0x00000200; + fseek(f, 0x000001ce, SEEK_SET); + fread(&base, 1, 2, f); + base <<= 4; + fseek(f, 0x00000200, SEEK_SET); + carts[drive].buf = (uint8_t *) malloc(size); + memset(carts[drive].buf, 0x00, size); + fread(carts[drive].buf, 1, size, f); + fclose(f); + } else { + base = drive ? 0xe0000 : 0xd0000; + fseek(f, 0x00000000, SEEK_SET); + carts[drive].buf = (uint8_t *) malloc(size); + memset(carts[drive].buf, 0x00, size); + fread(carts[drive].buf, 1, size, f); + fclose(f); + } + + cartridge_log("cart_image_load(): %s at %08X-%08X\n", fn, base, base + size - 1); + carts[drive].base = base; + mem_mapping_set_addr(&cart_mappings[drive], base, size); + mem_mapping_set_exec(&cart_mappings[drive], carts[drive].buf); + mem_mapping_set_p(&cart_mappings[drive], &(carts[drive])); +} + + +static void +cart_load_common(int drive, char *fn, uint8_t hard_reset) +{ + FILE *f; + + cartridge_log("Cartridge: loading drive %d with '%s'\n", drive, fn); + + if (!fn) + return; + f = plat_fopen(fn, "rb"); + if (f) { + fclose(f); + strcpy(cart_fns[drive], fn); + cart_image_load(drive, cart_fns[drive]); + /* On the real PCjr, inserting a cartridge causes a reset + in order to boot from the cartridge. */ + if (!hard_reset) + resetx86(); + } else + cart_load_error(drive, fn); +} + + +void +cart_load(int drive, char *fn) +{ + cart_load_common(drive, fn, 0); +} + + +void +cart_close(int drive) +{ + cartridge_log("Cartridge: closing drive %d\n", drive); + + cart_image_close(drive); + cart_fns[drive][0] = 0; + ui_sb_update_icon_state(SB_CARTRIDGE | drive, 1); +} + + +void +cart_reset(void) +{ + int i; + + cart_image_close(1); + cart_image_close(0); + + if (!(machines[machine].flags & MACHINE_CARTRIDGE)) + return; + + for (i = 0; i < 2; i++) { + mem_mapping_add(&cart_mappings[i], 0x000d0000, 0x00002000, + cart_read,NULL,NULL, + NULL,NULL,NULL, + NULL, MEM_MAPPING_EXTERNAL, NULL); + mem_mapping_disable(&cart_mappings[i]); + } + + cart_load_common(0, cart_fns[0], 1); + cart_load_common(1, cart_fns[1], 1); +} diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index c4439c7b4..f8016793a 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -489,24 +489,24 @@ fdd_load(int drive, char *fn) if (!p) return; f = plat_fopen(fn, "rb"); - if (!f) - return; - if (fseek(f, -1, SEEK_END) == -1) - fatal("fdd_load(): Error seeking to the end of the file\n"); - size = ftell(f) + 1; - fclose(f); - while (loaders[c].ext) { - if (!strcasecmp(p, (char *) loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1)) { - driveloaders[drive] = c; - strcpy(floppyfns[drive], fn); - d86f_setup(drive); - loaders[c].load(drive, floppyfns[drive]); - drive_empty[drive] = 0; - fdd_forced_seek(drive, 0); - fdd_changed[drive] = 1; - return; + if (f) { + if (fseek(f, -1, SEEK_END) == -1) + fatal("fdd_load(): Error seeking to the end of the file\n"); + size = ftell(f) + 1; + fclose(f); + while (loaders[c].ext) { + if (!strcasecmp(p, (char *) loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1)) { + driveloaders[drive] = c; + strcpy(floppyfns[drive], fn); + d86f_setup(drive); + loaders[c].load(drive, floppyfns[drive]); + drive_empty[drive] = 0; + fdd_forced_seek(drive, 0); + fdd_changed[drive] = 1; + return; + } + c++; } - c++; } fdd_log("FDD: could not load '%s' %s\n",fn,p); drive_empty[drive] = 1; diff --git a/src/include/86box/cartridge.h b/src/include/86box/cartridge.h new file mode 100644 index 000000000..390604e79 --- /dev/null +++ b/src/include/86box/cartridge.h @@ -0,0 +1,40 @@ +/* + * 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. + * + * Definitions for the PCjr cartridge emulation. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2021 Miran Grca. + */ +#ifndef EMU_CARTRIDGE_H +# define EMU_CARTRIDGE_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +extern char cart_fns[2][512]; + + +extern void cart_load(int drive, char *fn); +extern void cart_close(int drive); + +extern void cart_reset(void); + + +#ifdef __cplusplus +} +#endif + + +#endif /*EMU_CARTRIDGE_H*/ diff --git a/src/include/86box/language.h b/src/include/86box/language.h index ec4b8d721..7e096fbf4 100644 --- a/src/include/86box/language.h +++ b/src/include/86box/language.h @@ -121,8 +121,10 @@ #define IDS_2145 2145 // "You are loading an unsupported..." #define IDS_2146 2146 // "CPU type filtering based on..." #define IDS_2147 2147 // "Continue" -#define IDS_2148 2148 // "Continue" -#define IDS_2149 2149 // "Continue" +#define IDS_2148 2148 // "Cassette: %s" +#define IDS_2149 2149 // "Cassette images (*.PCM;*.RAW;*..." +#define IDS_2150 2150 // "Cartridge %i: %ls" +#define IDS_2151 2151 // "Cartridge images (*.JRC)\0*.JRC\0..." #define IDS_4096 4096 // "Hard disk (%s)" #define IDS_4097 4097 // "%01i:%01i" @@ -231,7 +233,7 @@ #define IDS_LANG_ENUS IDS_7168 -#define STR_NUM_2048 102 +#define STR_NUM_2048 104 #define STR_NUM_3072 11 #define STR_NUM_4096 40 #define STR_NUM_4352 6 diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index f40745a05..2996133dc 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -82,6 +82,7 @@ #define MACHINE_IDE_QUAD 0x07800000 /* sys has int quad IDE/ATAPI - mark as dual + both ter and and qua IDE/ATAPI */ #define MACHINE_SCSI 0x08000000 /* sys has int single SCSI - mark as pri SCSI */ #define MACHINE_SCSI_DUAL 0x18000000 /* sys has int dual SCSI - mark as both pri and sec SCSI */ +#define MACHINE_CARTRIDGE 0x20000000 /* sys has two cartridge bays */ #define IS_ARCH(m, a) (machines[m].flags & (a)) ? 1 : 0; #define IS_AT(m) ((machines[m].flags & 0x00000FC8) && !(machines[m].flags & MACHINE_PC98)) ? 1 : 0; diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 9f16e149f..208d7d3bd 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -133,6 +133,8 @@ extern void plat_power_off(void); /* Platform-specific device support. */ extern void cassette_mount(char *fn, uint8_t wp); extern void cassette_eject(void); +extern void cartridge_mount(uint8_t id, char *fn, uint8_t wp); +extern void cartridge_eject(uint8_t id); extern void floppy_mount(uint8_t id, char *fn, uint8_t wp); extern void floppy_eject(uint8_t id); extern void cdrom_mount(uint8_t id, char *fn); diff --git a/src/include/86box/resource.h b/src/include/86box/resource.h index 50e35ab91..91291dfd8 100644 --- a/src/include/86box/resource.h +++ b/src/include/86box/resource.h @@ -389,29 +389,32 @@ #define IDM_CASSETTE_FAST_FORWARD 0x1800 #define IDM_CASSETTE_EJECT 0x1900 -#define IDM_FLOPPY_IMAGE_NEW 0x2200 -#define IDM_FLOPPY_IMAGE_EXISTING 0x2300 -#define IDM_FLOPPY_IMAGE_EXISTING_WP 0x2400 -#define IDM_FLOPPY_EXPORT_TO_86F 0x2500 -#define IDM_FLOPPY_EJECT 0x2600 +#define IDM_CARTRIDGE_IMAGE 0x2200 +#define IDM_CARTRIDGE_EJECT 0x2300 -#define IDM_CDROM_MUTE 0x3200 -#define IDM_CDROM_EMPTY 0x3300 -#define IDM_CDROM_RELOAD 0x3400 -#define IDM_CDROM_IMAGE 0x3500 -#define IDM_CDROM_HOST_DRIVE 0x3600 +#define IDM_FLOPPY_IMAGE_NEW 0x3200 +#define IDM_FLOPPY_IMAGE_EXISTING 0x3300 +#define IDM_FLOPPY_IMAGE_EXISTING_WP 0x3400 +#define IDM_FLOPPY_EXPORT_TO_86F 0x3500 +#define IDM_FLOPPY_EJECT 0x3600 -#define IDM_ZIP_IMAGE_NEW 0x4200 -#define IDM_ZIP_IMAGE_EXISTING 0x4300 -#define IDM_ZIP_IMAGE_EXISTING_WP 0x4400 -#define IDM_ZIP_EJECT 0x4500 -#define IDM_ZIP_RELOAD 0x4600 +#define IDM_CDROM_MUTE 0x4200 +#define IDM_CDROM_EMPTY 0x4300 +#define IDM_CDROM_RELOAD 0x4400 +#define IDM_CDROM_IMAGE 0x4500 +#define IDM_CDROM_HOST_DRIVE 0x4600 -#define IDM_MO_IMAGE_NEW 0x5200 -#define IDM_MO_IMAGE_EXISTING 0x5300 -#define IDM_MO_IMAGE_EXISTING_WP 0x5400 -#define IDM_MO_EJECT 0x5500 -#define IDM_MO_RELOAD 0x5600 +#define IDM_ZIP_IMAGE_NEW 0x5200 +#define IDM_ZIP_IMAGE_EXISTING 0x5300 +#define IDM_ZIP_IMAGE_EXISTING_WP 0x5400 +#define IDM_ZIP_EJECT 0x5500 +#define IDM_ZIP_RELOAD 0x5600 + +#define IDM_MO_IMAGE_NEW 0x6200 +#define IDM_MO_IMAGE_EXISTING 0x6300 +#define IDM_MO_IMAGE_EXISTING_WP 0x6400 +#define IDM_MO_EJECT 0x6500 +#define IDM_MO_RELOAD 0x6600 /* Next default values for new objects */ diff --git a/src/include/86box/ui.h b/src/include/86box/ui.h index 09bd29b24..8b4e77fcd 100644 --- a/src/include/86box/ui.h +++ b/src/include/86box/ui.h @@ -51,14 +51,15 @@ extern void ui_check_menu_item(int id, int checked); /* Status Bar functions. */ #define SB_ICON_WIDTH 24 #define SB_CASSETTE 0x00 -#define SB_FLOPPY 0x10 -#define SB_CDROM 0x20 -#define SB_ZIP 0x30 -#define SB_MO 0x40 -#define SB_HDD 0x50 -#define SB_NETWORK 0x60 -#define SB_SOUND 0x70 -#define SB_TEXT 0x80 +#define SB_CARTRIDGE 0x10 +#define SB_FLOPPY 0x20 +#define SB_CDROM 0x30 +#define SB_ZIP 0x40 +#define SB_MO 0x50 +#define SB_HDD 0x60 +#define SB_NETWORK 0x70 +#define SB_SOUND 0x80 +#define SB_TEXT 0x90 extern wchar_t *ui_window_title(wchar_t *s); extern void ui_status_update(void); diff --git a/src/include/86box/win.h b/src/include/86box/win.h index affbe2cc4..079463214 100644 --- a/src/include/86box/win.h +++ b/src/include/86box/win.h @@ -59,6 +59,7 @@ DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); #define SDL_SUB_CLASS_NAME L"86BoxSDLSubWnd" #define CASSETTE_SUBMENU_NAME L"CassetteSubmenu" +#define CARTRIDGE_SUBMENU_NAME L"CartridgeSubmenu" #define FLOPPY_SUBMENU_NAME L"FloppySubmenu" #define CDROM_SUBMENU_NAME L"CdromSubmenu" #define ZIP_SUBMENU_NAME L"ZIPSubmenu" @@ -222,11 +223,13 @@ extern void media_menu_init(); extern void media_menu_reset(); extern int media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); extern HMENU media_menu_get_cassette(void); +extern HMENU media_menu_get_cartridge(int id); extern HMENU media_menu_get_floppy(int id); extern HMENU media_menu_get_cdrom(int id); extern HMENU media_menu_get_zip(int id); extern HMENU media_menu_get_mo(int id); extern void media_menu_update_cassette(void); +extern void media_menu_update_cartridge(int id); extern void media_menu_update_floppy(int id); extern void media_menu_update_cdrom(int id); extern void media_menu_update_zip(int id); diff --git a/src/machine/machine.c b/src/machine/machine.c index 565e9f038..afa79b02c 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -28,6 +28,7 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/cassette.h> +#include <86box/cartridge.h> #include <86box/dma.h> #include <86box/pic.h> #include <86box/pit.h> @@ -94,6 +95,8 @@ machine_init_ex(int m) if (cassette_enable) device_add(&cassette_device); + + cart_reset(); } /* All good, boot the machine! */ diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 0fd1ebcca..936f94281 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -62,7 +62,7 @@ const machine_t machines[] = { /* 8088 Machines */ { "[8088] IBM PC (1981)", "ibmpc", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 16, 64, 16, 0, machine_pc_init, NULL }, { "[8088] IBM PC (1982)", "ibmpc82", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 256, 256, 0, machine_pc82_init, NULL }, - { "[8088] IBM PCjr", "ibmpcjr", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 4772728, 4772728, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device }, + { "[8088] IBM PCjr", "ibmpcjr", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 4772728, 4772728, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED | MACHINE_CARTRIDGE, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device }, { "[8088] IBM XT (1982)", "ibmxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 256, 64, 0, machine_xt_init, NULL }, { "[8088] IBM XT (1986)", "ibmxt86", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 640, 64, 0, machine_xt86_init, NULL }, { "[8088] American XT Computer", "americxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_americxt_init, NULL }, diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 601afe4f9..c5205f85f 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -205,6 +205,16 @@ BEGIN END END +CartridgeSubmenu MENU DISCARDABLE +BEGIN + POPUP "" + BEGIN + MENUITEM "&Image...", IDM_CARTRIDGE_IMAGE + MENUITEM SEPARATOR + MENUITEM "E&ject", IDM_CARTRIDGE_EJECT + END +END + FloppySubmenu MENU DISCARDABLE BEGIN POPUP "" @@ -831,6 +841,7 @@ END 81 ICON DISCARDABLE ICON_PATH "icons/hard_disk_active.ico" 96 ICON DISCARDABLE ICON_PATH "icons/network.ico" 97 ICON DISCARDABLE ICON_PATH "icons/network_active.ico" +104 ICON DISCARDABLE ICON_PATH "icons/cartridge.ico" 144 ICON DISCARDABLE ICON_PATH "icons/floppy_525_empty.ico" 145 ICON DISCARDABLE ICON_PATH "icons/floppy_525_empty_active.ico" 152 ICON DISCARDABLE ICON_PATH "icons/floppy_35_empty.ico" @@ -843,6 +854,7 @@ END 185 ICON DISCARDABLE ICON_PATH "icons/mo_empty_active.ico" 192 ICON DISCARDABLE ICON_PATH "icons/cassette_empty.ico" 193 ICON DISCARDABLE ICON_PATH "icons/cassette_empty_active.ico" +232 ICON DISCARDABLE ICON_PATH "icons/cartridge_empty.ico" 240 ICON DISCARDABLE ICON_PATH "icons/machine.ico" 241 ICON DISCARDABLE ICON_PATH "icons/display.ico" 242 ICON DISCARDABLE ICON_PATH "icons/input_devices.ico" @@ -1144,6 +1156,8 @@ BEGIN IDS_2147 "Continue" IDS_2148 "Cassette: %s" IDS_2149 "Cassette images (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" + IDS_2150 "Cartridge %i: %ls" + IDS_2151 "Cartridge images (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" END STRINGTABLE DISCARDABLE diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index a7fa1286d..29de899d7 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -636,7 +636,7 @@ MCHOBJ := machine.o machine_table.o \ m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o \ m_at_misc.o -DEVOBJ := bugger.o cassette.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o \ +DEVOBJ := bugger.o cartridge.o cassette.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o \ ibm_5161.o isamem.o isartc.o lpt.o pci_bridge.o postcard.o serial.o \ vpc2007.o clock_ics9xxx.o isapnp.o \ i2c.o i2c_gpio.o smbus_piix4.o \ @@ -760,6 +760,7 @@ VIDOBJ := video.o \ vid_ht216.o \ vid_oak_oti.o \ vid_paradise.o \ + vid_rage128pro.o \ vid_rtg310x.o \ vid_ti_cf62011.o \ vid_tvga.o \ diff --git a/src/win/win_cdrom.c b/src/win/win_cdrom.c index a743ad14a..8a32df295 100644 --- a/src/win/win_cdrom.c +++ b/src/win/win_cdrom.c @@ -32,6 +32,7 @@ #include <86box/timer.h> #include <86box/device.h> #include <86box/cassette.h> +#include <86box/cartridge.h> #include <86box/fdd.h> #include <86box/hdd.h> #include <86box/scsi_device.h> @@ -72,6 +73,29 @@ cassette_eject(void) } +void +cartridge_mount(uint8_t id, char *fn, uint8_t wp) +{ + cart_close(id); + cart_load(id, fn); + ui_sb_update_icon_state(SB_CARTRIDGE | id, strlen(cart_fns[id]) ? 0 : 1); + media_menu_update_cartridge(id); + ui_sb_update_tip(SB_CARTRIDGE | id); + config_save(); +} + + +void +cartridge_eject(uint8_t id) +{ + cart_close(id); + ui_sb_update_icon_state(SB_CARTRIDGE | id, 1); + media_menu_update_cartridge(id); + ui_sb_update_tip(SB_CARTRIDGE | id); + config_save(); +} + + void floppy_mount(uint8_t id, char *fn, uint8_t wp) { diff --git a/src/win/win_media_menu.c b/src/win/win_media_menu.c index 7b7aae788..f72c2aae1 100644 --- a/src/win/win_media_menu.c +++ b/src/win/win_media_menu.c @@ -9,6 +9,7 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/cassette.h> +#include <86box/cartridge.h> #include <86box/fdd.h> #include <86box/fdd_86f.h> #include <86box/hdc.h> @@ -27,14 +28,15 @@ #define MACHINE_HAS_SCSI (machines[machine].flags & MACHINE_SCSI_DUAL) #define CASSETTE_FIRST 0 -#define FDD_FIRST 1 +#define CARTRIDGE_FIRST CASSETTE_FIRST + 1 +#define FDD_FIRST CARTRIDGE_FIRST + 2 #define CDROM_FIRST FDD_FIRST + FDD_NUM #define ZIP_FIRST CDROM_FIRST + CDROM_NUM #define MO_FIRST ZIP_FIRST + ZIP_NUM static HMENU media_menu, stbar_menu; -static HMENU menus[1 + FDD_NUM + CDROM_NUM + ZIP_NUM + MO_NUM]; +static HMENU menus[1 + 2 + FDD_NUM + CDROM_NUM + ZIP_NUM + MO_NUM]; static char index_map[255]; @@ -95,6 +97,29 @@ media_menu_set_name_cassette(void) } +static void +media_menu_set_name_cartridge(int drive) +{ + wchar_t name[512], fn[512]; + MENUITEMINFO mii = { 0 }; + + if (strlen(floppyfns[drive]) == 0) { + _swprintf(name, plat_get_string(IDS_2150), + drive + 1, plat_get_string(IDS_2057)); + } else { + mbstoc16s(fn, floppyfns[drive], sizeof_w(fn)); + _swprintf(name, plat_get_string(IDS_2150), + drive + 1, fn); + } + + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_STRING; + mii.dwTypeData = name; + + SetMenuItemInfo(media_menu, (UINT_PTR)menus[CARTRIDGE_FIRST + drive], FALSE, &mii); +} + + static void media_menu_set_name_floppy(int drive) { @@ -241,6 +266,20 @@ media_menu_update_cassette(void) } +void +media_menu_update_cartridge(int id) +{ + int i = CARTRIDGE_FIRST + id; + + if (strlen(cart_fns[id]) == 0) + EnableMenuItem(menus[i], IDM_CARTRIDGE_EJECT | id, MF_BYCOMMAND | MF_GRAYED); + else + EnableMenuItem(menus[i], IDM_CARTRIDGE_EJECT | id, MF_BYCOMMAND | MF_ENABLED); + + media_menu_set_name_cartridge(id); +} + + void media_menu_update_floppy(int id) { @@ -334,6 +373,11 @@ media_menu_load_submenus() menus[curr] = media_menu_load_resource(CASSETTE_SUBMENU_NAME); media_menu_set_ids(menus[curr++], 0); + for(int i = 0; i < 2; i++) { + menus[curr] = media_menu_load_resource(CARTRIDGE_SUBMENU_NAME); + media_menu_set_ids(menus[curr++], i); + } + for(int i = 0; i < FDD_NUM; i++) { menus[curr] = media_menu_load_resource(FLOPPY_SUBMENU_NAME); media_menu_set_ids(menus[curr++], i); @@ -356,6 +400,13 @@ media_menu_load_submenus() } +static inline int +is_valid_cartridge(void) +{ + return ((machines[machine].flags & MACHINE_CARTRIDGE) ? 1 : 0); +} + + static inline int is_valid_fdd(int i) { @@ -420,6 +471,14 @@ media_menu_reset() } curr++; + for(int i = 0; i < 2; i++) { + if(is_valid_cartridge()) { + AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR)menus[curr], L"Test"); + media_menu_update_cartridge(i); + } + curr++; + } + for(int i = 0; i < FDD_NUM; i++) { if(is_valid_fdd(i)) { AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR)menus[curr], L"Test"); @@ -548,6 +607,16 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) cassette_eject(); break; + case IDM_CARTRIDGE_IMAGE: + ret = file_dlg_st(hwnd, IDS_2151, floppyfns[id], NULL, 0); + if (! ret) + cartridge_mount(id, openfilestring, wp); + break; + + case IDM_CARTRIDGE_EJECT: + cartridge_eject(id); + break; + case IDM_FLOPPY_IMAGE_NEW: NewFloppyDialogCreate(hwnd, id, 0); break; @@ -654,6 +723,13 @@ media_menu_get_cassette(void) } +HMENU +media_menu_get_cartridge(int id) +{ + return menus[CARTRIDGE_FIRST + id]; +} + + HMENU media_menu_get_floppy(int id) { diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index 893c9c63d..6d37e54f0 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -35,6 +35,7 @@ #include <86box/machine.h> #include <86box/timer.h> #include <86box/cassette.h> +#include <86box/cartridge.h> #include <86box/hdd.h> #include <86box/hdc.h> #include <86box/fdd.h> @@ -200,6 +201,33 @@ StatusBarCreateCassetteTip(int part) } +static void +StatusBarCreateCartridgeTip(int part) +{ + WCHAR tempTip[512]; + WCHAR fn[512]; + int drive = sb_part_meanings[part] & 0xf; + + int type = zip_drives[drive].is_250 ? 250 : 100; + + if (strlen(cart_fns[drive]) == 0) { + _swprintf(tempTip, plat_get_string(IDS_2150), + drive+1, plat_get_string(IDS_2057)); + } else { + mbstoc16s(fn, cart_fns[drive], sizeof_w(fn)); + _swprintf(tempTip, plat_get_string(IDS_2150), + drive+1, fn); + } + + if (sbTips[part] != NULL) { + free(sbTips[part]); + sbTips[part] = NULL; + } + sbTips[part] = (WCHAR *)malloc((wcslen(tempTip) << 1) + 2); + wcscpy(sbTips[part], tempTip); +} + + static void StatusBarCreateFloppyTip(int part) { @@ -391,6 +419,10 @@ ui_sb_update_tip(int meaning) StatusBarCreateCassetteTip(part); break; + case SB_CARTRIDGE: + StatusBarCreateCartridgeTip(part); + break; + case SB_FLOPPY: StatusBarCreateFloppyTip(part); break; @@ -467,7 +499,7 @@ void ui_sb_update_panes(void) { int i, id; - int mfm_int, xta_int, esdi_int, ide_int, scsi_int; + int cart_int, mfm_int, xta_int, esdi_int, ide_int, scsi_int; int edge = 0; int c_mfm, c_esdi, c_xta; int c_ide, c_scsi; @@ -481,6 +513,7 @@ ui_sb_update_panes(void) sb_ready = 0; } + cart_int = (machines[machine].flags & MACHINE_CARTRIDGE) ? 1 : 0; mfm_int = (machines[machine].flags & MACHINE_MFM) ? 1 : 0; xta_int = (machines[machine].flags & MACHINE_XTA) ? 1 : 0; esdi_int = (machines[machine].flags & MACHINE_ESDI) ? 1 : 0; @@ -521,6 +554,8 @@ ui_sb_update_panes(void) sb_parts = 0; if (cassette_enable) sb_parts++; + if (cart_int) + sb_parts += 2; for (i=0; i