More Sound Blaster 16+ / ViBRA 16 fixes, added optional PC speaker control via the Sound Blaster 16+ / ViBRA 16, and removed some left-over temporary code from device.c.

This commit is contained in:
OBattler
2023-10-21 06:53:11 +02:00
parent f3ca2a6dcd
commit 28e2eb3ce5
347 changed files with 250776 additions and 101 deletions

View File

@@ -197,8 +197,8 @@ low_iir(int c, int i, double NewSample)
0.93726236021404663000
};
static double y[2][2][NCoef + 1]; /* output samples */
static double x[2][2][NCoef + 1]; /* input samples */
static double y[3][2][NCoef + 1]; /* output samples */
static double x[3][2][NCoef + 1]; /* input samples */
int n;
/* shift the old samples */
@@ -232,8 +232,8 @@ low_cut_iir(int c, int i, double NewSample)
0.93726236021916731000
};
static double y[2][2][NCoef + 1]; /* output samples */
static double x[2][2][NCoef + 1]; /* input samples */
static double y[3][2][NCoef + 1]; /* output samples */
static double x[3][2][NCoef + 1]; /* input samples */
int n;
/* shift the old samples */
@@ -266,8 +266,8 @@ high_iir(int c, int i, double NewSample)
-1.36640781670578510000,
0.52352474706139873000
};
static double y[2][2][NCoef + 1]; /* output samples */
static double x[2][2][NCoef + 1]; /* input samples */
static double y[3][2][NCoef + 1]; /* output samples */
static double x[3][2][NCoef + 1]; /* input samples */
int n;
/* shift the old samples */
@@ -300,8 +300,8 @@ high_cut_iir(int c, int i, double NewSample)
-1.36640781666419950000,
0.52352474703279628000
};
static double y[2][2][NCoef + 1]; /* output samples */
static double x[2][2][NCoef + 1]; /* input samples */
static double y[3][2][NCoef + 1]; /* output samples */
static double x[3][2][NCoef + 1]; /* input samples */
int n;
/* shift the old samples */
@@ -334,8 +334,8 @@ deemph_iir(int i, double NewSample)
-1.05429146278569141337,
0.26412280202756849290
};
static double y[2][NCoef + 1]; /* output samples */
static double x[2][NCoef + 1]; /* input samples */
static double y[3][NCoef + 1]; /* output samples */
static double x[3][NCoef + 1]; /* input samples */
int n;
/* shift the old samples */
@@ -372,8 +372,8 @@ sb_iir(int c, int i, double NewSample)
0.55326988968868285000
};
static double y[2][2][NCoef + 1]; /* output samples */
static double x[2][2][NCoef + 1]; /* input samples */
static double y[3][2][NCoef + 1]; /* output samples */
static double x[3][2][NCoef + 1]; /* input samples */
int n;
/* shift the old samples */
@@ -395,13 +395,13 @@ sb_iir(int c, int i, double NewSample)
#define NCoef 1
#define SB16_NCoef 51
extern double low_fir_sb16_coef[2][SB16_NCoef];
extern double low_fir_sb16_coef[3][SB16_NCoef];
static inline double
low_fir_sb16(int c, int i, double NewSample)
{
static double x[2][2][SB16_NCoef + 1]; // input samples
static int pos[2] = { 0, 0 };
static double x[3][2][SB16_NCoef + 1]; // input samples
static int pos[3] = { 0, 0 };
double out = 0.0;
int n;

View File

@@ -0,0 +1,150 @@
/*
* 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.
*
* Definitions for the NS8250/16450/16550/16650/16750/16850/16950
* UART emulation.
*
*
*
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2020 Sarah Walker.
* Copyright 2016-2020 Miran Grca.
* Copyright 2017-2020 Fred N. van Kempen.
*/
#ifndef EMU_SERIAL_H
#define EMU_SERIAL_H
#define SERIAL_8250 0
#define SERIAL_8250_PCJR 1
#define SERIAL_16450 2
#define SERIAL_16550 3
#define SERIAL_16650 4
#define SERIAL_16750 5
#define SERIAL_16850 6
#define SERIAL_16950 7
#define SERIAL_FIFO_SIZE 16
/* Default settings for the standard ports. */
#define COM1_ADDR 0x03f8
#define COM1_IRQ 4
#define COM2_ADDR 0x02f8
#define COM2_IRQ 3
#define COM3_ADDR 0x03e8
#define COM3_IRQ 4
#define COM4_ADDR 0x02e8
#define COM4_IRQ 3
struct serial_device_s;
struct serial_s;
typedef struct serial_s {
uint8_t lsr;
uint8_t thr;
uint8_t mctrl;
uint8_t rcr;
uint8_t iir;
uint8_t ier;
uint8_t lcr;
uint8_t msr;
uint8_t dat;
uint8_t int_status;
uint8_t scratch;
uint8_t fcr;
uint8_t irq;
uint8_t type;
uint8_t inst;
uint8_t transmit_enabled;
uint8_t fifo_enabled;
uint8_t rcvr_fifo_len;
uint8_t bits;
uint8_t data_bits;
uint8_t baud_cycles;
uint8_t rcvr_fifo_full;
uint8_t txsr;
uint8_t out;
uint8_t msr_set;
uint8_t pad;
uint8_t irq_state;
uint8_t pad0;
uint16_t dlab;
uint16_t base_address;
uint16_t out_new;
uint16_t pad1;
uint8_t xmit_fifo_pos;
uint8_t xmit_fifo_end;
uint8_t xmit_fifo[SERIAL_FIFO_SIZE];
void *rcvr_fifo;
pc_timer_t transmit_timer;
pc_timer_t timeout_timer;
pc_timer_t receive_timer;
double clock_src;
double transmit_period;
struct serial_device_s *sd;
} serial_t;
typedef struct serial_device_s {
void (*rcr_callback)(struct serial_s *serial, void *p);
void (*dev_write)(struct serial_s *serial, void *p, uint8_t data);
void (*lcr_callback)(struct serial_s *serial, void *p, uint8_t lcr);
void (*transmit_period_callback)(struct serial_s *serial, void *p, double transmit_period);
void *priv;
serial_t *serial;
} serial_device_t;
typedef struct serial_port_s {
uint8_t enabled;
} serial_port_t;
extern serial_port_t com_ports[SERIAL_MAX];
extern serial_t *serial_attach_ex(int port,
void (*rcr_callback)(struct serial_s *serial, void *p),
void (*dev_write)(struct serial_s *serial, void *p, uint8_t data),
void (*transmit_period_callback)(struct serial_s *serial, void *p, double transmit_period),
void (*lcr_callback)(struct serial_s *serial, void *p, uint8_t data_bits),
void *priv);
#define serial_attach(port, rcr_callback, dev_write, priv) \
serial_attach_ex(port, rcr_callback, dev_write, NULL, NULL, priv);
extern void serial_remove(serial_t *dev);
extern void serial_set_type(serial_t *dev, int type);
extern void serial_setup(serial_t *dev, uint16_t addr, uint8_t irq);
extern void serial_clear_fifo(serial_t *dev);
extern void serial_write_fifo(serial_t *dev, uint8_t dat);
extern void serial_set_next_inst(int ni);
extern void serial_standalone_init(void);
extern void serial_set_clock_src(serial_t *dev, double clock_src);
extern void serial_reset_port(serial_t *dev);
extern void serial_device_timeout(void *priv);
extern void serial_set_cts(serial_t *dev, uint8_t enabled);
extern void serial_set_dsr(serial_t *dev, uint8_t enabled);
extern void serial_set_dcd(serial_t *dev, uint8_t enabled);
extern const device_t ns8250_device;
extern const device_t ns8250_pcjr_device;
extern const device_t ns16450_device;
extern const device_t ns16550_device;
extern const device_t ns16650_device;
extern const device_t ns16750_device;
extern const device_t ns16850_device;
extern const device_t ns16950_device;
#endif /*EMU_SERIAL_H*/

View File

@@ -144,6 +144,7 @@ typedef struct sb_t {
void *gameport;
int pos;
int pnp;
uint8_t pos_regs[8];
uint8_t pnp_rom[512];

View File

@@ -52,9 +52,16 @@ extern int sound_card_current[SOUND_CARD_MAX];
extern void sound_add_handler(void (*get_buffer)(int32_t *buffer,
int len, void *priv),
void *priv);
extern void sound_set_cd_audio_filter(void (*filter)(int channel,
double *buffer, void *priv),
void *priv);
extern void sound_set_pc_speaker_filter(void (*filter)(int channel,
double *buffer, void *priv),
void *priv);
extern void (*filter_pc_speaker)(int channel, double *buffer, void *priv);
extern void *filter_pc_speaker_p;
extern int sound_card_available(int card);
#ifdef EMU_DEVICE_H

View File

@@ -0,0 +1,194 @@
#ifndef _TIMER_H_
#define _TIMER_H_
#include "cpu.h"
/* Maximum period, currently 1 second. */
#define MAX_USEC64 1000000ULL
#define MAX_USEC 1000000.0
#define TIMER_PROCESS 4
#define TIMER_SPLIT 2
#define TIMER_ENABLED 1
#pragma pack(push, 1)
typedef struct ts_struct_t
{
uint32_t frac;
uint32_t integer;
} ts_struct_t;
#pragma pack(pop)
typedef union ts_t {
uint64_t ts64;
ts_struct_t ts32;
} ts_t;
/*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.
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; /* The flags are defined above. */
int pad;
double period; /* This is used for large period timers to count
the microseconds and split the period. */
void (*callback)(void *priv);
void *priv;
struct pc_timer_t *prev;
struct pc_timer_t *next;
} pc_timer_t;
#ifdef __cplusplus
extern "C" {
#endif
/*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 *priv), void *priv, int start_timer);
/*1us in 32:32 format*/
extern uint64_t TIMER_USEC;
/*True if timer a expires before timer b*/
#define TIMER_LESS_THAN(a, b) ((int64_t) ((a)->ts.ts64 - (b)->ts.ts64) <= 0)
/*True if timer a expires before 32 bit integer timestamp b*/
#define TIMER_LESS_THAN_VAL(a, b) ((int32_t) ((a)->ts.ts32.integer - (b)) <= 0)
/*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)
{
timer->ts.ts64 += delay;
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)
{
timer->ts.ts64 = 0ULL;
timer->ts.ts32.integer = tsc;
timer->ts.ts64 += delay;
timer_enable(timer);
}
/*True if timer currently enabled*/
static __inline int
timer_is_enabled(pc_timer_t *timer)
{
return !!(timer->flags & TIMER_ENABLED);
}
/*True if timer currently on*/
static __inline int
timer_is_on(pc_timer_t *timer)
{
// return ((timer->flags & TIMER_SPLIT) || (timer->flags & TIMER_ENABLED));
return !!(timer->flags & TIMER_ENABLED);
}
/*Return integer timestamp of timer*/
static __inline uint32_t
timer_get_ts_int(pc_timer_t *timer)
{
return timer->ts.ts32.integer;
}
/*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) {
remaining = (int64_t) (timer->ts.ts64 - (uint64_t) (tsc << 32));
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) {
remaining = (int64_t) (timer->ts.ts64 - (uint64_t) (tsc << 32));
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 *priv))
{
timer->callback = callback;
}
/*Set timer private data*/
static __inline void
timer_set_p(pc_timer_t *timer, void *priv)
{
timer->priv = priv;
}
/* The API for big timer periods starts here. */
extern void timer_stop(pc_timer_t *timer);
extern void timer_on_auto(pc_timer_t *timer, double period);
#ifdef __cplusplus
}
#endif
#endif /*_TIMER_H_*/

View File

@@ -0,0 +1,67 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
#ifndef VIDEO_MDA_H
#define VIDEO_MDA_H
typedef struct mda_t {
mem_mapping_t mapping;
uint8_t crtc[32];
int crtcreg;
uint8_t ctrl;
uint8_t stat;
uint64_t dispontime;
uint64_t dispofftime;
pc_timer_t timer;
pc_timer_t dot_timer;
int firstline;
int lastline;
int linepos;
int displine;
int vc;
int sc;
uint16_t ma;
uint16_t maback;
int con;
int coff;
int cursoron;
int dispon;
int blink;
int vsynctime;
int vadj;
int monitor_index;
int prev_monitor_index;
uint8_t *vram;
} mda_t;
#define VIDEO_MONITOR_PROLOGUE() \
{ \
mda->prev_monitor_index = monitor_index_global; \
monitor_index_global = mda->monitor_index; \
}
#define VIDEO_MONITOR_EPILOGUE() \
{ \
monitor_index_global = mda->prev_monitor_index; \
}
void mda_init(mda_t *mda);
void mda_setcol(int chr, int blink, int fg, uint8_t cga_ink);
void mda_out(uint16_t addr, uint8_t val, void *priv);
uint8_t mda_in(uint16_t addr, void *priv);
void mda_write(uint32_t addr, uint8_t val, void *priv);
uint8_t mda_read(uint32_t addr, void *priv);
void mda_recalctimings(mda_t *mda);
void mda_poll(void *priv);
#ifdef EMU_DEVICE_H
extern const device_t mda_device;
#endif
#endif /*VIDEO_MDA_H*/