Another big change, this time to the NVR. It has been re-done, integrated with the RTC code, and is now ready to be used by other, non-AT-compatible systems, including an ISA card for PC/XT.

This commit is contained in:
waltje
2017-10-03 16:26:55 -04:00
parent a1b3c33054
commit 633adc6b02
31 changed files with 1027 additions and 911 deletions

View File

@@ -8,7 +8,7 @@
#
# Modified Makefile for Win32 (MinGW32) environment.
#
# Version: @(#)Makefile.mingw 1.0.51 2017/10/01
# Version: @(#)Makefile.mingw 1.0.52 2017/10/02
#
# Authors: Miran Grca, <mgrca8@gmail.com>
# Fred N. van Kempen, <decwiz@yahoo.com>
@@ -224,8 +224,8 @@ endif
MAINOBJ := pc.o config.o random.o timer.o io.o dma.o nmi.o pic.o \
pit.o ppi.o pci.o mca.o mcr.o mem.o memregs.o rom.o \
device.o rtc.o nvr.o nvr_ps2.o intel.o intel_flash.o \
intel_sio.o
device.o nvr.o nvr_at.o nvr_ps2.o \
intel.o intel_flash.o intel_sio.o
CPUOBJ := cpu.o 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o \
codegen.o \

View File

@@ -9,7 +9,7 @@
* Implementation of the CD-ROM drive with SCSI(-like)
* commands, for both ATAPI and SCSI usage.
*
* Version: @(#)cdrom.c 1.0.8 2017/10/01
* Version: @(#)cdrom.c 1.0.9 2017/10/02
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016,2017 Miran Grca.
@@ -990,16 +990,16 @@ void cdrom_mode_sense_load(uint8_t id)
switch(id)
{
case 0:
f = _wfopen(nvr_concat(L"cdrom_1_mode_sense.bin"), L"rb");
f = _wfopen(nvr_path(L"cdrom_1_mode_sense.bin"), L"rb");
break;
case 1:
f = _wfopen(nvr_concat(L"cdrom_2_mode_sense.bin"), L"rb");
f = _wfopen(nvr_path(L"cdrom_2_mode_sense.bin"), L"rb");
break;
case 2:
f = _wfopen(nvr_concat(L"cdrom_3_mode_sense.bin"), L"rb");
f = _wfopen(nvr_path(L"cdrom_3_mode_sense.bin"), L"rb");
break;
case 3:
f = _wfopen(nvr_concat(L"cdrom_4_mode_sense.bin"), L"rb");
f = _wfopen(nvr_path(L"cdrom_4_mode_sense.bin"), L"rb");
break;
default:
return;
@@ -1018,16 +1018,16 @@ void cdrom_mode_sense_save(uint8_t id)
switch(id)
{
case 0:
f = _wfopen(nvr_concat(L"cdrom_1_mode_sense.bin"), L"wb");
f = _wfopen(nvr_path(L"cdrom_1_mode_sense.bin"), L"wb");
break;
case 1:
f = _wfopen(nvr_concat(L"cdrom_2_mode_sense.bin"), L"wb");
f = _wfopen(nvr_path(L"cdrom_2_mode_sense.bin"), L"wb");
break;
case 2:
f = _wfopen(nvr_concat(L"cdrom_3_mode_sense.bin"), L"wb");
f = _wfopen(nvr_path(L"cdrom_3_mode_sense.bin"), L"wb");
break;
case 3:
f = _wfopen(nvr_concat(L"cdrom_4_mode_sense.bin"), L"wb");
f = _wfopen(nvr_path(L"cdrom_4_mode_sense.bin"), L"wb");
break;
default:
return;

View File

@@ -8,7 +8,7 @@
*
* Configuration file handler.
*
* Version: @(#)config.c 1.0.10 2017/10/01
* Version: @(#)config.c 1.0.12 2017/10/02
*
* Authors: Sarah Walker,
* Miran Grca, <mgrca8@gmail.com>
@@ -30,10 +30,10 @@
#include <inttypes.h>
#include "ibm.h"
#include "cpu/cpu.h"
#include "nvr.h"
#include "config.h"
#include "device.h"
#include "lpt.h"
#include "nvr.h"
#include "cdrom/cdrom.h"
#include "disk/hdd.h"
#include "disk/hdc.h"
@@ -493,7 +493,6 @@ static void
load_machine(void)
{
char *cat = "Machine";
wchar_t *wp;
char *p;
p = config_get_string(cat, "machine", NULL);
@@ -537,42 +536,15 @@ load_machine(void)
mem_size = 1048576;
}
memset(nvr_path, 0x00, sizeof(nvr_path));
wp = config_get_wstring(cat, "nvr_path", L"");
if (wp != NULL) {
if (wcslen(wp) && (wcslen(wp) <= 992))
{
#if 1
/*
* 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, exe_path, wcslen(exe_path))) {
/*
* Yep, its absolute and prefixed
* with the EXE path. Just strip
* that off for now...
*/
wcscpy(nvr_path, &wp[wcslen(exe_path)]);
} else
#endif
wcscpy(nvr_path, wp);
}
else
{
wcscpy(nvr_path, L"nvr\\");
}
}
else wcscpy(nvr_path, L"nvr\\");
cpu_use_dynarec = !!config_get_int(cat, "cpu_use_dynarec", 0);
enable_external_fpu = !!config_get_int(cat, "cpu_enable_fpu", 0);
enable_sync = !!config_get_int(cat, "enable_sync", 1);
/* Remove this after a while.. */
if (config_get_string(cat, "nvr_path", NULL) != NULL)
config_delete_var(cat, "nvr_path");
}
@@ -1433,7 +1405,7 @@ config_load(wchar_t *fn)
if (fn == NULL)
fn = config_file_default;
pclog("Loading config file '%S'..\n", fn);
pclog("Loading config file '%ws'..\n", fn);
i = config_read(fn);
if (i == 0)
@@ -1667,8 +1639,6 @@ save_machine(void)
config_set_int(cat, "mem_size", mem_size);
}
config_set_wstring(cat, "nvr_path", nvr_path);
config_set_int(cat, "cpu_use_dynarec", cpu_use_dynarec);
if (enable_external_fpu == 0)

View File

@@ -8,7 +8,7 @@
*
* x86 CPU segment emulation.
*
* Version: @(#)x86seg.c 1.0.1 2017/09/24
* Version: @(#)x86seg.c 1.0.2 2017/10/02
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -29,6 +29,7 @@
#include "386_common.h"
#include "cpu.h"
/*Controls whether the accessed bit in a descriptor is set when CS is loaded.*/
#define CS_ACCESSED
@@ -63,7 +64,7 @@ void x86abort(const char *format, ...)
vprintf(format, ap);
va_end(ap);
fflush(stdout);
savenvr();
nvr_save();
dumpregs(1);
fflush(stdout);
exit(-1);

View File

@@ -9,7 +9,7 @@
* Generic floppy disk interface that communicates with the
* other handlers.
*
* Version: @(#)floppy.c 1.0.4 2017/09/24
* Version: @(#)floppy.c 1.0.5 2017/10/02
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -153,7 +153,7 @@ void floppy_load(int drive, wchar_t *fn)
}
c++;
}
pclog_w(L"Couldn't load %s %s\n",fn,p);
pclog("Couldn't load %ws %s\n",fn,p);
drive_empty[drive] = 1;
fdd_set_head(real_drive(drive), 0);
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));

View File

@@ -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.c 1.0.4 2017/09/24
* Version: @(#)floppy_86f.c 1.0.5 2017/10/02
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016,2017 Miran Grca.
@@ -3471,7 +3471,7 @@ void d86f_load(int drive, wchar_t *fn)
if (d86f[drive].is_compressed)
{
memcpy(temp_file_name, drive ? nvr_concat(L"TEMP$$$1.$$$") : nvr_concat(L"TEMP$$$0.$$$"), 256);
memcpy(temp_file_name, drive ? nvr_path(L"TEMP$$$1.$$$") : nvr_path(L"TEMP$$$0.$$$"), 256);
memcpy(d86f[drive].original_file_name, fn, (wcslen(fn) << 1) + 2);
fclose(d86f[drive].f);
@@ -3666,7 +3666,7 @@ void d86f_close(int drive)
{
wchar_t temp_file_name[2048];
memcpy(temp_file_name, drive ? nvr_concat(L"TEMP$$$1.$$$") : nvr_concat(L"TEMP$$$0.$$$"), 26);
memcpy(temp_file_name, drive ? nvr_path(L"TEMP$$$1.$$$") : nvr_path(L"TEMP$$$0.$$$"), 26);
if (d86f[drive].f)
{

View File

@@ -10,7 +10,7 @@
*
* !!!NOTE!!! The goal is to GET RID of this file. Do NOT add stuff !!
*
* Version: @(#)ibm.h 1.0.7 2017/10/01
* Version: @(#)ibm.h 1.0.7 2017/10/02
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -480,7 +480,6 @@ extern int gated,speakval,speakon;
extern wchar_t exe_path[1024];
extern wchar_t cfg_path[1024];
extern wchar_t nvr_path[1024];
/*Keyboard*/
@@ -586,8 +585,8 @@ extern int scale;
/* Function prototypes. */
extern void pclog(const char *format, ...);
extern void pclog_w(const wchar_t *format, ...);
extern void fatal(const char *format, ...);
extern wchar_t *pc_concat(wchar_t *str);
extern void pc_init_modules(void);
extern void pc_init(int argc, wchar_t *argv[]);
extern void pc_close(void);

View File

@@ -8,7 +8,7 @@
*
* Implementation of the Intel 2 Mbit 8-bit flash devices.
*
* Version: @(#)intel_flash.c 1.0.3 2017/09/24
* Version: @(#)intel_flash.c 1.0.4 2017/10/02
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -193,7 +193,7 @@ void *intel_flash_init(uint8_t type)
wcscpy(flash_path, flash_name);
pclog_w(L"Flash path: %s\n", flash_name);
pclog("Flash path: %ws\n", flash_name);
flash->flash_id = (type & FLASH_IS_BXB) ? 0x95 : 0x94;
flash->invert_high_pin = (type & FLASH_INVERT);
@@ -255,7 +255,7 @@ void *intel_flash_init(uint8_t type)
flash->command = CMD_READ_ARRAY;
flash->status = 0;
f = nvrfopen(flash_path, L"rb");
f = nvr_fopen(flash_path, L"rb");
if (f)
{
fread(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f);
@@ -298,7 +298,7 @@ void intel_flash_close(void *p)
FILE *f;
flash_t *flash = (flash_t *)p;
f = nvrfopen(flash_path, L"wb");
f = nvr_fopen(flash_path, L"wb");
fwrite(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f);
fwrite(&(flash->array[flash->block_start[BLOCK_DATA1]]), flash->block_len[BLOCK_DATA1], 1, f);
fwrite(&(flash->array[flash->block_start[BLOCK_DATA2]]), flash->block_len[BLOCK_DATA2], 1, f);

View File

@@ -144,7 +144,10 @@ void machine_amstrad_init(void)
mem_add_bios();
amstrad_init();
keyboard_amstrad_init();
nvr_init();
/* FIXME: make sure this is correct? */
nvr_at_init(1);
nmi_init();
fdc_set_dskchg_activelow();
if (joystick_type != 7)

View File

@@ -30,7 +30,7 @@ void machine_at_init(void)
pit_set_out_func(&pit, 1, pit_refresh_timer_at);
dma16_init();
keyboard_at_init();
nvr_init();
nvr_at_init(8);
pic2_init();
if (joystick_type != 7)
device_add(&gameport_device);

View File

@@ -42,7 +42,10 @@ void machine_olim24_init(void)
machine_common_init();
mem_add_bios();
keyboard_olim24_init();
nvr_init();
/* FIXME: make sure this is correct?? */
nvr_at_init(8);
olivetti_m24_init();
nmi_init();
if (joystick_type != 7) device_add(&gameport_device);

View File

@@ -348,7 +348,7 @@ static void machine_ps1_common_init(void)
ide_init();
}
keyboard_at_init();
nvr_init();
nvr_at_init(8);
pic2_init();
if (romset != ROM_IBMPS1_2133)
{

View File

@@ -163,7 +163,7 @@ void machine_ps2_m30_286_init(void)
pit_set_out_func(&pit, 1, pit_refresh_timer_at);
dma16_init();
keyboard_at_init();
nvr_init();
nvr_at_init(8);
pic2_init();
ps2board_init();
fdc_set_dskchg_activelow();

View File

@@ -813,7 +813,7 @@ static void machine_ps2_common_init(void)
keyboard_at_init();
keyboard_at_init_ps2();
mouse_ps2_init();
nvr_init();
nvr_at_init(8);
pic2_init();
pit_ps2_init();

1026
src/nvr.c

File diff suppressed because it is too large Load Diff

View File

@@ -6,32 +6,107 @@
*
* This file is part of the 86Box distribution.
*
* CMOS NVRAM emulation.
* Definitions for a defacto-standard RTC/NVRAM device.
*
* Version: @(#)nvr.h 1.0.2 2017/06/19
* Version: @(#)nvr.h 1.0.3 2017/10/02
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Mahod,
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016-2017 Miran Grca.
* Copyright 2016-2017 Mahod.
* Copyright 2017 Fred N. van Kempen.
*/
#ifndef EMU_NVR_H
# define EMU_NVR_H
extern int enable_sync;
extern int nvr_dosave;
/* Conversion from BCD to Binary and vice versa. */
#define RTC_BCD(x) (((x) % 10) | (((x) / 10) << 4))
#define RTC_DCB(x) ((((x) & 0xf0) >> 4) * 10 + ((x) & 0x0f))
/* RTC registers and bit definitions. */
#define RTC_SECONDS 0
#define RTC_ALSECONDS 1
#define RTC_MINUTES 2
#define RTC_ALMINUTES 3
#define RTC_HOURS 4
# define RTC_AMPM 0x80 /* PM flag if 12h format in use */
#define RTC_ALHOURS 5
#define RTC_DOW 6
#define RTC_DOM 7
#define RTC_MONTH 8
#define RTC_YEAR 9
#define RTC_REGA 10
# define REGA_UIP 0x80
# define REGA_DV2 0x40
# define REGA_DV1 0x20
# define REGA_DV0 0x10
# define REGA_DV 0x70
# define REGA_RS3 0x08
# define REGA_RS2 0x04
# define REGA_RS1 0x02
# define REGA_RS0 0x01
# define REGA_RS 0x0f
#define RTC_REGB 11
# define REGB_SET 0x80
# define REGB_PIE 0x40
# define REGB_AIE 0x20
# define REGB_UIE 0x10
# define REGB_SQWE 0x08
# define REGB_DM 0x04
# define REGB_2412 0x02
# define REGB_DSE 0x01
#define RTC_REGC 12
# define REGC_IRQF 0x80
# define REGC_PF 0x40
# define REGC_AF 0x20
# define REGC_UF 0x10
#define RTC_REGD 13
# define REGD_VRT 0x80
#define RTC_CENTURY 0x32 /* century register */
#define RTC_REGS 14 /* number of registers */
extern wchar_t *nvr_concat(wchar_t *to_concat);
extern void nvr_init(void);
extern FILE *nvrfopen(wchar_t *fn, wchar_t *mode);
extern void time_get(char *nvrram);
/* Define a (defacto-standard) RTC/NVRAM chip. */
typedef struct _nvr_ {
uint8_t regs[RTC_REGS+114]; /* these are the registers */
int upd_stat,
upd_ecount,
onesec_time,
onesec_cnt,
rtctime,
oldmachine;
int mask,
irq,
addr;
void (*set)(struct _nvr_ *, uint16_t, uint8_t);
uint8_t (*get)(struct _nvr_ *, uint16_t);
wchar_t *fname;
} nvr_t;
extern int enable_sync;
extern int nvr_dosave;
extern void nvr_init(nvr_t *);
extern void nvr_load(void);
extern void nvr_save(void);
extern void nvr_recalc(void);
extern void loadnvr(void);
extern void savenvr(void);
extern wchar_t *nvr_path(wchar_t *str);
extern FILE *nvr_fopen(wchar_t *str, wchar_t *mode);
extern void nvr_at_init(int irq);
#endif /*EMU_NVR_H*/

108
src/nvr_at.c Normal file
View File

@@ -0,0 +1,108 @@
/*
* 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.
*
* IBM PC/AT RTC/NVRAM ("CMOS") emulation.
*
* The original PC/AT series had DS12885 series modules; later
* versions and clones used the 12886 and/or 1288(C)7 series,
* or the MC146818 series, all with an external battery. Many
* of those batteries would create corrosion issues later on
* in mainboard life...
*
* Version: @(#)nvr_at.c 1.0.5 2017/10/02
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2016,2017 Miran Grca.
* Copyright 2017 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include "ibm.h"
#include "cpu/cpu.h"
#include "io.h"
#include "device.h"
#include "machine/machine.h"
#include "nvr.h"
static void
nvr_write(uint16_t addr, uint8_t val, void *priv)
{
nvr_t *nvr = (nvr_t *)priv;
if (! (addr & 1)) {
nvr->addr = (val & nvr->mask);
#if 0
nvr->nmi_mask = (~val & 0x80);
#endif
return;
}
/* Write the chip's registers. */
(*nvr->set)(nvr, nvr->addr, val);
}
static uint8_t
nvr_read(uint16_t addr, void *priv)
{
nvr_t *nvr = (nvr_t *)priv;
uint8_t ret;
if (addr & 1) {
/* Read from the chip's registers. */
ret = (*nvr->get)(nvr, nvr->addr);
} else {
ret = nvr->addr;
}
return(ret);
}
void
nvr_at_close(void *priv)
{
nvr_t *nvr = (nvr_t *)priv;
if (nvr->fname != NULL)
free(nvr->fname);
free(nvr);
}
void
nvr_at_init(int irq)
{
nvr_t *nvr;
/* Allocate an NVR for this machine. */
nvr = (nvr_t *)malloc(sizeof(nvr_t));
if (nvr == NULL) return;
memset(nvr, 0x00, sizeof(nvr_t));
/* This is machine specific. */
nvr->mask = machines[machine].nvrmask;
nvr->irq = irq;
/* Set up any local handlers here. */
/* Initialize the actual NVR. */
nvr_init(nvr);
/* Set up the PC/AT handler for this device. */
io_sethandler(0x0070, 2,
nvr_read, NULL, NULL, nvr_write, NULL, NULL, nvr);
}

View File

@@ -65,7 +65,7 @@ static void *ps2_nvr_init()
switch (romset)
{
case ROM_IBMPS2_M80: f = nvrfopen(L"ibmps2_m80_sec.nvr", L"rb"); break;
case ROM_IBMPS2_M80: f = nvr_fopen(L"ibmps2_m80_sec.nvr", L"rb"); break;
}
if (f)
{
@@ -85,7 +85,7 @@ static void ps2_nvr_close(void *p)
switch (romset)
{
case ROM_IBMPS2_M80: f = nvrfopen(L"ibmps2_m80_sec.nvr", L"wb"); break;
case ROM_IBMPS2_M80: f = nvr_fopen(L"ibmps2_m80_sec.nvr", L"wb"); break;
}
if (f)
{

View File

@@ -70,6 +70,7 @@
#include "win/plat_midi.h"
#include "win/plat_mouse.h"
#include "win/plat_ui.h"
#include "win/win.h"
#include "scsi/scsi.h"
#include "serial.h"
#include "sound/sound.h"
@@ -87,10 +88,6 @@
#include "cpu/x86_ops.h"
wchar_t exe_path[1024];
wchar_t cfg_path[1024];
wchar_t nvr_path[1024];
int window_w, window_h, window_x, window_y, window_remember;
int dump_on_exit = 0;
int start_in_fullscreen = 0;
@@ -109,6 +106,8 @@ int pollmouse_delay = 2;
int mousecapture;
int suppress_overscan = 0;
int cpuspeed2;
wchar_t exe_path[1024];
wchar_t cfg_path[1024];
extern int mmuflush;
@@ -129,20 +128,6 @@ pclog(const char *format, ...)
}
/* Log something to the logfile or stdout. */
void
pclog_w(const wchar_t *format, ...)
{
#ifndef RELEASE_BUILD
va_list ap;
va_start(ap, format);
vwprintf(format, ap);
va_end(ap);
fflush(stdout);
#endif
}
/* Log a fatal error, and display a UI message before exiting. */
void
fatal(const char *format, ...)
@@ -157,7 +142,7 @@ fatal(const char *format, ...)
va_end(ap);
fflush(stdout);
savenvr();
nvr_save();
config_save();
@@ -177,6 +162,33 @@ fatal(const char *format, ...)
}
/*
* This function returns the absolute pathname to a file (str)
* that is to be found in the user (formerly 'nvr_path' area.
*/
wchar_t *
pc_concat(wchar_t *str)
{
static wchar_t temp[1024];
/* Get the full prefix in place. */
memset(temp, 0x00, sizeof(temp));
wcscpy(temp, cfg_path);
#ifndef __unix
/* Create the directory if needed. */
if (! DirectoryExists(temp))
CreateDirectory(temp, NULL);
#endif
/* Now append the actual filename. */
wcscat(temp, L"\\");
wcscat(temp, str);
return(temp);
}
static void
usage(void)
{
@@ -201,7 +213,7 @@ usage(void)
void
pc_init(int argc, wchar_t *argv[])
{
wchar_t *config_file = NULL;
wchar_t *cfg = NULL;
wchar_t *p;
#ifdef WALTJE
struct direct *dp;
@@ -213,7 +225,7 @@ pc_init(int argc, wchar_t *argv[])
get_executable_name(exe_path, sizeof(exe_path)-1);
p = get_filename_w(exe_path);
*p = L'\0';
pclog("exe_path=%S\n", exe_path);
pclog("exe_path=%ws\n", exe_path);
/*
* Get the current working directory.
@@ -233,7 +245,7 @@ usage:
!_wcsicmp(argv[c], L"-C")) {
if ((c+1) == argc) break;
config_file = argv[++c];
cfg = argv[++c];
} else if (!_wcsicmp(argv[c], L"--dump") ||
!_wcsicmp(argv[c], L"-D")) {
dump_on_exit = 1;
@@ -245,15 +257,15 @@ usage:
#ifdef WALTJE
dir = opendirw(exe_path);
if (dir != NULL) {
printf("Directory '%S':\n", exe_path);
printf("Directory '%ws':\n", exe_path);
for (;;) {
dp = readdir(dir);
if (dp == NULL) break;
printf(">> '%S'\n", dp->d_name);
printf(">> '%ws'\n", dp->d_name);
}
closedir(dir);
} else {
printf("Could not open '%S'..\n", exe_path);
printf("Could not open '%ws'..\n", exe_path);
}
#endif
@@ -276,9 +288,9 @@ usage:
(cfg_path[wcslen(cfg_path)-1] != L'/')) {
wcscat(cfg_path, L"\\");
}
pclog("cwd_path=%S\n", cfg_path);
pclog("cfg_path=%ws\n", cfg_path);
if (config_file != NULL) {
if (cfg != NULL) {
/*
* The user specified a configuration file.
*
@@ -287,14 +299,14 @@ usage:
* Otherwise, assume the pathname given is
* relative to whatever the cfg_path is.
*/
if ((config_file[1] == L':') || /* drive letter present */
(config_file[0] == L'\\')) /* backslash, root dir */
if ((cfg[1] == L':') || /* drive letter present */
(cfg[0] == L'\\')) /* backslash, root dir */
append_filename_w(config_file_default,
NULL, config_file, 511);
NULL, cfg, 511);
else
append_filename_w(config_file_default,
cfg_path, config_file, 511);
config_file = NULL;
cfg_path, cfg, 511);
cfg = NULL;
} else {
append_filename_w(config_file_default, cfg_path, CONFIG_FILE_W, 511);
}
@@ -307,7 +319,7 @@ usage:
*/
hdd_init();
config_load(config_file);
config_load(cfg);
}
@@ -407,7 +419,7 @@ pc_init_modules(void)
floppy_load(3, floppyfns[3]);
#endif
loadnvr();
nvr_load();
sound_init();
@@ -490,7 +502,7 @@ resetpchard_close(void)
{
suppress_overscan = 0;
savenvr();
nvr_save();
device_close_all();
mouse_emu_close();
@@ -554,7 +566,7 @@ resetpchard_init(void)
mouse_emu_init();
loadnvr();
nvr_load();
shadowbios = 0;

249
src/rtc.c
View File

@@ -1,249 +0,0 @@
/* Emulation of:
Dallas Semiconductor DS12C887 Real Time Clock
http://datasheets.maximintegrated.com/en/ds/DS12885-DS12C887A.pdf
http://dev-docs.atariforge.org/files/MC146818A_RTC_1984.pdf
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <time.h>
#include "nvr.h"
#include "rtc.h"
int enable_sync;
struct
{
int sec;
int min;
int hour;
int mday;
int mon;
int year;
} internal_clock;
/* Table for days in each month */
static int rtc_days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/* Called to determine whether the year is leap or not */
static int rtc_is_leap(int org_year)
{
if (org_year % 400 == 0) return 1;
if (org_year % 100 == 0) return 0;
if (org_year % 4 == 0) return 1;
return 0;
}
/* Called to determine the days in the current month */
static int rtc_get_days(int org_month, int org_year)
{
if (org_month != 2)
return rtc_days_in_month[org_month - 1];
else
return rtc_is_leap(org_year) ? 29 : 28;
}
/* Called when the internal clock gets updated */
static void rtc_recalc(void)
{
if (internal_clock.sec == 60)
{
internal_clock.sec = 0;
internal_clock.min++;
}
if (internal_clock.min == 60)
{
internal_clock.min = 0;
internal_clock.hour++;
}
if (internal_clock.hour == 24)
{
internal_clock.hour = 0;
internal_clock.mday++;
}
if (internal_clock.mday == (rtc_get_days(internal_clock.mon, internal_clock.year) + 1))
{
internal_clock.mday = 1;
internal_clock.mon++;
}
if (internal_clock.mon == 13)
{
internal_clock.mon = 1;
internal_clock.year++;
}
}
/* Called when ticking the second */
void rtc_tick(void)
{
internal_clock.sec++;
rtc_recalc();
}
/* Called when modifying the NVR registers */
void time_update(char *nvrram, int reg)
{
int temp;
switch(reg)
{
case RTC_SECONDS:
internal_clock.sec = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_SECONDS] : DCB(nvrram[RTC_SECONDS]);
break;
case RTC_MINUTES:
internal_clock.min = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MINUTES] : DCB(nvrram[RTC_MINUTES]);
break;
case RTC_HOURS:
temp = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_HOURS] : DCB(nvrram[RTC_HOURS]);
if (nvrram[RTC_REGB] & RTC_2412)
internal_clock.hour = temp;
else
internal_clock.hour = ((temp & ~RTC_AMPM) % 12) + ((temp & RTC_AMPM) ? 12 : 0);
break;
case RTC_DOM:
internal_clock.mday = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_DOM] : DCB(nvrram[RTC_DOM]);
break;
case RTC_MONTH:
internal_clock.mon = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MONTH] : DCB(nvrram[RTC_MONTH]);
break;
case RTC_YEAR:
internal_clock.year = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_YEAR] : DCB(nvrram[RTC_YEAR]);
internal_clock.year += (nvrram[RTC_REGB] & RTC_DM) ? 1900 : (DCB(nvrram[RTC_CENTURY]) * 100);
break;
case RTC_CENTURY:
if (nvrram[RTC_REGB] & RTC_DM)
return;
internal_clock.year %= 100;
internal_clock.year += (DCB(nvrram[RTC_CENTURY]) * 100);
break;
}
}
/* Called to obtain the current day of the week based on the internal clock */
static int time_week_day(void)
{
int day_of_month = internal_clock.mday;
int month2 = internal_clock.mon;
int year2 = internal_clock.year % 100;
int century = ((internal_clock.year - year2) / 100) % 4;
int sum = day_of_month + month2 + year2 + century;
/* (Sum mod 7) gives 0 for Saturday, we need it for Sunday, so +6 for Saturday to get 6 and Sunday 0 */
int raw_wd = ((sum + 6) % 7);
return raw_wd;
}
/* Called to get time into the internal clock */
static void time_internal_get(struct tm *time_var)
{
time_var->tm_sec = internal_clock.sec;
time_var->tm_min = internal_clock.min;
time_var->tm_hour = internal_clock.hour;
time_var->tm_wday = time_week_day();
time_var->tm_mday = internal_clock.mday;
time_var->tm_mon = internal_clock.mon - 1;
time_var->tm_year = internal_clock.year - 1900;
}
static void time_internal_set(struct tm *time_var)
{
internal_clock.sec = time_var->tm_sec;
internal_clock.min = time_var->tm_min;
internal_clock.hour = time_var->tm_hour;
internal_clock.mday = time_var->tm_mday;
internal_clock.mon = time_var->tm_mon + 1;
internal_clock.year = time_var->tm_year + 1900;
}
static void time_set_nvrram(char *nvrram, struct tm *cur_time_tm)
{
if (nvrram[RTC_REGB] & RTC_DM)
{
nvrram[RTC_SECONDS] = cur_time_tm->tm_sec;
nvrram[RTC_MINUTES] = cur_time_tm->tm_min;
nvrram[RTC_DOW] = cur_time_tm->tm_wday + 1;
nvrram[RTC_DOM] = cur_time_tm->tm_mday;
nvrram[RTC_MONTH] = cur_time_tm->tm_mon + 1;
nvrram[RTC_YEAR] = cur_time_tm->tm_year % 100;
if (nvrram[RTC_REGB] & RTC_2412)
{
nvrram[RTC_HOURS] = cur_time_tm->tm_hour;
}
else
{
nvrram[RTC_HOURS] = (cur_time_tm->tm_hour % 12) ? (cur_time_tm->tm_hour % 12) : 12;
if (cur_time_tm->tm_hour > 11)
nvrram[RTC_HOURS] |= RTC_AMPM;
}
}
else
{
nvrram[RTC_SECONDS] = BCD(cur_time_tm->tm_sec);
nvrram[RTC_MINUTES] = BCD(cur_time_tm->tm_min);
nvrram[RTC_DOW] = BCD(cur_time_tm->tm_wday + 1);
nvrram[RTC_DOM] = BCD(cur_time_tm->tm_mday);
nvrram[RTC_MONTH] = BCD(cur_time_tm->tm_mon + 1);
nvrram[RTC_YEAR] = BCD(cur_time_tm->tm_year % 100);
if (nvrram[RTC_REGB] & RTC_2412)
{
nvrram[RTC_HOURS] = BCD(cur_time_tm->tm_hour);
}
else
{
nvrram[RTC_HOURS] = (cur_time_tm->tm_hour % 12) ? BCD(cur_time_tm->tm_hour % 12) : BCD(12);
if (cur_time_tm->tm_hour > 11)
nvrram[RTC_HOURS] |= RTC_AMPM;
}
}
}
void time_internal_set_nvrram(char *nvrram)
{
int temp;
/* Load the entire internal clock state from the NVR. */
internal_clock.sec = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_SECONDS] : DCB(nvrram[RTC_SECONDS]);
internal_clock.min = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MINUTES] : DCB(nvrram[RTC_MINUTES]);
temp = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_HOURS] : DCB(nvrram[RTC_HOURS]);
if (nvrram[RTC_REGB] & RTC_2412)
internal_clock.hour = temp;
else
internal_clock.hour = ((temp & ~RTC_AMPM) % 12) + ((temp & RTC_AMPM) ? 12 : 0);
internal_clock.mday = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_DOM] : DCB(nvrram[RTC_DOM]);
internal_clock.mon = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MONTH] : DCB(nvrram[RTC_MONTH]);
internal_clock.year = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_YEAR] : DCB(nvrram[RTC_YEAR]);
internal_clock.year += (nvrram[RTC_REGB] & RTC_DM) ? 1900 : (DCB(nvrram[RTC_CENTURY]) * 100);
}
void time_internal_sync(char *nvrram)
{
struct tm *cur_time_tm;
time_t cur_time;
time(&cur_time);
cur_time_tm = localtime(&cur_time);
time_internal_set(cur_time_tm);
time_set_nvrram(nvrram, cur_time_tm);
}
void time_get(char *nvrram)
{
struct tm cur_time_tm;
time_internal_get(&cur_time_tm);
time_set_nvrram(nvrram, &cur_time_tm);
}

