Added the IBM 5161 ISA expansion for PC and XT;

Cleaned up the parallel port emulation, added IRQ support, and made enabling/disabling per port;
Added the Award 430NX and the Intel Classic/PCI (Alfredo, 420TX);
Finished the 586MC1;
Added 8087 emulation;
Moved Cyrix 6x86'es to the Dev branch;
Sanitized/cleaned up memregs.c/h and intel.c/h;
Split the chipsets from machines and sanitized Port 92 emulation;
Added support for the 15bpp mode to the Compaq ATI 28800;
Moved the MR 386DX and 486 machines to the Dev branch;
Ported the new dynamic recompiler from PCem, but it remains in Dev branch until after v2.00;
Ported the new timer code from PCem;
Cleaned up the CPU table of unused stuff and better optimized its structure;
Ported the Open-XT and Open-AT from VARCem, the Open-AT is in the Dev branch;
Ported the XT MFM controller rewrite and adding of more controllers (incl. two RLL ones), from VARCem;
Added the AHA-1540A and the BusTek BT-542B;
Moved the Sumo SCSI-AT to the Dev branch;
Minor IDE, FDC, and floppy drive code clean-ups;
Made NCR 5380/53C400-based cards' BIOS address configurable;
Got rid of the legacy romset variable;
Unified (video) buffer and buffer32 into one and make the unified buffer 32-bit;
Added the Amstead PPC512 per PCem patch by John Elliott;
Switched memory mapping granularity from 16k to 4k (less than 1k not possible due to internal pages);
Rewrote the CL-GD 54xx blitter, fixes Win-OS/2 on the 54x6 among other thing;
Added the Image Manager 1024 and Professional Graphics Controller per PCem patch by John Elliott and work done on VARCem;
Added Headland HT-216, GC-205 and Video 7 VGA 1024i emulation based on PCem commit;
Implemented the fuction keys for the Toshiba T1000/T1200/T3100 enhancement;
Amstrad MegaPC does now works correctly with non-internal graphics card;
The SLiRP code no longer casts a packed struct type to a non-packed struct type;
The Xi8088 and PB410a no longer hang on 86Box when PS/2 mouse is not present;
The S3 Virge on BeOS is no longer broken (was broken by build #1591);
OS/2 2.0 build 6.167 now sees key presses again;
Xi8088 now work on CGA again;
86F images converted from either the old or new variants of the HxC MFM format now work correctly;
Hardware interrupts with a vector of 0xFF are now handled correctly;
OPTi 495SX boards no longer incorrectly have 64 MB maximum RAM when 32 MB is correct;
Fixed VNC keyboard input bugs;
Fixed AT RTC periodic interrupt - Chicago 58s / 73f / 73g  / 81 MIDI play no longer hangs with the build's own VTD driver;
Fixed mouse polling with internal mice - Amstrad and Olivetti mice now work correctly;
Triones ATAPI DMA driver now correctly reads a file at the end of a CD image with a sectors number not divisible by 4;
Compaq Portable now works with all graphics cards;
Fixed various MDSI Genius bugs;
Added segment limit checks and improved page fault checks for several CPU instructions - Memphis 15xx WINSETUP and Chicago 58s WINDISK.CPL no longer issue a GPF, and some S3 drivers that used to have glitches, now work correctly;
Further improved the 808x emulation, also fixes the noticably choppy sound when using 808x CPU's, also fixes #355;
OS/2 installer no logner locks up on splash screen on PS/2 Model 70 and 80, fixes #400.
Fixed several Amstead bugs, GEM no longer crashes on the Amstrad 1640, fixes #391.
Ported John Elliott's Amstrad fixes and improvement from PCem, and fixed the default language so it's correctly Engliish, fixes #278, fixes #389.
Fixed a minor IDE timing bug, fixes #388.
Fixed Toshiba T1000 RAM issues, fixes #379.
Fixed EGA/(S)VGA overscan border handling, fixes #378;
Got rid of the now long useless IDE channel 2 auto-removal, fixes #370;
Fixed the BIOS files used by the AMSTRAD PC1512, fixes #366;
Ported the Unicode CD image file name fix from VARCem, fixes #365;
Fixed high density floppy disks on the Xi8088, fixes #359;
Fixed some bugs in the Hercules emulation, fixes #346, fixes #358;
Fixed the SCSI hard disk mode sense pages, fixes #356;
Removed the AMI Unknown 386SX because of impossibility to identify the chipset, closes #349;
Fixed bugs in the serial mouse emulation, fixes #344;
Compiled 86Box binaries now include all the required .DLL's, fixes #341;
Made some combo boxes in the Settings dialog slightly wider, fixes #276.
This commit is contained in:
OBattler
2019-09-20 14:02:30 +02:00
parent b06296bbf6
commit 552a87ea3d
524 changed files with 129555 additions and 21862 deletions

View File

@@ -189,16 +189,16 @@
* including the later update (DS12887A) which implemented a
* "century" register to be compatible with Y2K.
*
* Version: @(#)nvr_at.c 1.0.14 2018/10/06
* Version: @(#)nvr_at.c 1.0.15 2019/03/16
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Mahod,
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2017-2019 Fred N. van Kempen.
* Copyright 2016-2019 Miran Grca.
* Copyright 2008-2019 Sarah Walker.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -232,9 +232,9 @@
#include "mem.h"
#include "nmi.h"
#include "pic.h"
#include "timer.h"
#include "pit.h"
#include "rom.h"
#include "timer.h"
#include "device.h"
#include "nvr.h"
@@ -292,8 +292,10 @@ typedef struct {
uint8_t addr;
int64_t ecount,
rtctime;
uint64_t ecount,
rtc_time;
pc_timer_t update_timer,
rtc_timer;
} local_t;
@@ -406,6 +408,8 @@ timer_update(void *priv)
local_t *local = (local_t *)nvr->data;
struct tm tm;
local->ecount = 0LL;
if (! (nvr->regs[RTC_REGB] & REGB_SET)) {
/* Get the current time from the internal clock. */
nvr_time_get(&tm);
@@ -443,27 +447,47 @@ timer_update(void *priv)
picint(1 << nvr->irq);
}
}
local->ecount = 0;
}
/* Re-calculate the timer values. */
static void
timer_recalc(nvr_t *nvr, int add)
static double
timer_nvr_period(nvr_t *nvr)
{
local_t *local = (local_t *)nvr->data;
int64_t c, nt;
double dusec = (double) TIMER_USEC;
c = 1ULL << ((nvr->regs[RTC_REGA] & REGA_RS) - 1);
nt = (int64_t)(RTCCONST * c * (1<<TIMER_SHIFT));
if (add == 2) {
local->rtctime = nt;
return;
} else if (add == 1)
local->rtctime += nt;
else if (local->rtctime > nt)
local->rtctime = nt;
switch (nvr->regs[RTC_REGA] & REGA_RS) {
case 0:
default:
return 0.0;
case 1:
case 8:
return 3906.25 * dusec;
case 2:
case 9:
return 7812.5 * dusec;
case 3:
return 122.070 * dusec;
case 4:
return 244.141 * dusec;
case 5:
return 488.281 * dusec;
case 6:
return 976.5625 * dusec;
case 7:
return 1953.125 * dusec;
case 10:
return 15625.0 * dusec;
case 11:
return 31250.0 * dusec;
case 12:
return 62500.0 * dusec;
case 13:
return 125000.0 * dusec;
case 14:
return 250000.0 * dusec;
case 15:
return 500000.0 * dusec;
}
}
@@ -473,14 +497,14 @@ timer_intr(void *priv)
nvr_t *nvr = (nvr_t *)priv;
local_t *local = (local_t *)nvr->data;
if (! (nvr->regs[RTC_REGA] & REGA_RS)) {
local->rtctime = 0x7fffffff;
if (nvr->regs[RTC_REGA] & REGA_RS) {
local->rtc_time = timer_nvr_period(nvr);
timer_advance_u64(&local->rtc_timer, (uint64_t) local->rtc_time);
} else {
local->rtc_time = 0ULL;
return;
}
/* Update our timer interval. */
timer_recalc(nvr, 1);
nvr->regs[RTC_REGC] |= REGC_PF;
if (nvr->regs[RTC_REGB] & REGB_PIE) {
nvr->regs[RTC_REGC] |= REGC_IRQF;
@@ -506,7 +530,22 @@ timer_tick(nvr_t *nvr)
rtc_tick();
/* Schedule the actual update. */
local->ecount = (int64_t)((244.0 + 1984.0) * TIMER_USEC);
local->ecount = (244ULL + 1984ULL) * TIMER_USEC;
timer_set_delay_u64(&local->update_timer, local->ecount);
}
}
static void
nvr_pie_start(nvr_t *nvr)
{
local_t *local = (local_t *)nvr->data;
local->rtc_time = 0ULL;
timer_disable(&local->rtc_timer);
if ((nvr->regs[RTC_REGA] & REGA_RS) && ((nvr->regs[RTC_REGA] & 0x70) == 0x20)) {
local->rtc_time = timer_nvr_period(nvr);
timer_set_delay_u64(&local->rtc_timer, local->rtc_time);
}
}
@@ -520,17 +559,14 @@ nvr_write(uint16_t addr, uint8_t val, void *priv)
struct tm tm;
uint8_t old;
cycles -= ISA_CYCLES(8);
sub_cycles(ISA_CYCLES(8));
if (addr & 1) {
old = nvr->regs[local->addr];
switch(local->addr) {
case RTC_REGA:
nvr->regs[RTC_REGA] = val;
if (val & REGA_RS)
timer_recalc(nvr, 1);
else
local->rtctime = 0x7fffffff;
nvr_pie_start(nvr);
break;
case RTC_REGB:
@@ -544,7 +580,7 @@ nvr_write(uint16_t addr, uint8_t val, void *priv)
case RTC_REGC: /* R/O */
case RTC_REGD: /* R/O */
break;
break;
default: /* non-RTC registers are just NVRAM */
if (nvr->regs[local->addr] != val) {
@@ -567,7 +603,7 @@ nvr_write(uint16_t addr, uint8_t val, void *priv)
} else {
local->addr = (val & (nvr->size - 1));
if (!(machines[machine].flags & MACHINE_MCA) &&
(machines[machine].flags & MACHINE_NONMI))
!(machines[machine].flags & MACHINE_NONMI))
nmi_mask = (~val & 0x80);
}
}
@@ -581,9 +617,9 @@ nvr_read(uint16_t addr, void *priv)
local_t *local = (local_t *)nvr->data;
uint8_t ret;
cycles -= ISA_CYCLES(8);
sub_cycles(ISA_CYCLES(8));
if (addr & 1) switch(local->addr) {
if (addr & 1) switch(local->addr) {
case RTC_REGA:
ret = (nvr->regs[RTC_REGA] & 0x7f) | local->stat;
break;
@@ -602,9 +638,8 @@ nvr_read(uint16_t addr, void *priv)
default:
ret = nvr->regs[local->addr];
break;
} else {
} else
ret = local->addr;
}
return(ret);
}
@@ -630,7 +665,20 @@ nvr_reset(nvr_t *nvr)
static void
nvr_start(nvr_t *nvr)
{
int i;
local_t *local = (local_t *) nvr->data;
struct tm tm;
int default_found = 0;
for (i = 0; i < nvr->size; i++) {
if (nvr->regs[i] == local->def)
default_found++;
}
if (default_found == nvr->size)
nvr->regs[0x0e] = 0xff; /* If load failed or it loaded an uninitialized NVR,
mark everything as bad. */
/* Initialize the internal and chip times. */
if (time_sync & TIME_SYNC_ENABLED) {
@@ -646,14 +694,25 @@ nvr_start(nvr_t *nvr)
/* Start the RTC. */
nvr->regs[RTC_REGA] = (REGA_RS2|REGA_RS1);
nvr->regs[RTC_REGB] = REGB_2412;
timer_recalc(nvr, 1);
}
static void
nvr_recalc(nvr_t *nvr)
nvr_at_speed_changed(void *priv)
{
timer_recalc(nvr, 0);
nvr_t *nvr = (nvr_t *) priv;
local_t *local = (local_t *) nvr->data;
timer_disable(&local->rtc_timer);
if (local->rtc_time > 0ULL)
timer_set_delay_u64(&local->rtc_timer, local->rtc_time);
timer_disable(&local->update_timer);
if (local->ecount > 0ULL)
timer_set_delay_u64(&local->update_timer, local->ecount);
timer_disable(&nvr->onesec_time);
timer_set_delay_u64(&nvr->onesec_time, (10000ULL * TIMER_USEC));
}
@@ -709,14 +768,13 @@ nvr_at_init(const device_t *info)
nvr->reset = nvr_reset;
nvr->start = nvr_start;
nvr->tick = timer_tick;
nvr->recalc = nvr_recalc;
/* Initialize the generic NVR. */
nvr_init(nvr);
/* Start the timers. */
timer_add(timer_update, &local->ecount, &local->ecount, nvr);
timer_add(timer_intr, &local->rtctime, TIMER_ALWAYS_ENABLED, nvr);
timer_add(&local->update_timer, timer_update, nvr, 0);
timer_add(&local->rtc_timer, timer_intr, nvr, 0);
/* Set up the I/O handler for this device. */
io_sethandler(0x0070, 2,
@@ -729,7 +787,14 @@ nvr_at_init(const device_t *info)
static void
nvr_at_close(void *priv)
{
nvr_t *nvr = (nvr_t *)priv;
nvr_t *nvr = (nvr_t *) priv;
local_t *local = (local_t *) nvr->data;
nvr_close();
timer_disable(&local->rtc_timer);
timer_disable(&local->update_timer);
timer_disable(&nvr->onesec_time);
if (nvr->fn != NULL)
free(nvr->fn);
@@ -746,7 +811,7 @@ const device_t at_nvr_old_device = {
DEVICE_ISA | DEVICE_AT,
0,
nvr_at_init, nvr_at_close, NULL,
NULL, NULL,
NULL, nvr_at_speed_changed,
NULL
};
@@ -755,7 +820,7 @@ const device_t at_nvr_device = {
DEVICE_ISA | DEVICE_AT,
1,
nvr_at_init, nvr_at_close, NULL,
NULL, NULL,
NULL, nvr_at_speed_changed,
NULL
};
@@ -764,7 +829,7 @@ const device_t ps_nvr_device = {
DEVICE_PS2,
2,
nvr_at_init, nvr_at_close, NULL,
NULL, NULL,
NULL, nvr_at_speed_changed,
NULL
};
@@ -773,7 +838,7 @@ const device_t amstrad_nvr_device = {
MACHINE_ISA | MACHINE_AT,
3,
nvr_at_init, nvr_at_close, NULL,
NULL, NULL,
NULL, nvr_at_speed_changed,
NULL
};
@@ -782,6 +847,6 @@ const device_t ibmat_nvr_device = {
DEVICE_ISA | DEVICE_AT,
4,
nvr_at_init, nvr_at_close, NULL,
NULL, NULL,
NULL, nvr_at_speed_changed,
NULL
};