Ported the cassette emulation from PCE, closes #835.
This commit is contained in:
56
src/config.c
56
src/config.c
@@ -37,6 +37,7 @@
|
||||
#include "cpu.h"
|
||||
#include <86box/device.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/cassette.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/config.h>
|
||||
#include <86box/isamem.h>
|
||||
@@ -1093,6 +1094,18 @@ load_storage_controllers(void)
|
||||
|
||||
ide_ter_enabled = !!config_get_int(cat, "ide_ter", 0);
|
||||
ide_qua_enabled = !!config_get_int(cat, "ide_qua", 0);
|
||||
|
||||
cassette_enable = !!config_get_int(cat, "cassette_enabled", 1);
|
||||
p = config_get_string(cat, "cassette_file", "");
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_storage_controllers(): strlen(p) > 511\n");
|
||||
else
|
||||
strncpy(cassette_fname, p, strlen(p) + 1);
|
||||
cassette_mode = config_get_string(cat, "cassette_mode", "load");
|
||||
cassette_pos = config_get_int(cat, "cassette_position", 0);
|
||||
cassette_srate = config_get_int(cat, "cassette_srate", 44100);
|
||||
cassette_append = !!config_get_int(cat, "cassette_append", 0);
|
||||
cassette_pcm = config_get_int(cat, "cassette_pcm", 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1954,6 +1967,14 @@ config_load(void)
|
||||
for (i = 0; i < ISAMEM_MAX; i++)
|
||||
isamem_type[i] = 0;
|
||||
|
||||
cassette_enable = 1;
|
||||
memset(cassette_fname, 0x00, sizeof(cassette_fname));
|
||||
cassette_mode = "load";
|
||||
cassette_pos = 0;
|
||||
cassette_srate = 44100;
|
||||
cassette_append = 0;
|
||||
cassette_pcm = 0;
|
||||
|
||||
config_log("Config file not present or invalid!\n");
|
||||
return;
|
||||
}
|
||||
@@ -2471,6 +2492,41 @@ save_storage_controllers(void)
|
||||
config_set_int(cat, "ide_qua", ide_qua_enabled);
|
||||
|
||||
delete_section_if_empty(cat);
|
||||
|
||||
if (cassette_enable == 1)
|
||||
config_delete_var(cat, "cassette_enabled");
|
||||
else
|
||||
config_set_int(cat, "cassette_enabled", cassette_enable);
|
||||
|
||||
if (cassette_fname == NULL)
|
||||
config_delete_var(cat, "cassette_file");
|
||||
else
|
||||
config_set_string(cat, "cassette_file", cassette_fname);
|
||||
|
||||
if (cassette_mode == NULL)
|
||||
config_delete_var(cat, "cassette_mode");
|
||||
else
|
||||
config_set_string(cat, "cassette_mode", cassette_mode);
|
||||
|
||||
if (cassette_pos == 0)
|
||||
config_delete_var(cat, "cassette_position");
|
||||
else
|
||||
config_set_int(cat, "cassette_position", cassette_pos);
|
||||
|
||||
if (cassette_srate == 44100)
|
||||
config_delete_var(cat, "cassette_srate");
|
||||
else
|
||||
config_set_int(cat, "cassette_srate", cassette_srate);
|
||||
|
||||
if (cassette_append == 0)
|
||||
config_delete_var(cat, "cassette_append");
|
||||
else
|
||||
config_set_int(cat, "cassette_append", cassette_append);
|
||||
|
||||
if (cassette_pcm == 0)
|
||||
config_delete_var(cat, "cassette_pcm");
|
||||
else
|
||||
config_set_int(cat, "cassette_pcm", cassette_pcm);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
# Copyright 2020,2021 David Hrdlička.
|
||||
#
|
||||
|
||||
add_library(dev OBJECT bugger.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c
|
||||
add_library(dev OBJECT bugger.c cassette.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
|
||||
|
715
src/device/cassette.c
Normal file
715
src/device/cassette.c
Normal file
@@ -0,0 +1,715 @@
|
||||
/*****************************************************************************
|
||||
* pce *
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* File name: src/arch/ibmpc/cassette.c *
|
||||
* Created: 2008-11-25 by Hampa Hug <hampa@hampa.ch> *
|
||||
* Copyright: (C) 2008-2019 Hampa Hug <hampa@hampa.ch> *
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* This program is free software. You can redistribute it and / or modify it *
|
||||
* under the terms of the GNU General Public License version 2 as published *
|
||||
* by the Free Software Foundation. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY, without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
|
||||
* Public License for more details. *
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/machine.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/ui.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/cassette.h>
|
||||
|
||||
// #include <lib/console.h>
|
||||
|
||||
|
||||
#define CAS_CLK 1193182
|
||||
|
||||
|
||||
pc_cassette_t * cassette;
|
||||
|
||||
char cassette_fname[512];
|
||||
char * cassette_mode;
|
||||
unsigned long cassette_pos, cassette_srate;
|
||||
int cassette_enable;
|
||||
int cassette_append, cassette_pcm;
|
||||
int cassette_ui_writeprot;
|
||||
|
||||
|
||||
static int cassette_cycles = -1;
|
||||
|
||||
|
||||
static void pc_cas_reset (pc_cassette_t *cas);
|
||||
|
||||
|
||||
#ifdef ENABLE_CASSETTE_LOG
|
||||
int cassette_do_log = ENABLE_CASSETTE_LOG;
|
||||
|
||||
|
||||
static void
|
||||
cassette_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (cassette_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define cassette_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
void pc_cas_init (pc_cassette_t *cas)
|
||||
{
|
||||
cas->save = 0;
|
||||
cas->pcm = 0;
|
||||
|
||||
cas->motor = 0;
|
||||
ui_sb_update_icon(SB_CASSETTE, 0);
|
||||
|
||||
cas->position = 0;
|
||||
|
||||
cas->position_save = 0;
|
||||
cas->position_load = 0;
|
||||
|
||||
cas->data_out = 0;
|
||||
cas->data_inp = 0;
|
||||
|
||||
cas->pcm_out_vol = 64;
|
||||
cas->pcm_out_val = 0;
|
||||
|
||||
cas->cas_out_cnt = 0;
|
||||
cas->cas_out_buf = 0;
|
||||
|
||||
cas->cas_inp_cnt = 0;
|
||||
cas->cas_inp_buf = 0;
|
||||
cas->cas_inp_bit = 0;
|
||||
|
||||
cas->clk = 0;
|
||||
|
||||
cas->clk_pcm = 0;
|
||||
|
||||
cas->clk_out = 0;
|
||||
cas->clk_inp = 0;
|
||||
|
||||
cas->srate = 44100;
|
||||
|
||||
cas->close = 0;
|
||||
cas->fname = NULL;
|
||||
cas->fp = NULL;
|
||||
|
||||
pc_cas_reset (cas);
|
||||
}
|
||||
|
||||
void pc_cas_free (pc_cassette_t *cas)
|
||||
{
|
||||
free (cas->fname);
|
||||
|
||||
if (cas->close) {
|
||||
fclose (cas->fp);
|
||||
}
|
||||
}
|
||||
|
||||
pc_cassette_t *pc_cas_new (void)
|
||||
{
|
||||
pc_cassette_t *cas;
|
||||
|
||||
cas = malloc (sizeof (pc_cassette_t));
|
||||
|
||||
if (cas == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
pc_cas_init (cas);
|
||||
|
||||
return (cas);
|
||||
}
|
||||
|
||||
void pc_cas_del (pc_cassette_t *cas)
|
||||
{
|
||||
if (cas != NULL) {
|
||||
pc_cas_free (cas);
|
||||
free (cas);
|
||||
}
|
||||
}
|
||||
|
||||
int pc_cas_set_fname (pc_cassette_t *cas, const char *fname)
|
||||
{
|
||||
unsigned n;
|
||||
const char * ext;
|
||||
|
||||
if (cas->close)
|
||||
fclose (cas->fp);
|
||||
|
||||
cas->close = 0;
|
||||
cas->fp = NULL;
|
||||
|
||||
free (cas->fname);
|
||||
cas->fname = NULL;
|
||||
|
||||
cas->position = 0;
|
||||
|
||||
cas->position_save = 0;
|
||||
cas->position_load = 0;
|
||||
|
||||
if (fname == NULL) {
|
||||
ui_sb_update_icon_state(SB_CASSETTE, 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
cas->fp = plat_fopen (fname, "r+b");
|
||||
|
||||
if (cas->fp == NULL)
|
||||
cas->fp = plat_fopen (fname, "w+b");
|
||||
|
||||
if (cas->fp == NULL) {
|
||||
ui_sb_update_icon_state(SB_CASSETTE, 1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
cas->close = 1;
|
||||
|
||||
pc_cas_append (cas);
|
||||
|
||||
cas->position_save = cas->position;
|
||||
|
||||
if (cas->save == 0)
|
||||
pc_cas_set_position (cas, 0);
|
||||
|
||||
n = strlen (fname);
|
||||
|
||||
cas->fname = malloc ((n + 1) * sizeof(char));
|
||||
|
||||
if (cas->fname != NULL)
|
||||
memcpy (cas->fname, fname, (n + 1) * sizeof(char));
|
||||
|
||||
if (n > 4) {
|
||||
ext = fname + (n - 4);
|
||||
|
||||
/* Has to be 44.1 kHz, mono, 8-bit. */
|
||||
if (stricmp (ext, ".pcm") == 0)
|
||||
pc_cas_set_pcm (cas, 1);
|
||||
else if (stricmp (ext, ".raw") == 0)
|
||||
pc_cas_set_pcm (cas, 1);
|
||||
else if (stricmp (ext, ".wav") == 0)
|
||||
pc_cas_set_pcm (cas, 1);
|
||||
else if (stricmp (ext, ".cas") == 0)
|
||||
pc_cas_set_pcm (cas, 0);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static
|
||||
void pc_cas_reset (pc_cassette_t *cas)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
cas->clk_pcm = 0;
|
||||
|
||||
cas->clk_out = cas->clk;
|
||||
cas->clk_inp = 0;
|
||||
|
||||
cas->pcm_out_val = 0;
|
||||
|
||||
cas->cas_out_cnt = 0;
|
||||
cas->cas_out_buf = 0;
|
||||
|
||||
cas->cas_inp_cnt = 0;
|
||||
cas->cas_inp_buf = 0;
|
||||
cas->cas_inp_bit = 0;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
cas->pcm_inp_fir[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int pc_cas_get_mode (const pc_cassette_t *cas)
|
||||
{
|
||||
return (cas->save);
|
||||
}
|
||||
|
||||
void pc_cas_set_mode (pc_cassette_t *cas, int save)
|
||||
{
|
||||
save = (save != 0);
|
||||
|
||||
if (cas->save == save) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cas->save) {
|
||||
cas->position_save = cas->position;
|
||||
cas->position = cas->position_load;
|
||||
}
|
||||
else {
|
||||
cas->position_load = cas->position;
|
||||
cas->position = cas->position_save;
|
||||
}
|
||||
|
||||
cas->save = save;
|
||||
|
||||
if (cas->fp != NULL) {
|
||||
fflush (cas->fp);
|
||||
|
||||
pc_cas_set_position (cas, cas->position);
|
||||
}
|
||||
|
||||
pc_cas_reset (cas);
|
||||
}
|
||||
|
||||
int pc_cas_get_pcm (const pc_cassette_t *cas)
|
||||
{
|
||||
return (cas->pcm);
|
||||
}
|
||||
|
||||
void pc_cas_set_pcm (pc_cassette_t *cas, int pcm)
|
||||
{
|
||||
cas->pcm = (pcm != 0);
|
||||
|
||||
cassette_pcm = (pcm != 0);
|
||||
|
||||
pc_cas_reset (cas);
|
||||
}
|
||||
|
||||
unsigned long pc_cas_get_srate (const pc_cassette_t *cas)
|
||||
{
|
||||
return (cas->srate);
|
||||
}
|
||||
|
||||
void pc_cas_set_srate (pc_cassette_t *cas, unsigned long srate)
|
||||
{
|
||||
cas->srate = srate;
|
||||
|
||||
pc_cas_reset (cas);
|
||||
}
|
||||
|
||||
void pc_cas_rewind (pc_cassette_t *cas)
|
||||
{
|
||||
if (cas->fp != NULL) {
|
||||
rewind (cas->fp);
|
||||
cas->position = 0;
|
||||
}
|
||||
|
||||
pc_cas_reset (cas);
|
||||
}
|
||||
|
||||
void pc_cas_append (pc_cassette_t *cas)
|
||||
{
|
||||
if (cas->fp != NULL) {
|
||||
fseek (cas->fp, 0, SEEK_END);
|
||||
cas->position = ftell (cas->fp);
|
||||
}
|
||||
|
||||
pc_cas_reset (cas);
|
||||
}
|
||||
|
||||
unsigned long pc_cas_get_position (const pc_cassette_t *cas)
|
||||
{
|
||||
return (cas->position);
|
||||
}
|
||||
|
||||
int pc_cas_set_position (pc_cassette_t *cas, unsigned long pos)
|
||||
{
|
||||
if (cas->fp == NULL) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (fseek (cas->fp, pos, SEEK_SET) != 0) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
cas->position = pos;
|
||||
|
||||
pc_cas_reset (cas);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static
|
||||
void pc_cas_read_bit (pc_cassette_t *cas)
|
||||
{
|
||||
int val;
|
||||
|
||||
if (cas->cas_inp_cnt == 0) {
|
||||
if (cas->fp == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (feof (cas->fp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
val = fgetc (cas->fp);
|
||||
|
||||
if (val == EOF) {
|
||||
cassette_log ("cassette EOF at %lu\n", cas->position);
|
||||
return;
|
||||
}
|
||||
|
||||
cas->position += 1;
|
||||
|
||||
cas->cas_inp_cnt = 8;
|
||||
cas->cas_inp_buf = val;
|
||||
}
|
||||
|
||||
cas->cas_inp_bit = ((cas->cas_inp_buf & 0x80) != 0);
|
||||
|
||||
cas->cas_inp_buf = (cas->cas_inp_buf << 1) & 0xff;
|
||||
cas->cas_inp_cnt -= 1;
|
||||
}
|
||||
|
||||
static
|
||||
int pc_cas_read_smp (pc_cassette_t *cas)
|
||||
{
|
||||
int smp, *fir;
|
||||
|
||||
if (feof (cas->fp)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
smp = fgetc (cas->fp);
|
||||
|
||||
if (smp == EOF) {
|
||||
cassette_log ("cassette EOF at %lu\n", cas->position);
|
||||
return (0);
|
||||
}
|
||||
|
||||
cas->position += 1;
|
||||
|
||||
fir = cas->pcm_inp_fir;
|
||||
|
||||
fir[0] = fir[1];
|
||||
fir[1] = fir[2];
|
||||
fir[2] = (smp & 0x80) ? (smp - 256) : smp;
|
||||
|
||||
smp = (fir[0] + 2 * fir[1] + fir[2]) / 4;
|
||||
|
||||
return (smp);
|
||||
}
|
||||
|
||||
static
|
||||
void pc_cas_write_bit (pc_cassette_t *cas, unsigned char val)
|
||||
{
|
||||
if (val) {
|
||||
cas->cas_out_buf |= (0x80 >> cas->cas_out_cnt);
|
||||
}
|
||||
|
||||
cas->cas_out_cnt += 1;
|
||||
|
||||
if (cas->cas_out_cnt >= 8) {
|
||||
if (cas->fp != NULL) {
|
||||
fputc (cas->cas_out_buf, cas->fp);
|
||||
cas->position += 1;
|
||||
}
|
||||
|
||||
cas->cas_out_buf = 0;
|
||||
cas->cas_out_cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void pc_cas_write_smp (pc_cassette_t *cas, int val)
|
||||
{
|
||||
unsigned char smp;
|
||||
|
||||
if (val < 0) {
|
||||
smp = (val < -127) ? 0x80 : (val + 256);
|
||||
}
|
||||
else {
|
||||
smp = (val > 127) ? 0x7f : val;
|
||||
}
|
||||
|
||||
fputc (smp, cas->fp);
|
||||
|
||||
cas->position += 1;
|
||||
}
|
||||
|
||||
void pc_cas_set_motor (pc_cassette_t *cas, unsigned char val)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
val = (val != 0);
|
||||
|
||||
if (val == cas->motor) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((val == 0) && cas->save && cas->pcm) {
|
||||
for (i = 0; i < (cas->srate / 16); i++) {
|
||||
pc_cas_write_smp (cas, 0);
|
||||
}
|
||||
}
|
||||
|
||||
cassette_log ("cassette %S at %lu motor %s\n", (cas->fname != NULL) ? cas->fname : "<none>", cas->position, val ? "on" : "off");
|
||||
|
||||
cas->motor = val;
|
||||
|
||||
if (cas->fp != NULL) {
|
||||
fflush (cas->fp);
|
||||
|
||||
pc_cas_set_position (cas, cas->position);
|
||||
}
|
||||
|
||||
pc_cas_reset (cas);
|
||||
|
||||
if (cas->motor)
|
||||
timer_set_delay_u64(&cas->timer, 8ULL * PITCONST);
|
||||
else
|
||||
timer_disable(&cas->timer);
|
||||
|
||||
ui_sb_update_icon(SB_CASSETTE, !!val);
|
||||
}
|
||||
|
||||
unsigned char pc_cas_get_inp (const pc_cassette_t *cas)
|
||||
{
|
||||
return (cas->data_inp);
|
||||
}
|
||||
|
||||
void pc_cas_set_out (pc_cassette_t *cas, unsigned char val)
|
||||
{
|
||||
unsigned long clk;
|
||||
|
||||
val = (val != 0);
|
||||
|
||||
if (cas->motor == 0) {
|
||||
cas->data_inp = val;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cas->data_out == val) {
|
||||
return;
|
||||
}
|
||||
|
||||
cas->data_out = val;
|
||||
|
||||
if (cas->pcm) {
|
||||
cas->pcm_out_val = val ? -cas->pcm_out_vol : cas->pcm_out_vol;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cas->save == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (val == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
clk = cas->clk - cas->clk_out;
|
||||
cas->clk_out = cas->clk;
|
||||
|
||||
if (clk < (CAS_CLK / 4000)) {
|
||||
;
|
||||
}
|
||||
else if (clk < ((3 * CAS_CLK) / 4000)) {
|
||||
pc_cas_write_bit (cas, 0);
|
||||
}
|
||||
else if (clk < ((5 * CAS_CLK) / 4000)) {
|
||||
pc_cas_write_bit (cas, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void pc_cas_print_state (const pc_cassette_t *cas)
|
||||
{
|
||||
cassette_log ("%s %s %lu %s %lu\n", (cas->fname != NULL) ? cas->fname : "<none>", cas->pcm ? "pcm" : "cas", cas->srate, cas->save ? "save" : "load", cas->position);
|
||||
}
|
||||
|
||||
static
|
||||
void pc_cas_clock_pcm (pc_cassette_t *cas, unsigned long cnt)
|
||||
{
|
||||
unsigned long i, n;
|
||||
int v = 0;
|
||||
|
||||
n = cas->srate * cnt + cas->clk_pcm;
|
||||
|
||||
cas->clk_pcm = n % CAS_CLK;
|
||||
|
||||
n = n / CAS_CLK;
|
||||
|
||||
if (n == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cas->save) {
|
||||
for (i = 0; i < n; i++) {
|
||||
pc_cas_write_smp (cas, cas->pcm_out_val);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < n; i++) {
|
||||
v = pc_cas_read_smp (cas);
|
||||
}
|
||||
|
||||
cas->data_inp = (v < 0) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
void pc_cas_clock (pc_cassette_t *cas, unsigned long cnt)
|
||||
{
|
||||
cas->clk += cnt;
|
||||
|
||||
if (cas->motor == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cas->pcm) {
|
||||
pc_cas_clock_pcm (cas, cnt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cas->save) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cas->clk_inp > cnt) {
|
||||
cas->clk_inp -= cnt;
|
||||
return;
|
||||
}
|
||||
|
||||
cnt -= cas->clk_inp;
|
||||
|
||||
cas->data_inp = !cas->data_inp;
|
||||
|
||||
if (cas->data_inp) {
|
||||
pc_cas_read_bit (cas);
|
||||
}
|
||||
|
||||
if (cas->cas_inp_bit) {
|
||||
cas->clk_inp = CAS_CLK / 2000;
|
||||
}
|
||||
else {
|
||||
cas->clk_inp = CAS_CLK / 4000;
|
||||
}
|
||||
|
||||
if (cas->clk_inp > cnt) {
|
||||
cas->clk_inp -= cnt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pc_cas_advance (pc_cassette_t *cas)
|
||||
{
|
||||
int ticks;
|
||||
cpu_s = (CPU *) &cpu_f->cpus[cpu_effective];
|
||||
|
||||
if (cas->motor == 0)
|
||||
return;
|
||||
|
||||
if (cassette_cycles == -1)
|
||||
cassette_cycles = cycles;
|
||||
if (cycles <= cassette_cycles)
|
||||
ticks = (cassette_cycles - cycles);
|
||||
else
|
||||
ticks = (cassette_cycles + (cpu_s->rspeed / 100) - cycles);
|
||||
cassette_cycles = cycles;
|
||||
|
||||
pc_cas_clock(cas, ticks);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cassette_close(void *p)
|
||||
{
|
||||
if (cassette != NULL) {
|
||||
free(cassette);
|
||||
cassette = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cassette_callback(void *p)
|
||||
{
|
||||
pc_cassette_t *cas = (pc_cassette_t *) p;
|
||||
|
||||
pc_cas_clock (cas, 8);
|
||||
|
||||
if (cas->motor)
|
||||
ui_sb_update_icon(SB_CASSETTE, 1);
|
||||
|
||||
timer_advance_u64(&cas->timer, 8ULL * PITCONST);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
cassette_init(const device_t *info)
|
||||
{
|
||||
cassette = NULL;
|
||||
|
||||
if (cassette_pcm == 1)
|
||||
cassette_pcm = -1;
|
||||
|
||||
cassette_log("CASSETTE: file=%s mode=%s pcm=%d srate=%lu pos=%lu append=%d\n",
|
||||
(cassette_fname != NULL) ? cassette_fname : "<none>", cassette_mode, cassette_pcm, cassette_srate, cassette_pos, cassette_append);
|
||||
|
||||
cassette = pc_cas_new();
|
||||
|
||||
if (cassette == NULL) {
|
||||
cassette_log("ERROR: *** alloc failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strlen(cassette_fname) == 0) {
|
||||
if (pc_cas_set_fname (cassette, NULL)) {
|
||||
cassette_log("ERROR: *** opening file failed (%s)\n", cassette_fname);
|
||||
}
|
||||
} else {
|
||||
if (pc_cas_set_fname (cassette, cassette_fname)) {
|
||||
cassette_log("ERROR: *** opening file failed (%s)\n", cassette_fname);
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp (cassette_mode, "load") == 0)
|
||||
pc_cas_set_mode (cassette, 0);
|
||||
else if (strcmp (cassette_mode, "save") == 0)
|
||||
pc_cas_set_mode (cassette, 1);
|
||||
else {
|
||||
cassette_log ("ERROR: *** unknown cassette mode (%s)\n", cassette_mode);
|
||||
}
|
||||
|
||||
if (cassette_append)
|
||||
pc_cas_append (cassette);
|
||||
else
|
||||
pc_cas_set_position (cassette, cassette_pos);
|
||||
|
||||
if (cassette_pcm >= 0)
|
||||
pc_cas_set_pcm (cassette, cassette_pcm);
|
||||
|
||||
pc_cas_set_srate (cassette, cassette_srate);
|
||||
|
||||
timer_add(&cassette->timer, cassette_callback, cassette, 0);
|
||||
|
||||
return cassette;
|
||||
}
|
||||
|
||||
|
||||
const device_t cassette_device = {
|
||||
"IBM PC/PCjr Cassette Device",
|
||||
0,
|
||||
0,
|
||||
cassette_init, cassette_close, NULL,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
@@ -33,6 +33,7 @@
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/m_xt_t1000.h>
|
||||
#include <86box/cassette.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
@@ -515,13 +516,14 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
timer_process();
|
||||
|
||||
if (kbd->type <= 1)
|
||||
pc_cas_set_motor(cassette, (kbd->pb & 0x08) == 0);
|
||||
|
||||
speaker_update();
|
||||
if ((kbd->type <= 1) && !(kbd->pb & 0x08))
|
||||
speaker_gated = speaker_enable = 1;
|
||||
else {
|
||||
speaker_gated = val & 1;
|
||||
speaker_enable = val & 2;
|
||||
}
|
||||
|
||||
speaker_gated = val & 1;
|
||||
speaker_enable = val & 2;
|
||||
|
||||
if (speaker_enable)
|
||||
was_speaker_enable = 1;
|
||||
pit_ctr_set_gate(&pit->counters[2], val & 1);
|
||||
@@ -622,8 +624,12 @@ kbd_read(uint16_t port, void *priv)
|
||||
|
||||
/* This is needed to avoid error 131 (cassette error).
|
||||
This is serial read: bit 5 = clock, bit 4 = data, cassette header is 256 x 0xff. */
|
||||
if (kbd->type <= 1)
|
||||
ret |= (ppispeakon ? 0x10 : 0);
|
||||
if (kbd->type <= 1) {
|
||||
if (cassette == NULL)
|
||||
ret |= (ppispeakon ? 0x10 : 0);
|
||||
else
|
||||
ret |= (pc_cas_get_inp(cassette) ? 0x10 : 0);
|
||||
}
|
||||
|
||||
if (kbd->type == 5)
|
||||
ret |= (tandy1k_eeprom_read() ? 0x10 : 0);
|
||||
|
@@ -512,7 +512,7 @@ fdd_load(int drive, char *fn)
|
||||
drive_empty[drive] = 1;
|
||||
fdd_set_head(drive, 0);
|
||||
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
|
||||
ui_sb_update_icon_state(drive, 1);
|
||||
ui_sb_update_icon_state(SB_FLOPPY | drive, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -538,7 +538,7 @@ fdd_close(int drive)
|
||||
drives[drive].byteperiod = NULL;
|
||||
drives[drive].stop = NULL;
|
||||
d86f_destroy(drive);
|
||||
ui_sb_update_icon_state(drive, 1);
|
||||
ui_sb_update_icon_state(SB_FLOPPY | drive, 1);
|
||||
}
|
||||
|
||||
|
||||
|
173
src/include/86box/cassette.h
Normal file
173
src/include/86box/cassette.h
Normal file
@@ -0,0 +1,173 @@
|
||||
/*****************************************************************************
|
||||
* pce *
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* File name: src/ibmpc/cassette.h *
|
||||
* Created: 2008-11-25 by Hampa Hug <hampa@hampa.ch> *
|
||||
* Copyright: (C) 2008-2019 Hampa Hug <hampa@hampa.ch> *
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* This program is free software. You can redistribute it and / or modify it *
|
||||
* under the terms of the GNU General Public License version 2 as published *
|
||||
* by the Free Software Foundation. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY, without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
|
||||
* Public License for more details. *
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#ifndef PCE_IBMPC_CASSETTE_H
|
||||
#define PCE_IBMPC_CASSETTE_H 1
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
char save;
|
||||
char pcm;
|
||||
|
||||
unsigned char motor;
|
||||
|
||||
unsigned long position;
|
||||
|
||||
unsigned long position_save;
|
||||
unsigned long position_load;
|
||||
|
||||
unsigned char data_out;
|
||||
unsigned char data_inp;
|
||||
|
||||
int pcm_out_vol;
|
||||
int pcm_out_val;
|
||||
|
||||
unsigned cas_out_cnt;
|
||||
unsigned char cas_out_buf;
|
||||
|
||||
unsigned cas_inp_cnt;
|
||||
unsigned char cas_inp_buf;
|
||||
unsigned char cas_inp_bit;
|
||||
|
||||
int pcm_inp_fir[3];
|
||||
|
||||
unsigned long clk;
|
||||
|
||||
unsigned long clk_pcm;
|
||||
|
||||
unsigned long clk_out;
|
||||
unsigned long clk_inp;
|
||||
|
||||
unsigned long srate;
|
||||
|
||||
char close;
|
||||
char *fname;
|
||||
FILE *fp;
|
||||
pc_timer_t timer;
|
||||
} pc_cassette_t;
|
||||
|
||||
|
||||
void pc_cas_init (pc_cassette_t *cas);
|
||||
void pc_cas_free (pc_cassette_t *cas);
|
||||
|
||||
pc_cassette_t *pc_cas_new (void);
|
||||
void pc_cas_del (pc_cassette_t *cas);
|
||||
|
||||
/*!***************************************************************************
|
||||
* @short Set the cassette file
|
||||
* @return True on error, false otherwise
|
||||
*****************************************************************************/
|
||||
int pc_cas_set_fname (pc_cassette_t *cas, const char *fname);
|
||||
|
||||
/*!***************************************************************************
|
||||
* @short Get the cassette mode
|
||||
* @return True if in save mode, false if in load mode
|
||||
*****************************************************************************/
|
||||
int pc_cas_get_mode (const pc_cassette_t *cas);
|
||||
|
||||
/*!***************************************************************************
|
||||
* @short Set the cassette mode
|
||||
* @param save If true set save mode, otherwise set load mode
|
||||
*****************************************************************************/
|
||||
void pc_cas_set_mode (pc_cassette_t *cas, int save);
|
||||
|
||||
/*!***************************************************************************
|
||||
* @short Get the cassette pcm mode
|
||||
* @return True if in pcm mode, false if in binary mode
|
||||
*****************************************************************************/
|
||||
int pc_cas_get_pcm (const pc_cassette_t *cas);
|
||||
|
||||
/*!***************************************************************************
|
||||
* @short Set the cassette pcm mode
|
||||
* @param pcm If true set pcm mode, otherwise set binary mode
|
||||
*****************************************************************************/
|
||||
void pc_cas_set_pcm (pc_cassette_t *cas, int pcm);
|
||||
|
||||
/*!***************************************************************************
|
||||
* @short Get the pcm sample rate
|
||||
* @return The sample rate in Hz
|
||||
*****************************************************************************/
|
||||
unsigned long pc_cas_get_srate (const pc_cassette_t *cas);
|
||||
|
||||
/*!***************************************************************************
|
||||
* @short Set the pcm sample rate
|
||||
* @param pcm The sample rate in Hz
|
||||
*****************************************************************************/
|
||||
void pc_cas_set_srate (pc_cassette_t *cas, unsigned long srate);
|
||||
|
||||
/*!***************************************************************************
|
||||
* @short Rewind the cassette
|
||||
*****************************************************************************/
|
||||
void pc_cas_rewind (pc_cassette_t *cas);
|
||||
|
||||
/*!***************************************************************************
|
||||
* @short Fast forward to the end of the cassette
|
||||
*****************************************************************************/
|
||||
void pc_cas_append (pc_cassette_t *cas);
|
||||
|
||||
/*!***************************************************************************
|
||||
* @short Get the current load/save position
|
||||
*****************************************************************************/
|
||||
unsigned long pc_cas_get_position (const pc_cassette_t *cas);
|
||||
|
||||
/*!***************************************************************************
|
||||
* @short Set the current load/save position
|
||||
*****************************************************************************/
|
||||
int pc_cas_set_position (pc_cassette_t *cas, unsigned long pos);
|
||||
|
||||
/*!***************************************************************************
|
||||
* @short Set the cassette motor status
|
||||
*****************************************************************************/
|
||||
void pc_cas_set_motor (pc_cassette_t *cas, unsigned char val);
|
||||
|
||||
/*!***************************************************************************
|
||||
* @short Get the current input from the cassette
|
||||
*****************************************************************************/
|
||||
unsigned char pc_cas_get_inp (const pc_cassette_t *cas);
|
||||
|
||||
/*!***************************************************************************
|
||||
* @short Set the current output to the cassette
|
||||
*****************************************************************************/
|
||||
void pc_cas_set_out (pc_cassette_t *cas, unsigned char val);
|
||||
|
||||
void pc_cas_print_state (const pc_cassette_t *cas);
|
||||
|
||||
void pc_cas_clock (pc_cassette_t *cas, unsigned long cnt);
|
||||
void pc_cas_advance (pc_cassette_t *cas);
|
||||
|
||||
|
||||
extern pc_cassette_t * cassette;
|
||||
|
||||
extern char cassette_fname[512];
|
||||
extern char * cassette_mode;
|
||||
extern unsigned long cassette_pos, cassette_srate;
|
||||
extern int cassette_enable;
|
||||
extern int cassette_append, cassette_pcm;
|
||||
extern int cassette_ui_writeprot;
|
||||
|
||||
extern const device_t cassette_device;
|
||||
|
||||
|
||||
#endif
|
@@ -121,6 +121,8 @@
|
||||
#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_4096 4096 // "Hard disk (%s)"
|
||||
#define IDS_4097 4097 // "%01i:%01i"
|
||||
@@ -229,7 +231,7 @@
|
||||
|
||||
#define IDS_LANG_ENUS IDS_7168
|
||||
|
||||
#define STR_NUM_2048 100
|
||||
#define STR_NUM_2048 102
|
||||
#define STR_NUM_3072 11
|
||||
#define STR_NUM_4096 40
|
||||
#define STR_NUM_4352 6
|
||||
|
@@ -131,6 +131,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 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);
|
||||
|
@@ -195,6 +195,7 @@
|
||||
#define IDC_CONFIGURE_SCSI_2 1093
|
||||
#define IDC_CONFIGURE_SCSI_3 1094
|
||||
#define IDC_CONFIGURE_SCSI_4 1095
|
||||
#define IDC_CHECK_CASSETTE 1096
|
||||
|
||||
#define IDC_HARD_DISKS 1100 /* hard disks config */
|
||||
#define IDC_LIST_HARD_DISKS 1101
|
||||
@@ -379,29 +380,36 @@
|
||||
* and 5 bits for Removable Disks (5 bits for ID), so we use an
|
||||
* 8bit (256 entries) space for these devices.
|
||||
*/
|
||||
#define IDM_FLOPPY_IMAGE_NEW 0x1200
|
||||
#define IDM_FLOPPY_IMAGE_EXISTING 0x1300
|
||||
#define IDM_FLOPPY_IMAGE_EXISTING_WP 0x1400
|
||||
#define IDM_FLOPPY_EXPORT_TO_86F 0x1500
|
||||
#define IDM_FLOPPY_EJECT 0x1600
|
||||
#define IDM_CASSETTE_IMAGE_NEW 0x1200
|
||||
#define IDM_CASSETTE_IMAGE_EXISTING 0x1300
|
||||
#define IDM_CASSETTE_IMAGE_EXISTING_WP 0x1400
|
||||
#define IDM_CASSETTE_REWIND 0x1500
|
||||
#define IDM_CASSETTE_FAST_FORWARD 0x1600
|
||||
#define IDM_CASSETTE_EJECT 0x1700
|
||||
|
||||
#define IDM_CDROM_MUTE 0x2200
|
||||
#define IDM_CDROM_EMPTY 0x2300
|
||||
#define IDM_CDROM_RELOAD 0x2400
|
||||
#define IDM_CDROM_IMAGE 0x2500
|
||||
#define IDM_CDROM_HOST_DRIVE 0x2600
|
||||
#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_ZIP_IMAGE_NEW 0x3200
|
||||
#define IDM_ZIP_IMAGE_EXISTING 0x3300
|
||||
#define IDM_ZIP_IMAGE_EXISTING_WP 0x3400
|
||||
#define IDM_ZIP_EJECT 0x3500
|
||||
#define IDM_ZIP_RELOAD 0x3600
|
||||
#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_MO_IMAGE_NEW 0x4200
|
||||
#define IDM_MO_IMAGE_EXISTING 0x4300
|
||||
#define IDM_MO_IMAGE_EXISTING_WP 0x4400
|
||||
#define IDM_MO_EJECT 0x4500
|
||||
#define IDM_MO_RELOAD 0x4600
|
||||
#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_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
|
||||
|
||||
|
||||
/* Next default values for new objects */
|
||||
|
@@ -50,14 +50,15 @@ extern void ui_check_menu_item(int id, int checked);
|
||||
|
||||
/* Status Bar functions. */
|
||||
#define SB_ICON_WIDTH 24
|
||||
#define SB_FLOPPY 0x00
|
||||
#define SB_CDROM 0x10
|
||||
#define SB_ZIP 0x20
|
||||
#define SB_MO 0x30
|
||||
#define SB_HDD 0x40
|
||||
#define SB_NETWORK 0x50
|
||||
#define SB_SOUND 0x60
|
||||
#define SB_TEXT 0x70
|
||||
#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
|
||||
|
||||
extern wchar_t *ui_window_title(wchar_t *s);
|
||||
extern void ui_status_update(void);
|
||||
|
@@ -58,6 +58,7 @@ DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
|
||||
#define SDL_CLASS_NAME L"86BoxSDLWnd"
|
||||
#define SDL_SUB_CLASS_NAME L"86BoxSDLSubWnd"
|
||||
|
||||
#define CASSETTE_SUBMENU_NAME L"CassetteSubmenu"
|
||||
#define FLOPPY_SUBMENU_NAME L"FloppySubmenu"
|
||||
#define CDROM_SUBMENU_NAME L"CdromSubmenu"
|
||||
#define ZIP_SUBMENU_NAME L"ZIPSubmenu"
|
||||
@@ -220,10 +221,12 @@ extern wchar_t *BrowseFolder(wchar_t *saved_path, wchar_t *title);
|
||||
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_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_floppy(int id);
|
||||
extern void media_menu_update_cdrom(int id);
|
||||
extern void media_menu_update_zip(int id);
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/cassette.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
@@ -90,6 +91,9 @@ machine_init_ex(int m)
|
||||
smbase = is_am486dxl ? 0x00060000 : 0x00030000;
|
||||
|
||||
lpt_init();
|
||||
|
||||
if (cassette_enable)
|
||||
device_add(&cassette_device);
|
||||
}
|
||||
|
||||
/* All good, boot the machine! */
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include "cpu.h"
|
||||
#include <86box/device.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/cassette.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/nmi.h>
|
||||
@@ -734,6 +735,9 @@ pit_speaker_timer(int new_out, int old_out)
|
||||
{
|
||||
int l;
|
||||
|
||||
if (cassette != NULL)
|
||||
pc_cas_set_out(cassette, new_out);
|
||||
|
||||
speaker_update();
|
||||
|
||||
l = pit->counters[2].l ? pit->counters[2].l : 0x10000;
|
||||
|
@@ -187,6 +187,22 @@ BEGIN
|
||||
MENUITEM SEPARATOR
|
||||
END
|
||||
|
||||
CassetteSubmenu MENU DISCARDABLE
|
||||
BEGIN
|
||||
POPUP ""
|
||||
BEGIN
|
||||
MENUITEM "&New image...", IDM_CASSETTE_IMAGE_NEW
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Existing image...", IDM_CASSETTE_IMAGE_EXISTING
|
||||
MENUITEM "Existing image (&Write-protected)...", IDM_CASSETTE_IMAGE_EXISTING_WP
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Rewind to the beginning", IDM_CASSETTE_REWIND
|
||||
MENUITEM "&Fast forward to the end", IDM_CASSETTE_FAST_FORWARD
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "E&ject", IDM_CASSETTE_EJECT
|
||||
END
|
||||
END
|
||||
|
||||
FloppySubmenu MENU DISCARDABLE
|
||||
BEGIN
|
||||
POPUP ""
|
||||
@@ -549,7 +565,7 @@ BEGIN
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,118,94,10
|
||||
END
|
||||
|
||||
DLG_CFG_STORAGE DIALOG DISCARDABLE 107, 0, 267, 211
|
||||
DLG_CFG_STORAGE DIALOG DISCARDABLE 107, 0, 267, 203
|
||||
STYLE DS_CONTROL | WS_CHILD
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
@@ -588,6 +604,9 @@ BEGIN
|
||||
COMBOBOX IDC_COMBO_SCSI_4,73,157,137,120,
|
||||
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI_4,213,157,38,12
|
||||
|
||||
CONTROL "Cassette",IDC_CHECK_CASSETTE,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,185,94,10
|
||||
END
|
||||
|
||||
DLG_CFG_HARD_DISKS DIALOG DISCARDABLE 107, 0, 267, 154
|
||||
@@ -1121,6 +1140,8 @@ BEGIN
|
||||
IDS_2145 "You are loading an unsupported configuration"
|
||||
IDS_2146 "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid."
|
||||
IDS_2147 "Continue"
|
||||
IDS_2148 "Cassette: %s"
|
||||
IDS_2149 "Cassette images (*.CAS;*.PCM)\0*.CAS;*.PCM\0All files (*.*)\0*.*\0"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
|
@@ -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 hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o \
|
||||
DEVOBJ := bugger.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 \
|
||||
|
@@ -27,8 +27,11 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/config.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/cassette.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/scsi_device.h>
|
||||
@@ -41,6 +44,33 @@
|
||||
#include <86box/win.h>
|
||||
|
||||
|
||||
void
|
||||
cassette_mount(char *fn, uint8_t wp)
|
||||
{
|
||||
pc_cas_set_fname(cassette, NULL);
|
||||
memset(cassette_fname, 0, sizeof(cassette_fname));
|
||||
cassette_ui_writeprot = wp;
|
||||
pc_cas_set_fname(cassette, fn);
|
||||
if (fn != NULL)
|
||||
memcpy(cassette_fname, fn, MIN(511, strlen(fn)));
|
||||
ui_sb_update_icon_state(SB_CASSETTE, (fn == NULL) ? 1 : 0);
|
||||
media_menu_update_cassette();
|
||||
ui_sb_update_tip(SB_CASSETTE);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cassette_eject(void)
|
||||
{
|
||||
pc_cas_set_fname(cassette, NULL);
|
||||
ui_sb_update_icon_state(SB_CASSETTE, 1);
|
||||
media_menu_update_cassette();
|
||||
ui_sb_update_tip(SB_CASSETTE);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
floppy_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
{
|
||||
@@ -53,6 +83,7 @@ floppy_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
floppy_eject(uint8_t id)
|
||||
{
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#include <86box/config.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/cassette.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdd_86f.h>
|
||||
#include <86box/hdc.h>
|
||||
@@ -22,18 +23,22 @@
|
||||
#include <86box/zip.h>
|
||||
#include <86box/win.h>
|
||||
|
||||
#define MACHINE_HAS_IDE (machines[machine].flags & MACHINE_IDE_QUAD)
|
||||
#define MACHINE_HAS_IDE (machines[machine].flags & MACHINE_IDE_QUAD)
|
||||
#define MACHINE_HAS_SCSI (machines[machine].flags & MACHINE_SCSI_DUAL)
|
||||
|
||||
#define FDD_FIRST 0
|
||||
#define CDROM_FIRST FDD_FIRST + FDD_NUM
|
||||
#define ZIP_FIRST CDROM_FIRST + CDROM_NUM
|
||||
#define MO_FIRST ZIP_FIRST + ZIP_NUM
|
||||
#define CASSETTE_FIRST 0
|
||||
#define FDD_FIRST 1
|
||||
#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[FDD_NUM + CDROM_NUM + ZIP_NUM + MO_NUM];
|
||||
|
||||
static char index_map[255];
|
||||
|
||||
|
||||
static void
|
||||
media_menu_set_ids(HMENU hMenu, int id)
|
||||
{
|
||||
@@ -51,6 +56,7 @@ media_menu_set_ids(HMENU hMenu, int id)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Loads the submenu from resource by name */
|
||||
static HMENU
|
||||
media_menu_load_resource(wchar_t *lpName)
|
||||
@@ -67,6 +73,28 @@ media_menu_load_resource(wchar_t *lpName)
|
||||
return actual;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
media_menu_set_name_cassette(void)
|
||||
{
|
||||
wchar_t name[512], fn[512];
|
||||
MENUITEMINFO mii = { 0 };
|
||||
|
||||
if (strlen(cassette_fname) == 0)
|
||||
_swprintf(name, plat_get_string(IDS_2148), plat_get_string(IDS_2057));
|
||||
else {
|
||||
mbstoc16s(fn, cassette_fname, sizeof_w(fn));
|
||||
_swprintf(name, plat_get_string(IDS_2148), fn);
|
||||
}
|
||||
|
||||
mii.cbSize = sizeof(mii);
|
||||
mii.fMask = MIIM_STRING;
|
||||
mii.dwTypeData = name;
|
||||
|
||||
SetMenuItemInfo(media_menu, (UINT_PTR)menus[CASSETTE_FIRST], FALSE, &mii);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
media_menu_set_name_floppy(int drive)
|
||||
{
|
||||
@@ -91,6 +119,7 @@ media_menu_set_name_floppy(int drive)
|
||||
SetMenuItemInfo(media_menu, (UINT_PTR)menus[FDD_FIRST + drive], FALSE, &mii);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
media_menu_set_name_cdrom(int drive)
|
||||
{
|
||||
@@ -121,6 +150,7 @@ media_menu_set_name_cdrom(int drive)
|
||||
SetMenuItemInfo(media_menu, (UINT_PTR)menus[CDROM_FIRST + drive], FALSE, &mii);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
media_menu_set_name_zip(int drive)
|
||||
{
|
||||
@@ -150,6 +180,7 @@ media_menu_set_name_zip(int drive)
|
||||
SetMenuItemInfo(media_menu, (UINT_PTR)menus[ZIP_FIRST + drive], FALSE, &mii);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
media_menu_set_name_mo(int drive)
|
||||
{
|
||||
@@ -177,6 +208,26 @@ media_menu_set_name_mo(int drive)
|
||||
SetMenuItemInfo(media_menu, (UINT_PTR)menus[MO_FIRST + drive], FALSE, &mii);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
media_menu_update_cassette(void)
|
||||
{
|
||||
int i = CASSETTE_FIRST;
|
||||
|
||||
if (strlen(cassette_fname) == 0) {
|
||||
EnableMenuItem(menus[i], IDM_CASSETTE_EJECT, MF_BYCOMMAND | MF_GRAYED);
|
||||
EnableMenuItem(menus[i], IDM_CASSETTE_REWIND, MF_BYCOMMAND | MF_GRAYED);
|
||||
EnableMenuItem(menus[i], IDM_CASSETTE_FAST_FORWARD, MF_BYCOMMAND | MF_GRAYED);
|
||||
} else {
|
||||
EnableMenuItem(menus[i], IDM_CASSETTE_EJECT, MF_BYCOMMAND | MF_ENABLED);
|
||||
EnableMenuItem(menus[i], IDM_CASSETTE_REWIND, MF_BYCOMMAND | MF_ENABLED);
|
||||
EnableMenuItem(menus[i], IDM_CASSETTE_FAST_FORWARD, MF_BYCOMMAND | MF_ENABLED);
|
||||
}
|
||||
|
||||
media_menu_set_name_cassette();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
media_menu_update_floppy(int id)
|
||||
{
|
||||
@@ -193,6 +244,7 @@ media_menu_update_floppy(int id)
|
||||
media_menu_set_name_floppy(id);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
media_menu_update_cdrom(int id)
|
||||
{
|
||||
@@ -220,6 +272,7 @@ media_menu_update_cdrom(int id)
|
||||
media_menu_set_name_cdrom(id);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
media_menu_update_zip(int id)
|
||||
{
|
||||
@@ -238,6 +291,7 @@ media_menu_update_zip(int id)
|
||||
media_menu_set_name_zip(id);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
media_menu_update_mo(int id)
|
||||
{
|
||||
@@ -256,6 +310,7 @@ media_menu_update_mo(int id)
|
||||
media_menu_set_name_mo(id);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
media_menu_load_submenus()
|
||||
{
|
||||
@@ -263,6 +318,9 @@ media_menu_load_submenus()
|
||||
|
||||
int curr = 0;
|
||||
|
||||
menus[curr] = media_menu_load_resource(CASSETTE_SUBMENU_NAME);
|
||||
media_menu_set_ids(menus[curr++], 0);
|
||||
|
||||
for(int i = 0; i < FDD_NUM; i++) {
|
||||
menus[curr] = media_menu_load_resource(FLOPPY_SUBMENU_NAME);
|
||||
media_menu_set_ids(menus[curr++], i);
|
||||
@@ -284,12 +342,14 @@ media_menu_load_submenus()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
is_valid_fdd(int i)
|
||||
{
|
||||
return fdd_get_type(i) != 0;
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
is_valid_cdrom(int i)
|
||||
{
|
||||
@@ -302,6 +362,7 @@ is_valid_cdrom(int i)
|
||||
return cdrom[i].bus_type != 0;
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
is_valid_zip(int i)
|
||||
{
|
||||
@@ -314,6 +375,7 @@ is_valid_zip(int i)
|
||||
return zip_drives[i].bus_type != 0;
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
is_valid_mo(int i)
|
||||
{
|
||||
@@ -326,6 +388,7 @@ is_valid_mo(int i)
|
||||
return mo_drives[i].bus_type != 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
media_menu_reset()
|
||||
{
|
||||
@@ -338,6 +401,12 @@ media_menu_reset()
|
||||
/* Add new ones. */
|
||||
int curr = 0;
|
||||
|
||||
if(cassette_enable) {
|
||||
AppendMenu(media_menu, MF_POPUP | MF_STRING, (UINT_PTR)menus[curr], L"Test");
|
||||
media_menu_update_cassette();
|
||||
}
|
||||
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");
|
||||
@@ -371,6 +440,7 @@ media_menu_reset()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Initializes the Media menu in the main menu bar. */
|
||||
static void
|
||||
media_menu_main_init()
|
||||
@@ -394,6 +464,7 @@ media_menu_main_init()
|
||||
free(lpMenuName);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
media_menu_init()
|
||||
{
|
||||
@@ -411,6 +482,7 @@ media_menu_init()
|
||||
media_menu_reset();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
@@ -419,6 +491,40 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
id = LOWORD(wParam) & 0x00ff;
|
||||
|
||||
switch (LOWORD(wParam) & 0xff00) {
|
||||
case IDM_CASSETTE_IMAGE_NEW:
|
||||
ret = file_dlg_st(hwnd, IDS_2149, "", NULL, 1);
|
||||
if (! ret) {
|
||||
if (strlen(openfilestring) == 0)
|
||||
cassette_mount(NULL, wp);
|
||||
else
|
||||
cassette_mount(openfilestring, wp);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDM_CASSETTE_REWIND:
|
||||
pc_cas_rewind(cassette);
|
||||
break;
|
||||
case IDM_CASSETTE_FAST_FORWARD:
|
||||
pc_cas_append(cassette);
|
||||
break;
|
||||
|
||||
case IDM_CASSETTE_IMAGE_EXISTING_WP:
|
||||
wp = 1;
|
||||
/* FALLTHROUGH */
|
||||
case IDM_CASSETTE_IMAGE_EXISTING:
|
||||
ret = file_dlg_st(hwnd, IDS_2149, cassette_fname, NULL, 0);
|
||||
if (! ret) {
|
||||
if (strlen(openfilestring) == 0)
|
||||
cassette_mount(NULL, wp);
|
||||
else
|
||||
cassette_mount(openfilestring, wp);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDM_CASSETTE_EJECT:
|
||||
cassette_eject();
|
||||
break;
|
||||
|
||||
case IDM_FLOPPY_IMAGE_NEW:
|
||||
NewFloppyDialogCreate(hwnd, id, 0);
|
||||
break;
|
||||
@@ -428,9 +534,8 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
/* FALLTHROUGH */
|
||||
case IDM_FLOPPY_IMAGE_EXISTING:
|
||||
ret = file_dlg_st(hwnd, IDS_2109, floppyfns[id], NULL, 0);
|
||||
if (! ret) {
|
||||
if (! ret)
|
||||
floppy_mount(id, openfilestring, wp);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDM_FLOPPY_EJECT:
|
||||
@@ -518,24 +623,35 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
HMENU
|
||||
media_menu_get_cassette(void)
|
||||
{
|
||||
return menus[CASSETTE_FIRST];
|
||||
}
|
||||
|
||||
|
||||
HMENU
|
||||
media_menu_get_floppy(int id)
|
||||
{
|
||||
return menus[FDD_FIRST + id];
|
||||
}
|
||||
|
||||
|
||||
HMENU
|
||||
media_menu_get_cdrom(int id)
|
||||
{
|
||||
return menus[CDROM_FIRST + id];
|
||||
}
|
||||
|
||||
|
||||
HMENU
|
||||
media_menu_get_zip(int id)
|
||||
{
|
||||
return menus[ZIP_FIRST + id];
|
||||
}
|
||||
|
||||
|
||||
HMENU
|
||||
media_menu_get_mo(int id)
|
||||
{
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include <86box/rom.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/cassette.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/gameport.h>
|
||||
@@ -103,7 +104,7 @@ static int temp_lpt_devices[3];
|
||||
static int temp_serial[4], temp_lpt[3];
|
||||
|
||||
/* Other peripherals category */
|
||||
static int temp_fdc_card, temp_hdc, temp_ide_ter, temp_ide_qua;
|
||||
static int temp_fdc_card, temp_hdc, temp_ide_ter, temp_ide_qua, temp_cassette;
|
||||
static int temp_scsi_card[SCSI_BUS_MAX];
|
||||
static int temp_bugger;
|
||||
static int temp_postcard;
|
||||
@@ -369,23 +370,17 @@ win_settings_init(void)
|
||||
for (i = 0; i < 4; i++)
|
||||
temp_serial[i] = serial_enabled[i];
|
||||
|
||||
/* Other peripherals category */
|
||||
/* Storage devices category */
|
||||
for (i = 0; i < SCSI_BUS_MAX; i++)
|
||||
temp_scsi_card[i] = scsi_card_current[i];
|
||||
temp_fdc_card = fdc_type;
|
||||
temp_hdc = hdc_current;
|
||||
temp_ide_ter = ide_ter_enabled;
|
||||
temp_ide_qua = ide_qua_enabled;
|
||||
temp_bugger = bugger_enabled;
|
||||
temp_postcard = postcard_enabled;
|
||||
temp_isartc = isartc_type;
|
||||
|
||||
/* ISA memory boards. */
|
||||
for (i = 0; i < ISAMEM_MAX; i++)
|
||||
temp_isamem[i] = isamem_type[i];
|
||||
temp_cassette = cassette_enable;
|
||||
|
||||
mfm_tracking = xta_tracking = esdi_tracking = ide_tracking = 0;
|
||||
for (i = 0; i < 2; i++)
|
||||
for (i = 0; i < 8; i++)
|
||||
scsi_tracking[i] = 0;
|
||||
|
||||
/* Hard disks category */
|
||||
@@ -433,6 +428,15 @@ win_settings_init(void)
|
||||
scsi_tracking[mo_drives[i].scsi_device_id >> 3] |= (1 << ((mo_drives[i].scsi_device_id & 0x07) << 3));
|
||||
}
|
||||
|
||||
/* Other peripherals category */
|
||||
temp_bugger = bugger_enabled;
|
||||
temp_postcard = postcard_enabled;
|
||||
temp_isartc = isartc_type;
|
||||
|
||||
/* ISA memory boards. */
|
||||
for (i = 0; i < ISAMEM_MAX; i++)
|
||||
temp_isamem[i] = isamem_type[i];
|
||||
|
||||
temp_deviceconfig = 0;
|
||||
}
|
||||
|
||||
@@ -486,20 +490,14 @@ win_settings_changed(void)
|
||||
for (j = 0; j < 4; j++)
|
||||
i = i || (temp_serial[j] != serial_enabled[j]);
|
||||
|
||||
/* Peripherals category */
|
||||
/* Storage devices category */
|
||||
for (j = 0; j < SCSI_BUS_MAX; j++)
|
||||
i = i || (temp_scsi_card[j] != scsi_card_current[j]);
|
||||
i = i || (fdc_type != temp_fdc_card);
|
||||
i = i || (hdc_current != temp_hdc);
|
||||
i = i || (temp_ide_ter != ide_ter_enabled);
|
||||
i = i || (temp_ide_qua != ide_qua_enabled);
|
||||
i = i || (temp_bugger != bugger_enabled);
|
||||
i = i || (temp_postcard != postcard_enabled);
|
||||
i = i || (temp_isartc != isartc_type);
|
||||
|
||||
/* ISA memory boards. */
|
||||
for (j = 0; j < ISAMEM_MAX; j++)
|
||||
i = i || (temp_isamem[j] != isamem_type[j]);
|
||||
i = i || (temp_cassette != cassette_enable);
|
||||
|
||||
/* Hard disks category */
|
||||
i = i || memcmp(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t));
|
||||
@@ -516,6 +514,15 @@ win_settings_changed(void)
|
||||
i = i || memcmp(zip_drives, temp_zip_drives, ZIP_NUM * sizeof(zip_drive_t));
|
||||
i = i || memcmp(mo_drives, temp_mo_drives, MO_NUM * sizeof(mo_drive_t));
|
||||
|
||||
/* Other peripherals category */
|
||||
i = i || (temp_bugger != bugger_enabled);
|
||||
i = i || (temp_postcard != postcard_enabled);
|
||||
i = i || (temp_isartc != isartc_type);
|
||||
|
||||
/* ISA memory boards. */
|
||||
for (j = 0; j < ISAMEM_MAX; j++)
|
||||
i = i || (temp_isamem[j] != isamem_type[j]);
|
||||
|
||||
i = i || !!temp_deviceconfig;
|
||||
|
||||
return i;
|
||||
@@ -574,20 +581,14 @@ win_settings_save(void)
|
||||
for (i = 0; i < 4; i++)
|
||||
serial_enabled[i] = temp_serial[i];
|
||||
|
||||
/* Peripherals category */
|
||||
/* Storage devices category */
|
||||
for (i = 0; i < SCSI_BUS_MAX; i++)
|
||||
scsi_card_current[i] = temp_scsi_card[i];
|
||||
hdc_current = temp_hdc;
|
||||
fdc_type = temp_fdc_card;
|
||||
ide_ter_enabled = temp_ide_ter;
|
||||
ide_qua_enabled = temp_ide_qua;
|
||||
bugger_enabled = temp_bugger;
|
||||
postcard_enabled = temp_postcard;
|
||||
isartc_type = temp_isartc;
|
||||
|
||||
/* ISA memory boards. */
|
||||
for (i = 0; i < ISAMEM_MAX; i++)
|
||||
isamem_type[i] = temp_isamem[i];
|
||||
cassette_enable = temp_cassette;
|
||||
|
||||
/* Hard disks category */
|
||||
memcpy(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t));
|
||||
@@ -624,6 +625,15 @@ win_settings_save(void)
|
||||
mo_drives[i].priv = NULL;
|
||||
}
|
||||
|
||||
/* Other peripherals category */
|
||||
bugger_enabled = temp_bugger;
|
||||
postcard_enabled = temp_postcard;
|
||||
isartc_type = temp_isartc;
|
||||
|
||||
/* ISA memory boards. */
|
||||
for (i = 0; i < ISAMEM_MAX; i++)
|
||||
isamem_type[i] = temp_isamem[i];
|
||||
|
||||
/* Mark configuration as changed. */
|
||||
config_changed = 2;
|
||||
|
||||
@@ -1656,6 +1666,7 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
settings_enable_window(hdlg, IDC_BUTTON_IDE_QUA, is_at && temp_ide_qua);
|
||||
settings_set_check(hdlg, IDC_CHECK_IDE_TER, temp_ide_ter);
|
||||
settings_set_check(hdlg, IDC_CHECK_IDE_QUA, temp_ide_qua);
|
||||
settings_set_check(hdlg, IDC_CHECK_CASSETTE, temp_cassette);
|
||||
|
||||
free(stransi);
|
||||
free(lptsTemp);
|
||||
@@ -1723,6 +1734,7 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
temp_scsi_card[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI_1 + c)];
|
||||
temp_ide_ter = settings_get_check(hdlg, IDC_CHECK_IDE_TER);
|
||||
temp_ide_qua = settings_get_check(hdlg, IDC_CHECK_IDE_QUA);
|
||||
temp_cassette = settings_get_check(hdlg, IDC_CHECK_CASSETTE);
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include <86box/device.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/cassette.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/fdd.h>
|
||||
@@ -177,6 +178,28 @@ ui_sb_update_icon_state(int tag, int state)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
StatusBarCreateCassetteTip(int part)
|
||||
{
|
||||
WCHAR tempTip[512];
|
||||
WCHAR fn[512];
|
||||
|
||||
if (strlen(cassette_fname) == 0)
|
||||
_swprintf(tempTip, plat_get_string(IDS_2148), plat_get_string(IDS_2057));
|
||||
else {
|
||||
mbstoc16s(fn, cassette_fname, sizeof_w(fn));
|
||||
_swprintf(tempTip, plat_get_string(IDS_2148), 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)
|
||||
{
|
||||
@@ -364,6 +387,10 @@ ui_sb_update_tip(int meaning)
|
||||
|
||||
if (part != 0xff) {
|
||||
switch(meaning & 0xf0) {
|
||||
case SB_CASSETTE:
|
||||
StatusBarCreateCassetteTip(part);
|
||||
break;
|
||||
|
||||
case SB_FLOPPY:
|
||||
StatusBarCreateFloppyTip(part);
|
||||
break;
|
||||
@@ -492,6 +519,8 @@ ui_sb_update_panes(void)
|
||||
memset(sb_map, 0xff, sizeof(sb_map));
|
||||
|
||||
sb_parts = 0;
|
||||
if (cassette_enable)
|
||||
sb_parts++;
|
||||
for (i=0; i<FDD_NUM; i++) {
|
||||
if (fdd_get_type(i) != 0)
|
||||
sb_parts++;
|
||||
@@ -565,6 +594,13 @@ ui_sb_update_panes(void)
|
||||
memset(sbTips, 0, sb_parts * sizeof(WCHAR *));
|
||||
|
||||
sb_parts = 0;
|
||||
if (cassette_enable) {
|
||||
edge += icon_width;
|
||||
iStatusWidths[sb_parts] = edge;
|
||||
sb_part_meanings[sb_parts] = SB_CASSETTE;
|
||||
sb_map[SB_CASSETTE] = sb_parts;
|
||||
sb_parts++;
|
||||
}
|
||||
for (i=0; i<FDD_NUM; i++) {
|
||||
if (fdd_get_type(i) != 0) {
|
||||
edge += icon_width;
|
||||
@@ -685,6 +721,12 @@ ui_sb_update_panes(void)
|
||||
|
||||
for (i=0; i<sb_parts; i++) {
|
||||
switch (sb_part_meanings[i] & 0xf0) {
|
||||
case SB_CASSETTE: /* Cassette */
|
||||
sb_part_icons[i] = (strlen(cassette_fname) == 0) ? 128 : 0;
|
||||
sb_part_icons[i] |= 64;
|
||||
StatusBarCreateCassetteTip(i);
|
||||
break;
|
||||
|
||||
case SB_FLOPPY: /* Floppy */
|
||||
sb_part_icons[i] = (strlen(floppyfns[sb_part_meanings[i] & 0xf]) == 0) ? 128 : 0;
|
||||
sb_part_icons[i] |= fdd_type_to_icon(fdd_get_type(sb_part_meanings[i] & 0xf));
|
||||
@@ -758,6 +800,9 @@ StatusBarPopupMenu(HWND hwnd, POINT pt, int id)
|
||||
ClientToScreen(hwnd, (LPPOINT) &pt);
|
||||
|
||||
switch(sb_part_meanings[id] & 0xF0) {
|
||||
case SB_CASSETTE:
|
||||
menu = media_menu_get_cassette();
|
||||
break;
|
||||
case SB_FLOPPY:
|
||||
menu = media_menu_get_floppy(sb_part_meanings[id] & 0x0F);
|
||||
break;
|
||||
|
Reference in New Issue
Block a user