174
src/rtc.h
View File

@@ -1,174 +0,0 @@
#define BCD(X) (((X) % 10) | (((X) / 10) << 4))
#define DCB(X) ((((X) & 0xF0) >> 4) * 10 + ((X) & 0x0F))
enum RTC_ADDR
{
RTC_SECONDS,
RTC_ALARMSECONDS,
RTC_MINUTES,
RTC_ALARMMINUTES,
RTC_HOURS,
RTC_ALARMHOURS,
RTC_DOW,
RTC_DOM,
RTC_MONTH,
RTC_YEAR,
RTC_REGA,
RTC_REGB,
RTC_REGC,
RTC_REGD
};
/* The century register at location 32h is a BCD register designed to automatically load the BCD value 20 as the year register changes from 99 to 00.
The MSB of this register is not affected when the load of 20 occurs, and remains at the value written by the user. */
#define RTC_CENTURY 0x32
/* When the 12-hour format is selected, the higher-order bit of the hours byte represents PM when it is logic 1. */
#define RTC_AMPM 0x80
/* Register A bitflags */
enum RTC_RA_BITS
{
/* Rate Selector (RS0)
These four rate-selection bits select one of the 13 taps on the 15-stage divider or disable the divider output.
The tap selected can be used to generate an output square wave (SQW pin) and/or a periodic interrupt.
The user can do one of the following:
- Enable the interrupt with the PIE bit;
- Enable the SQW output pin with the SQWE bit;
- Enable both at the same time and the same rate; or
- Enable neither.
Table 3 lists the periodic interrupt rates and the square wave frequencies that can be chosen with the RS bits.
These four read/write bits are not affected by !RESET. */
RTC_RS = 0xF,
/* DV0
These three bits are used to turn the oscillator on or off and to reset the countdown chain.
A pattern of 010 is the only combination of bits that turn the oscillator on and allow the RTC to keep time.
A pattern of 11x enables the oscillator but holds the countdown chain in reset.
The next update occurs at 500ms after a pattern of 010 is written to DV0, DV1, and DV2. */
RTC_DV0 = 0x70,
/* Update-In-Progress (UIP)
This bit is a status flag that can be monitored. When the UIP bit is a 1, the update transfer occurs soon.
When UIP is a 0, the update transfer does not occur for at least 244us.
The time, calendar, and alarm information in RAM is fully available for access when the UIP bit is 0.
The UIP bit is read-only and is not affected by !RESET.
Writing the SET bit in Register B to a 1 inhibits any update transfer and clears the UIP status bit. */
RTC_UIP = 0x80
};
/* Register B bitflags */
enum RTC_RB_BITS
{
/* Daylight Saving Enable (DSE)
This bit is a read/write bit that enables two daylight saving adjustments when DSE is set to 1.
On the first Sunday in April (or the last Sunday in April in the MC146818A), the time increments from 1:59:59 AM to 3:00:00 AM.
On the last Sunday in October when the time first reaches 1:59:59 AM, it changes to 1:00:00 AM.
When DSE is enabled, the internal logic test for the first/last Sunday condition at midnight.
If the DSE bit is not set when the test occurs, the daylight saving function does not operate correctly.
These adjustments do not occur when the DSE bit is 0. This bit is not affected by internal functions or !RESET. */
RTC_DSE = 0x1,
/* 24/12
The 24/12 control bit establishes the format of the hours byte. A 1 indicates the 24-hour mode and a 0 indicates the 12-hour mode.
This bit is read/write and is not affected by internal functions or !RESET. */
RTC_2412 = 0x2,
/* Data Mode (DM)
This bit indicates whether time and calendar information is in binary or BCD format.
The DM bit is set by the program to the appropriate format and can be read as required.
This bit is not modified by internal functions or !RESET. A 1 in DM signifies binary data, while a 0 in DM specifies BCD data. */
RTC_DM = 0x4,
/* Square-Wave Enable (SQWE)
When this bit is set to 1, a square-wave signal at the frequency set by the rate-selection bits RS3-RS0 is driven out on the SQW pin.
When the SQWE bit is set to 0, the SQW pin is held low. SQWE is a read/write bit and is cleared by !RESET.
SQWE is low if disabled, and is high impedance when VCC is below VPF. SQWE is cleared to 0 on !RESET. */
RTC_SQWE = 0x8,
/* Update-Ended Interrupt Enable (UIE)
This bit is a read/write bit that enables the update-end flag (UF) bit in Register C to assert !IRQ.
The !RESET pin going low or the SET bit going high clears the UIE bit.
The internal functions of the device do not affect the UIE bit, but is cleared to 0 on !RESET. */
RTC_UIE = 0x10,
/* Alarm Interrupt Enable (AIE)
This bit is a read/write bit that, when set to 1, permits the alarm flag (AF) bit in Register C to assert !IRQ.
An alarm interrupt occurs for each second that the three time bytes equal the three alarm bytes, including a don't-care alarm code of binary 11XXXXXX.
The AF bit does not initiate the !IRQ signal when the AIE bit is set to 0.
The internal functions of the device do not affect the AIE bit, but is cleared to 0 on !RESET. */
RTC_AIE = 0x20,
/* Periodic Interrupt Enable (PIE)
The PIE bit is a read/write bit that allows the periodic interrupt flag (PF) bit in Register C to drive the !IRQ pin low.
When the PIE bit is set to 1, periodic interrupts are generated by driving the !IRQ pin low at a rate specified by the RS3-RS0 bits of Register A.
A 0 in the PIE bit blocks the !IRQ output from being driven by a periodic interrupt, but the PF bit is still set at the periodic rate.
PIE is not modified by any internal device functions, but is cleared to 0 on !RESET. */
RTC_PIE = 0x40,
/* SET
When the SET bit is 0, the update transfer functions normally by advancing the counts once per second.
When the SET bit is written to 1, any update transfer is inhibited, and the program can initialize the time and calendar bytes without an update
occurring in the midst of initializing. Read cycles can be executed in a similar manner. SET is a read/write bit and is not affected by !RESET or
internal functions of the device. */
RTC_SET = 0x80
};
/* Register C bitflags */
enum RTC_RC_BITS
{
/* Unused
These bits are unused in Register C. These bits always read 0 and cannot be written. */
RTC_RC = 0xF,
/* Update-Ended Interrupt Flag (UF)
This bit is set after each update cycle. When the UIE bit is set to 1, the 1 in UF causes the IRQF bit to be a 1, which asserts the !IRQ pin.
This bit can be cleared by reading Register C or with a !RESET. */
RTC_UF = 0x10,
/* Alarm Interrupt Flag (AF)
A 1 in the AF bit indicates that the current time has matched the alarm time.
If the AIE bit is also 1, the !IRQ pin goes low and a 1 appears in the IRQF bit. This bit can be cleared by reading Register C or with a !RESET. */
RTC_AF = 0x20,
/* Periodic Interrupt Flag (PF)
This bit is read-only and is set to 1 when an edge is detected on the selected tap of the divider chain.
The RS3 through RS0 bits establish the periodic rate. PF is set to 1 independent of the state of the PIE bit.
When both PF and PIE are 1s, the !IRQ signal is active and sets the IRQF bit. This bit can be cleared by reading Register C or with a !RESET. */
RTC_PF = 0x40,
/* Interrupt Request Flag (IRQF)
The interrupt request flag (IRQF) is set to a 1 when one or more of the following are true:
- PF == PIE == 1
- AF == AIE == 1
- UF == UIE == 1
Any time the IRQF bit is a 1, the !IRQ pin is driven low.
All flag bits are cleared after Register C is read by the program or when the !RESET pin is low. */
RTC_IRQF = 0x80
};
/* Register D bitflags */
enum RTC_RD_BITS
{
/* Unused
The remaining bits of Register D are not usable. They cannot be written and they always read 0. */
RTC_RD = 0x7F,
/* Valid RAM and Time (VRT)
This bit indicates the condition of the battery connected to the VBAT pin. This bit is not writeable and should always be 1 when read.
If a 0 is ever present, an exhausted internal lithium energy source is indicated and both the contents of the RTC data and RAM data are questionable.
This bit is unaffected by !RESET. */
RTC_VRT = 0x80
};
extern void rtc_tick(void);
extern void time_update(char *nvrram, int reg);
extern void time_get(char *nvrram);
extern void time_internal_set_nvrram(char *nvrram);
extern void time_internal_sync(char *nvrram);

