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

@@ -1,57 +1,228 @@
#ifndef _TIMER_H_
#define _TIMER_H_
#include "cpu/cpu.h"
extern int64_t timer_start;
/* Maximum period, currently 1 second. */
#define MAX_USEC64 1000000ULL
#define MAX_USEC 1000000.0
#define timer_start_period(cycles) \
timer_start = cycles;
#define TIMER_SPLIT 2
#define TIMER_ENABLED 1
#define timer_end_period(cycles) \
do \
{ \
int64_t diff = timer_start - (cycles); \
timer_count -= diff; \
timer_start = cycles; \
if (timer_count <= 0) \
{ \
timer_process(); \
timer_update_outstanding(); \
} \
} while (0)
#define timer_clock() \
do \
{ \
int64_t diff; \
if (AT) \
{ \
diff = timer_start - (cycles << TIMER_SHIFT); \
timer_start = cycles << TIMER_SHIFT; \
} \
else \
{ \
diff = timer_start - (cycles * xt_cpu_multi); \
timer_start = cycles * xt_cpu_multi; \
} \
timer_count -= diff; \
timer_process(); \
timer_update_outstanding(); \
} while (0)
#pragma pack(push,1)
typedef struct
{
uint32_t frac;
uint32_t integer;
} ts_struct_t;
#pragma pack(pop)
extern void timer_process(void);
extern void timer_update_outstanding(void);
extern void timer_reset(void);
extern int64_t timer_add(void (*callback)(void *priv), int64_t *count, int64_t *enable, void *priv);
extern void timer_set_callback(int64_t timer, void (*callback)(void *priv));
typedef union
{
uint64_t ts64;
ts_struct_t ts32;
} ts_t;
#define TIMER_ALWAYS_ENABLED &timer_one
extern int64_t timer_count;
extern int64_t timer_one;
/*Timers are based on the CPU Time Stamp Counter. Timer timestamps are in a
32:32 fixed point format, with the integer part compared against the TSC. The
fractional part is used when advancing the timestamp to ensure a more accurate
period.
As the timer only stores 32 bits of integer timestamp, and the TSC is 64 bits,
the timer period can only be at most 0x7fffffff CPU cycles. To allow room for
(optimistic) CPU frequency growth, timer period must be at most 1 second.
#define TIMER_SHIFT 6
When a timer callback is called, the timer has been disabled. If the timer is
to repeat, the callback must call timer_advance_u64(). This is a change from
the old timer API.*/
typedef struct pc_timer_t
{
#ifdef USE_PCEM_TIMER
uint32_t ts_integer;
uint32_t ts_frac;
#else
ts_t ts;
#endif
int flags, pad; /* The flags are defined above. */
double period; /* This is used for large period timers to count
the microseconds and split the period. */
extern int64_t TIMER_USEC;
void (*callback)(void *p);
void *p;
struct pc_timer_t *prev, *next;
} pc_timer_t;
/*Timestamp of nearest enabled timer. CPU emulation must call timer_process()
when TSC matches or exceeds this.*/
extern uint32_t timer_target;
/*Enable timer, without updating timestamp*/
extern void timer_enable(pc_timer_t *timer);
/*Disable timer*/
extern void timer_disable(pc_timer_t *timer);
/*Process any pending timers*/
extern void timer_process(void);
/*Reset timer system*/
extern void timer_close(void);
extern void timer_init(void);
/*Add new timer. If start_timer is set, timer will be enabled with a zero
timestamp - this is useful for permanently enabled timers*/
extern void timer_add(pc_timer_t *timer, void (*callback)(void *p), void *p, int start_timer);
/*1us in 32:32 format*/
extern uint64_t TIMER_USEC;
/*True if timer a expires before timer b*/
#if 0
#define TIMER_LESS_THAN(a, b) ((int32_t)((a)->ts_integer - (b)->ts_integer) <= 0)
#else
#define TIMER_LESS_THAN(a, b) ((int64_t)((a)->ts.ts64 - (b)->ts.ts64) <= 0)
#endif
/*True if timer a expires before 32 bit integer timestamp b*/
#if 0
#define TIMER_LESS_THAN_VAL(a, b) ((int32_t)((a)->ts_integer - (b)) <= 0)
#else
#define TIMER_LESS_THAN_VAL(a, b) ((int32_t)((a)->ts.ts32.integer - (b)) <= 0)
#endif
/*True if 32 bit integer timestamp a expires before 32 bit integer timestamp b*/
#define TIMER_VAL_LESS_THAN_VAL(a, b) ((int32_t)((a) - (b)) <= 0)
/*Advance timer by delay, specified in 32:32 format. This should be used to
resume a recurring timer in a callback routine*/
static __inline void
timer_advance_u64(pc_timer_t *timer, uint64_t delay)
{
#if 0
uint32_t int_delay = delay >> 32;
uint32_t frac_delay = delay & 0xffffffff;
if ((frac_delay + timer->ts_frac) < frac_delay)
timer->ts_integer++;
timer->ts_frac += frac_delay;
timer->ts_integer += int_delay;
#else
timer->ts.ts64 += delay;
#endif
timer_enable(timer);
}
/*Set a timer to the given delay, specified in 32:32 format. This should be used
when starting a timer*/
static __inline void
timer_set_delay_u64(pc_timer_t *timer, uint64_t delay)
{
#if 0
uint32_t int_delay = delay >> 32;
uint32_t frac_delay = delay & 0xffffffff;
timer->ts_frac = frac_delay;
timer->ts_integer = int_delay + (uint32_t)tsc;
#else
timer->ts.ts64 = 0ULL;
timer->ts.ts32.integer = tsc;
timer->ts.ts64 += delay;
#endif
timer_enable(timer);
}
/*True if timer currently enabled*/
static __inline int
timer_is_enabled(pc_timer_t *timer)
{
return !!(timer->flags & TIMER_ENABLED);
}
/*Return integer timestamp of timer*/
static __inline uint32_t
timer_get_ts_int(pc_timer_t *timer)
{
#if 0
return timer->ts_integer;
#else
return timer->ts.ts32.integer;
#endif
}
/*Return remaining time before timer expires, in us. If the timer has already
expired then return 0*/
static __inline uint32_t
timer_get_remaining_us(pc_timer_t *timer)
{
int64_t remaining;
if (timer->flags & TIMER_ENABLED) {
#if 0
remaining = (((uint64_t)timer->ts_integer << 32) | timer->ts_frac) - (tsc << 32);
#else
remaining = (int64_t) (timer->ts.ts64 - (uint64_t)(tsc << 32));
#endif
if (remaining < 0)
return 0;
return remaining / TIMER_USEC;
}
return 0;
}
/*Return remaining time before timer expires, in 32:32 timestamp format. If the
timer has already expired then return 0*/
static __inline uint64_t
timer_get_remaining_u64(pc_timer_t *timer)
{
int64_t remaining;
if (timer->flags & TIMER_ENABLED) {
#if 0
remaining = (((uint64_t)timer->ts_integer << 32) | timer->ts_frac) - (tsc << 32);
#else
remaining = (int64_t) (timer->ts.ts64 - (uint64_t)(tsc << 32));
#endif
if (remaining < 0)
return 0;
return remaining;
}
return 0;
}
/*Set timer callback function*/
static __inline void
timer_set_callback(pc_timer_t *timer, void (*callback)(void *p))
{
timer->callback = callback;
}
/*Set timer private data*/
static __inline void
timer_set_p(pc_timer_t *timer, void *p)
{
timer->p = p;
}
/* The API for big timer periods starts here. */
extern void timer_stop(pc_timer_t *timer);
extern void timer_advance_ex(pc_timer_t *timer, int start);
extern void timer_on(pc_timer_t *timer, double period, int start);
extern void timer_on_auto(pc_timer_t *timer, double period);
#endif /*_TIMER_H_*/