Applied all relevant PCem commits;

Extensively cleaned up and changed the CD-ROM code;
Removed CD-ROM IOCTTL (it was causing performance and stability issues);
Turned a lot of things into device_t's;
Added the PS/1 Model 2011 XTA and standalone XTA hard disk controllers, ported from Varcem;
Numerous FDC fixes for the PS/1 Model 2121;
NVR changes ported from Varcem;
The PCap code no longer requires libpcap to be compiled;
Numerous fixes to various SCSI controllers;
Updated NukedOPL to 1.8;
Fixes to OpenAL initialization and closing, should give less Audio issues now;
Revorked parts of the common (S)VGA code (also based on code from QEMU);
Removed the Removable SCSI hard disks (they were a never finished experiment so there was no need to keep them there);
Cleaned up the SCSI hard disk and Iomega ZIP code (but more cleanups of that are coming in the future);
In some occasions (IDE hard disks in multiple sector mode and SCSI hard disks) the status bar icon is no longer updated, should improve performance a bit;
Redid the way the tertiary and quaternary IDE controllers are configured (and they are now device_t's);
Extensively reworked the IDE code and fixed quite a few bugs;
Fixes to XT MFM, AT MFM, and AT ESDI code;
Some changes to XTIDE and MCA ESDI code;
Some fixes to the CD-ROM image handler.
This commit is contained in:
OBattler
2018-04-25 23:51:13 +02:00
parent 2789adca0e
commit a412ceb4d9
151 changed files with 21026 additions and 21058 deletions

315
src/nvr.c
View File

@@ -8,9 +8,7 @@
*
* Implement a generic NVRAM/CMOS/RTC device.
*
* NOTE: I should re-do 'intclk' using a TM struct.
*
* Version: @(#)nvr.c 1.0.3 2018/03/19
* Version: @(#)nvr.c 1.0.6 2018/04/11
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*
@@ -65,23 +63,11 @@
#include "nvr.h"
/* Define the internal clock. */
typedef struct {
int16_t year;
int8_t sec;
int8_t min;
int8_t hour;
int8_t mday;
int8_t mon;
} intclk_t;
int enable_sync; /* configuration variable: enable time sync */
int nvr_dosave; /* NVR is dirty, needs saved */
static int8_t days_in_month[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
static intclk_t intclk;
static struct tm intclk;
static nvr_t *saved_nvr = NULL;
@@ -113,25 +99,23 @@ static void
rtc_tick(void)
{
/* Ping the internal clock. */
if (++intclk.sec == 60) {
intclk.sec = 0;
intclk.min++;
}
if (intclk.min == 60) {
intclk.min = 0;
intclk.hour++;
}
if (intclk.hour == 24) {
intclk.hour = 0;
intclk.mday++;
}
if (intclk.mday == (nvr_get_days(intclk.mon, intclk.year) + 1)) {
intclk.mday = 1;
intclk.mon++;
}
if (intclk.mon == 13) {
intclk.mon = 1;
intclk.year++;
if (++intclk.tm_sec == 60) {
intclk.tm_sec = 0;
if (++intclk.tm_min == 60) {
intclk.tm_min = 0;
if (++intclk.tm_hour == 24) {
intclk.tm_hour = 0;
if (++intclk.tm_mday == (nvr_get_days(intclk.tm_mon,
intclk.tm_year) + 1)) {
intclk.tm_mday = 1;
intclk.tm_mon++;
if (++intclk.tm_mon == 13) {
intclk.tm_mon = 1;
intclk.tm_year++;
}
}
}
}
}
}
@@ -168,9 +152,9 @@ nvr_init(nvr_t *nvr)
/* Set up the NVR file's name. */
sprintf(temp, "%s.nvr", machine_get_internal_name());
c = strlen(temp)+1;
nvr->fn = (wchar_t *)malloc(c*sizeof(wchar_t));
mbstowcs(nvr->fn, temp, c);
c = strlen(temp);
nvr->fn = (wchar_t *)malloc((c + 1) * sizeof(wchar_t));
mbstowcs(nvr->fn, temp, c + 1);
/* Initialize the internal clock as needed. */
memset(&intclk, 0x00, sizeof(intclk));
@@ -183,8 +167,8 @@ nvr_init(nvr_t *nvr)
nvr_time_set(tm);
} else {
/* Reset the internal clock to 1980/01/01 00:00. */
intclk.mon = 1;
intclk.year = 1980;
intclk.tm_mon = 1;
intclk.tm_year = 1980;
}
/* Set up our timer. */
@@ -201,124 +185,7 @@ nvr_init(nvr_t *nvr)
}
/*
* Load an NVR from file.
*
* This function does two things, really. It clears and initializes
* the RTC and NVRAM areas, sets up defaults for the RTC part, and
* then attempts to load data from a saved file.
*
* Either way, after that, it will continue to configure the local
* RTC to operate, so it can update either the local RTC, and/or
* the one supplied by a client.
*/
int
nvr_load(void)
{
FILE *f;
/* Make sure we have been initialized. */
if (saved_nvr == NULL) return(0);
/* Clear out any old data. */
memset(saved_nvr->regs, 0xff, sizeof(saved_nvr->regs));
/* Set the defaults. */
if (saved_nvr->reset != NULL)
saved_nvr->reset(saved_nvr);
/* Load the (relevant) part of the NVR contents. */
if (saved_nvr->size != 0) {
pclog("NVR: loading from '%ls'\n", nvr_path(saved_nvr->fn));
f = plat_fopen(nvr_path(saved_nvr->fn), L"rb");
if (f != NULL) {
/* Read NVR contents from file. */
(void)fread(saved_nvr->regs, saved_nvr->size, 1, f);
(void)fclose(f);
}
}
if (romset == ROM_T1000)
t1000_nvr_load();
else if (romset == ROM_T1200)
t1200_nvr_load();
/* Get the local RTC running! */
if (saved_nvr->start != NULL)
saved_nvr->start(saved_nvr);
return(1);
}
/* Save the current NVR to a file. */
int
nvr_save(void)
{
FILE *f;
/* Make sure we have been initialized. */
if (saved_nvr == NULL) return(0);
if (saved_nvr->size != 0) {
pclog("NVR: saving to '%ls'\n", nvr_path(saved_nvr->fn));
f = plat_fopen(nvr_path(saved_nvr->fn), L"wb");
if (f != NULL) {
/* Save NVR contents to file. */
(void)fwrite(saved_nvr->regs, saved_nvr->size, 1, f);
fclose(f);
}
}
if (romset == ROM_T1000)
t1000_nvr_save();
else if (romset == ROM_T1200)
t1200_nvr_save();
/* Device is clean again. */
nvr_dosave = 0;
return(1);
}
/* Get current time from internal clock. */
void
nvr_time_get(struct tm *tm)
{
int8_t dom, mon, sum, wd;
int16_t cent, yr;
tm->tm_sec = intclk.sec;
tm->tm_min = intclk.min;
tm->tm_hour = intclk.hour;
dom = intclk.mday;
mon = intclk.mon;
yr = (intclk.year % 100);
cent = ((intclk.year - yr) / 100) % 4;
sum = dom+mon+yr+cent;
wd = ((sum + 6) % 7);
tm->tm_wday = wd;
tm->tm_mday = intclk.mday;
tm->tm_mon = (intclk.mon - 1);
tm->tm_year = (intclk.year - 1900);
}
/* Set internal clock time. */
void
nvr_time_set(struct tm *tm)
{
intclk.sec = tm->tm_sec;
intclk.min = tm->tm_min;
intclk.hour = tm->tm_hour;
intclk.mday = tm->tm_mday;
intclk.mon = (tm->tm_mon + 1);
intclk.year = (tm->tm_year + 1900);
}
/* Get an absolute path to the NVR folder. */
/* Get path to the NVR folder. */
wchar_t *
nvr_path(wchar_t *str)
{
@@ -341,6 +208,138 @@ nvr_path(wchar_t *str)
}
/*
* Load an NVR from file.
*
* This function does two things, really. It clears and initializes
* the RTC and NVRAM areas, sets up defaults for the RTC part, and
* then attempts to load data from a saved file.
*
* Either way, after that, it will continue to configure the local
* RTC to operate, so it can update either the local RTC, and/or
* the one supplied by a client.
*/
int
nvr_load(void)
{
wchar_t *path;
FILE *fp;
/* Make sure we have been initialized. */
if (saved_nvr == NULL) return(0);
/* Clear out any old data. */
memset(saved_nvr->regs, 0x00, sizeof(saved_nvr->regs));
/* Set the defaults. */
if (saved_nvr->reset != NULL)
saved_nvr->reset(saved_nvr);
/* Load the (relevant) part of the NVR contents. */
if (saved_nvr->size != 0) {
path = nvr_path(saved_nvr->fn);
pclog("NVR: loading from '%ls'\n", path);
fp = plat_fopen(path, L"rb");
if (fp != NULL) {
/* Read NVR contents from file. */
(void)fread(saved_nvr->regs, saved_nvr->size, 1, fp);
(void)fclose(fp);
}
}
if (romset == ROM_T1000)
t1000_nvr_load();
else if (romset == ROM_T1200)
t1200_nvr_load();
/* Get the local RTC running! */
if (saved_nvr->start != NULL)
saved_nvr->start(saved_nvr);
return(1);
}
/* Save the current NVR to a file. */
int
nvr_save(void)
{
wchar_t *path;
FILE *fp;
/* Make sure we have been initialized. */
if (saved_nvr == NULL) return(0);
if (saved_nvr->size != 0) {
path = nvr_path(saved_nvr->fn);
pclog("NVR: saving to '%ls'\n", path);
fp = plat_fopen(path, L"wb");
if (fp != NULL) {
/* Save NVR contents to file. */
(void)fwrite(saved_nvr->regs, saved_nvr->size, 1, fp);
fclose(fp);
}
}
if (romset == ROM_T1000)
t1000_nvr_save();
else if (romset == ROM_T1200)
t1200_nvr_save();
/* Device is clean again. */
nvr_dosave = 0;
return(1);
}
void
nvr_period_recalc(void)
{
/* Make sure we have been initialized. */
if (saved_nvr == NULL) return;
if (saved_nvr->size != 0)
saved_nvr->recalc(saved_nvr);
}
/* Get current time from internal clock. */
void
nvr_time_get(struct tm *tm)
{
int8_t dom, mon, sum, wd;
int16_t cent, yr;
tm->tm_sec = intclk.tm_sec;
tm->tm_min = intclk.tm_min;
tm->tm_hour = intclk.tm_hour;
dom = intclk.tm_mday;
mon = intclk.tm_mon;
yr = (intclk.tm_year % 100);
cent = ((intclk.tm_year - yr) / 100) % 4;
sum = dom+mon+yr+cent;
wd = ((sum + 6) % 7);
tm->tm_wday = wd;
tm->tm_mday = intclk.tm_mday;
tm->tm_mon = (intclk.tm_mon - 1);
tm->tm_year = (intclk.tm_year - 1900);
}
/* Set internal clock time. */
void
nvr_time_set(struct tm *tm)
{
intclk.tm_sec = tm->tm_sec;
intclk.tm_min = tm->tm_min;
intclk.tm_hour = tm->tm_hour;
intclk.tm_mday = tm->tm_mday;
intclk.tm_mon = (tm->tm_mon + 1);
intclk.tm_year = (tm->tm_year + 1900);
}
/* Open or create a file in the NVR area. */
FILE *
nvr_fopen(wchar_t *str, wchar_t *mode)