View File

@@ -12,7 +12,7 @@
*
* NOTE: THIS IS CURRENTLY A MESS, but will be cleaned up as I go.
*
* Version: @(#)scsi_aha154x.c 1.0.18 2017/09/24
* Version: @(#)scsi_aha154x.c 1.0.19 2017/10/02
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Original Buslogic version by SA1988 and Miran Grca.
@@ -1838,7 +1838,7 @@ aha_setbios(aha_t *dev)
if (dev->bios_path == NULL) return;
/* Open the BIOS image file and make sure it exists. */
pclog_w(L"%S: loading BIOS from '%s'\n", dev->name, dev->bios_path);
pclog("%s: loading BIOS from '%ws'\n", dev->name, dev->bios_path);
if ((f = rom_fopen(dev->bios_path, L"rb")) == NULL) {
pclog("%s: BIOS ROM not found!\n", dev->name);
return;

View File

@@ -10,7 +10,7 @@
* 0 - BT-545C ISA;
* 1 - BT-958D PCI (but BT-545C ISA on non-PCI machines)
*
* Version: @(#)scsi_buslogic.c 1.0.14 2017/09/24
* Version: @(#)scsi_buslogic.c 1.0.15 2017/10/02
*
* Authors: TheCollector1995, <mariogplayer@gmail.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -733,7 +733,7 @@ static void BuslogicInitializeAutoSCSIRam(Buslogic_t *bl)
{
FILE *f;
f = nvrfopen(BuslogicGetNVRFileName(bl), L"rb");
f = nvr_fopen(BuslogicGetNVRFileName(bl), L"rb");
if (f)
{
fread(&(bl->LocalRAM.structured.autoSCSIData), 1, 64, f);
@@ -2068,7 +2068,7 @@ BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
BuslogicAutoSCSIRamSetDefaults(bl, 3);
break;
case 1:
f = nvrfopen(BuslogicGetNVRFileName(bl), L"wb");
f = nvr_fopen(BuslogicGetNVRFileName(bl), L"wb");
if (f)
{
fwrite(&(bl->LocalRAM.structured.autoSCSIData), 1, 64, f);

View File

@@ -777,7 +777,7 @@ void *adgold_init()
for (; c >= 0; c--)
attenuation[c] = 0;
f = nvrfopen(L"adgold.bin", L"rb");
f = nvr_fopen(L"adgold.bin", L"rb");
if (f)
{
fread(adgold->adgold_eeprom, 0x18, 1, f);
@@ -817,7 +817,7 @@ void adgold_close(void *p)
FILE *f;
adgold_t *adgold = (adgold_t *)p;
f = nvrfopen(L"adgold.bin", L"wb");
f = nvr_fopen(L"adgold.bin", L"wb");
if (f)
{
fwrite(adgold->adgold_eeprom, 0x18, 1, f);

View File

@@ -136,10 +136,10 @@ static void *tandy_eeprom_init(void)
switch (romset)
{
case ROM_TANDY1000HX:
f = nvrfopen(L"tandy1000hx.bin", L"rb");
f = nvr_fopen(L"tandy1000hx.bin", L"rb");
break;
case ROM_TANDY1000SL2:
f = nvrfopen(L"tandy1000sl2.bin", L"rb");
f = nvr_fopen(L"tandy1000sl2.bin", L"rb");
break;
}
if (f)
@@ -164,10 +164,10 @@ void tandy_eeprom_close(void *p)
switch (eeprom->romset)
{
case ROM_TANDY1000HX:
f = nvrfopen(L"tandy1000hx.bin", L"wb");
f = nvr_fopen(L"tandy1000hx.bin", L"wb");
break;
case ROM_TANDY1000SL2:
f = nvrfopen(L"tandy1000sl2.bin", L"wb");
f = nvr_fopen(L"tandy1000sl2.bin", L"wb");
break;
}
fwrite(eeprom->store, 128, 1, f);

View File

@@ -43,7 +43,7 @@ void ati_eeprom_load(ati_eeprom_t *eeprom, wchar_t *fn, int type)
FILE *f;
eeprom->type = type;
wcscpy(eeprom->fn, fn);
f = nvrfopen(eeprom->fn, L"rb");
f = nvr_fopen(eeprom->fn, L"rb");
if (!f)
{
memset(eeprom->data, 0, eeprom->type ? 512 : 128);
@@ -55,7 +55,7 @@ void ati_eeprom_load(ati_eeprom_t *eeprom, wchar_t *fn, int type)
void ati_eeprom_save(ati_eeprom_t *eeprom)
{
FILE *f = nvrfopen(eeprom->fn, L"wb");
FILE *f = nvr_fopen(eeprom->fn, L"wb");
if (!f) return;
fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f);
fclose(f);

View File

@@ -11,7 +11,7 @@
* This is intended to be used by another SVGA driver,
* and not as a card in it's own right.
*
* Version: @(#)vid_svga.c 1.0.3 2017/09/24
* Version: @(#)vid_svga.c 1.0.4 2017/10/02
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -1939,7 +1939,7 @@ void svga_dump_vram()
return;
}
f = nvrfopen(L"svga_vram.dmp", L"wb");
f = nvr_fopen(L"svga_vram.dmp", L"wb");
if (f == NULL)
{
return;

View File

@@ -8,7 +8,7 @@
*
* Windows resource script.
*
* Version: @(#)86Box.rc 1.0.13 2017/10/01
* Version: @(#)86Box.rc 1.0.14 2017/10/01
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
@@ -266,9 +266,6 @@ BEGIN
12,12
LTEXT "MB",IDT_1705,123,64,10,10
LTEXT "Memory:",IDT_1706,7,64,30,10
LTEXT "NVR Path:",IDT_1700,7,83,60,10
EDITTEXT IDC_EDIT_NVR_PATH,71,82,138,12,ES_AUTOHSCROLL
PUSHBUTTON "&Specify...",IDC_BUTTON_NVR_PATH,214,82,46,12
CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,100,94,10
CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX |
@@ -689,7 +686,9 @@ BEGIN
IDS_2053 "Invalid number of sectors (valid values are between 1 and 63)"
IDS_2054 "Invalid number of heads (valid values are between 1 and 16)"
IDS_2055 "Invalid number of cylinders (valid values are between 1 and 266305)"
IDS_2056 "Specify the NVR Path"
#if NOTUSED
IDS_2056
#endif
IDS_2057 "(empty)"
IDS_2058 "(host drive %c:)"
IDS_2059 "Turbo"

View File

@@ -9,10 +9,11 @@
* Windows resource defines.
*
* NOTE: FIXME: Strings 2176 and 2193 are same.
* NOTE: FIXME: string 2052 not in use.
* NOTE: FIXME: string 2095 not in use.
* NOTE: FIXME: strings 2152-2154 not in use.
* NOTE: FIXME: strings 2153-2154 not in use.
*
* Version: @(#)resource.h 1.0.8 2017/10/01
* Version: @(#)resource.h 1.0.9 2017/10/01
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -105,8 +106,6 @@
#define IDC_MEMTEXT 1017
#define IDC_MEMSPIN 1018
#define IDC_TEXT_MB IDT_1705
#define IDC_EDIT_NVR_PATH 1019
#define IDC_BUTTON_NVR_PATH 1020
#define IDC_VIDEO 1030 /* video config */
#define IDC_COMBO_VIDEO 1031

View File

@@ -8,7 +8,7 @@
*
* The Emulator's Windows core.
*
* Version: @(#)win.c 1.0.14 2017/10/01
* Version: @(#)win.c 1.0.14 2017/10/02
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -338,8 +338,8 @@ void mainthread(LPVOID param)
if (frames >= 200 && nvr_dosave)
{
frames = 0;
nvr_save();
nvr_dosave = 0;
savenvr();
}
end_time = timer_read();
main_time += end_time - start_time;
@@ -1904,7 +1904,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpsz
Sleep(200);
TerminateThread(mainthreadh, 0);
savenvr();
nvr_save();
config_save();
@@ -2022,7 +2022,7 @@ win_pc_reset(int hard)
Sleep(100);
savenvr();
nvr_save();
config_save();

View File

@@ -8,7 +8,7 @@
*
* Windows 86Box Settings dialog handler.
*
* Version: @(#)win_settings.c 1.0.17 2017/10/01
* Version: @(#)win_settings.c 1.0.17 2017/10/02
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016,2017 Miran Grca.
@@ -56,7 +56,6 @@
/* Machine category */
static int temp_machine, temp_cpu_m, temp_cpu, temp_wait_states, temp_mem_size, temp_dynarec, temp_fpu, temp_sync;
static wchar_t temp_nvr_path[520];
/* Video category */
static int temp_gfxcard, temp_video_speed, temp_voodoo;
@@ -115,8 +114,6 @@ static void win_settings_init(void)
temp_wait_states = cpu_waitstates;
temp_cpu = cpu;
temp_mem_size = mem_size;
memset(temp_nvr_path, 0, sizeof(temp_nvr_path));
wcscpy(temp_nvr_path, nvr_path);
temp_dynarec = cpu_use_dynarec;
temp_fpu = enable_external_fpu;
temp_sync = enable_sync;
@@ -187,7 +184,6 @@ static int win_settings_changed(void)
i = i || (cpu_waitstates != temp_wait_states);
i = i || (cpu != temp_cpu);
i = i || (mem_size != temp_mem_size);
i = i || wcscmp(temp_nvr_path, nvr_path);
i = i || (temp_dynarec != cpu_use_dynarec);
i = i || (temp_fpu != enable_external_fpu);
i = i || (temp_sync != enable_sync);
@@ -292,8 +288,6 @@ static void win_settings_save(void)
cpu_waitstates = temp_wait_states;
cpu = temp_cpu;
mem_size = temp_mem_size;
memset(nvr_path, 0, sizeof(nvr_path));
wcscpy(nvr_path, temp_nvr_path);
cpu_use_dynarec = temp_dynarec;
enable_external_fpu = temp_fpu;
enable_sync = temp_sync;
@@ -548,7 +542,6 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM w
int d = 0;
LPTSTR lptsTemp;
char *stransi;
wchar_t *p;
switch (message)
{
@@ -600,9 +593,6 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM w
win_settings_machine_recalc_machine(hdlg);
h = GetDlgItem(hdlg, IDC_EDIT_NVR_PATH);
SendMessage(h, WM_SETTEXT, 0, (LPARAM) temp_nvr_path);
free(lptsTemp);
return TRUE;
@@ -644,24 +634,6 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM w
deviceconfig_open(hdlg, (void *)machine_getdevice(temp_machine));
break;
case IDC_BUTTON_NVR_PATH:
p = BrowseFolder(temp_nvr_path, win_language_get_string_from_id(IDS_2056));
if (wcscmp(p, L""))
{
memset(temp_nvr_path, 0, sizeof(temp_nvr_path));
wcscpy(temp_nvr_path, p);
if (temp_nvr_path[wcslen(temp_nvr_path) - 1] == L'/')
{
temp_nvr_path[wcslen(temp_nvr_path) - 1] = L'\\';
}
else if (temp_nvr_path[wcslen(temp_nvr_path) - 1] != L'\\')
{
temp_nvr_path[wcslen(temp_nvr_path)] = L'\\';
}
h = GetDlgItem(hdlg, IDC_EDIT_NVR_PATH);
SendMessage(h, WM_SETTEXT, 0, (LPARAM) temp_nvr_path);
}
break;
}
return FALSE;