mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 09:58:19 -07:00
Merge branch 'master' into pc98x1
This commit is contained in:
@@ -32,6 +32,7 @@ It is also recommended to use a manager application with 86Box for easier handli
|
||||
|
||||
* [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only)
|
||||
* [86Box Manager X](https://github.com/RetBox/86BoxManagerX) by [xafero](https://github.com/xafero) (Cross platform Port of 86Box Manager using Avalonia)
|
||||
* [Avalonia 86](https://github.com/notBald/Avalonia86) by [notBald](https://github.com/notBald) (Windows and Linux)
|
||||
* [sl86](https://github.com/DDXofficial/sl86) by [DDX](https://github.com/DDXofficial) (Command-line 86Box machine manager written in Python)
|
||||
* [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by [Dungeonseeker](https://github.com/Dungeonseeker/) (Linux focused, should work on Windows though untested)
|
||||
* [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOS only)
|
||||
|
||||
45
src/86box.c
45
src/86box.c
@@ -103,6 +103,7 @@
|
||||
#include <86box/machine_status.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/nv/vid_nv_rivatimer.h>
|
||||
|
||||
// Disable c99-designator to avoid the warnings about int ng
|
||||
#ifdef __clang__
|
||||
@@ -252,12 +253,36 @@ static volatile atomic_int do_pause_ack = 0;
|
||||
static volatile atomic_int pause_ack = 0;
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
static char buff[1024];
|
||||
static int seen = 0;
|
||||
|
||||
#define LOG_SIZE_BUFFER 1024 /* Log size buffer */
|
||||
|
||||
static char buff[LOG_SIZE_BUFFER];
|
||||
|
||||
static int seen = 0;
|
||||
|
||||
static int suppr_seen = 1;
|
||||
|
||||
// Functions only used in this translation unit
|
||||
void pclog_ensure_stdlog_open(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
Ensures STDLOG is open for pclog_ex and pclog_ex_cyclic
|
||||
*/
|
||||
void pclog_ensure_stdlog_open(void)
|
||||
{
|
||||
#ifndef RELEASE_BUILD
|
||||
if (stdlog == NULL) {
|
||||
if (log_path[0] != '\0') {
|
||||
stdlog = plat_fopen(log_path, "w");
|
||||
if (stdlog == NULL)
|
||||
stdlog = stdout;
|
||||
} else
|
||||
stdlog = stdout;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Log something to the logfile or stdout.
|
||||
*
|
||||
@@ -269,19 +294,12 @@ void
|
||||
pclog_ex(const char *fmt, va_list ap)
|
||||
{
|
||||
#ifndef RELEASE_BUILD
|
||||
char temp[1024];
|
||||
char temp[LOG_SIZE_BUFFER];
|
||||
|
||||
if (strcmp(fmt, "") == 0)
|
||||
return;
|
||||
|
||||
if (stdlog == NULL) {
|
||||
if (log_path[0] != '\0') {
|
||||
stdlog = plat_fopen(log_path, "w");
|
||||
if (stdlog == NULL)
|
||||
stdlog = stdout;
|
||||
} else
|
||||
stdlog = stdout;
|
||||
}
|
||||
pclog_ensure_stdlog_open();
|
||||
|
||||
vsprintf(temp, fmt, ap);
|
||||
if (suppr_seen && !strcmp(buff, temp))
|
||||
@@ -298,6 +316,8 @@ pclog_ex(const char *fmt, va_list ap)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
pclog_toggle_suppr(void)
|
||||
{
|
||||
@@ -1427,6 +1447,9 @@ pc_run(void)
|
||||
pc_reset_hard_init();
|
||||
}
|
||||
|
||||
/* Update the guest-CPU independent timer for devices with independent clock speed */
|
||||
rivatimer_update_all();
|
||||
|
||||
/* Run a block of code. */
|
||||
startblit();
|
||||
cpu_exec((int32_t) cpu_s->rspeed / 100);
|
||||
|
||||
@@ -156,9 +156,9 @@ mitsumi_cdrom_is_ready(const cdrom_t *dev)
|
||||
static void
|
||||
mitsumi_cdrom_reset(mcd_t *dev)
|
||||
{
|
||||
cdrom_t cdrom;
|
||||
|
||||
dev->stat = mitsumi_cdrom_is_ready(&cdrom) ? (STAT_READY | STAT_CHANGE) : 0;
|
||||
cdrom_t *cdrom = calloc(1, sizeof(cdrom_t));
|
||||
|
||||
dev->stat = mitsumi_cdrom_is_ready(cdrom) ? (STAT_READY | STAT_CHANGE) : 0;
|
||||
dev->cmdrd_count = 0;
|
||||
dev->cmdbuf_count = 0;
|
||||
dev->buf_count = 0;
|
||||
@@ -176,12 +176,12 @@ mitsumi_cdrom_reset(mcd_t *dev)
|
||||
static int
|
||||
mitsumi_cdrom_read_sector(mcd_t *dev, int first)
|
||||
{
|
||||
cdrom_t cdrom;
|
||||
cdrom_t *cdrom = calloc(1, sizeof(cdrom_t));
|
||||
uint8_t status;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (dev->drvmode == DRV_MODE_CDDA) {
|
||||
status = cdrom_mitsumi_audio_play(&cdrom, dev->readmsf, dev->readcount);
|
||||
status = cdrom_mitsumi_audio_play(cdrom, dev->readmsf, dev->readcount);
|
||||
if (status == 1)
|
||||
return status;
|
||||
else
|
||||
@@ -195,15 +195,15 @@ mitsumi_cdrom_read_sector(mcd_t *dev, int first)
|
||||
dev->data = 0;
|
||||
return 0;
|
||||
}
|
||||
cdrom_stop(&cdrom);
|
||||
ret = cdrom_readsector_raw(&cdrom, dev->buf, cdrom.seek_pos, 0, 2, 0x10, (int *) &dev->readcount, 0);
|
||||
cdrom_stop(cdrom);
|
||||
ret = cdrom_readsector_raw(cdrom, dev->buf, cdrom->seek_pos, 0, 2, 0x10, (int *) &dev->readcount, 0);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
if (dev->mode & 0x40) {
|
||||
dev->buf[12] = CD_BCD((dev->readmsf >> 16) & 0xff);
|
||||
dev->buf[13] = CD_BCD((dev->readmsf >> 8) & 0xff);
|
||||
}
|
||||
dev->readmsf = cdrom_lba_to_msf_accurate(cdrom.seek_pos + 1);
|
||||
dev->readmsf = cdrom_lba_to_msf_accurate(cdrom->seek_pos + 1);
|
||||
dev->buf_count = dev->dmalen + 1;
|
||||
dev->buf_idx = 0;
|
||||
dev->data = 1;
|
||||
@@ -224,7 +224,7 @@ static uint8_t
|
||||
mitsumi_cdrom_in(uint16_t port, void *priv)
|
||||
{
|
||||
mcd_t *dev = (mcd_t *) priv;
|
||||
uint8_t ret;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
pclog("Mitsumi CD-ROM IN=%03x\n", port);
|
||||
switch (port & 1) {
|
||||
@@ -259,14 +259,14 @@ mitsumi_cdrom_in(uint16_t port, void *priv)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
mcd_t *dev = (mcd_t *) priv;
|
||||
cdrom_t cdrom;
|
||||
cdrom_t *cdrom = calloc(1, sizeof(cdrom_t));
|
||||
|
||||
pclog("Mitsumi CD-ROM OUT=%03x, val=%02x\n", port, val);
|
||||
switch (port & 1) {
|
||||
@@ -348,19 +348,19 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
}
|
||||
if (!dev->cmdrd_count)
|
||||
dev->stat = mitsumi_cdrom_is_ready(&cdrom) ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0;
|
||||
dev->stat = mitsumi_cdrom_is_ready(cdrom) ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0;
|
||||
return;
|
||||
}
|
||||
dev->cmd = val;
|
||||
dev->cmdbuf_idx = 0;
|
||||
dev->cmdrd_count = 0;
|
||||
dev->cmdbuf_count = 1;
|
||||
dev->cmdbuf[0] = mitsumi_cdrom_is_ready(&cdrom) ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0;
|
||||
dev->cmdbuf[0] = mitsumi_cdrom_is_ready(cdrom) ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0;
|
||||
dev->data = 0;
|
||||
switch (val) {
|
||||
case CMD_GET_INFO:
|
||||
if (mitsumi_cdrom_is_ready(&cdrom)) {
|
||||
cdrom_get_track_buffer(&cdrom, &(dev->cmdbuf[1]));
|
||||
if (mitsumi_cdrom_is_ready(cdrom)) {
|
||||
cdrom_get_track_buffer(cdrom, &(dev->cmdbuf[1]));
|
||||
dev->cmdbuf_count = 10;
|
||||
dev->readcount = 0;
|
||||
} else {
|
||||
@@ -369,8 +369,8 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
}
|
||||
break;
|
||||
case CMD_GET_Q:
|
||||
if (mitsumi_cdrom_is_ready(&cdrom)) {
|
||||
cdrom_get_q(&cdrom, &(dev->cmdbuf[1]), &dev->cur_toc_track, dev->mode & MODE_GET_TOC);
|
||||
if (mitsumi_cdrom_is_ready(cdrom)) {
|
||||
cdrom_get_q(cdrom, &(dev->cmdbuf[1]), &dev->cur_toc_track, dev->mode & MODE_GET_TOC);
|
||||
dev->cmdbuf_count = 11;
|
||||
dev->readcount = 0;
|
||||
} else {
|
||||
@@ -386,7 +386,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
case CMD_STOPCDDA:
|
||||
case CMD_STOP:
|
||||
cdrom_stop(&cdrom);
|
||||
cdrom_stop(cdrom);
|
||||
dev->drvmode = DRV_MODE_STOP;
|
||||
dev->cur_toc_track = 0;
|
||||
break;
|
||||
@@ -395,7 +395,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
case CMD_READ1X:
|
||||
case CMD_READ2X:
|
||||
if (mitsumi_cdrom_is_ready(&cdrom)) {
|
||||
if (mitsumi_cdrom_is_ready(cdrom)) {
|
||||
dev->readcount = 0;
|
||||
dev->drvmode = (val == CMD_READ1X) ? DRV_MODE_CDDA : DRV_MODE_READ;
|
||||
dev->cmdrd_count = 6;
|
||||
@@ -411,7 +411,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
dev->cmdbuf_count = 3;
|
||||
break;
|
||||
case CMD_EJECT:
|
||||
cdrom_stop(&cdrom);
|
||||
cdrom_stop(cdrom);
|
||||
cdrom_eject(0);
|
||||
dev->readcount = 0;
|
||||
break;
|
||||
@@ -440,10 +440,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
static void *
|
||||
mitsumi_cdrom_init(UNUSED(const device_t *info))
|
||||
{
|
||||
mcd_t *dev;
|
||||
|
||||
dev = malloc(sizeof(mcd_t));
|
||||
memset(dev, 0x00, sizeof(mcd_t));
|
||||
mcd_t *dev = calloc(1, sizeof(mcd_t));
|
||||
|
||||
dev->irq = MCD_DEFAULT_IRQ;
|
||||
dev->dma = MCD_DEFAULT_DMA;
|
||||
|
||||
@@ -225,12 +225,8 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
ali1531_shadow_recalc(val, dev);
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x56:
|
||||
case 0x50 ... 0x52:
|
||||
case 0x54 ... 0x56:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
@@ -247,8 +243,7 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
dev->pci_conf[addr] = val & 0x86;
|
||||
break;
|
||||
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x59 ... 0x5a:
|
||||
case 0x5c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
@@ -270,8 +265,7 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
spd_write_drbs_interleaved(dev->pci_conf, 0x60, 0x6f, 1);
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
case 0x71:
|
||||
case 0x70 ... 0x71:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
@@ -283,8 +277,7 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
dev->pci_conf[addr] = val & 0x2b;
|
||||
break;
|
||||
|
||||
case 0x76:
|
||||
case 0x77:
|
||||
case 0x76 ... 0x77:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
|
||||
#define EMS_MAXPAGE 4
|
||||
#define EMS_PGSIZE 16384
|
||||
#define EMS_PGMASK 16383
|
||||
|
||||
#define REG_MASK 0x0f
|
||||
|
||||
/* CS8221 82C211 controller registers. */
|
||||
#define REG_RA0 0x60 /* PROCCLK selector */
|
||||
@@ -194,37 +197,47 @@
|
||||
#define RB10_P0EXT 0xc0 /* page 0 extension */
|
||||
#define RB10_P0EXT_SH 6
|
||||
|
||||
#define REG_RB11 0x6f /* Miscellaneous */
|
||||
#define RB11_MASK 0xe6 /* 111R R11R */
|
||||
#define RB11_GA20 0x02 /* gate for A20 */
|
||||
#define RB11_RASTMO 0x04 /* enable RAS timeout counter */
|
||||
#define RB11_EMSLEN 0xe0 /* EMS memory chunk size */
|
||||
#define RB11_EMSLEN_SH 5
|
||||
#define REG_RB12 0x6f /* Miscellaneous */
|
||||
#define RB12_MASK 0xe6 /* 111R R11R */
|
||||
#define RB12_GA20 0x02 /* gate for A20 */
|
||||
#define RB12_RASTMO 0x04 /* enable RAS timeout counter */
|
||||
#define RB12_EMSLEN 0xe0 /* EMS memory chunk size */
|
||||
#define RB12_EMSLEN_SH 5
|
||||
|
||||
typedef struct emspage_t {
|
||||
int8_t enabled; /* 1=ENABLED */
|
||||
#define RAM_FLAG_EMS 0x08
|
||||
#define RAM_FLAG_ROMCS 0x04
|
||||
#define RAM_FLAG_SHREAD 0x02
|
||||
#define RAM_FLAG_SHWRITE 0x01
|
||||
#define RAM_FMASK_EMS 0x08
|
||||
#define RAM_FMASK_SHADOW 0x07
|
||||
|
||||
typedef struct ram_page_t {
|
||||
int8_t enabled; /* 1=ENABLED */
|
||||
char pad;
|
||||
uint16_t page; /* selected page in EMS block */
|
||||
uint32_t start; /* start of EMS in RAM */
|
||||
uint8_t *addr; /* start addr in EMS RAM */
|
||||
mem_mapping_t mapping; /* mapping entry for page */
|
||||
} emspage_t;
|
||||
uint32_t phys_base;
|
||||
uint32_t virt_base;
|
||||
mem_mapping_t mapping; /* mapping entry for page */
|
||||
} ram_page_t;
|
||||
|
||||
typedef struct neat_t {
|
||||
uint8_t regs[128]; /* all the CS8221 registers */
|
||||
uint8_t indx; /* programmed index into registers */
|
||||
uint8_t ram_flags[32];
|
||||
uint8_t regs[128]; /* all the CS8221 registers */
|
||||
uint8_t indx; /* programmed index into registers */
|
||||
|
||||
char pad;
|
||||
char pad;
|
||||
|
||||
uint16_t ems_base; /* configured base address */
|
||||
uint16_t ems_oldbase;
|
||||
uint32_t ems_frame; /* configured frame address */
|
||||
uint32_t ems_oldframe;
|
||||
uint16_t ems_size; /* EMS size in KB */
|
||||
uint16_t ems_pages; /* EMS size in pages */
|
||||
emspage_t ems[EMS_MAXPAGE]; /* EMS page registers */
|
||||
uint16_t ems_base; /* configured base address */
|
||||
uint32_t ems_frame; /* configured frame address */
|
||||
uint16_t ems_size; /* EMS size in KB */
|
||||
uint16_t ems_pages; /* EMS size in pages */
|
||||
|
||||
ram_page_t ems[EMS_MAXPAGE]; /* EMS page registers */
|
||||
ram_page_t shadow[32]; /* Shadow RAM pages */
|
||||
} neat_t;
|
||||
|
||||
static uint8_t defaults[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00,
|
||||
0x00, 0x00, 0xa0, 0x63, 0x10, 0x00, 0x00, 0x12 };
|
||||
|
||||
#ifdef ENABLE_NEAT_LOG
|
||||
int neat_do_log = ENABLE_NEAT_LOG;
|
||||
|
||||
@@ -247,11 +260,11 @@ neat_log(const char *fmt, ...)
|
||||
static uint8_t
|
||||
ems_readb(uint32_t addr, void *priv)
|
||||
{
|
||||
neat_t *dev = (neat_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
/* Grab the data. */
|
||||
ret = *(uint8_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff));
|
||||
ret = *(uint8_t *) &(ram[addr - dev->virt_base + dev->phys_base]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -260,11 +273,11 @@ ems_readb(uint32_t addr, void *priv)
|
||||
static uint16_t
|
||||
ems_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
neat_t *dev = (neat_t *) priv;
|
||||
uint16_t ret = 0xffff;
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
/* Grab the data. */
|
||||
ret = *(uint16_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff));
|
||||
ret = *(uint16_t *) &(ram[addr - dev->virt_base + dev->phys_base]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -273,40 +286,113 @@ ems_readw(uint32_t addr, void *priv)
|
||||
static void
|
||||
ems_writeb(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
neat_t *dev = (neat_t *) priv;
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
|
||||
/* Write the data. */
|
||||
*(uint8_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff)) = val;
|
||||
*(uint8_t *) &(ram[addr - dev->virt_base + dev->phys_base]) = val;
|
||||
}
|
||||
|
||||
/* Write one word to paged RAM. */
|
||||
static void
|
||||
ems_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
neat_t *dev = (neat_t *) priv;
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
|
||||
/* Write the data. */
|
||||
*(uint16_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff)) = val;
|
||||
*(uint16_t *) &(ram[addr - dev->virt_base + dev->phys_base]) = val;
|
||||
}
|
||||
|
||||
static void
|
||||
neat_mem_update_state(neat_t *dev, uint32_t addr, uint32_t size, uint8_t new_flags, uint8_t mask)
|
||||
{
|
||||
if ((addr >= 0x00080000) && (addr < 0x00100000) &&
|
||||
((new_flags ^ dev->ram_flags[(addr - 0x00080000) / EMS_PGSIZE]) & mask)) {
|
||||
dev->ram_flags[(addr - 0x00080000) / EMS_PGSIZE] &= ~mask;
|
||||
dev->ram_flags[(addr - 0x00080000) / EMS_PGSIZE] |= new_flags;
|
||||
|
||||
new_flags = dev->ram_flags[(addr - 0x00080000) / EMS_PGSIZE];
|
||||
|
||||
neat_log("neat_mem_update_state(): %08X-%08X: %02X\n", addr, addr + size - 1, new_flags);
|
||||
|
||||
if (new_flags & RAM_FLAG_EMS)
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
else if (new_flags & RAM_FLAG_ROMCS)
|
||||
mem_set_mem_state(addr, size, MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
else switch (new_flags & (RAM_FLAG_SHREAD | RAM_FLAG_SHWRITE)) {
|
||||
case 0:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
shadow_recalc(neat_t *dev)
|
||||
{
|
||||
for (uint8_t i = 8; i < 32; i++) {
|
||||
int romcs = 0;
|
||||
int write = 1;
|
||||
int shadow_reg = REG_RB3 + ((i - 8) >> 3);
|
||||
int shadow_bit = i & 7;
|
||||
int ram_flags;
|
||||
int read;
|
||||
|
||||
if (i > 16) {
|
||||
int rb1_romcs_bit = 7 - (i >> 2);
|
||||
int rb1_write_bit = rb1_romcs_bit + 4;
|
||||
|
||||
romcs = !(dev->regs[REG_RB1] & (1 << rb1_romcs_bit));
|
||||
write = !(dev->regs[REG_RB1] & (1 << rb1_write_bit));
|
||||
} else if (i <= 8)
|
||||
shadow_bit ^= 4;
|
||||
|
||||
read = dev->regs[shadow_reg] & (1 << shadow_bit);
|
||||
write = write && read;
|
||||
|
||||
ram_flags = romcs ? RAM_FLAG_ROMCS : 0x00;
|
||||
ram_flags |= read ? RAM_FLAG_SHREAD : 0x00;
|
||||
ram_flags |= write ? RAM_FLAG_SHWRITE : 0x00;
|
||||
|
||||
if ((ram_flags > 0x00) && !(ram_flags & RAM_FLAG_ROMCS))
|
||||
mem_mapping_set_addr(&(dev->shadow[i].mapping), dev->shadow[i].virt_base, EMS_PGSIZE);
|
||||
else
|
||||
mem_mapping_disable(&(dev->shadow[i].mapping));
|
||||
|
||||
neat_mem_update_state(dev, dev->shadow[i].virt_base, EMS_PGSIZE, ram_flags, RAM_FMASK_SHADOW);
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-calculate the active-page physical address. */
|
||||
static void
|
||||
ems_recalc(neat_t *dev, emspage_t *ems)
|
||||
ems_recalc(neat_t *dev, ram_page_t *ems)
|
||||
{
|
||||
if (ems->page >= dev->ems_pages) {
|
||||
/* That page does not exist. */
|
||||
ems->enabled = 0;
|
||||
}
|
||||
uint32_t page = ems->phys_base / EMS_PGSIZE;
|
||||
|
||||
/* Pre-calculate the page address in EMS RAM. */
|
||||
ems->addr = ram + ems->start + (ems->page * EMS_PGSIZE);
|
||||
if ((dev->regs[REG_RB7] & RB7_EMSEN) && ems->enabled &&
|
||||
(page >= 0x40) && (page < (0x40 + dev->ems_pages))) {
|
||||
neat_log("ems_recalc(): %08X-%08X -> %08X-%08X\n",
|
||||
ems->virt_base, ems->virt_base + EMS_PGSIZE - 1,
|
||||
ems->phys_base, ems->phys_base + EMS_PGSIZE - 1);
|
||||
mem_mapping_set_addr(&ems->mapping, ems->virt_base, EMS_PGSIZE);
|
||||
|
||||
if (ems->enabled) {
|
||||
/* Update the EMS RAM address for this page. */
|
||||
mem_mapping_set_exec(&ems->mapping, ems->addr);
|
||||
mem_mapping_set_exec(&ems->mapping, ram + ems->phys_base);
|
||||
|
||||
/* Enable this page. */
|
||||
mem_mapping_enable(&ems->mapping);
|
||||
if ((ems->virt_base >= 0x00080000) && (ems->virt_base < 0x00100000))
|
||||
neat_mem_update_state(dev, ems->virt_base, EMS_PGSIZE, RAM_FLAG_EMS, RAM_FMASK_EMS);
|
||||
|
||||
#if NEAT_DEBUG > 1
|
||||
neat_log("NEAT EMS: page %d set to %08lx, %sabled)\n",
|
||||
@@ -315,15 +401,18 @@ ems_recalc(neat_t *dev, emspage_t *ems)
|
||||
} else {
|
||||
/* Disable this page. */
|
||||
mem_mapping_disable(&ems->mapping);
|
||||
|
||||
if ((ems->virt_base >= 0x00080000) && (ems->virt_base < 0x00100000))
|
||||
neat_mem_update_state(dev, ems->virt_base, EMS_PGSIZE, 0x00, RAM_FMASK_EMS);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ems_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
neat_t *dev = (neat_t *) priv;
|
||||
emspage_t *ems;
|
||||
int vpage;
|
||||
neat_t *dev = (neat_t *) priv;
|
||||
ram_page_t *ems;
|
||||
int vpage;
|
||||
|
||||
#if NEAT_DEBUG > 1
|
||||
neat_log("NEAT: ems_write(%04x, %02x)\n", port, val);
|
||||
@@ -337,8 +426,7 @@ ems_write(uint16_t port, uint8_t val, void *priv)
|
||||
case 0x0008:
|
||||
case 0x0009:
|
||||
ems->enabled = !!(val & 0x80);
|
||||
ems->page &= 0x0180; /* clear lower bits */
|
||||
ems->page |= (val & 0x7f); /* add new bits */
|
||||
ems->phys_base = (ems->phys_base & 0xffe00000) | ((val & 0x7f) * EMS_PGSIZE);
|
||||
ems_recalc(dev, ems);
|
||||
break;
|
||||
default:
|
||||
@@ -358,7 +446,7 @@ ems_read(uint16_t port, void *priv)
|
||||
|
||||
switch (port & 0x000f) {
|
||||
case 0x0008: /* page number register */
|
||||
ret = dev->ems[vpage].page & 0x7f;
|
||||
ret = (dev->ems[vpage].phys_base / EMS_PGSIZE) & 0x7f;
|
||||
if (dev->ems[vpage].enabled)
|
||||
ret |= 0x80;
|
||||
break;
|
||||
@@ -373,68 +461,21 @@ ems_read(uint16_t port, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Initialize the EMS module. */
|
||||
static void
|
||||
ems_init(neat_t *dev, int en)
|
||||
ems_update(neat_t *dev, int en)
|
||||
{
|
||||
uint8_t j;
|
||||
|
||||
/* Remove if needed. */
|
||||
if (!en) {
|
||||
if (dev->ems_base > 0)
|
||||
for (uint8_t i = 0; i < EMS_MAXPAGE; i++) {
|
||||
/* Disable for now. */
|
||||
mem_mapping_disable(&dev->ems[i].mapping);
|
||||
|
||||
/* Remove I/O handler. */
|
||||
io_removehandler(dev->ems_base + (i * EMS_PGSIZE), 2,
|
||||
ems_read, NULL, NULL, ems_write, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NEAT_LOG
|
||||
neat_log("NEAT: EMS disabled\n");
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get configured I/O address. */
|
||||
j = (dev->regs[REG_RB9] & RB9_BASE) >> RB9_BASE_SH;
|
||||
dev->ems_base = 0x0208 + (0x10 * j);
|
||||
|
||||
/* Get configured frame address. */
|
||||
j = (dev->regs[REG_RB9] & RB9_FRAME) >> RB9_FRAME_SH;
|
||||
dev->ems_frame = 0xC0000 + (EMS_PGSIZE * j);
|
||||
|
||||
/*
|
||||
* For each supported page (we can have a maximum of 4),
|
||||
* create, initialize and disable the mappings, and set
|
||||
* up the I/O control handler.
|
||||
*/
|
||||
for (uint8_t i = 0; i < EMS_MAXPAGE; i++) {
|
||||
/* Create and initialize a page mapping. */
|
||||
mem_mapping_add(&dev->ems[i].mapping,
|
||||
dev->ems_frame + (EMS_PGSIZE * i), EMS_PGSIZE,
|
||||
ems_readb, ems_readw, NULL,
|
||||
ems_writeb, ems_writew, NULL,
|
||||
ram, MEM_MAPPING_EXTERNAL,
|
||||
dev);
|
||||
|
||||
/* Disable for now. */
|
||||
mem_mapping_disable(&dev->ems[i].mapping);
|
||||
|
||||
/* Set up an I/O port handler. */
|
||||
io_sethandler(dev->ems_base + (i * EMS_PGSIZE), 2,
|
||||
ems_read, NULL, NULL, ems_write, NULL, NULL, dev);
|
||||
io_handler(en, dev->ems_base + (i * EMS_PGSIZE), 2,
|
||||
ems_read, NULL, NULL, ems_write, NULL, NULL, dev);
|
||||
|
||||
/*
|
||||
* TODO: update the 'high_mem' mapping to reflect that we now
|
||||
* have NN MB less extended memory available..
|
||||
*/
|
||||
if (en)
|
||||
dev->ems[i].virt_base = dev->ems_frame + (i * EMS_PGSIZE);
|
||||
|
||||
ems_recalc(dev, &(dev->ems[i]));
|
||||
}
|
||||
|
||||
neat_log("NEAT: EMS enabled, I/O=%04xH, Frame=%05XH\n",
|
||||
dev->ems_base, dev->ems_frame);
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -442,6 +483,7 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
neat_t *dev = (neat_t *) priv;
|
||||
uint8_t xval;
|
||||
uint8_t j;
|
||||
uint8_t *reg;
|
||||
int i;
|
||||
|
||||
@@ -493,6 +535,7 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
case REG_RB1:
|
||||
val &= RB1_MASK;
|
||||
*reg = (*reg & ~RB1_MASK) | val;
|
||||
shadow_recalc(dev);
|
||||
#if NEAT_DEBUG > 1
|
||||
neat_log("NEAT: RB1=%02x(%02x)\n", val, *reg);
|
||||
#endif
|
||||
@@ -501,6 +544,10 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
case REG_RB2:
|
||||
val &= RB2_MASK;
|
||||
*reg = (*reg & ~RB2_MASK) | val;
|
||||
if (val & RB2_TOP128)
|
||||
neat_mem_update_state(dev, 0x00080000, 0x00020000, RAM_FLAG_SHREAD | RAM_FLAG_SHWRITE, RAM_FMASK_SHADOW);
|
||||
else
|
||||
neat_mem_update_state(dev, 0x00080000, 0x00020000, 0x00, RAM_FMASK_SHADOW);
|
||||
#if NEAT_DEBUG > 1
|
||||
neat_log("NEAT: RB2=%02x(%02x)\n", val, *reg);
|
||||
#endif
|
||||
@@ -509,6 +556,7 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
case REG_RB3:
|
||||
val &= RB3_MASK;
|
||||
*reg = (*reg & ~RB3_MASK) | val;
|
||||
shadow_recalc(dev);
|
||||
#if NEAT_DEBUG > 1
|
||||
neat_log("NEAT: RB3=%02x(%02x)\n", val, *reg);
|
||||
#endif
|
||||
@@ -517,6 +565,7 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
case REG_RB4:
|
||||
val &= RB4_MASK;
|
||||
*reg = (*reg & ~RB4_MASK) | val;
|
||||
shadow_recalc(dev);
|
||||
#if NEAT_DEBUG > 1
|
||||
neat_log("NEAT: RB4=%02x(%02x)\n", val, *reg);
|
||||
#endif
|
||||
@@ -525,6 +574,7 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
case REG_RB5:
|
||||
val &= RB5_MASK;
|
||||
*reg = (*reg & ~RB5_MASK) | val;
|
||||
shadow_recalc(dev);
|
||||
#if NEAT_DEBUG > 1
|
||||
neat_log("NEAT: RB5=%02x(%02x)\n", val, *reg);
|
||||
#endif
|
||||
@@ -544,10 +594,9 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
#if NEAT_DEBUG > 1
|
||||
neat_log("NEAT: RB7=%02x(%02x)\n", val, *reg);
|
||||
#endif
|
||||
if (val & RB7_EMSEN)
|
||||
ems_init(dev, 1);
|
||||
else if (xval & RB7_EMSEN)
|
||||
ems_init(dev, 0);
|
||||
|
||||
if (xval & RB7_EMSEN)
|
||||
ems_update(dev, !!(val & RB7_EMSEN));
|
||||
|
||||
if (xval & RB7_UMAREL) {
|
||||
if (val & RB7_UMAREL)
|
||||
@@ -571,10 +620,19 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
#if NEAT_DEBUG > 1
|
||||
neat_log("NEAT: RB9=%02x(%02x)\n", val, *reg);
|
||||
#endif
|
||||
if (dev->regs[REG_RB7] & RB7_EMSEN) {
|
||||
ems_init(dev, 0);
|
||||
ems_init(dev, 1);
|
||||
}
|
||||
|
||||
ems_update(dev, 0);
|
||||
|
||||
/* Get configured I/O address. */
|
||||
j = (dev->regs[REG_RB9] & RB9_BASE) >> RB9_BASE_SH;
|
||||
dev->ems_base = 0x0208 + (0x10 * j);
|
||||
|
||||
/* Get configured frame address. */
|
||||
j = (dev->regs[REG_RB9] & RB9_FRAME) >> RB9_FRAME_SH;
|
||||
dev->ems_frame = 0xc0000 + (EMS_PGSIZE * j);
|
||||
|
||||
if (dev->regs[REG_RB7] & RB7_EMSEN)
|
||||
ems_update(dev, 1);
|
||||
break;
|
||||
|
||||
case REG_RB10:
|
||||
@@ -584,23 +642,29 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
neat_log("NEAT: RB10=%02x(%02x)\n", val, *reg);
|
||||
#endif
|
||||
|
||||
dev->ems[3].start = ((val & RB10_P3EXT) >> RB10_P3EXT_SH) << 21;
|
||||
dev->ems[2].start = ((val & RB10_P2EXT) >> RB10_P2EXT_SH) << 21;
|
||||
dev->ems[1].start = ((val & RB10_P1EXT) >> RB10_P1EXT_SH) << 21;
|
||||
dev->ems[0].start = ((val & RB10_P0EXT) >> RB10_P0EXT_SH) << 21;
|
||||
for (i = 0; i < EMS_MAXPAGE; i++)
|
||||
ems_recalc(dev, &dev->ems[i]);
|
||||
dev->ems[3].phys_base = (dev->ems[3].phys_base & 0x001fffff) |
|
||||
(((val & RB10_P3EXT) >> RB10_P3EXT_SH) << 21);
|
||||
dev->ems[2].phys_base = (dev->ems[2].phys_base & 0x001fffff) |
|
||||
(((val & RB10_P2EXT) >> RB10_P2EXT_SH) << 21);
|
||||
dev->ems[1].phys_base = (dev->ems[1].phys_base & 0x001fffff) |
|
||||
(((val & RB10_P1EXT) >> RB10_P1EXT_SH) << 21);
|
||||
dev->ems[0].phys_base = (dev->ems[0].phys_base & 0x001fffff) |
|
||||
(((val & RB10_P0EXT) >> RB10_P0EXT_SH) << 21);
|
||||
|
||||
if (dev->regs[REG_RB7] & RB7_EMSEN)
|
||||
for (i = 0; i < EMS_MAXPAGE; i++)
|
||||
ems_recalc(dev, &dev->ems[i]);
|
||||
break;
|
||||
|
||||
case REG_RB11:
|
||||
val &= RB11_MASK;
|
||||
*reg = (*reg & ~RB11_MASK) | val;
|
||||
case REG_RB12:
|
||||
val &= RB12_MASK;
|
||||
*reg = (*reg & ~RB12_MASK) | val;
|
||||
#if NEAT_DEBUG > 1
|
||||
neat_log("NEAT: RB11=%02x(%02x)\n", val, *reg);
|
||||
neat_log("NEAT: RB12=%02x(%02x)\n", val, *reg);
|
||||
#endif
|
||||
i = (val & RB11_EMSLEN) >> RB11_EMSLEN_SH;
|
||||
i = (val & RB12_EMSLEN) >> RB12_EMSLEN_SH;
|
||||
switch (i) {
|
||||
case 0: /* "less than 2MB" */
|
||||
case 0: /* "less than 1MB" */
|
||||
dev->ems_size = 512;
|
||||
break;
|
||||
|
||||
@@ -617,10 +681,18 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
}
|
||||
dev->ems_pages = (dev->ems_size << 10) / EMS_PGSIZE;
|
||||
|
||||
if (dev->regs[REG_RB7] & RB7_EMSEN)
|
||||
for (i = 0; i < EMS_MAXPAGE; i++)
|
||||
ems_recalc(dev, &dev->ems[i]);
|
||||
|
||||
if (dev->regs[REG_RB7] & RB7_EMSEN) {
|
||||
neat_log("NEAT: EMS %iKB (%i pages)\n",
|
||||
dev->ems_size, dev->ems_pages);
|
||||
}
|
||||
|
||||
mem_a20_key = val & RB12_GA20;
|
||||
mem_a20_recalc();
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -629,6 +701,7 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -646,8 +719,10 @@ neat_read(uint16_t port, void *priv)
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
if ((dev->indx >= 0x60) && (dev->indx <= 0x6f))
|
||||
if ((dev->indx >= 0x60) && (dev->indx <= 0x6e))
|
||||
ret = dev->regs[dev->indx];
|
||||
else if (dev->indx == 0x6f)
|
||||
ret = (dev->regs[dev->indx] & 0xfd) | (mem_a20_key & 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -674,16 +749,50 @@ neat_init(UNUSED(const device_t *info))
|
||||
{
|
||||
neat_t *dev;
|
||||
uint8_t dram_mode = 0;
|
||||
uint8_t i;
|
||||
uint8_t j;
|
||||
|
||||
/* Create an instance. */
|
||||
dev = (neat_t *) malloc(sizeof(neat_t));
|
||||
memset(dev, 0x00, sizeof(neat_t));
|
||||
|
||||
/* Get configured I/O address. */
|
||||
j = (dev->regs[REG_RB9] & RB9_BASE) >> RB9_BASE_SH;
|
||||
dev->ems_base = 0x0208 + (0x10 * j);
|
||||
|
||||
/* Get configured frame address. */
|
||||
j = (dev->regs[REG_RB9] & RB9_FRAME) >> RB9_FRAME_SH;
|
||||
dev->ems_frame = 0xc0000 + (EMS_PGSIZE * j);
|
||||
|
||||
mem_mapping_disable(&ram_mid_mapping);
|
||||
|
||||
/*
|
||||
* For each supported page (we can have a maximum of 4),
|
||||
* create, initialize and disable the mappings, and set
|
||||
* up the I/O control handler.
|
||||
*/
|
||||
for (uint8_t i = 0; i < EMS_MAXPAGE; i++) {
|
||||
/* Create and initialize a page mapping. */
|
||||
mem_mapping_add(&dev->ems[i].mapping,
|
||||
dev->ems_frame + (EMS_PGSIZE * i), EMS_PGSIZE,
|
||||
ems_readb, ems_readw, NULL,
|
||||
ems_writeb, ems_writew, NULL,
|
||||
ram, MEM_MAPPING_INTERNAL,
|
||||
&(dev->ems[i]));
|
||||
|
||||
/* Disable for now. */
|
||||
mem_mapping_disable(&dev->ems[i].mapping);
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 32; i++) {
|
||||
dev->shadow[i].virt_base = dev->shadow[i].phys_base =
|
||||
(i * EMS_PGSIZE) + 0x00080000;
|
||||
dev->shadow[i].enabled = 1;
|
||||
}
|
||||
|
||||
/* Initialize some of the registers to specific defaults. */
|
||||
for (i = REG_RA0; i <= REG_RB11; i++) {
|
||||
for (uint8_t i = REG_RA0; i <= REG_RB12; i++) {
|
||||
dev->indx = i;
|
||||
neat_write(0x0023, 0x00, dev);
|
||||
neat_write(0x0023, defaults[i & REG_MASK], dev);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -101,6 +101,8 @@ typedef struct scamp_t {
|
||||
int ram_interleaved[2];
|
||||
int ibank_shift[2];
|
||||
|
||||
int ram_flags[24];
|
||||
|
||||
port_92_t *port_92;
|
||||
} scamp_t;
|
||||
|
||||
@@ -593,6 +595,35 @@ scamp_ems_write(uint32_t addr, uint8_t val, void *priv)
|
||||
ram[addr] = val;
|
||||
}
|
||||
|
||||
static void
|
||||
scamp_mem_update_state(scamp_t *dev, uint32_t addr, uint32_t size)
|
||||
{
|
||||
uint8_t flags;
|
||||
|
||||
if ((addr >= 0x000a0000) && (addr < 0x00100000)) {
|
||||
flags = dev->ram_flags[(addr - 0x000a0000) >> 14];
|
||||
|
||||
if (flags & 4)
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
else switch (flags & 3) {
|
||||
case 0:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recalc_ems(scamp_t *dev)
|
||||
{
|
||||
@@ -630,34 +661,48 @@ recalc_ems(scamp_t *dev)
|
||||
if (new_mappings[segment] < (mem_size * 1024)) {
|
||||
mem_mapping_set_exec(&dev->ems_mappings[segment], ram + dev->mappings[segment]);
|
||||
mem_mapping_enable(&dev->ems_mappings[segment]);
|
||||
} else
|
||||
dev->ram_flags[segment] |= 0x04;
|
||||
} else {
|
||||
mem_mapping_disable(&dev->ems_mappings[segment]);
|
||||
dev->ram_flags[segment] &= 0xfb;
|
||||
}
|
||||
|
||||
scamp_mem_update_state(dev, 0xa0000 + segment * 0x4000, 0x4000);
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
shadow_control(uint32_t addr, uint32_t size, int state, int ems_enable)
|
||||
shadow_control(scamp_t *dev, uint32_t addr, uint32_t size, int state)
|
||||
{
|
||||
if (ems_enable)
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
switch (state) {
|
||||
case 0:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
dev->ram_flags[(addr - 0x000a0000) >> 14] &= 0xfc;
|
||||
dev->ram_flags[(addr - 0x000a0000) >> 14] |= state;
|
||||
|
||||
if (size == 0x8000) {
|
||||
dev->ram_flags[((addr - 0x000a0000) >> 14) + 1] &= 0xfc;
|
||||
dev->ram_flags[((addr - 0x000a0000) >> 14) + 1] |= state;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
scamp_mem_update_state(dev, addr, size);
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
@@ -669,47 +714,38 @@ shadow_recalc(scamp_t *dev)
|
||||
uint8_t caxs = (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) ? 0 : dev->cfg_regs[CFG_CAXS];
|
||||
uint8_t daxs = (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) ? 0 : dev->cfg_regs[CFG_DAXS];
|
||||
uint8_t feaxs = (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) ? 0 : dev->cfg_regs[CFG_FEAXS];
|
||||
uint32_t ems_enable;
|
||||
|
||||
if (dev->cfg_regs[CFG_EMSEN1] & EMSEN1_EMSENAB) {
|
||||
if (dev->cfg_regs[CFG_EMSEN1] & EMSEN1_EMSMAP) /*Axxx/Bxxx/Dxxx*/
|
||||
ems_enable = (dev->cfg_regs[CFG_EMSEN2] & 0xf) | ((dev->cfg_regs[CFG_EMSEN1] & 0xf) << 4) | ((dev->cfg_regs[CFG_EMSEN2] & 0xf0) << 8);
|
||||
else /*Cxxx/Dxxx/Exxx*/
|
||||
ems_enable = (dev->cfg_regs[CFG_EMSEN2] << 8) | ((dev->cfg_regs[CFG_EMSEN1] & 0xf) << 16);
|
||||
} else
|
||||
ems_enable = 0;
|
||||
|
||||
/*Enabling remapping will disable all shadowing*/
|
||||
if (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)
|
||||
mem_remap_top(384);
|
||||
|
||||
shadow_control(0xa0000, 0x4000, abaxs & 3, ems_enable & 0x00001);
|
||||
shadow_control(0xa0000, 0x4000, abaxs & 3, ems_enable & 0x00002);
|
||||
shadow_control(0xa8000, 0x4000, (abaxs >> 2) & 3, ems_enable & 0x00004);
|
||||
shadow_control(0xa8000, 0x4000, (abaxs >> 2) & 3, ems_enable & 0x00008);
|
||||
shadow_control(dev, 0xa0000, 0x4000, abaxs & 3);
|
||||
shadow_control(dev, 0xa0000, 0x4000, abaxs & 3);
|
||||
shadow_control(dev, 0xa8000, 0x4000, (abaxs >> 2) & 3);
|
||||
shadow_control(dev, 0xa8000, 0x4000, (abaxs >> 2) & 3);
|
||||
|
||||
shadow_control(0xb0000, 0x4000, (abaxs >> 4) & 3, ems_enable & 0x00010);
|
||||
shadow_control(0xb0000, 0x4000, (abaxs >> 4) & 3, ems_enable & 0x00020);
|
||||
shadow_control(0xb8000, 0x4000, (abaxs >> 6) & 3, ems_enable & 0x00040);
|
||||
shadow_control(0xb8000, 0x4000, (abaxs >> 6) & 3, ems_enable & 0x00080);
|
||||
shadow_control(dev, 0xb0000, 0x4000, (abaxs >> 4) & 3);
|
||||
shadow_control(dev, 0xb0000, 0x4000, (abaxs >> 4) & 3);
|
||||
shadow_control(dev, 0xb8000, 0x4000, (abaxs >> 6) & 3);
|
||||
shadow_control(dev, 0xb8000, 0x4000, (abaxs >> 6) & 3);
|
||||
|
||||
shadow_control(0xc0000, 0x4000, caxs & 3, ems_enable & 0x00100);
|
||||
shadow_control(0xc4000, 0x4000, (caxs >> 2) & 3, ems_enable & 0x00200);
|
||||
shadow_control(0xc8000, 0x4000, (caxs >> 4) & 3, ems_enable & 0x00400);
|
||||
shadow_control(0xcc000, 0x4000, (caxs >> 6) & 3, ems_enable & 0x00800);
|
||||
shadow_control(dev, 0xc0000, 0x4000, caxs & 3);
|
||||
shadow_control(dev, 0xc4000, 0x4000, (caxs >> 2) & 3);
|
||||
shadow_control(dev, 0xc8000, 0x4000, (caxs >> 4) & 3);
|
||||
shadow_control(dev, 0xcc000, 0x4000, (caxs >> 6) & 3);
|
||||
|
||||
shadow_control(0xd0000, 0x4000, daxs & 3, ems_enable & 0x01000);
|
||||
shadow_control(0xd4000, 0x4000, (daxs >> 2) & 3, ems_enable & 0x02000);
|
||||
shadow_control(0xd8000, 0x4000, (daxs >> 4) & 3, ems_enable & 0x04000);
|
||||
shadow_control(0xdc000, 0x4000, (daxs >> 6) & 3, ems_enable & 0x08000);
|
||||
shadow_control(dev, 0xd0000, 0x4000, daxs & 3);
|
||||
shadow_control(dev, 0xd4000, 0x4000, (daxs >> 2) & 3);
|
||||
shadow_control(dev, 0xd8000, 0x4000, (daxs >> 4) & 3);
|
||||
shadow_control(dev, 0xdc000, 0x4000, (daxs >> 6) & 3);
|
||||
|
||||
shadow_control(0xe0000, 0x4000, feaxs & 3, ems_enable & 0x10000);
|
||||
shadow_control(0xe4000, 0x4000, feaxs & 3, ems_enable & 0x20000);
|
||||
shadow_control(0xe8000, 0x4000, (feaxs >> 2) & 3, ems_enable & 0x40000);
|
||||
shadow_control(0xec000, 0x4000, (feaxs >> 2) & 3, ems_enable & 0x80000);
|
||||
shadow_control(dev, 0xe0000, 0x4000, feaxs & 3);
|
||||
shadow_control(dev, 0xe4000, 0x4000, feaxs & 3);
|
||||
shadow_control(dev, 0xe8000, 0x4000, (feaxs >> 2) & 3);
|
||||
shadow_control(dev, 0xec000, 0x4000, (feaxs >> 2) & 3);
|
||||
|
||||
shadow_control(0xf0000, 0x8000, (feaxs >> 4) & 3, 0);
|
||||
shadow_control(0xf8000, 0x8000, (feaxs >> 6) & 3, 0);
|
||||
shadow_control(dev, 0xf0000, 0x8000, (feaxs >> 4) & 3);
|
||||
shadow_control(dev, 0xf8000, 0x8000, (feaxs >> 6) & 3);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -106,7 +106,7 @@ sis_5513_apc_reset(sis_5513_pci_to_isa_t *dev)
|
||||
{
|
||||
memset(dev->apc_regs, 0x00, sizeof(dev->apc_regs));
|
||||
|
||||
if (dev->rev == 0b0) {
|
||||
if (dev->rev == 0xb0) {
|
||||
dev->apc_regs[0x03] = 0x80;
|
||||
dev->apc_regs[0x04] = 0x38;
|
||||
dev->apc_regs[0x07] = 0x01;
|
||||
|
||||
100
src/config.c
100
src/config.c
@@ -475,8 +475,6 @@ load_input_devices(void)
|
||||
{
|
||||
ini_section_t cat = ini_find_section(config, "Input devices");
|
||||
char temp[512];
|
||||
int c;
|
||||
int d;
|
||||
char *p;
|
||||
|
||||
p = ini_section_get_string(cat, "mouse_type", NULL);
|
||||
@@ -495,8 +493,8 @@ load_input_devices(void)
|
||||
/* Workaround for ini_section_get_int returning 0 on non-integer data */
|
||||
joystick_type = joystick_get_from_internal_name("2axis_2button");
|
||||
else {
|
||||
c = ini_section_get_int(cat, "joystick_type", 8);
|
||||
switch (c) {
|
||||
int js = ini_section_get_int(cat, "joystick_type", 8);
|
||||
switch (js) {
|
||||
case JS_TYPE_2AXIS_4BUTTON:
|
||||
joystick_type = joystick_get_from_internal_name("2axis_4button");
|
||||
break;
|
||||
@@ -527,25 +525,25 @@ load_input_devices(void)
|
||||
} else
|
||||
joystick_type = JS_TYPE_NONE;
|
||||
|
||||
for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) {
|
||||
sprintf(temp, "joystick_%i_nr", c);
|
||||
joystick_state[c].plat_joystick_nr = ini_section_get_int(cat, temp, 0);
|
||||
for (int js = 0; js < joystick_get_max_joysticks(joystick_type); js++) {
|
||||
sprintf(temp, "joystick_%i_nr", js);
|
||||
joystick_state[js].plat_joystick_nr = ini_section_get_int(cat, temp, 0);
|
||||
|
||||
if (joystick_state[c].plat_joystick_nr) {
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++) {
|
||||
sprintf(temp, "joystick_%i_axis_%i", c, d);
|
||||
joystick_state[c].axis_mapping[d] = ini_section_get_int(cat, temp, d);
|
||||
if (joystick_state[js].plat_joystick_nr) {
|
||||
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) {
|
||||
sprintf(temp, "joystick_%i_axis_%i", js, axis_nr);
|
||||
joystick_state[js].axis_mapping[axis_nr] = ini_section_get_int(cat, temp, axis_nr);
|
||||
}
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++) {
|
||||
sprintf(temp, "joystick_%i_button_%i", c, d);
|
||||
joystick_state[c].button_mapping[d] = ini_section_get_int(cat, temp, d);
|
||||
for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) {
|
||||
sprintf(temp, "joystick_%i_button_%i", js, button_nr);
|
||||
joystick_state[js].button_mapping[button_nr] = ini_section_get_int(cat, temp, button_nr);
|
||||
}
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++) {
|
||||
sprintf(temp, "joystick_%i_pov_%i", c, d);
|
||||
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) {
|
||||
sprintf(temp, "joystick_%i_pov_%i", js, pov_nr);
|
||||
p = ini_section_get_string(cat, temp, "0, 0");
|
||||
joystick_state[c].pov_mapping[d][0] = joystick_state[c].pov_mapping[d][1] = 0;
|
||||
sscanf(p, "%i, %i", &joystick_state[c].pov_mapping[d][0],
|
||||
&joystick_state[c].pov_mapping[d][1]);
|
||||
joystick_state[js].pov_mapping[pov_nr][0] = joystick_state[js].pov_mapping[pov_nr][1] = 0;
|
||||
sscanf(p, "%i, %i", &joystick_state[js].pov_mapping[pov_nr][0],
|
||||
&joystick_state[js].pov_mapping[pov_nr][1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -743,11 +741,9 @@ load_ports(void)
|
||||
ini_section_t cat = ini_find_section(config, "Ports (COM & LPT)");
|
||||
char *p;
|
||||
char temp[512];
|
||||
int c;
|
||||
|
||||
memset(temp, 0, sizeof(temp));
|
||||
|
||||
for (c = 0; c < SERIAL_MAX; c++) {
|
||||
for (int c = 0; c < SERIAL_MAX; c++) {
|
||||
sprintf(temp, "serial%d_enabled", c + 1);
|
||||
com_ports[c].enabled = !!ini_section_get_int(cat, temp, (c >= 2) ? 0 : 1);
|
||||
|
||||
@@ -758,7 +754,7 @@ load_ports(void)
|
||||
config_log("Serial Port %d: passthrough enabled.\n\n", c + 1);
|
||||
}
|
||||
|
||||
for (c = 0; c < PARALLEL_MAX; c++) {
|
||||
for (int c = 0; c < PARALLEL_MAX; c++) {
|
||||
sprintf(temp, "lpt%d_enabled", c + 1);
|
||||
lpt_ports[c].enabled = !!ini_section_get_int(cat, temp, (c == 0) ? 1 : 0);
|
||||
|
||||
@@ -776,11 +772,10 @@ load_storage_controllers(void)
|
||||
ini_section_t migration_cat;
|
||||
char *p;
|
||||
char temp[512];
|
||||
int c;
|
||||
int min = 0;
|
||||
int free_p = 0;
|
||||
|
||||
for (c = min; c < SCSI_CARD_MAX; c++) {
|
||||
for (int c = min; c < SCSI_CARD_MAX; c++) {
|
||||
sprintf(temp, "scsicard_%d", c + 1);
|
||||
|
||||
p = ini_section_get_string(cat, temp, NULL);
|
||||
@@ -932,7 +927,7 @@ load_storage_controllers(void)
|
||||
ini_section_delete_var(cat, "cassette_ui_writeprot");
|
||||
}
|
||||
|
||||
for (c = 0; c < 2; c++) {
|
||||
for (int c = 0; c < 2; c++) {
|
||||
sprintf(temp, "cartridge_%02i_fn", c + 1);
|
||||
p = ini_section_get_string(cat, temp, "");
|
||||
|
||||
@@ -2140,50 +2135,49 @@ save_input_devices(void)
|
||||
ini_section_t cat = ini_find_or_create_section(config, "Input devices");
|
||||
char temp[512];
|
||||
char tmp2[512];
|
||||
int c;
|
||||
int d;
|
||||
|
||||
ini_section_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type));
|
||||
|
||||
if (!joystick_type) {
|
||||
ini_section_delete_var(cat, "joystick_type");
|
||||
|
||||
for (c = 0; c < 16; c++) {
|
||||
sprintf(tmp2, "joystick_%i_nr", c);
|
||||
for (int js = 0; js < MAX_PLAT_JOYSTICKS; js++) {
|
||||
sprintf(tmp2, "joystick_%i_nr", js);
|
||||
ini_section_delete_var(cat, tmp2);
|
||||
|
||||
for (d = 0; d < 16; d++) {
|
||||
sprintf(tmp2, "joystick_%i_axis_%i", c, d);
|
||||
for (int axis_nr = 0; axis_nr < MAX_JOY_AXES; axis_nr++) {
|
||||
sprintf(tmp2, "joystick_%i_axis_%i", js, axis_nr);
|
||||
ini_section_delete_var(cat, tmp2);
|
||||
}
|
||||
for (d = 0; d < 16; d++) {
|
||||
sprintf(tmp2, "joystick_%i_button_%i", c, d);
|
||||
for (int button_nr = 0; button_nr < MAX_JOY_BUTTONS; button_nr++) {
|
||||
sprintf(tmp2, "joystick_%i_button_%i", js, button_nr);
|
||||
ini_section_delete_var(cat, tmp2);
|
||||
}
|
||||
for (d = 0; d < 16; d++) {
|
||||
sprintf(tmp2, "joystick_%i_pov_%i", c, d);
|
||||
for (int pov_nr = 0; pov_nr < MAX_JOY_POVS; pov_nr++) {
|
||||
sprintf(tmp2, "joystick_%i_pov_%i", js, pov_nr);
|
||||
ini_section_delete_var(cat, tmp2);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ini_section_set_string(cat, "joystick_type", joystick_get_internal_name(joystick_type));
|
||||
|
||||
for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) {
|
||||
sprintf(tmp2, "joystick_%i_nr", c);
|
||||
ini_section_set_int(cat, tmp2, joystick_state[c].plat_joystick_nr);
|
||||
for (int js = 0; js < joystick_get_max_joysticks(joystick_type); js++) {
|
||||
sprintf(tmp2, "joystick_%i_nr", js);
|
||||
ini_section_set_int(cat, tmp2, joystick_state[js].plat_joystick_nr);
|
||||
|
||||
if (joystick_state[c].plat_joystick_nr) {
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++) {
|
||||
sprintf(tmp2, "joystick_%i_axis_%i", c, d);
|
||||
ini_section_set_int(cat, tmp2, joystick_state[c].axis_mapping[d]);
|
||||
if (joystick_state[js].plat_joystick_nr) {
|
||||
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) {
|
||||
sprintf(tmp2, "joystick_%i_axis_%i", js, axis_nr);
|
||||
ini_section_set_int(cat, tmp2, joystick_state[js].axis_mapping[axis_nr]);
|
||||
}
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++) {
|
||||
sprintf(tmp2, "joystick_%i_button_%i", c, d);
|
||||
ini_section_set_int(cat, tmp2, joystick_state[c].button_mapping[d]);
|
||||
for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) {
|
||||
sprintf(tmp2, "joystick_%i_button_%i", js, button_nr);
|
||||
ini_section_set_int(cat, tmp2, joystick_state[js].button_mapping[button_nr]);
|
||||
}
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++) {
|
||||
sprintf(tmp2, "joystick_%i_pov_%i", c, d);
|
||||
sprintf(temp, "%i, %i", joystick_state[c].pov_mapping[d][0], joystick_state[c].pov_mapping[d][1]);
|
||||
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) {
|
||||
sprintf(tmp2, "joystick_%i_pov_%i", js, pov_nr);
|
||||
sprintf(temp, "%i, %i", joystick_state[js].pov_mapping[pov_nr][0],
|
||||
joystick_state[js].pov_mapping[pov_nr][1]);
|
||||
ini_section_set_string(cat, tmp2, temp);
|
||||
}
|
||||
}
|
||||
@@ -2341,10 +2335,8 @@ save_ports(void)
|
||||
{
|
||||
ini_section_t cat = ini_find_or_create_section(config, "Ports (COM & LPT)");
|
||||
char temp[512];
|
||||
int c;
|
||||
int d;
|
||||
|
||||
for (c = 0; c < SERIAL_MAX; c++) {
|
||||
for (int c = 0; c < SERIAL_MAX; c++) {
|
||||
sprintf(temp, "serial%d_enabled", c + 1);
|
||||
if (((c < 2) && com_ports[c].enabled) || ((c >= 2) && !com_ports[c].enabled))
|
||||
ini_section_delete_var(cat, temp);
|
||||
@@ -2358,9 +2350,9 @@ save_ports(void)
|
||||
ini_section_delete_var(cat, temp);
|
||||
}
|
||||
|
||||
for (c = 0; c < PARALLEL_MAX; c++) {
|
||||
for (int c = 0; c < PARALLEL_MAX; c++) {
|
||||
sprintf(temp, "lpt%d_enabled", c + 1);
|
||||
d = (c == 0) ? 1 : 0;
|
||||
int d = (c == 0) ? 1 : 0;
|
||||
if (lpt_ports[c].enabled == d)
|
||||
ini_section_delete_var(cat, temp);
|
||||
else
|
||||
|
||||
@@ -1634,28 +1634,75 @@ cpu_data_opff_rm(void)
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
cpu_inb(uint16_t port)
|
||||
{
|
||||
int old_cycles = cycles;
|
||||
uint8_t ret;
|
||||
|
||||
wait(is_mazovia ? 5 : 4, 1);
|
||||
old_cycles = cycles;
|
||||
|
||||
ret = inb(port);
|
||||
|
||||
resub_cycles(old_cycles);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
cpu_inw(uint16_t port)
|
||||
{
|
||||
int old_cycles = cycles;
|
||||
uint16_t ret;
|
||||
|
||||
wait(is_mazovia ? 5 : 4, 1);
|
||||
if (is8086 && !(port & 1)) {
|
||||
wait(4, 0);
|
||||
old_cycles = cycles;
|
||||
ret = inw(port);
|
||||
} else {
|
||||
wait(8, 0);
|
||||
wait(is_mazovia ? 5 : 4, 1);
|
||||
old_cycles = cycles;
|
||||
ret = inb(port++);
|
||||
ret |= (inb(port) << 8);
|
||||
}
|
||||
|
||||
return inw(port);
|
||||
resub_cycles(old_cycles);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_outb(uint16_t port, uint16_t val)
|
||||
{
|
||||
int old_cycles = cycles;
|
||||
|
||||
wait(is_mazovia ? 5 : 4, 1);
|
||||
old_cycles = cycles;
|
||||
|
||||
outb(port, val);
|
||||
|
||||
resub_cycles(old_cycles);
|
||||
}
|
||||
|
||||
void
|
||||
cpu_outw(uint16_t port, uint16_t val)
|
||||
{
|
||||
int old_cycles = cycles;
|
||||
|
||||
wait(is_mazovia ? 5 : 4, 1);
|
||||
|
||||
if (is8086 && !(port & 1)) {
|
||||
wait(4, 0);
|
||||
old_cycles = cycles;
|
||||
outw(port, val);
|
||||
} else {
|
||||
wait(8, 0);
|
||||
wait(is_mazovia ? 5 : 4, 1);
|
||||
old_cycles = cycles;
|
||||
outb(port++, val);
|
||||
outb(port, val >> 8);
|
||||
}
|
||||
|
||||
return outw(port, val);
|
||||
resub_cycles(old_cycles);
|
||||
}
|
||||
|
||||
/* Executes instructions up to the specified number of cycles. */
|
||||
@@ -1804,8 +1851,7 @@ execx86(int cycs)
|
||||
writememw(es, DI, cpu_inw(DX));
|
||||
DI += (cpu_state.flags & D_FLAG) ? -2 : 2;
|
||||
} else {
|
||||
wait(4, 0);
|
||||
writememb(es, DI, inb(DX));
|
||||
writememb(es, DI, cpu_inb(DX));
|
||||
DI += (cpu_state.flags & D_FLAG) ? -1 : 1;
|
||||
}
|
||||
|
||||
@@ -1833,8 +1879,7 @@ execx86(int cycs)
|
||||
cpu_outw(DX, readmemw(dest_seg, SI));
|
||||
SI += (cpu_state.flags & D_FLAG) ? -2 : 2;
|
||||
} else {
|
||||
wait(4, 0);
|
||||
outb(DX, readmemb(dest_seg + SI));
|
||||
cpu_outb(DX, readmemb(dest_seg + SI));
|
||||
SI += (cpu_state.flags & D_FLAG) ? -1 : 1;
|
||||
}
|
||||
if (in_rep == 0)
|
||||
|
||||
@@ -22,12 +22,8 @@ opSYSCALL(uint32_t fetchdat)
|
||||
|
||||
ret = syscall_op(fetchdat);
|
||||
|
||||
if (ret <= 1) {
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
if (ret <= 1)
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -41,12 +37,8 @@ opSYSRET(uint32_t fetchdat)
|
||||
|
||||
ret = sysret(fetchdat);
|
||||
|
||||
if (ret <= 1) {
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
if (ret <= 1)
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -18,12 +18,8 @@ opSYSENTER(uint32_t fetchdat)
|
||||
{
|
||||
int ret = sysenter(fetchdat);
|
||||
|
||||
if (ret <= 1) {
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
if (ret <= 1)
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -33,12 +29,8 @@ opSYSEXIT(uint32_t fetchdat)
|
||||
{
|
||||
int ret = sysexit(fetchdat);
|
||||
|
||||
if (ret <= 1) {
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
if (ret <= 1)
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -118,7 +110,8 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
fpu_state.swd &= ~(FPU_SW_Summary | FPU_SW_Backward);
|
||||
}
|
||||
|
||||
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
|
||||
// CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
/* FXSAVE */
|
||||
writememw(easeg, cpu_state.eaaddr, i387_get_control_word());
|
||||
@@ -163,7 +156,7 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
writememw(easeg, cpu_state.eaaddr + (index * 16) + 40, fp.signExp);
|
||||
}
|
||||
|
||||
CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
|
||||
return cpu_state.abrt;
|
||||
@@ -327,7 +320,8 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
}
|
||||
}
|
||||
|
||||
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
|
||||
// CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
/* FXSAVE */
|
||||
if ((twd & 0x0003) != 0x0003)
|
||||
@@ -372,7 +366,7 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr;
|
||||
|
||||
CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
|
||||
return cpu_state.abrt;
|
||||
@@ -400,8 +394,7 @@ static int
|
||||
opHINT_NOP_a16(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
CLOCK_CYCLES((is486) ? 1 : 3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -409,7 +402,6 @@ static int
|
||||
opHINT_NOP_a32(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
CLOCK_CYCLES((is486) ? 1 : 3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
249
src/device.c
249
src/device.c
@@ -19,7 +19,7 @@
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2021 Andreas J. Reichel.
|
||||
* Copyright 2021-2022 Jasmine Iwanek.
|
||||
* Copyright 2021-2025 Jasmine Iwanek.
|
||||
*
|
||||
* 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
|
||||
@@ -89,38 +89,38 @@ device_init(void)
|
||||
}
|
||||
|
||||
void
|
||||
device_set_context(device_context_t *c, const device_t *dev, int inst)
|
||||
device_set_context(device_context_t *ctx, const device_t *dev, int inst)
|
||||
{
|
||||
memset(c, 0, sizeof(device_context_t));
|
||||
c->dev = dev;
|
||||
c->instance = inst;
|
||||
memset(ctx, 0, sizeof(device_context_t));
|
||||
ctx->dev = dev;
|
||||
ctx->instance = inst;
|
||||
if (inst) {
|
||||
sprintf(c->name, "%s #%i", dev->name, inst);
|
||||
sprintf(ctx->name, "%s #%i", dev->name, inst);
|
||||
|
||||
/* If a numbered section is not present, but a non-numbered of the same name
|
||||
is, rename the non-numbered section to numbered. */
|
||||
const void *sec = config_find_section(c->name);
|
||||
const void *sec = config_find_section(ctx->name);
|
||||
void * single_sec = config_find_section((char *) dev->name);
|
||||
if ((sec == NULL) && (single_sec != NULL))
|
||||
config_rename_section(single_sec, c->name);
|
||||
config_rename_section(single_sec, ctx->name);
|
||||
} else if (!strcmp(dev->name, "PS/2 Mouse")) {
|
||||
sprintf(c->name, "%s", dev->name);
|
||||
sprintf(ctx->name, "%s", dev->name);
|
||||
|
||||
/* Migrate the old "Standard PS/2 Mouse" section */
|
||||
const void *sec = config_find_section(c->name);
|
||||
const void *sec = config_find_section(ctx->name);
|
||||
void * old_sec = config_find_section("Standard PS/2 Mouse");
|
||||
if ((sec == NULL) && (old_sec != NULL))
|
||||
config_rename_section(old_sec, c->name);
|
||||
config_rename_section(old_sec, ctx->name);
|
||||
} else if (!strcmp(dev->name, "Microsoft RAMCard")) {
|
||||
sprintf(c->name, "%s", dev->name);
|
||||
sprintf(ctx->name, "%s", dev->name);
|
||||
|
||||
/* Migrate the old "Standard PS/2 Mouse" section */
|
||||
const void *sec = config_find_section(c->name);
|
||||
/* Migrate the old "Microsoft RAMCard for IBM PC" section */
|
||||
const void *sec = config_find_section(ctx->name);
|
||||
void * old_sec = config_find_section("Microsoft RAMCard for IBM PC");
|
||||
if ((sec == NULL) && (old_sec != NULL))
|
||||
config_rename_section(old_sec, c->name);
|
||||
config_rename_section(old_sec, ctx->name);
|
||||
} else
|
||||
sprintf(c->name, "%s", dev->name);
|
||||
sprintf(ctx->name, "%s", dev->name);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -153,7 +153,7 @@ device_add_common(const device_t *dev, void *p, void *params, int inst)
|
||||
{
|
||||
device_t *init_dev = NULL;
|
||||
void *priv = NULL;
|
||||
int c;
|
||||
int16_t c;
|
||||
|
||||
if (params != NULL) {
|
||||
init_dev = calloc(1, sizeof(device_t));
|
||||
@@ -162,7 +162,7 @@ device_add_common(const device_t *dev, void *p, void *params, int inst)
|
||||
} else
|
||||
init_dev = (device_t *) dev;
|
||||
|
||||
for (c = 0; c < 256; c++) {
|
||||
for (c = 0; c < DEVICE_MAX; c++) {
|
||||
if (!inst && (devices[c] == dev)) {
|
||||
device_log("DEVICE: device already exists!\n");
|
||||
return (NULL);
|
||||
@@ -244,6 +244,7 @@ void *
|
||||
device_add_linked(const device_t *dev, void *priv)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
device_common_priv = priv;
|
||||
ret = device_add_common(dev, NULL, NULL, 0);
|
||||
device_common_priv = NULL;
|
||||
@@ -311,7 +312,8 @@ device_close_all(void)
|
||||
#endif
|
||||
if (devices[c]->close != NULL)
|
||||
devices[c]->close(device_priv[c]);
|
||||
devices[c] = device_priv[c] = NULL;
|
||||
devices[c] = NULL;
|
||||
device_priv[c] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -372,7 +374,7 @@ device_available(const device_t *dev)
|
||||
if (dev != NULL) {
|
||||
config = dev->config;
|
||||
if (config != NULL) {
|
||||
while (config->type != -1) {
|
||||
while (config->type != CONFIG_END) {
|
||||
if (config->type == CONFIG_BIOS) {
|
||||
int roms_present = 0;
|
||||
|
||||
@@ -414,7 +416,7 @@ device_get_bios_file(const device_t *dev, const char *internal_name, int file_no
|
||||
if (dev != NULL) {
|
||||
config = dev->config;
|
||||
if (config != NULL) {
|
||||
while (config->type != -1) {
|
||||
while (config->type != CONFIG_END) {
|
||||
if (config->type == CONFIG_BIOS) {
|
||||
bios = config->bios;
|
||||
|
||||
@@ -452,7 +454,7 @@ device_has_config(const device_t *dev)
|
||||
|
||||
config = dev->config;
|
||||
|
||||
while (config->type != -1) {
|
||||
while (config->type != CONFIG_END) {
|
||||
c++;
|
||||
config++;
|
||||
}
|
||||
@@ -543,8 +545,7 @@ device_get_name(const device_t *dev, int bus, char *name)
|
||||
strcat(pbus, ")");
|
||||
|
||||
/* Allocate the temporary device name string and set it to all zeroes. */
|
||||
tname = (char *) malloc(strlen(dev->name) + 1);
|
||||
memset(tname, 0x00, strlen(dev->name) + 1);
|
||||
tname = (char *) calloc(1, strlen(dev->name) + 1);
|
||||
|
||||
/* First strip the bus string with parentheses. */
|
||||
fbus = strstr(dev->name, pbus);
|
||||
@@ -612,256 +613,256 @@ device_get_instance(void)
|
||||
}
|
||||
|
||||
const char *
|
||||
device_get_config_string(const char *s)
|
||||
device_get_config_string(const char *str)
|
||||
{
|
||||
const device_config_t *c = device_current.dev->config;
|
||||
const device_config_t *cfg = device_current.dev->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (!strcmp(s, c->name))
|
||||
return (config_get_string((char *) device_current.name, (char *) s, (char *) c->default_string));
|
||||
while (cfg && cfg->type != CONFIG_END) {
|
||||
if (!strcmp(str, cfg->name))
|
||||
return (config_get_string((char *) device_current.name, (char *) str, (char *) cfg->default_string));
|
||||
|
||||
c++;
|
||||
cfg++;
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
device_get_config_int(const char *s)
|
||||
device_get_config_int(const char *str)
|
||||
{
|
||||
const device_config_t *c = device_current.dev->config;
|
||||
const device_config_t *cfg = device_current.dev->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (!strcmp(s, c->name))
|
||||
return (config_get_int((char *) device_current.name, (char *) s, c->default_int));
|
||||
while (cfg && cfg->type != CONFIG_END) {
|
||||
if (!strcmp(str, cfg->name))
|
||||
return (config_get_int((char *) device_current.name, (char *) str, cfg->default_int));
|
||||
|
||||
c++;
|
||||
cfg++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
device_get_config_int_ex(const char *s, int def)
|
||||
device_get_config_int_ex(const char *str, int def)
|
||||
{
|
||||
const device_config_t *c = device_current.dev->config;
|
||||
const device_config_t *cfg = device_current.dev->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (!strcmp(s, c->name))
|
||||
return (config_get_int((char *) device_current.name, (char *) s, def));
|
||||
while (cfg && cfg->type != CONFIG_END) {
|
||||
if (!strcmp(str, cfg->name))
|
||||
return (config_get_int((char *) device_current.name, (char *) str, def));
|
||||
|
||||
c++;
|
||||
cfg++;
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
int
|
||||
device_get_config_hex16(const char *s)
|
||||
device_get_config_hex16(const char *str)
|
||||
{
|
||||
const device_config_t *c = device_current.dev->config;
|
||||
const device_config_t *cfg = device_current.dev->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (!strcmp(s, c->name))
|
||||
return (config_get_hex16((char *) device_current.name, (char *) s, c->default_int));
|
||||
while (cfg && cfg->type != CONFIG_END) {
|
||||
if (!strcmp(str, cfg->name))
|
||||
return (config_get_hex16((char *) device_current.name, (char *) str, cfg->default_int));
|
||||
|
||||
c++;
|
||||
cfg++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
device_get_config_hex20(const char *s)
|
||||
device_get_config_hex20(const char *str)
|
||||
{
|
||||
const device_config_t *c = device_current.dev->config;
|
||||
const device_config_t *cfg = device_current.dev->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (!strcmp(s, c->name))
|
||||
return (config_get_hex20((char *) device_current.name, (char *) s, c->default_int));
|
||||
while (cfg && cfg->type != CONFIG_END) {
|
||||
if (!strcmp(str, cfg->name))
|
||||
return (config_get_hex20((char *) device_current.name, (char *) str, cfg->default_int));
|
||||
|
||||
c++;
|
||||
cfg++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
device_get_config_mac(const char *s, int def)
|
||||
device_get_config_mac(const char *str, int def)
|
||||
{
|
||||
const device_config_t *c = device_current.dev->config;
|
||||
const device_config_t *cfg = device_current.dev->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (!strcmp(s, c->name))
|
||||
return (config_get_mac((char *) device_current.name, (char *) s, def));
|
||||
while (cfg && cfg->type != CONFIG_END) {
|
||||
if (!strcmp(str, cfg->name))
|
||||
return (config_get_mac((char *) device_current.name, (char *) str, def));
|
||||
|
||||
c++;
|
||||
cfg++;
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
void
|
||||
device_set_config_int(const char *s, int val)
|
||||
device_set_config_int(const char *str, int val)
|
||||
{
|
||||
const device_config_t *c = device_current.dev->config;
|
||||
const device_config_t *cfg = device_current.dev->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (!strcmp(s, c->name)) {
|
||||
config_set_int((char *) device_current.name, (char *) s, val);
|
||||
while (cfg && cfg->type != CONFIG_END) {
|
||||
if (!strcmp(str, cfg->name)) {
|
||||
config_set_int((char *) device_current.name, (char *) str, val);
|
||||
break;
|
||||
}
|
||||
|
||||
c++;
|
||||
cfg++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
device_set_config_hex16(const char *s, int val)
|
||||
device_set_config_hex16(const char *str, int val)
|
||||
{
|
||||
const device_config_t *c = device_current.dev->config;
|
||||
const device_config_t *cfg = device_current.dev->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (!strcmp(s, c->name)) {
|
||||
config_set_hex16((char *) device_current.name, (char *) s, val);
|
||||
while (cfg && cfg->type != CONFIG_END) {
|
||||
if (!strcmp(str, cfg->name)) {
|
||||
config_set_hex16((char *) device_current.name, (char *) str, val);
|
||||
break;
|
||||
}
|
||||
|
||||
c++;
|
||||
cfg++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
device_set_config_hex20(const char *s, int val)
|
||||
device_set_config_hex20(const char *str, int val)
|
||||
{
|
||||
const device_config_t *c = device_current.dev->config;
|
||||
const device_config_t *cfg = device_current.dev->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (!strcmp(s, c->name)) {
|
||||
config_set_hex20((char *) device_current.name, (char *) s, val);
|
||||
while (cfg && cfg->type != CONFIG_END) {
|
||||
if (!strcmp(str, cfg->name)) {
|
||||
config_set_hex20((char *) device_current.name, (char *) str, val);
|
||||
break;
|
||||
}
|
||||
|
||||
c++;
|
||||
cfg++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
device_set_config_mac(const char *s, int val)
|
||||
device_set_config_mac(const char *str, int val)
|
||||
{
|
||||
const device_config_t *c = device_current.dev->config;
|
||||
const device_config_t *cfg = device_current.dev->config;
|
||||
|
||||
while (c && c->type != -1) {
|
||||
if (!strcmp(s, c->name)) {
|
||||
config_set_mac((char *) device_current.name, (char *) s, val);
|
||||
while (cfg && cfg->type != CONFIG_END) {
|
||||
if (!strcmp(str, cfg->name)) {
|
||||
config_set_mac((char *) device_current.name, (char *) str, val);
|
||||
break;
|
||||
}
|
||||
|
||||
c++;
|
||||
cfg++;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
device_is_valid(const device_t *device, int m)
|
||||
device_is_valid(const device_t *device, int mch)
|
||||
{
|
||||
if (device == NULL)
|
||||
return 1;
|
||||
|
||||
if ((device->flags & DEVICE_PCJR) && !machine_has_bus(m, MACHINE_BUS_PCJR))
|
||||
if ((device->flags & DEVICE_PCJR) && !machine_has_bus(mch, MACHINE_BUS_PCJR))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_XTKBC) && machine_has_bus(m, MACHINE_BUS_ISA16) && !machine_has_bus(m, MACHINE_BUS_DM_KBC))
|
||||
if ((device->flags & DEVICE_XTKBC) && machine_has_bus(mch, MACHINE_BUS_ISA16) && !machine_has_bus(mch, MACHINE_BUS_DM_KBC))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_AT) && !machine_has_bus(m, MACHINE_BUS_ISA16))
|
||||
if ((device->flags & DEVICE_AT) && !machine_has_bus(mch, MACHINE_BUS_ISA16))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_ATKBC) && !machine_has_bus(m, MACHINE_BUS_ISA16) && !machine_has_bus(m, MACHINE_BUS_DM_KBC))
|
||||
if ((device->flags & DEVICE_ATKBC) && !machine_has_bus(mch, MACHINE_BUS_ISA16) && !machine_has_bus(mch, MACHINE_BUS_DM_KBC))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_PS2) && !machine_has_bus(m, MACHINE_BUS_PS2_PORTS))
|
||||
if ((device->flags & DEVICE_PS2) && !machine_has_bus(mch, MACHINE_BUS_PS2_PORTS))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_ISA) && !machine_has_bus(m, MACHINE_BUS_ISA))
|
||||
if ((device->flags & DEVICE_ISA) && !machine_has_bus(mch, MACHINE_BUS_ISA))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_CBUS) && !machine_has_bus(m, MACHINE_BUS_CBUS))
|
||||
if ((device->flags & DEVICE_CBUS) && !machine_has_bus(mch, MACHINE_BUS_CBUS))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_PCMCIA) && !machine_has_bus(m, MACHINE_BUS_PCMCIA) && !machine_has_bus(m, MACHINE_BUS_ISA))
|
||||
if ((device->flags & DEVICE_PCMCIA) && !machine_has_bus(mch, MACHINE_BUS_PCMCIA) && !machine_has_bus(mch, MACHINE_BUS_ISA))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_MCA) && !machine_has_bus(m, MACHINE_BUS_MCA))
|
||||
if ((device->flags & DEVICE_MCA) && !machine_has_bus(mch, MACHINE_BUS_MCA))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_HIL) && !machine_has_bus(m, MACHINE_BUS_HIL))
|
||||
if ((device->flags & DEVICE_HIL) && !machine_has_bus(mch, MACHINE_BUS_HIL))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_EISA) && !machine_has_bus(m, MACHINE_BUS_EISA))
|
||||
if ((device->flags & DEVICE_EISA) && !machine_has_bus(mch, MACHINE_BUS_EISA))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_AT32) && !machine_has_bus(m, MACHINE_BUS_AT32))
|
||||
if ((device->flags & DEVICE_AT32) && !machine_has_bus(mch, MACHINE_BUS_AT32))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_OLB) && !machine_has_bus(m, MACHINE_BUS_OLB))
|
||||
if ((device->flags & DEVICE_OLB) && !machine_has_bus(mch, MACHINE_BUS_OLB))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_VLB) && !machine_has_bus(m, MACHINE_BUS_VLB))
|
||||
if ((device->flags & DEVICE_VLB) && !machine_has_bus(mch, MACHINE_BUS_VLB))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_PCI) && !machine_has_bus(m, MACHINE_BUS_PCI))
|
||||
if ((device->flags & DEVICE_PCI) && !machine_has_bus(mch, MACHINE_BUS_PCI))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_CARDBUS) && !machine_has_bus(m, MACHINE_BUS_CARDBUS) && !machine_has_bus(m, MACHINE_BUS_PCI))
|
||||
if ((device->flags & DEVICE_CARDBUS) && !machine_has_bus(mch, MACHINE_BUS_CARDBUS) && !machine_has_bus(mch, MACHINE_BUS_PCI))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_USB) && !machine_has_bus(m, MACHINE_BUS_USB))
|
||||
if ((device->flags & DEVICE_USB) && !machine_has_bus(mch, MACHINE_BUS_USB))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_AGP) && !machine_has_bus(m, MACHINE_BUS_AGP))
|
||||
if ((device->flags & DEVICE_AGP) && !machine_has_bus(mch, MACHINE_BUS_AGP))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_AC97) && !machine_has_bus(m, MACHINE_BUS_AC97))
|
||||
if ((device->flags & DEVICE_AC97) && !machine_has_bus(mch, MACHINE_BUS_AC97))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
machine_get_config_int(char *s)
|
||||
machine_get_config_int(char *str)
|
||||
{
|
||||
const device_t *d = machine_get_device(machine);
|
||||
const device_config_t *c;
|
||||
const device_t *dev = machine_get_device(machine);
|
||||
const device_config_t *cfg;
|
||||
|
||||
if (d == NULL)
|
||||
if (dev == NULL)
|
||||
return 0;
|
||||
|
||||
c = d->config;
|
||||
while (c && c->type != -1) {
|
||||
if (!strcmp(s, c->name))
|
||||
return (config_get_int((char *) d->name, s, c->default_int));
|
||||
cfg = dev->config;
|
||||
while (cfg && cfg->type != CONFIG_END) {
|
||||
if (!strcmp(str, cfg->name))
|
||||
return (config_get_int((char *) dev->name, str, cfg->default_int));
|
||||
|
||||
c++;
|
||||
cfg++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
machine_get_config_string(char *s)
|
||||
machine_get_config_string(char *str)
|
||||
{
|
||||
const device_t *d = machine_get_device(machine);
|
||||
const device_config_t *c;
|
||||
const device_t *dev = machine_get_device(machine);
|
||||
const device_config_t *cfg;
|
||||
|
||||
if (d == NULL)
|
||||
if (dev == NULL)
|
||||
return 0;
|
||||
|
||||
c = d->config;
|
||||
while (c && c->type != -1) {
|
||||
if (!strcmp(s, c->name))
|
||||
return (config_get_string((char *) d->name, s, (char *) c->default_string));
|
||||
cfg = dev->config;
|
||||
while (cfg && cfg->type != CONFIG_END) {
|
||||
if (!strcmp(str, cfg->name))
|
||||
return (config_get_string((char *) dev->name, str, (char *) cfg->default_string));
|
||||
|
||||
c++;
|
||||
cfg++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -881,7 +882,7 @@ const device_t device_none = {
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -895,7 +896,7 @@ const device_t device_internal = {
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -57,7 +57,7 @@ add_library(dev OBJECT
|
||||
mouse_microtouch_touchscreen.c
|
||||
)
|
||||
|
||||
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT MSVC)
|
||||
target_link_libraries(86Box atomic)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -2127,6 +2127,13 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv)
|
||||
} else if (fast_reset && ((val & 0xf0) == 0xf0)) {
|
||||
pulse_output(dev, val & 0x0f);
|
||||
|
||||
dev->state = STATE_MAIN_IBF;
|
||||
return;
|
||||
} else if (val == 0xae) {
|
||||
/* Fast track it because of the LG MultiNet. */
|
||||
kbc_at_log("ATkbc: enable keyboard\n");
|
||||
set_enable_kbd(dev, 1);
|
||||
|
||||
dev->state = STATE_MAIN_IBF;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1961,18 +1961,24 @@ keyboard_at_write(void *priv)
|
||||
}
|
||||
} else {
|
||||
if (dev->flags & FLAG_CTRLDAT) {
|
||||
/* Special case - another command during another command that wants input - proceed
|
||||
/*
|
||||
Special case - another command during another command that wants input - proceed
|
||||
as normal but do not cancel the command (so keep waiting for input), unless the
|
||||
command in progress is ED (Set/reset LEDs). */
|
||||
if (val == 0xed) {
|
||||
keyboard_scan = 1;
|
||||
command in progress is ED (Set/reset LEDs).
|
||||
|
||||
It appears to also apply to command EE (Echo), F4 (Enable), F5 (Diable and Set
|
||||
Default), and F6 (SetDefault).
|
||||
*/
|
||||
if ((val == 0xed) || (val == 0xee) || (val == 0xf4) || (val == 0xf5) || (val == 0xf6))
|
||||
dev->flags &= ~FLAG_CTRLDAT;
|
||||
} else
|
||||
else
|
||||
dev->state = DEV_STATE_MAIN_WANT_IN;
|
||||
}
|
||||
|
||||
switch (val) {
|
||||
case 0xed: /* set/reset LEDs */
|
||||
if ((dev->flags & FLAG_CTRLDAT) && (dev->command == 0xed))
|
||||
keyboard_scan = 1;
|
||||
dev->command = val;
|
||||
keyboard_at_log("%s: set/reset LEDs\n", dev->name);
|
||||
dev->flags |= FLAG_CTRLDAT;
|
||||
|
||||
@@ -282,8 +282,8 @@ static const device_config_t serial_passthrough_config[] = {
|
||||
.type = CONFIG_SERPORT,
|
||||
.default_string = "",
|
||||
.file_filter = NULL,
|
||||
.spinner = {},
|
||||
.selection = {}
|
||||
.spinner = { 0 },
|
||||
.selection = { { 0 } }
|
||||
},
|
||||
#ifdef _WIN32
|
||||
{
|
||||
@@ -292,8 +292,8 @@ static const device_config_t serial_passthrough_config[] = {
|
||||
.type = CONFIG_STRING,
|
||||
.default_string = "\\\\.\\pipe\\86Box\\test",
|
||||
.file_filter = NULL,
|
||||
.spinner = {},
|
||||
.selection = {}
|
||||
.spinner = { 0 },
|
||||
.selection = { { 0 } }
|
||||
},
|
||||
#endif
|
||||
{
|
||||
|
||||
@@ -104,8 +104,8 @@ struct unittester_state {
|
||||
/* 0x04: Exit */
|
||||
uint8_t exit_code;
|
||||
};
|
||||
static struct unittester_state unittester;
|
||||
static const struct unittester_state unittester_defaults = {
|
||||
static struct unittester_state unittester;
|
||||
static struct unittester_state unittester_defaults = {
|
||||
.trigger_port = 0x0080,
|
||||
.iobase_port = 0xFFFF,
|
||||
.fsm1 = UT_FSM1_WAIT_8,
|
||||
@@ -589,7 +589,7 @@ unittester_trigger_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv))
|
||||
static void *
|
||||
unittester_init(UNUSED(const device_t *info))
|
||||
{
|
||||
unittester = (struct unittester_state) unittester_defaults;
|
||||
unittester = unittester_defaults;
|
||||
|
||||
unittester_exit_enabled = !!device_get_config_int("exit_enabled");
|
||||
|
||||
|
||||
@@ -1114,7 +1114,7 @@ static const device_config_t wdxt150_config[] = {
|
||||
.default_string = "",
|
||||
.default_int = 0x0320,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 }, /*W2*/
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "320H", .value = 0x0320 },
|
||||
{ .description = "324H", .value = 0x0324 },
|
||||
@@ -1128,7 +1128,7 @@ static const device_config_t wdxt150_config[] = {
|
||||
.default_string = "",
|
||||
.default_int = 5,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 }, /*W3*/
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "IRQ 5", .value = 5 },
|
||||
{ .description = "IRQ 4", .value = 4 },
|
||||
@@ -1142,7 +1142,7 @@ static const device_config_t wdxt150_config[] = {
|
||||
.default_string = "",
|
||||
.default_int = 0xc8000,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 }, /*W1*/
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "C800H", .value = 0xc8000 },
|
||||
{ .description = "CA00H", .value = 0xca000 },
|
||||
@@ -1156,7 +1156,7 @@ static const device_config_t wdxt150_config[] = {
|
||||
.default_string = "rev_1",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 }, /*W1*/
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "Revision 1.0", .internal_name = "rev_1", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 8192, .files = { WD_REV_1_BIOS_FILE, "" } },
|
||||
|
||||
@@ -238,7 +238,7 @@ static const device_config_t xtide_config[] = {
|
||||
.default_string = "xt",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 }, /*W1*/
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "Regular XT", .internal_name = "xt", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 8192, .files = { ROM_PATH_XT, "" } },
|
||||
@@ -260,7 +260,7 @@ static const device_config_t xtide_at_config[] = {
|
||||
.default_string = "at",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 }, /*W1*/
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "Regular AT", .internal_name = "at", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 8192, .files = { ROM_PATH_AT, "" } },
|
||||
|
||||
@@ -448,9 +448,13 @@ static hdd_preset_t hdd_speed_presets[] = {
|
||||
{ .name = "[ATA-2] Quantum Fireball 640AT", .internal_name = "FB64A341", .model = "QUANTUM FIREBALL 640AT", .zones = 2, .avg_spt = 120, .heads = 2, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3.1, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 },
|
||||
{ .name = "[ATA-2] Quantum Fireball TM1080AT", .internal_name = "TM10A462", .model = "QUANTUM FIREBALL TM1.0A", .zones = 2, .avg_spt = 120, .heads = 2, .rpm = 4500, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 },
|
||||
{ .name = "[ATA-2] Quantum Fireball TM1.2AT", .internal_name = "TM12A012", .model = "QUANTUM FIREBALL TM1.2A", .zones = 4, .avg_spt = 120, .heads = 2, .rpm = 4500, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 },
|
||||
{ .name = "[ATA-2] Quantum Fireball SE8.4A", .internal_name = "SE84A011", .model = "QUANTUM FIREBALL SE8.4A", .zones = 4, .avg_spt = 100, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
|
||||
{ .name = "[ATA-2] Quantum Fireball SE6.4A", .internal_name = "SE64A011", .model = "QUANTUM FIREBALL SE6.4A", .zones = 3, .avg_spt = 100, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
|
||||
{ .name = "[ATA-2] Quantum Fireball ST3.2AT", .internal_name = "ST32A461", .model = "QUANTUM FIREBALL ST3.2A", .zones = 4, .avg_spt = 100, .heads = 4, .rpm = 5400, .full_stroke_ms = 21, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
|
||||
{ .name = "[ATA-2] Quantum Fireball CR4.3AT", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 110, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 },
|
||||
{ .name = "[ATA-2] Quantum Fireball EX5.1AT", .internal_name = "EX51A012", .model = "QUANTUM FIREBALL EX5.1A", .zones = 8, .avg_spt = 110, .heads = 4, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 },
|
||||
{ .name = "[ATA-2] Quantum Fireball CR4.3AT", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 110, .heads = 3, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 },
|
||||
{ .name = "[ATA-2] Quantum Fireball EX5.1A", .internal_name = "EX51A012", .model = "QUANTUM FIREBALL EX5.1A", .zones = 8, .avg_spt = 110, .heads = 4, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 },
|
||||
{ .name = "[ATA-2] Quantum Fireball EX10.2A", .internal_name = "EX10A011", .model = "QUANTUM FIREBALL EX10.2A", .zones = 3, .avg_spt = 110, .heads = 6, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 },
|
||||
{ .name = "[ATA-2] Quantum Fireball EX12.7A", .internal_name = "EX12A011", .model = "QUANTUM FIREBALL EX12.7A", .zones = 4, .avg_spt = 110, .heads = 8, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 },
|
||||
{ .name = "[ATA-2] Samsung PLS-31274A", .internal_name = "PLS31274A", .model = "SAMSUNG PLS-31274A", .zones = 4, .avg_spt = 110, .heads = 4, .rpm = 4500, .full_stroke_ms = 45, .track_seek_ms = 4.5, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 },
|
||||
{ .name = "[ATA-2] Samsung Winner-1", .internal_name = "WNR31601A", .model = "SAMSUNG WNR-31601A", .zones = 8, .avg_spt = 110, .heads = 4, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
|
||||
{ .name = "[ATA-2] Seagate Medalist (ST3780A)", .internal_name = "ST3780A", .model = "ST3780A", .zones = 8, .avg_spt = 120, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 16 },
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
add_library(fdd OBJECT
|
||||
fdd.c
|
||||
fdc.c
|
||||
fdc_compaticard.c
|
||||
fdc_magitronic.c
|
||||
fdc_monster.c
|
||||
fdc_pii15xb.c
|
||||
|
||||
@@ -103,15 +103,18 @@ typedef const struct {
|
||||
|
||||
static fdc_cards_t fdc_cards[] = {
|
||||
// clang-format off
|
||||
{ &device_none },
|
||||
{ &device_internal },
|
||||
{ &fdc_xt_device },
|
||||
{ &fdc_at_device },
|
||||
{ &fdc_b215_device },
|
||||
{ &fdc_pii151b_device },
|
||||
{ &fdc_pii158b_device },
|
||||
{ &fdc_monster_device },
|
||||
{ NULL }
|
||||
{ &device_none },
|
||||
{ &device_internal },
|
||||
{ &fdc_b215_device },
|
||||
{ &fdc_pii151b_device },
|
||||
{ &fdc_pii158b_device },
|
||||
{ &fdc_compaticard_i_device },
|
||||
{ &fdc_compaticard_ii_device },
|
||||
#if 0
|
||||
{ &fdc_compaticard_iv_device },
|
||||
#endif
|
||||
{ &fdc_monster_device },
|
||||
{ NULL }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
||||
355
src/floppy/fdc_compaticard.c
Normal file
355
src/floppy/fdc_compaticard.c
Normal file
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Emulation of Micro Solutions CompatiCard I/II/IV.
|
||||
*
|
||||
* Authors: Jasmine Iwanek, <jasmine@iwanek.co.uk>
|
||||
*
|
||||
* Copyright 2022-2025 Jasmine Iwanek.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/fdc_ext.h>
|
||||
|
||||
#define DEVICE_COMPATICARD_I 0
|
||||
#define DEVICE_COMPATICARD_II 1
|
||||
#define DEVICE_COMPATICARD_IV 2
|
||||
|
||||
#define BIOS_ADDR (uint32_t)(device_get_config_hex20("bios_addr") & 0x000fffff)
|
||||
#define ROM_COMPATICARD_IV "roms/floppy/compaticard/ccivbios1.05.bin"
|
||||
|
||||
#define CR_2_MASK 0x2f /* 00101111b */
|
||||
|
||||
typedef struct compaticard_s {
|
||||
rom_t bios_rom;
|
||||
fdc_t *fdc;
|
||||
/*
|
||||
* 7 - Reserved - Set to 0
|
||||
* 6 - Reserved - Set to 0
|
||||
* 5 - Programmable Pin 2 Logic I sets Pin 2 low (TODO)
|
||||
* 4 - Reserved - Set to 0
|
||||
* 3-0 - Data Transfer Rate Select (TODO)
|
||||
* 0000---250 Kbps
|
||||
* 0001-300 Kbps
|
||||
* 1111-500 Kbps
|
||||
*/
|
||||
uint8_t cr_2;
|
||||
} compaticard_t;
|
||||
|
||||
static void
|
||||
compaticard_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
compaticard_t *dev = (compaticard_t *) priv;
|
||||
|
||||
dev->cr_2 = (val & CR_2_MASK);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
compaticard_in(uint16_t port, void *priv)
|
||||
{
|
||||
compaticard_t *dev = (compaticard_t *) priv;
|
||||
uint8_t ret = (dev->cr_2 &CR_2_MASK);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
compaticard_close(void *priv)
|
||||
{
|
||||
compaticard_t *dev = (compaticard_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
compaticard_init(const device_t *info)
|
||||
{
|
||||
compaticard_t *dev = calloc(1, sizeof(compaticard_t));
|
||||
uint16_t base_addr = device_get_config_hex16("base");
|
||||
uint8_t irq = 6;
|
||||
uint8_t dma = 2;
|
||||
uint16_t cr2_addr = 0x7f2; // Control Register 2
|
||||
|
||||
// CompatiCard II & IV have configurable IRQ and DMA
|
||||
if (info->local >= DEVICE_COMPATICARD_II) {
|
||||
irq = device_get_config_int("irq");
|
||||
dma = device_get_config_int("dma");
|
||||
}
|
||||
|
||||
// Only on CompatiCard IV
|
||||
if ((info->local == DEVICE_COMPATICARD_IV) && (BIOS_ADDR != 0))
|
||||
rom_init(&dev->bios_rom, ROM_COMPATICARD_IV, BIOS_ADDR, 0x2000, 0x1ffff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
// TODO: Make this neater
|
||||
switch (base_addr) {
|
||||
case FDC_SECONDARY_ADDR:
|
||||
cr2_addr = 0x772;
|
||||
if (info->local == DEVICE_COMPATICARD_IV)
|
||||
dev->fdc = device_add(&fdc_at_sec_device);
|
||||
else
|
||||
dev->fdc = device_add(&fdc_xt_sec_device);
|
||||
break;
|
||||
|
||||
case FDC_TERTIARY_ADDR:
|
||||
cr2_addr = 0x762;
|
||||
if (info->local == DEVICE_COMPATICARD_IV)
|
||||
dev->fdc = device_add(&fdc_at_ter_device);
|
||||
else
|
||||
dev->fdc = device_add(&fdc_xt_ter_device);
|
||||
break;
|
||||
|
||||
case FDC_QUATERNARY_ADDR:
|
||||
cr2_addr = 0x7e2;
|
||||
if (info->local == DEVICE_COMPATICARD_IV)
|
||||
dev->fdc = device_add(&fdc_at_qua_device);
|
||||
else
|
||||
dev->fdc = device_add(&fdc_xt_qua_device);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (info->local == DEVICE_COMPATICARD_IV)
|
||||
dev->fdc = device_add(&fdc_at_device);
|
||||
else
|
||||
dev->fdc = device_add(&fdc_xt_device);
|
||||
break;
|
||||
}
|
||||
|
||||
fdc_set_irq(dev->fdc, irq);
|
||||
fdc_set_dma_ch(dev->fdc, dma);
|
||||
|
||||
io_sethandler(cr2_addr, 0x0001,
|
||||
compaticard_in, NULL, NULL,
|
||||
compaticard_out, NULL, NULL,
|
||||
dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static int compaticard_iv_available(void)
|
||||
{
|
||||
return rom_present(ROM_COMPATICARD_IV);
|
||||
}
|
||||
|
||||
static const device_config_t compaticard_i_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "base",
|
||||
.description = "Address",
|
||||
.type = CONFIG_HEX16,
|
||||
.default_string = "",
|
||||
.default_int = 0x3f0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "0x3f0", .value = 0x3f0 },
|
||||
{ .description = "0x370", .value = 0x370 },
|
||||
{ .description = "0x360", .value = 0x360 },
|
||||
{ .description = "0x3e0", .value = 0x3e0 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static const device_config_t compaticard_ii_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "base",
|
||||
.description = "Address",
|
||||
.type = CONFIG_HEX16,
|
||||
.default_string = "",
|
||||
.default_int = 0x3f0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "0x3f0", .value = 0x3f0 },
|
||||
{ .description = "0x370", .value = 0x370 },
|
||||
{ .description = "0x360", .value = 0x360 },
|
||||
{ .description = "0x3e0", .value = 0x3e0 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{
|
||||
.name = "irq",
|
||||
.description = "IRQ",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = 6,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "IRQ 2", .value = 2 },
|
||||
{ .description = "IRQ 3", .value = 3 },
|
||||
{ .description = "IRQ 4", .value = 4 },
|
||||
{ .description = "IRQ 5", .value = 5 },
|
||||
{ .description = "IRQ 6", .value = 6 },
|
||||
{ .description = "IRQ 7", .value = 7 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{
|
||||
.name = "dma",
|
||||
.description = "DMA channel",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = 2,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "DMA 1", .value = 1 },
|
||||
{ .description = "DMA 2", .value = 2 },
|
||||
{ .description = "DMA 3", .value = 3 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static const device_config_t compaticard_iv_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "base",
|
||||
.description = "Address",
|
||||
.type = CONFIG_HEX16,
|
||||
.default_string = "",
|
||||
.default_int = 0x3f0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "0x3f0", .value = 0x3f0 },
|
||||
{ .description = "0x370", .value = 0x370 },
|
||||
{ .description = "0x360", .value = 0x360 },
|
||||
{ .description = "0x3e0", .value = 0x3e0 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{
|
||||
.name = "irq",
|
||||
.description = "IRQ",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = 6,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "IRQ 2", .value = 2 },
|
||||
{ .description = "IRQ 3", .value = 3 },
|
||||
{ .description = "IRQ 4", .value = 4 },
|
||||
{ .description = "IRQ 5", .value = 5 },
|
||||
{ .description = "IRQ 6", .value = 6 },
|
||||
{ .description = "IRQ 7", .value = 7 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{
|
||||
.name = "dma",
|
||||
.description = "DMA channel",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = 2,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "DMA 1", .value = 1 },
|
||||
{ .description = "DMA 2", .value = 2 },
|
||||
{ .description = "DMA 3", .value = 3 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{
|
||||
.name = "bios_addr",
|
||||
.description = "BIOS Address:",
|
||||
.type = CONFIG_HEX20,
|
||||
.default_string = "",
|
||||
.default_int = 0xce000,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Disabled", .value = 0 },
|
||||
{ .description = "CC00H", .value = 0xcc000 },
|
||||
{ .description = "CE00H", .value = 0xce000 },
|
||||
{ .description = "D000H", .value = 0xd0000 },
|
||||
{ .description = "D800H", .value = 0xd8000 },
|
||||
{ .description = "DE00H", .value = 0xde000 },
|
||||
{ .description = "E000H", .value = 0xe0000 },
|
||||
{ .description = "E800H", .value = 0xe8000 },
|
||||
{ .description = "EE00H", .value = 0xee000 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
#if 0
|
||||
{
|
||||
.name = "autoboot_enabled",
|
||||
.description = "Enable Autoboot",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_string = "",
|
||||
.default_int = 0
|
||||
},
|
||||
#endif
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t fdc_compaticard_i_device = {
|
||||
.name = "Micro Solutions CompatiCard I",
|
||||
.internal_name = "compaticard_i",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = compaticard_init,
|
||||
.close = compaticard_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = compaticard_i_config
|
||||
};
|
||||
|
||||
const device_t fdc_compaticard_ii_device = {
|
||||
.name = "Micro Solutions CompatiCard II",
|
||||
.internal_name = "compaticard_ii",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 1,
|
||||
.init = compaticard_init,
|
||||
.close = compaticard_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = compaticard_ii_config
|
||||
};
|
||||
|
||||
const device_t fdc_compaticard_iv_device = {
|
||||
.name = "Micro Solutions CompatiCard IV",
|
||||
.internal_name = "compaticard_iv",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 2,
|
||||
.init = compaticard_init,
|
||||
.close = compaticard_close,
|
||||
.reset = NULL,
|
||||
.available = compaticard_iv_available,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = compaticard_iv_config
|
||||
};
|
||||
@@ -20,7 +20,11 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#endif
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/timer.h>
|
||||
|
||||
@@ -62,17 +62,13 @@ joystick_standard_read(UNUSED(void *priv))
|
||||
{
|
||||
uint8_t ret = 0xf0;
|
||||
|
||||
if (JOYSTICK_PRESENT(0)) {
|
||||
if (joystick_state[0].button[0])
|
||||
ret &= ~0x10;
|
||||
if (joystick_state[0].button[1])
|
||||
ret &= ~0x20;
|
||||
}
|
||||
if (JOYSTICK_PRESENT(1)) {
|
||||
if (joystick_state[1].button[0])
|
||||
ret &= ~0x40;
|
||||
if (joystick_state[1].button[1])
|
||||
ret &= ~0x80;
|
||||
for (int js = 0; js < 2; js++) {
|
||||
if (JOYSTICK_PRESENT(js)) {
|
||||
if (joystick_state[js].button[0])
|
||||
ret &= ~0x10;
|
||||
if (joystick_state[js].button[1])
|
||||
ret &= ~0x20;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -140,9 +136,7 @@ joystick_standard_read_axis_4button(UNUSED(void *priv), int axis)
|
||||
case 1:
|
||||
return joystick_state[0].axis[1];
|
||||
case 2:
|
||||
return 0;
|
||||
case 3:
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -162,7 +156,6 @@ joystick_standard_read_axis_3axis(UNUSED(void *priv), int axis)
|
||||
case 2:
|
||||
return joystick_state[0].axis[2];
|
||||
case 3:
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -119,8 +119,7 @@ sw_parity(uint16_t data)
|
||||
static void *
|
||||
sw_init(void)
|
||||
{
|
||||
sw_data *sw = (sw_data *) malloc(sizeof(sw_data));
|
||||
memset(sw, 0, sizeof(sw_data));
|
||||
sw_data *sw = (sw_data *) calloc(1, sizeof(sw_data));
|
||||
|
||||
timer_add(&sw->poll_timer, sw_timer_over, sw, 0);
|
||||
timer_add(&sw->trigger_timer, sw_trigger_timer_over, sw, 0);
|
||||
@@ -191,24 +190,24 @@ sw_write(void *priv)
|
||||
sw->poll_data = 1;
|
||||
}
|
||||
|
||||
for (uint8_t c = 0; c < 4; c++) {
|
||||
for (uint8_t js = 0; js < 4; js++) {
|
||||
uint16_t data = 0x3fff;
|
||||
|
||||
if (!JOYSTICK_PRESENT(c))
|
||||
if (!JOYSTICK_PRESENT(js))
|
||||
break;
|
||||
|
||||
if (joystick_state[c].axis[1] < -16383)
|
||||
if (joystick_state[js].axis[1] < -16383)
|
||||
data &= ~1;
|
||||
if (joystick_state[c].axis[1] > 16383)
|
||||
if (joystick_state[js].axis[1] > 16383)
|
||||
data &= ~2;
|
||||
if (joystick_state[c].axis[0] > 16383)
|
||||
if (joystick_state[js].axis[0] > 16383)
|
||||
data &= ~4;
|
||||
if (joystick_state[c].axis[0] < -16383)
|
||||
if (joystick_state[js].axis[0] < -16383)
|
||||
data &= ~8;
|
||||
|
||||
for (uint8_t b = 0; b < 10; b++) {
|
||||
if (joystick_state[c].button[b])
|
||||
data &= ~(1 << (b + 4));
|
||||
for (uint8_t button_nr = 0; button_nr < 10; button_nr++) {
|
||||
if (joystick_state[js].button[button_nr])
|
||||
data &= ~(1 << (button_nr + 4));
|
||||
}
|
||||
|
||||
if (sw_parity(data))
|
||||
@@ -216,10 +215,10 @@ sw_write(void *priv)
|
||||
|
||||
if (sw->poll_mode) {
|
||||
sw->poll_left += 5;
|
||||
sw->poll_data |= (data << (c * 15 + 3));
|
||||
sw->poll_data |= (data << (js * 15 + 3));
|
||||
} else {
|
||||
sw->poll_left += 15;
|
||||
sw->poll_data |= (data << (c * 15 + 1));
|
||||
sw->poll_data |= (data << (js * 15 + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,12 +187,17 @@ extern int config_changed; /* config has changed */
|
||||
|
||||
/* Function prototypes. */
|
||||
#ifdef HAVE_STDARG_H
|
||||
extern void pclog_ex(const char *fmt, va_list);
|
||||
extern void fatal_ex(const char *fmt, va_list);
|
||||
extern void pclog_ex(const char *fmt, va_list ap);
|
||||
extern void fatal_ex(const char *fmt, va_list ap);
|
||||
#endif
|
||||
extern void pclog_toggle_suppr(void);
|
||||
#ifdef _MSC_VER
|
||||
extern void pclog(const char *fmt, ...);
|
||||
extern void fatal(const char *fmt, ...);
|
||||
#else
|
||||
extern void pclog(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
extern void fatal(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
#endif
|
||||
extern void set_screen_size(int x, int y);
|
||||
extern void set_screen_size_monitor(int x, int y, int monitor_index);
|
||||
extern void reset_screen_size(void);
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2021 Andreas J. Reichel.
|
||||
* Copyright 2021-2022 Jasmine Iwanek.
|
||||
* Copyright 2021-2025 Jasmine Iwanek.
|
||||
*
|
||||
* 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
|
||||
@@ -197,12 +197,12 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
extern void device_init(void);
|
||||
extern void device_set_context(device_context_t *c, const device_t *dev, int inst);
|
||||
extern void device_set_context(device_context_t *ctx, const device_t *dev, int inst);
|
||||
extern void device_context(const device_t *dev);
|
||||
extern void device_context_inst(const device_t *dev, int inst);
|
||||
extern void device_context_restore(void);
|
||||
extern void *device_add(const device_t *d);
|
||||
extern void *device_add_linked(const device_t *d, void *priv);
|
||||
extern void *device_add(const device_t *dev);
|
||||
extern void *device_add_linked(const device_t *dev, void *priv);
|
||||
extern void *device_add_params(const device_t *dev, void *params);
|
||||
extern void device_add_ex(const device_t *dev, void *priv);
|
||||
extern void device_add_ex_params(const device_t *dev, void *priv, void *params);
|
||||
@@ -223,27 +223,27 @@ extern void device_get_name(const device_t *dev, int bus, char *name);
|
||||
extern int device_has_config(const device_t *dev);
|
||||
extern const char *device_get_bios_file(const device_t *dev, const char *internal_name, int file_no);
|
||||
|
||||
extern int device_is_valid(const device_t *, int m);
|
||||
extern int device_is_valid(const device_t *, int mch);
|
||||
|
||||
extern const device_t* device_context_get_device(void);
|
||||
|
||||
extern int device_get_config_int(const char *name);
|
||||
extern int device_get_config_int_ex(const char *s, int dflt_int);
|
||||
extern int device_get_config_int_ex(const char *str, int def);
|
||||
extern int device_get_config_hex16(const char *name);
|
||||
extern int device_get_config_hex20(const char *name);
|
||||
extern int device_get_config_mac(const char *name, int dflt_int);
|
||||
extern void device_set_config_int(const char *s, int val);
|
||||
extern void device_set_config_hex16(const char *s, int val);
|
||||
extern void device_set_config_hex20(const char *s, int val);
|
||||
extern void device_set_config_mac(const char *s, int val);
|
||||
extern int device_get_config_mac(const char *name, int def);
|
||||
extern void device_set_config_int(const char *str, int val);
|
||||
extern void device_set_config_hex16(const char *str, int val);
|
||||
extern void device_set_config_hex20(const char *str, int val);
|
||||
extern void device_set_config_mac(const char *str, int val);
|
||||
extern const char *device_get_config_string(const char *name);
|
||||
extern int device_get_instance(void);
|
||||
#define device_get_config_bios device_get_config_string
|
||||
|
||||
extern const char *device_get_internal_name(const device_t *dev);
|
||||
|
||||
extern int machine_get_config_int(char *s);
|
||||
extern char *machine_get_config_string(char *s);
|
||||
extern int machine_get_config_int(char *str);
|
||||
extern char *machine_get_config_string(char *str);
|
||||
|
||||
extern const device_t device_none;
|
||||
extern const device_t device_internal;
|
||||
|
||||
@@ -34,6 +34,10 @@ extern const device_t fdc_b215_device;
|
||||
extern const device_t fdc_pii151b_device;
|
||||
extern const device_t fdc_pii158b_device;
|
||||
|
||||
extern const device_t fdc_compaticard_i_device;
|
||||
extern const device_t fdc_compaticard_ii_device;
|
||||
extern const device_t fdc_compaticard_iv_device;
|
||||
|
||||
extern const device_t fdc_monster_device;
|
||||
|
||||
extern void fdc_card_init(void);
|
||||
|
||||
@@ -12,9 +12,11 @@
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Connor Hyde <mario64crashed@gmail.com, nomorestarfrost@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Miran Grca.
|
||||
* Copyright 2021 Fred N. van Kempen.
|
||||
* Copyright 2025 Connor Hyde.
|
||||
*/
|
||||
|
||||
#ifndef EMU_LOG_H
|
||||
@@ -26,11 +28,16 @@
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
#define LOG_SIZE_BUFFER 1024 /* Log size buffer */
|
||||
#define LOG_SIZE_BUFFER_CYCLIC_LINES 32 /* Cyclic log size buffer (number of lines that should be cehcked) */
|
||||
#define LOG_MINIMUM_REPEAT_ORDER 4 /* Minimum repeat size */
|
||||
|
||||
/* Function prototypes. */
|
||||
extern void log_set_suppr_seen(void *priv, int suppr_seen);
|
||||
extern void log_set_dev_name(void *priv, char *dev_name);
|
||||
# ifdef HAVE_STDARG_H
|
||||
extern void log_out(void *priv, const char *fmt, va_list);
|
||||
extern void log_out_cyclic(void* priv, const char *fmt, va_list);
|
||||
extern void log_fatal(void *priv, const char *fmt, ...);
|
||||
# endif
|
||||
extern void *log_open(char *dev_name);
|
||||
|
||||
@@ -817,6 +817,7 @@ extern int machine_at_p2bls_init(const machine_t *);
|
||||
extern int machine_at_lgibmx7g_init(const machine_t *);
|
||||
extern int machine_at_p3bf_init(const machine_t *);
|
||||
extern int machine_at_bf6_init(const machine_t *);
|
||||
extern int machine_at_bx6_init(const machine_t *);
|
||||
extern int machine_at_ax6bc_init(const machine_t *);
|
||||
extern int machine_at_atc6310bxii_init(const machine_t *);
|
||||
extern int machine_at_686bx_init(const machine_t *);
|
||||
|
||||
84
src/include/86box/nv/vid_nv_rivatimer.h
Normal file
84
src/include/86box/nv/vid_nv_rivatimer.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Fast, high-frequency, guest CPU-independent timer for Riva emulation.
|
||||
*
|
||||
*
|
||||
* Authors: Connor Hyde, <mario64crashed@gmail.com> I need a better email address ;^)
|
||||
*
|
||||
* Copyright 2024-2025 starfrost
|
||||
*/
|
||||
|
||||
/*
|
||||
RivaTimer
|
||||
|
||||
This is a fast, high-frequency, guest CPU-independent timer.
|
||||
|
||||
The main 86box timer is dependent on the TSC (time-stamp counter) register of the emulated CPU core.
|
||||
This is fine for most purposes and has advantages in the fields of synchronisation and integrates neatly with
|
||||
the clock dividers of the PC architecture, but in the case of the RIVA 128 it does not particularly suffice
|
||||
(although it can be made to work with various techniques) since the clock source on the RIVA 128 is on the board itself
|
||||
and the GPU has several different clocks that control different parts of the GPU (e.g., PTIMER runs on the memory clock but the core gpu is using the pixel clock).
|
||||
|
||||
As faster graphics cards that offload more and more of the 3D graphics pipeline are emulated in the future, more and more work needs to be done by the emulator and
|
||||
issues of synchronisation with a host CPU will simply make that work harder. Some features that are required for
|
||||
|
||||
Architecture Brand Name 3D Features
|
||||
NV1 (1995) NV1 Some weird URBS rectangle crap but feature set generally similar to nv3 but a bit worse
|
||||
NV3 (1997) RIVA 128 (ZX) Triangle setup, edge-slope calculations, edge interpolation, span-slope calculations, span interpolation (Color-buffer, z-buffer, texture mapping, filtering)
|
||||
NV4 (1998) RIVA TNT NV3 + 2x1 pixel pipelines + 32-bit colour + larger textures + trilinear + more ram (16mb)
|
||||
NV5 (1999) RIVA TNT2 NV4 + higher clock speed
|
||||
NV10 (1999) GeForce 256 NV5 + initial geometry transformation + lighting (8x lights) + MPEG-2 motion compensation + 4x1 pixel pipelines
|
||||
NV15 (2000) GeForce 2 NV10 + First attempt at programmability + 4x2 pixel pipelines
|
||||
NV20 (2001) GeForce 3 Programmable shaders!
|
||||
|
||||
As you can see, the performance basically exponentially increases over a period of only 4 years.
|
||||
|
||||
So I decided to create this timer that is completely separate from the CPU Core.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <86box/86box.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
// Linux & MacOS should have the same API since OSX 10.12
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
typedef struct rivatimer_s
|
||||
{
|
||||
struct rivatimer_s* prev; // Previous Rivatimer
|
||||
double period; // Period in uS before firing
|
||||
double value; // The current value of the rivatimer
|
||||
bool running; // Is this RivaTimer running?
|
||||
struct rivatimer_s* next; // Next RivaTimer
|
||||
void (*callback)(double real_time); // Callback to call on fire
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER starting_time; // Starting time.
|
||||
#else
|
||||
struct timespec starting_time; // Starting time.
|
||||
#endif
|
||||
double time; // Accumulated time in uS.
|
||||
} rivatimer_t;
|
||||
|
||||
void rivatimer_init(void); // Initialise the Rivatimer.
|
||||
rivatimer_t* rivatimer_create(double period, void (*callback)(double real_time));
|
||||
void rivatimer_destroy(rivatimer_t* rivatimer_ptr);
|
||||
|
||||
void rivatimer_update_all(void);
|
||||
void rivatimer_start(rivatimer_t* rivatimer_ptr);
|
||||
void rivatimer_stop(rivatimer_t* rivatimer_ptr);
|
||||
double rivatimer_get_time(rivatimer_t* rivatimer_ptr);
|
||||
void rivatimer_set_callback(rivatimer_t* rivatimer_ptr, void (*callback)(double real_time));
|
||||
void rivatimer_set_period(rivatimer_t* rivatimer_ptr, double period);
|
||||
@@ -104,6 +104,7 @@ typedef struct ncr_t {
|
||||
int state;
|
||||
int clear_req;
|
||||
int wait_data;
|
||||
int wait_data_back;
|
||||
int wait_complete;
|
||||
int command_pos;
|
||||
int data_pos;
|
||||
|
||||
@@ -29,15 +29,19 @@
|
||||
|
||||
enum {
|
||||
SADLIB = 1, /* No DSP */
|
||||
SB1, /* DSP v1.05 */
|
||||
SB15, /* DSP v2.00 */
|
||||
SB2, /* DSP v2.01 - needed for high-speed DMA */
|
||||
SBPRO, /* DSP v3.00 */
|
||||
SBPRO2, /* DSP v3.02 + OPL3 */
|
||||
SB16, /* DSP v4.05 + OPL3 */
|
||||
SBAWE32, /* DSP v4.12 + OPL3 */
|
||||
SBAWE32PNP, /* DSP v4.13 + OPL3 */
|
||||
SBAWE64 /* DSP v4.16 + OPL3 */
|
||||
SB_DSP_105, /* DSP v1.05, Original CT1320 (Also known as CT1310) */
|
||||
SB_DSP_200, /* DSP v2.00 */
|
||||
SB_DSP_201, /* DSP v2.01 - needed for high-speed DMA, Seen on CT1350B with CT1336 */
|
||||
SB_DSP_202, /* DSP v2.02 - Seen on CT1350B with CT1336A */
|
||||
SBPRO_DSP_300, /* DSP v3.00 */
|
||||
SBPRO2_DSP_302, /* DSP v3.02 + OPL3 */
|
||||
SB16_DSP_404, /* DSP v4.05 + OPL3 */
|
||||
SB16_DSP_405, /* DSP v4.05 + OPL3 */
|
||||
SB16_DSP_406, /* DSP v4.06 + OPL3 */
|
||||
SB16_DSP_411, /* DSP v4.11 + OPL3 */
|
||||
SBAWE32_DSP_412, /* DSP v4.12 + OPL3 */
|
||||
SBAWE32_DSP_413, /* DSP v4.13 + OPL3 */
|
||||
SBAWE64_DSP_416 /* DSP v4.16 + OPL3 */
|
||||
};
|
||||
|
||||
/* SB 2.0 CD version */
|
||||
|
||||
@@ -138,6 +138,7 @@ typedef struct ibm8514_t {
|
||||
int output2;
|
||||
|
||||
int ssv_len;
|
||||
int ssv_len_back;
|
||||
uint8_t ssv_dir;
|
||||
uint8_t ssv_draw;
|
||||
int odd_in;
|
||||
|
||||
167
src/log.c
167
src/log.c
@@ -12,12 +12,15 @@
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Connor Hyde <mario64crashed@gmail.com, nomorestarfrost@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Miran Grca.
|
||||
* Copyright 2021 Fred N. van Kempen.
|
||||
* Copyright 2025 Connor Hyde.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@@ -36,13 +39,31 @@
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
typedef struct log_t {
|
||||
char buff[1024];
|
||||
char *dev_name;
|
||||
int seen;
|
||||
int suppr_seen;
|
||||
char buff[1024];
|
||||
char *dev_name;
|
||||
int seen;
|
||||
int suppr_seen;
|
||||
char cyclic_buff[LOG_SIZE_BUFFER_CYCLIC_LINES][LOG_SIZE_BUFFER]; // Cyclical log buffer. This is 32kb, might calloc?
|
||||
int32_t cyclic_last_line;
|
||||
int32_t log_cycles;
|
||||
} log_t;
|
||||
|
||||
extern FILE *stdlog; /* file to log output to */
|
||||
// Functions only used in this translation unit
|
||||
void log_ensure_stdlog_open(void);
|
||||
|
||||
void
|
||||
log_ensure_stdlog_open(void)
|
||||
{
|
||||
if (stdlog == NULL) {
|
||||
if (log_path[0] != '\0') {
|
||||
stdlog = plat_fopen(log_path, "w");
|
||||
if (stdlog == NULL)
|
||||
stdlog = stdout;
|
||||
} else
|
||||
stdlog = stdout;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
log_set_suppr_seen(void *priv, int suppr_seen)
|
||||
@@ -91,14 +112,7 @@ log_out(void *priv, const char *fmt, va_list ap)
|
||||
if (strcmp(fmt, "") == 0)
|
||||
return;
|
||||
|
||||
if (stdlog == NULL) {
|
||||
if (log_path[0] != '\0') {
|
||||
stdlog = plat_fopen(log_path, "w");
|
||||
if (stdlog == NULL)
|
||||
stdlog = stdout;
|
||||
} else
|
||||
stdlog = stdout;
|
||||
}
|
||||
log_ensure_stdlog_open();
|
||||
|
||||
vsprintf(temp, fmt, ap);
|
||||
if (log->suppr_seen && !strcmp(log->buff, temp))
|
||||
@@ -117,6 +131,131 @@ log_out(void *priv, const char *fmt, va_list ap)
|
||||
fflush(stdlog);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Starfrost, 7-8 January 2025:
|
||||
|
||||
For RIVA 128 emulation I needed a way to suppress logging if a repeated pattern of the same set of lines were found.
|
||||
|
||||
Implements a version of the Rabin-Karp algorithm https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm
|
||||
*/
|
||||
void
|
||||
log_out_cyclic(void* priv, const char* fmt, va_list ap)
|
||||
{
|
||||
#ifndef RELEASE_BUILD
|
||||
// get our new logging system instance.
|
||||
log_t* log = (log_t*)priv;
|
||||
|
||||
// does the log actually exist?
|
||||
if (!log)
|
||||
return;
|
||||
|
||||
// is the string empty?
|
||||
if (fmt[0] == '\0')
|
||||
return;
|
||||
|
||||
// ensure stdlog is open
|
||||
log_ensure_stdlog_open();
|
||||
|
||||
char temp[LOG_SIZE_BUFFER] = {0};
|
||||
|
||||
log->cyclic_last_line %= LOG_SIZE_BUFFER_CYCLIC_LINES;
|
||||
|
||||
vsprintf(temp, fmt, ap);
|
||||
|
||||
log_copy(log, log->cyclic_buff[log->cyclic_last_line], temp, LOG_SIZE_BUFFER);
|
||||
|
||||
uint32_t hashes[LOG_SIZE_BUFFER_CYCLIC_LINES] = {0};
|
||||
|
||||
// Random numbers
|
||||
uint32_t base = 257;
|
||||
uint32_t mod = 1000000007;
|
||||
|
||||
uint32_t repeat_order = 0;
|
||||
bool is_cycle = false;
|
||||
|
||||
// compute the set of hashes for the current log buffer
|
||||
for (int32_t log_line = 0; log_line < LOG_SIZE_BUFFER_CYCLIC_LINES; log_line++)
|
||||
{
|
||||
if (log->cyclic_buff[log_line][0] == '\0')
|
||||
continue; // skip
|
||||
|
||||
for (int32_t log_line_char = 0; log_line_char < LOG_SIZE_BUFFER; log_line_char++)
|
||||
{
|
||||
hashes[log_line] = hashes[log_line] * base + log->cyclic_buff[log_line][log_line_char] % mod;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now see if there are real cycles...
|
||||
// We implement a minimum repeat size.
|
||||
for (int32_t check_size = LOG_MINIMUM_REPEAT_ORDER; check_size < LOG_SIZE_BUFFER_CYCLIC_LINES / 2; check_size++)
|
||||
{
|
||||
//TODO: Log what we need for cycle 1.
|
||||
//TODO: Command line option that lets us turn off this behaviour.
|
||||
for (int32_t log_line_to_check = 0; log_line_to_check < check_size; log_line_to_check++)
|
||||
{
|
||||
if (hashes[log_line_to_check] == hashes[(log_line_to_check + check_size) % LOG_SIZE_BUFFER_CYCLIC_LINES])
|
||||
{
|
||||
repeat_order = check_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
is_cycle = (repeat_order != 0);
|
||||
|
||||
// if there still is a cycle..
|
||||
if (is_cycle)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (is_cycle)
|
||||
{
|
||||
if (log->cyclic_last_line % repeat_order == 0)
|
||||
{
|
||||
log->log_cycles++;
|
||||
|
||||
if (log->log_cycles == 1)
|
||||
{
|
||||
// 'Replay' the last few log entries so they actually show up
|
||||
// Todo: is this right?
|
||||
|
||||
for (uint32_t index = log->cyclic_last_line - 1; index > (log->cyclic_last_line - repeat_order); index--)
|
||||
{
|
||||
// *very important* to prevent out of bounds index
|
||||
uint32_t real_index = index % LOG_SIZE_BUFFER_CYCLIC_LINES;
|
||||
log_copy(log, temp, log->cyclic_buff[real_index], LOG_SIZE_BUFFER);
|
||||
|
||||
fprintf(stdlog, "%s", log->cyclic_buff[real_index]);
|
||||
|
||||
}
|
||||
|
||||
// restore the original line
|
||||
log_copy(log, temp, log->cyclic_buff[log->cyclic_last_line], LOG_SIZE_BUFFER);
|
||||
|
||||
fprintf(stdlog, "%s", temp); // allow normal logging
|
||||
}
|
||||
|
||||
|
||||
if (log->log_cycles > 1 && log->log_cycles < 100)
|
||||
fprintf(stdlog, "***** Cyclical Log Repeat of Order %d #%d *****\n", repeat_order, log->log_cycles);
|
||||
else if (log->log_cycles == 100)
|
||||
fprintf(stdlog, "Logged the same cycle 100 times...shutting up until something interesting happens\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log->log_cycles = 0;
|
||||
fprintf(stdlog, "%s", temp);
|
||||
}
|
||||
|
||||
log->cyclic_last_line++;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
log_fatal(void *priv, const char *fmt, ...)
|
||||
{
|
||||
@@ -145,6 +284,8 @@ log_open(char *dev_name)
|
||||
|
||||
log->dev_name = dev_name;
|
||||
log->suppr_seen = 1;
|
||||
log->cyclic_last_line = 0;
|
||||
log->log_cycles = 0;
|
||||
|
||||
return (void *) log;
|
||||
}
|
||||
|
||||
@@ -13,10 +13,12 @@
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Jasmine Iwanek, <jriwanek@gmail.com>
|
||||
*
|
||||
* Copyright 2017-2020 Fred N. van Kempen.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
* Copyright 2025 Jasmine Iwanek.
|
||||
*
|
||||
* 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
|
||||
@@ -36,7 +38,6 @@
|
||||
* Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@@ -53,6 +54,7 @@
|
||||
#include <86box/fdc_ext.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/gameport.h>
|
||||
#include <86box/ibm_5161.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/lpt.h>
|
||||
#include <86box/rom.h>
|
||||
@@ -149,10 +151,41 @@ machine_at_ps2_ide_init(const machine_t *model)
|
||||
device_add(&ide_isa_device);
|
||||
}
|
||||
|
||||
static const device_config_t ibmat_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "enable_5161",
|
||||
.description = "IBM 5161 Expansion Unit",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 0
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t ibmat_device = {
|
||||
.name = " IBM AT Devices",
|
||||
.internal_name = "ibmat_device",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = ibmat_config
|
||||
};
|
||||
|
||||
int
|
||||
machine_at_ibm_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
int ret;
|
||||
uint8_t enable_5161;
|
||||
|
||||
device_context(model->device);
|
||||
enable_5161 = machine_get_config_int("enable_5161");
|
||||
device_context_restore();
|
||||
|
||||
ret = bios_load_interleaved("roms/machines/ibmat/62x0820.u27",
|
||||
"roms/machines/ibmat/62x0821.u47",
|
||||
@@ -163,6 +196,9 @@ machine_at_ibm_init(const machine_t *model)
|
||||
|
||||
machine_at_ibm_common_init(model);
|
||||
|
||||
if (enable_5161)
|
||||
device_add(&ibm_5161_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -218,10 +254,41 @@ machine_at_ibmatpx_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const device_config_t ibmxt286_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "enable_5161",
|
||||
.description = "IBM 5161 Expansion Unit",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 0
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t ibmxt286_device = {
|
||||
.name = "IBM XT Model 286 Devices",
|
||||
.internal_name = "ibmxt286_device",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = ibmxt286_config
|
||||
};
|
||||
|
||||
int
|
||||
machine_at_ibmxt286_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
int ret;
|
||||
uint8_t enable_5161;
|
||||
|
||||
device_context(model->device);
|
||||
enable_5161 = machine_get_config_int("enable_5161");
|
||||
device_context_restore();
|
||||
|
||||
ret = bios_load_interleaved("roms/machines/ibmxt286/bios_5162_21apr86_u34_78x7460_27256.bin",
|
||||
"roms/machines/ibmxt286/bios_5162_21apr86_u35_78x7461_27256.bin",
|
||||
@@ -232,6 +299,9 @@ machine_at_ibmxt286_init(const machine_t *model)
|
||||
|
||||
machine_at_ibm_common_init(model);
|
||||
|
||||
if (enable_5161)
|
||||
device_add(&ibm_5161_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ machine_at_neat_ami_init(const machine_t *model)
|
||||
|
||||
// TODO
|
||||
// Onboard Paradise PVGA1A-JK VGA Graphics
|
||||
// Data Technology Corporation DTC7187 RLL Controller
|
||||
// Data Technology Corporation DTC7187 RLL Controller (Optional)
|
||||
int
|
||||
machine_at_ataripc4_init(const machine_t *model)
|
||||
{
|
||||
@@ -222,10 +222,6 @@ machine_at_ataripc4_init(const machine_t *model)
|
||||
|
||||
ret = bios_load_interleaved("roms/machines/ataripc4/AMI_PC4X_1.7_EVEN.BIN",
|
||||
"roms/machines/ataripc4/AMI_PC4X_1.7_ODD.BIN",
|
||||
#if 0
|
||||
ret = bios_load_interleaved("roms/machines/ataripc4/ami_pc4x_1.7_even.bin",
|
||||
"roms/machines/ataripc4/ami_pc4x_1.7_odd.bin",
|
||||
#endif
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
|
||||
@@ -684,14 +684,57 @@ machine_at_403tg_d_mr_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const device_config_t pb450_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "pci10a",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "PCI 1.0A", .internal_name = "pci10a", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pb450/OPTI802.bin", "" } },
|
||||
{ .name = "PNP 1.1A", .internal_name = "pnp11a", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pb450/PNP11A.bin", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t pb450_device = {
|
||||
.name = "Packard Bell PB450 Devices",
|
||||
.internal_name = "pb450_device",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = pb450_config
|
||||
};
|
||||
|
||||
int
|
||||
machine_at_pb450_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
const char* fn;
|
||||
|
||||
ret = bios_load_linear("roms/machines/pb450/OPTI802.bin",
|
||||
0x000e0000, 131072, 0);
|
||||
/* No ROMs available */
|
||||
if (!device_available(model->device))
|
||||
return ret;
|
||||
|
||||
device_context(model->device);
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0);
|
||||
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
|
||||
device_context_restore();
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -359,6 +359,37 @@ machine_at_bf6_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_bx6_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/bx6/BX6_EG.BIN",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
|
||||
device_add(&i440bx_device);
|
||||
device_add(&piix4e_device);
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&w83977f_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_ax6bc_init(const machine_t *model)
|
||||
{
|
||||
|
||||
@@ -58,10 +58,6 @@ machine_at_acerv35n_init(const machine_t *model)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
/* Yes, it's called amstrad_mega_pc_nvr_device, but it's basically the
|
||||
standard AT NVR, just initialized to 0x00's (perhaps that should be the
|
||||
default behavior?). */
|
||||
device_add(&amstrad_megapc_nvr_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
|
||||
@@ -252,7 +252,7 @@ static const device_config_t ps1_2011_config[] = {
|
||||
.default_string = "english_us",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 }, /*W1*/
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "English (US)", .internal_name = "english_us", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/FC0000_US.BIN", "" } },
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Standard PC/AT implementation.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Jasmine Iwanek, <jriwanek@gmail.com>
|
||||
*
|
||||
* Copyright 2017-2020 Fred N. van Kempen.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
* Copyright 2025 Jasmine Iwanek.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@@ -37,22 +59,94 @@ machine_xt_common_init(const machine_t *model, int fixed_floppy)
|
||||
standalone_gameport_type = &gameport_device;
|
||||
}
|
||||
|
||||
static const device_config_t ibmpc_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "ibm5150_5700671",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "5700671 (10/19/81)", .internal_name = "ibm5150_5700671", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/ibmpc/BIOS_IBM5150_19OCT81_5700671_U33.BIN", "" } },
|
||||
{ .name = "5700051 (04/24/81)", .internal_name = "ibm5150_5700051", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/ibmpc/BIOS_IBM5150_24APR81_5700051_U33.BIN", "" } },
|
||||
// The following are Diagnostic ROMs.
|
||||
{ .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } },
|
||||
{ .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } },
|
||||
{ .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "enable_5161",
|
||||
.description = "IBM 5161 Expansion Unit",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 0
|
||||
},
|
||||
{
|
||||
.name = "enable_basic",
|
||||
.description = "IBM Cassette Basic",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 1
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t ibmpc_device = {
|
||||
.name = "IBM PC (1981) Device",
|
||||
.internal_name = "ibmpc_device",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = ibmpc_config
|
||||
};
|
||||
|
||||
int
|
||||
machine_pc_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
int ret2;
|
||||
uint8_t enable_5161;
|
||||
uint8_t enable_basic;
|
||||
const char *fn;
|
||||
|
||||
ret = bios_load_linear("roms/machines/ibmpc/BIOS_5150_24APR81_U33.BIN",
|
||||
0x000fe000, 40960, 0);
|
||||
if (ret) {
|
||||
bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U29 - 5700019.bin",
|
||||
0x000f6000, 8192, 0);
|
||||
bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U30 - 5700027.bin",
|
||||
0x000f8000, 8192, 0);
|
||||
bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U31 - 5700035.bin",
|
||||
0x000fa000, 8192, 0);
|
||||
bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U32 - 5700043.bin",
|
||||
0x000fc000, 8192, 0);
|
||||
/* No ROMs available. */
|
||||
if (!device_available(model->device))
|
||||
return ret;
|
||||
|
||||
device_context(model->device);
|
||||
enable_5161 = machine_get_config_int("enable_5161");
|
||||
enable_basic = machine_get_config_int("enable_basic");
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0);
|
||||
ret = bios_load_linear(fn, 0x000fe000, 40960, 0);
|
||||
device_context_restore();
|
||||
|
||||
if (enable_basic && ret) {
|
||||
ret2 = bios_load_aux_linear("roms/machines/ibmpc/ibm-basic-1.00.rom",
|
||||
0x000f6000, 32768, 0);
|
||||
if (!ret2) {
|
||||
bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U29 - 5700019.bin",
|
||||
0x000f6000, 8192, 0);
|
||||
bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U30 - 5700027.bin",
|
||||
0x000f8000, 8192, 0);
|
||||
bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U31 - 5700035.bin",
|
||||
0x000fa000, 8192, 0);
|
||||
bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U32 - 5700043.bin",
|
||||
0x000fc000, 8192, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (bios_only || !ret)
|
||||
@@ -62,28 +156,98 @@ machine_pc_init(const machine_t *model)
|
||||
|
||||
machine_xt_common_init(model, 0);
|
||||
|
||||
if (enable_5161)
|
||||
device_add(&ibm_5161_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const device_config_t ibmpc82_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "ibm5150_1501476",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "1501476 (10/27/82)", .internal_name = "ibm5150_1501476", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/ibmpc82/BIOS_5150_27OCT82_1501476_U33.BIN", "" } },
|
||||
{ .name = "5000024 (08/16/82)", .internal_name = "ibm5150_5000024", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/ibmpc82/BIOS_5150_16AUG82_5000024_U33.BIN", "" } },
|
||||
// The following are Diagnostic ROMs.
|
||||
{ .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } },
|
||||
{ .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } },
|
||||
{ .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "enable_5161",
|
||||
.description = "IBM 5161 Expansion Unit",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 1
|
||||
},
|
||||
{
|
||||
.name = "enable_basic",
|
||||
.description = "IBM Cassette Basic",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 1
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t ibmpc82_device = {
|
||||
.name = "IBM PC (1982) Devices",
|
||||
.internal_name = "ibmpc82_device",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = ibmpc82_config
|
||||
};
|
||||
|
||||
int
|
||||
machine_pc82_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
int ret2;
|
||||
int ret = 0;
|
||||
int ret2;
|
||||
uint8_t enable_5161;
|
||||
uint8_t enable_basic;
|
||||
const char *fn;
|
||||
|
||||
ret = bios_load_linear("roms/machines/ibmpc82/pc102782.bin",
|
||||
0x000fe000, 40960, 0);
|
||||
if (ret) {
|
||||
/* No ROMs available. */
|
||||
if (!device_available(model->device))
|
||||
return ret;
|
||||
|
||||
device_context(model->device);
|
||||
enable_5161 = machine_get_config_int("enable_5161");
|
||||
enable_basic = machine_get_config_int("enable_basic");
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0);
|
||||
ret = bios_load_linear(fn, 0x000fe000, 40960, 0);
|
||||
device_context_restore();
|
||||
|
||||
if (enable_basic && ret) {
|
||||
ret2 = bios_load_aux_linear("roms/machines/ibmpc82/ibm-basic-1.10.rom",
|
||||
0x000f6000, 32768, 0);
|
||||
if (!ret2) {
|
||||
bios_load_aux_linear("roms/machines/ibmpc82/basicc11.f6",
|
||||
bios_load_aux_linear("roms/machines/ibmpc82/IBM 5150 - Cassette BASIC version C1.10 - U29 - 5000019.bin",
|
||||
0x000f6000, 8192, 0);
|
||||
bios_load_aux_linear("roms/machines/ibmpc82/basicc11.f8",
|
||||
bios_load_aux_linear("roms/machines/ibmpc82/IBM 5150 - Cassette BASIC version C1.10 - U30 - 5000021.bin",
|
||||
0x000f8000, 8192, 0);
|
||||
bios_load_aux_linear("roms/machines/ibmpc82/basicc11.fa",
|
||||
bios_load_aux_linear("roms/machines/ibmpc82/IBM 5150 - Cassette BASIC version C1.10 - U31 - 5000022.bin",
|
||||
0x000fa000, 8192, 0);
|
||||
bios_load_aux_linear("roms/machines/ibmpc82/basicc11.fc",
|
||||
bios_load_aux_linear("roms/machines/ibmpc82/IBM 5150 - Cassette BASIC version C1.10 - U32 - 5000023.bin",
|
||||
0x000fc000, 8192, 0);
|
||||
}
|
||||
}
|
||||
@@ -92,40 +256,110 @@ machine_pc82_init(const machine_t *model)
|
||||
return ret;
|
||||
|
||||
device_add(&keyboard_pc82_device);
|
||||
device_add(&ibm_5161_device);
|
||||
|
||||
machine_xt_common_init(model, 0);
|
||||
|
||||
if (enable_5161)
|
||||
device_add(&ibm_5161_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const device_config_t ibmxt_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "ibm5160_1501512_5000027",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "1501512 (11/08/82)", .internal_name = "ibm5160_1501512_5000027", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt/BIOS_5160_08NOV82_U18_1501512.BIN", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" } },
|
||||
{ .name = "1501512 (11/08/82) (Alt)", .internal_name = "ibm5160_1501512_6359116", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt/BIOS_5160_08NOV82_U18_1501512.BIN", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_6359116.BIN", "" } },
|
||||
{ .name = "5000026 (08/16/82)", .internal_name = "ibm5160_5000026_5000027", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt/BIOS_5160_16AUG82_U18_5000026.BIN", "roms/machines/ibmxt/BIOS_5160_16AUG82_U19_5000027.BIN", "" } },
|
||||
#if 0
|
||||
// The following are Diagnostic ROMs.
|
||||
{ .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } },
|
||||
{ .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } },
|
||||
{ .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } },
|
||||
#endif
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "enable_5161",
|
||||
.description = "IBM 5161 Expansion Unit",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 1
|
||||
},
|
||||
{
|
||||
.name = "enable_basic",
|
||||
.description = "IBM Cassette Basic",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 1
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t ibmxt_device = {
|
||||
.name = "IBM XT (1982) Device",
|
||||
.internal_name = "ibmxt_device",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = ibmxt_config
|
||||
};
|
||||
|
||||
int
|
||||
machine_xt_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
uint8_t enable_5161;
|
||||
uint8_t enable_basic;
|
||||
const char *fn;
|
||||
|
||||
ret = bios_load_linear("roms/machines/ibmxt/xt.rom",
|
||||
0x000f0000, 65536, 0);
|
||||
if (!ret) {
|
||||
ret = bios_load_linear("roms/machines/ibmxt/1501512.u18",
|
||||
0x000fe000, 65536, 0x6000);
|
||||
if (ret) {
|
||||
bios_load_aux_linear("roms/machines/ibmxt/1501512.u18",
|
||||
0x000f8000, 24576, 0);
|
||||
bios_load_aux_linear("roms/machines/ibmxt/5000027.u19",
|
||||
0x000f0000, 32768, 0);
|
||||
}
|
||||
/* No ROMs available. */
|
||||
if (!device_available(model->device))
|
||||
return ret;
|
||||
|
||||
device_context(model->device);
|
||||
enable_5161 = machine_get_config_int("enable_5161");
|
||||
enable_basic = machine_get_config_int("enable_basic");
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0);
|
||||
ret = bios_load_linear(fn, 0x000fe000, 65536, 0x6000);
|
||||
|
||||
if (enable_basic && ret) {
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0);
|
||||
(void) bios_load_aux_linear(fn, 0x000f8000, 24576, 0);
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 1);
|
||||
(void) bios_load_aux_linear(fn, 0x000f0000, 32768, 0);
|
||||
}
|
||||
device_context_restore();
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
|
||||
device_add(&keyboard_xt_device);
|
||||
device_add(&ibm_5161_device);
|
||||
|
||||
machine_xt_common_init(model, 0);
|
||||
|
||||
if (enable_5161)
|
||||
device_add(&ibm_5161_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -147,28 +381,93 @@ machine_genxt_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const device_config_t ibmxt86_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "ibm5160_050986",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "1501512 (05/09/86)", .internal_name = "ibm5160_050986", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt86/BIOS_5160_09MAY86_U18_59X7268_62X0890_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" } },
|
||||
{ .name = "5000026 (01/10/86)", .internal_name = "ibm5160_011086", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt86/BIOS_5160_10JAN86_U18_62X0851_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_10JAN86_U19_62X0854_27256_F000.BIN", "" } },
|
||||
{ .name = "1501512 (01/10/86) (Alt)", .internal_name = "ibm5160_011086_alt", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt86/BIOS_5160_10JAN86_U18_62X0852_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_10JAN86_U19_62X0853_27256_F000.BIN", "" } },
|
||||
#if 0
|
||||
// The following are Diagnostic ROMs.
|
||||
{ .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } },
|
||||
{ .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } },
|
||||
{ .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } },
|
||||
#endif
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "enable_5161",
|
||||
.description = "IBM 5161 Expansion Unit",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 1
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t ibmxt86_device = {
|
||||
.name = "IBM XT (1986) Device",
|
||||
.internal_name = "ibmxt86_device",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = ibmxt86_config
|
||||
};
|
||||
|
||||
int
|
||||
machine_xt86_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
uint8_t enable_5161;
|
||||
const char *fn;
|
||||
|
||||
/* No ROMs available. */
|
||||
if (!device_available(model->device))
|
||||
return ret;
|
||||
|
||||
device_context(model->device);
|
||||
enable_5161 = machine_get_config_int("enable_5161");
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0);
|
||||
ret = bios_load_linear(fn, 0x000fe000, 65536, 0x6000);
|
||||
|
||||
ret = bios_load_linear("roms/machines/ibmxt86/BIOS_5160_09MAY86_U18_59X7268_62X0890_27256_F800.BIN",
|
||||
0x000fe000, 65536, 0x6000);
|
||||
if (ret) {
|
||||
(void) bios_load_aux_linear("roms/machines/ibmxt86/BIOS_5160_09MAY86_U18_59X7268_62X0890_27256_F800.BIN",
|
||||
0x000f8000, 24576, 0);
|
||||
(void) bios_load_aux_linear("roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN",
|
||||
0x000f0000, 32768, 0);
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0);
|
||||
(void) bios_load_aux_linear(fn, 0x000f8000, 24576, 0);
|
||||
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 1);
|
||||
(void) bios_load_aux_linear(fn, 0x000f0000, 32768, 0);
|
||||
}
|
||||
device_context_restore();
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
device_add(&keyboard_xt86_device);
|
||||
device_add(&ibm_5161_device);
|
||||
|
||||
machine_xt_common_init(model, 0);
|
||||
|
||||
if (enable_5161)
|
||||
device_add(&ibm_5161_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -214,6 +513,7 @@ machine_xt_amixt_init(const machine_t *model)
|
||||
|
||||
// TODO
|
||||
// Onboard EGA Graphics (NSI Logic EVC315-S on early boards STMicroelectronics EGA on later revisions)
|
||||
// RTC
|
||||
// Adaptec ACB-2072 RLL Controller Card (Optional)
|
||||
// Atari PCM1 Mouse Support
|
||||
int
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Jasmine Iwanek, <jriwanek@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2017-2020 Fred N. van Kempen.
|
||||
* Copyright 2025 Jasmine Iwanek.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -55,6 +57,13 @@ extern const device_t vid_device_sl;
|
||||
extern const device_t t1200_video_device;
|
||||
extern const device_t compaq_plasma_device;
|
||||
extern const device_t ps1_2011_device;
|
||||
extern const device_t ibmpc_device;
|
||||
extern const device_t ibmpc82_device;
|
||||
extern const device_t ibmxt_device;
|
||||
extern const device_t ibmxt86_device;
|
||||
extern const device_t ibmat_device;
|
||||
extern const device_t ibmxt286_device;
|
||||
extern const device_t pb450_device;
|
||||
|
||||
const machine_filter_t machine_types[] = {
|
||||
{ "None", MACHINE_TYPE_NONE },
|
||||
@@ -243,7 +252,7 @@ const machine_t machines[] = {
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.device = &ibmpc_device,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
@@ -282,7 +291,7 @@ const machine_t machines[] = {
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.device = &ibmpc82_device,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
@@ -360,7 +369,7 @@ const machine_t machines[] = {
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.device = &ibmxt_device,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
@@ -399,7 +408,7 @@ const machine_t machines[] = {
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.device = &ibmxt86_device,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
@@ -2673,7 +2682,7 @@ const machine_t machines[] = {
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.device = &ibmat_device,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
@@ -2793,7 +2802,7 @@ const machine_t machines[] = {
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.device = &ibmxt286_device,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
@@ -6880,7 +6889,7 @@ const machine_t machines[] = {
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.device = &pb450_device,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = &gd5428_vlb_onboard_device,
|
||||
@@ -14623,6 +14632,47 @@ const machine_t machines[] = {
|
||||
},
|
||||
/* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC
|
||||
firmware. */
|
||||
|
||||
{
|
||||
.name = "[i440BX] ABIT BX6",
|
||||
.internal_name = "bx6",
|
||||
.type = MACHINE_TYPE_SLOT1,
|
||||
.chipset = MACHINE_CHIPSET_INTEL_440BX,
|
||||
.init = machine_at_bx6_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_SLOT1,
|
||||
.block = CPU_BLOCK_NONE,
|
||||
.min_bus = 66666667,
|
||||
.max_bus = 133333333,
|
||||
.min_voltage = 1500,
|
||||
.max_voltage = 3500,
|
||||
.min_multi = 2.0,
|
||||
.max_multi = 5.5
|
||||
},
|
||||
.bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB,
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB,
|
||||
.ram = {
|
||||
.min = 8192,
|
||||
.max = 524288,
|
||||
.step = 8192
|
||||
},
|
||||
.nvrmask = 255,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
|
||||
{
|
||||
.name = "[i440BX] ABIT BF6",
|
||||
.internal_name = "bf6",
|
||||
|
||||
@@ -41,7 +41,10 @@ pkg_check_modules(SLIRP REQUIRED IMPORTED_TARGET slirp)
|
||||
target_link_libraries(86Box PkgConfig::SLIRP)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(PkgConfig::SLIRP INTERFACE wsock32 ws2_32 iphlpapi iconv)
|
||||
target_link_libraries(PkgConfig::SLIRP INTERFACE wsock32 ws2_32 iphlpapi)
|
||||
if (NOT MSVC)
|
||||
target_link_libraries(PkgConfig::SLIRP INTERFACE iconv)
|
||||
endif()
|
||||
if(STATIC_BUILD)
|
||||
add_compile_definitions(LIBSLIRP_STATIC)
|
||||
endif()
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#ifdef _MVC_VER
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
@@ -531,14 +534,14 @@ rtl8139_write_buffer(RTL8139State *s, const void *buf, int size)
|
||||
|
||||
if (size > wrapped) {
|
||||
dma_bm_write(s->RxBuf + s->RxBufAddr,
|
||||
buf, size - wrapped, 1);
|
||||
(uint8_t *) buf, size - wrapped, 1);
|
||||
}
|
||||
|
||||
/* reset buffer pointer */
|
||||
s->RxBufAddr = 0;
|
||||
|
||||
dma_bm_write(s->RxBuf + s->RxBufAddr,
|
||||
buf + (size - wrapped), wrapped, 1);
|
||||
(uint8_t *) buf + (size - wrapped), wrapped, 1);
|
||||
|
||||
s->RxBufAddr = wrapped;
|
||||
|
||||
|
||||
@@ -54,7 +54,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <time.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
* Copyright 2015-2020 Andrew Jenner.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -522,7 +523,7 @@ pic_read(uint16_t addr, void *priv)
|
||||
simply read whatever is currently on the data bus. */
|
||||
}
|
||||
|
||||
pic_log("pic_read(%04X, %08X) = %02X\n", addr, priv, dev->data_bus);
|
||||
pic_log("pic_read(%04X) = %02X\n", addr, dev->data_bus);
|
||||
|
||||
return dev->data_bus;
|
||||
}
|
||||
|
||||
@@ -134,9 +134,14 @@ plat_cdrom_get_last_block(void *local)
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_ext_medium_changed(void *local)
|
||||
plat_cdrom_ext_medium_changed(UNUSED(void *local))
|
||||
{
|
||||
#if 0
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
#endif
|
||||
|
||||
int ret = 0;
|
||||
|
||||
dummy_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret);
|
||||
|
||||
@@ -230,7 +230,11 @@ static HarddiskDialog *callbackPtr = nullptr;
|
||||
static MVHDGeom
|
||||
create_drive_vhd_fixed(const QString &fileName, HarddiskDialog *p, uint16_t cyl, uint8_t heads, uint8_t spt)
|
||||
{
|
||||
MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt };
|
||||
MVHDGeom _86box_geometry = {
|
||||
.cyl = cyl,
|
||||
.heads = heads,
|
||||
.spt = spt
|
||||
};
|
||||
MVHDGeom vhd_geometry;
|
||||
adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry);
|
||||
|
||||
@@ -256,7 +260,11 @@ create_drive_vhd_fixed(const QString &fileName, HarddiskDialog *p, uint16_t cyl,
|
||||
static MVHDGeom
|
||||
create_drive_vhd_dynamic(const QString &fileName, uint16_t cyl, uint8_t heads, uint8_t spt, int blocksize)
|
||||
{
|
||||
MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt };
|
||||
MVHDGeom _86box_geometry = {
|
||||
.cyl = cyl,
|
||||
.heads = heads,
|
||||
.spt = spt
|
||||
};
|
||||
MVHDGeom vhd_geometry;
|
||||
adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry);
|
||||
int vhd_error = 0;
|
||||
|
||||
@@ -178,15 +178,17 @@ updateJoystickConfig(int type, int joystick_nr, QWidget *parent)
|
||||
|
||||
joystick_state[joystick_nr].plat_joystick_nr = jc.selectedDevice();
|
||||
if (joystick_state[joystick_nr].plat_joystick_nr) {
|
||||
for (int c = 0; c < joystick_get_axis_count(type); c++) {
|
||||
joystick_state[joystick_nr].axis_mapping[c] = get_axis(jc, c, joystick_nr);
|
||||
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(type); axis_nr++) {
|
||||
joystick_state[joystick_nr].axis_mapping[axis_nr] = get_axis(jc, axis_nr, joystick_nr);
|
||||
}
|
||||
for (int c = 0; c < joystick_get_button_count(type); c++) {
|
||||
joystick_state[joystick_nr].button_mapping[c] = jc.selectedButton(c);
|
||||
|
||||
for (int button_nr = 0; button_nr < joystick_get_button_count(type); button_nr++) {
|
||||
joystick_state[joystick_nr].button_mapping[button_nr] = jc.selectedButton(button_nr);
|
||||
}
|
||||
for (int c = 0; c < joystick_get_pov_count(type) * 2; c += 2) {
|
||||
joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(jc, c, joystick_nr);
|
||||
joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(jc, c + 1, joystick_nr);
|
||||
|
||||
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(type) * 2; pov_nr += 2) {
|
||||
joystick_state[joystick_nr].pov_mapping[pov_nr][0] = get_pov(jc, pov_nr, joystick_nr);
|
||||
joystick_state[joystick_nr].pov_mapping[pov_nr][1] = get_pov(jc, pov_nr + 1, joystick_nr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,6 +160,7 @@ SettingsPorts::on_pushButtonSerialPassThru4_clicked()
|
||||
DeviceConfig::ConfigureDevice(&serial_passthrough_device, 4, qobject_cast<Settings *>(Settings::settings));
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
SettingsPorts::on_pushButtonSerialPassThru5_clicked()
|
||||
{
|
||||
@@ -177,6 +178,7 @@ SettingsPorts::on_pushButtonSerialPassThru7_clicked()
|
||||
{
|
||||
DeviceConfig::ConfigureDevice(&serial_passthrough_device, 7, qobject_cast<Settings *>(Settings::settings));
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
SettingsPorts::on_checkBoxSerialPassThru1_clicked(bool checked)
|
||||
@@ -220,4 +222,4 @@ SettingsPorts::on_checkBoxSerialPassThru7_clicked(bool checked)
|
||||
{
|
||||
ui->pushButtonSerialPassThru7->setEnabled(checked);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -19,45 +19,23 @@ public:
|
||||
#if 0
|
||||
private slots:
|
||||
void on_checkBoxSerialPassThru7_clicked(bool checked);
|
||||
|
||||
private slots:
|
||||
void on_checkBoxSerialPassThru6_clicked(bool checked);
|
||||
|
||||
private slots:
|
||||
void on_checkBoxSerialPassThru5_clicked(bool checked);
|
||||
#endif
|
||||
|
||||
private slots:
|
||||
void on_checkBoxSerialPassThru4_clicked(bool checked);
|
||||
|
||||
private slots:
|
||||
void on_checkBoxSerialPassThru3_clicked(bool checked);
|
||||
|
||||
private slots:
|
||||
void on_checkBoxSerialPassThru2_clicked(bool checked);
|
||||
|
||||
private slots:
|
||||
void on_checkBoxSerialPassThru1_clicked(bool checked);
|
||||
|
||||
private slots:
|
||||
#if 0
|
||||
void on_pushButtonSerialPassThru7_clicked();
|
||||
|
||||
private slots:
|
||||
void on_pushButtonSerialPassThru6_clicked();
|
||||
|
||||
private slots:
|
||||
void on_pushButtonSerialPassThru5_clicked();
|
||||
|
||||
private slots:
|
||||
#endif
|
||||
void on_pushButtonSerialPassThru4_clicked();
|
||||
|
||||
private slots:
|
||||
void on_pushButtonSerialPassThru3_clicked();
|
||||
|
||||
private slots:
|
||||
void on_pushButtonSerialPassThru2_clicked();
|
||||
|
||||
private slots:
|
||||
void on_pushButtonSerialPassThru1_clicked();
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -30,10 +30,11 @@
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "qt_vulkanrenderer.hpp"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QFile>
|
||||
#include "qt_vulkanrenderer.hpp"
|
||||
|
||||
#if QT_CONFIG(vulkan)
|
||||
# include <QVulkanFunctions>
|
||||
|
||||
@@ -676,7 +677,7 @@ VulkanRenderer2::initResources()
|
||||
v_texcoord = texcoord;
|
||||
gl_Position = ubuf.mvp * position;
|
||||
}
|
||||
#endif
|
||||
#endif /* 0 */
|
||||
VkShaderModule vertShaderModule = createShader(QStringLiteral(":/texture_vert.spv"));
|
||||
#if 0
|
||||
#version 440
|
||||
@@ -691,7 +692,7 @@ VulkanRenderer2::initResources()
|
||||
{
|
||||
fragColor = texture(tex, v_texcoord);
|
||||
}
|
||||
#endif
|
||||
#endif /* 0 */
|
||||
VkShaderModule fragShaderModule = createShader(QStringLiteral(":/texture_frag.spv"));
|
||||
|
||||
// Graphics pipeline
|
||||
@@ -1009,4 +1010,4 @@ VulkanRenderer2::startNextFrame()
|
||||
m_window->frameReady();
|
||||
m_window->requestUpdate(); // render continuously, throttled by the presentation rate
|
||||
}
|
||||
#endif
|
||||
#endif /* QT_CONFIG(vulkan) */
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
****************************************************************************/
|
||||
#ifndef VULKANRENDERER_HPP
|
||||
#define VULKANRENDERER_HPP
|
||||
|
||||
#include <QVulkanWindow>
|
||||
#include <QImage>
|
||||
@@ -90,4 +92,6 @@ private:
|
||||
|
||||
QMatrix4x4 m_proj;
|
||||
};
|
||||
#endif
|
||||
#endif // QT_CONFIG(vulkan)
|
||||
|
||||
#endif // VULKANRENDERER_HPP
|
||||
|
||||
@@ -1,3 +1,35 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 Cacodemon345
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "qt_vulkanwindowrenderer.hpp"
|
||||
|
||||
#include <QMessageBox>
|
||||
@@ -697,7 +729,7 @@ public:
|
||||
# if VK_HEADER_VERSION >= 135 && VK_HEADER_VERSION < 162
|
||||
case VK_ERROR_INCOMPATIBLE_VERSION_KHR:
|
||||
return "VK_ERROR_INCOMPATIBLE_VERSION_KHR";
|
||||
# endif
|
||||
# endif /* VK_HEADER_VERSION >= 135 && VK_HEADER_VERSION < 162 */
|
||||
case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:
|
||||
return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT";
|
||||
case VK_ERROR_NOT_PERMITTED_EXT:
|
||||
@@ -788,7 +820,7 @@ public:
|
||||
m_devFuncs->vkDeviceWaitIdle(m_window->device());
|
||||
}
|
||||
};
|
||||
# endif
|
||||
# endif /* 0*/
|
||||
|
||||
VulkanWindowRenderer::VulkanWindowRenderer(QWidget *parent)
|
||||
: QVulkanWindow(parent->windowHandle())
|
||||
@@ -851,4 +883,4 @@ VulkanWindowRenderer::getBuffers()
|
||||
{
|
||||
return std::vector { std::make_tuple((uint8_t *) renderer->mappedPtr, &this->buf_usage[0]) };
|
||||
}
|
||||
#endif
|
||||
#endif /* QT_CONFIG(vulkan) */
|
||||
|
||||
@@ -35,6 +35,6 @@ private:
|
||||
|
||||
VulkanRenderer2 *renderer;
|
||||
};
|
||||
#endif
|
||||
#endif // QT_CONFIG(vulkan)
|
||||
|
||||
#endif // VULKANWINDOWRENDERER_HPP
|
||||
|
||||
@@ -56,14 +56,18 @@ std::unique_ptr<WindowsRawInputFilter>
|
||||
WindowsRawInputFilter::Register(MainWindow *window)
|
||||
{
|
||||
RAWINPUTDEVICE rid[2] = {
|
||||
{.usUsagePage = 0x01,
|
||||
.usUsage = 0x06,
|
||||
.dwFlags = RIDEV_NOHOTKEYS,
|
||||
.hwndTarget = nullptr},
|
||||
{ .usUsagePage = 0x01,
|
||||
.usUsage = 0x02,
|
||||
.dwFlags = 0,
|
||||
.hwndTarget = nullptr}
|
||||
{
|
||||
.usUsagePage = 0x01,
|
||||
.usUsage = 0x06,
|
||||
.dwFlags = RIDEV_NOHOTKEYS,
|
||||
.hwndTarget = nullptr
|
||||
},
|
||||
{
|
||||
.usUsagePage = 0x01,
|
||||
.usUsage = 0x02,
|
||||
.dwFlags = 0,
|
||||
.hwndTarget = nullptr
|
||||
}
|
||||
};
|
||||
|
||||
if (hook_enabled && (RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0])) == FALSE))
|
||||
@@ -89,14 +93,18 @@ WindowsRawInputFilter::WindowsRawInputFilter(MainWindow *window)
|
||||
WindowsRawInputFilter::~WindowsRawInputFilter()
|
||||
{
|
||||
RAWINPUTDEVICE rid[2] = {
|
||||
{.usUsagePage = 0x01,
|
||||
.usUsage = 0x06,
|
||||
.dwFlags = RIDEV_REMOVE,
|
||||
.hwndTarget = NULL},
|
||||
{ .usUsagePage = 0x01,
|
||||
.usUsage = 0x02,
|
||||
.dwFlags = RIDEV_REMOVE,
|
||||
.hwndTarget = NULL}
|
||||
{
|
||||
.usUsagePage = 0x01,
|
||||
.usUsage = 0x06,
|
||||
.dwFlags = RIDEV_REMOVE,
|
||||
.hwndTarget = NULL
|
||||
},
|
||||
{
|
||||
.usUsagePage = 0x01,
|
||||
.usUsage = 0x02,
|
||||
.dwFlags = RIDEV_REMOVE,
|
||||
.hwndTarget = NULL
|
||||
}
|
||||
};
|
||||
|
||||
if (hook_enabled)
|
||||
|
||||
@@ -54,28 +54,26 @@ joystick_init(void)
|
||||
joysticks_present = SDL_NumJoysticks();
|
||||
|
||||
memset(sdl_joy, 0, sizeof(sdl_joy));
|
||||
for (int c = 0; c < joysticks_present; c++) {
|
||||
sdl_joy[c] = SDL_JoystickOpen(c);
|
||||
for (int js = 0; js < joysticks_present; js++) {
|
||||
sdl_joy[js] = SDL_JoystickOpen(js);
|
||||
|
||||
if (sdl_joy[c]) {
|
||||
int d;
|
||||
if (sdl_joy[js]) {
|
||||
strncpy(plat_joystick_state[js].name, SDL_JoystickNameForIndex(js), 64);
|
||||
plat_joystick_state[js].nr_axes = MIN(SDL_JoystickNumAxes(sdl_joy[js]), MAX_JOY_AXES);
|
||||
plat_joystick_state[js].nr_buttons = MIN(SDL_JoystickNumButtons(sdl_joy[js]), MAX_JOY_BUTTONS);
|
||||
plat_joystick_state[js].nr_povs = MIN(SDL_JoystickNumHats(sdl_joy[js]), MAX_JOY_POVS);
|
||||
|
||||
strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64);
|
||||
plat_joystick_state[c].nr_axes = MIN(SDL_JoystickNumAxes(sdl_joy[c]), MAX_JOY_AXES);
|
||||
plat_joystick_state[c].nr_buttons = MIN(SDL_JoystickNumButtons(sdl_joy[c]), MAX_JOY_BUTTONS);
|
||||
plat_joystick_state[c].nr_povs = MIN(SDL_JoystickNumHats(sdl_joy[c]), MAX_JOY_POVS);
|
||||
|
||||
for (d = 0; d < plat_joystick_state[c].nr_axes; d++) {
|
||||
snprintf(plat_joystick_state[c].axis[d].name, sizeof(plat_joystick_state[c].axis[d].name), "Axis %i", d);
|
||||
plat_joystick_state[c].axis[d].id = d;
|
||||
for (int axis_nr = 0; axis_nr < plat_joystick_state[js].nr_axes; axis_nr++) {
|
||||
snprintf(plat_joystick_state[js].axis[axis_nr].name, sizeof(plat_joystick_state[js].axis[axis_nr].name), "Axis %i", axis_nr);
|
||||
plat_joystick_state[js].axis[axis_nr].id = axis_nr;
|
||||
}
|
||||
for (d = 0; d < plat_joystick_state[c].nr_buttons; d++) {
|
||||
snprintf(plat_joystick_state[c].button[d].name, sizeof(plat_joystick_state[c].button[d].name), "Button %i", d);
|
||||
plat_joystick_state[c].button[d].id = d;
|
||||
for (int button_nr = 0; button_nr < plat_joystick_state[js].nr_buttons; button_nr++) {
|
||||
snprintf(plat_joystick_state[js].button[button_nr].name, sizeof(plat_joystick_state[js].button[button_nr].name), "Button %i", button_nr);
|
||||
plat_joystick_state[js].button[button_nr].id = button_nr;
|
||||
}
|
||||
for (d = 0; d < plat_joystick_state[c].nr_povs; d++) {
|
||||
snprintf(plat_joystick_state[c].pov[d].name, sizeof(plat_joystick_state[c].pov[d].name), "POV %i", d);
|
||||
plat_joystick_state[c].pov[d].id = d;
|
||||
for (int pov_nr = 0; pov_nr < plat_joystick_state[js].nr_povs; pov_nr++) {
|
||||
snprintf(plat_joystick_state[js].pov[pov_nr].name, sizeof(plat_joystick_state[js].pov[pov_nr].name), "POV %i", pov_nr);
|
||||
plat_joystick_state[js].pov[pov_nr].id = pov_nr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,11 +82,9 @@ joystick_init(void)
|
||||
void
|
||||
joystick_close(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < joysticks_present; c++) {
|
||||
if (sdl_joy[c])
|
||||
SDL_JoystickClose(sdl_joy[c]);
|
||||
for (int js = 0; js < joysticks_present; js++) {
|
||||
if (sdl_joy[js])
|
||||
SDL_JoystickClose(sdl_joy[js]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,57 +128,60 @@ joystick_get_axis(int joystick_nr, int mapping)
|
||||
void
|
||||
joystick_process(void)
|
||||
{
|
||||
int c;
|
||||
int d;
|
||||
|
||||
if (!joystick_type)
|
||||
return;
|
||||
|
||||
SDL_JoystickUpdate();
|
||||
for (c = 0; c < joysticks_present; c++) {
|
||||
int b;
|
||||
for (int js = 0; js < joysticks_present; js++) {
|
||||
for (int axis_nr = 0; axis_nr < plat_joystick_state[js].nr_axes; axis_nr++)
|
||||
plat_joystick_state[js].a[axis_nr] = SDL_JoystickGetAxis(sdl_joy[js], axis_nr);
|
||||
|
||||
for (b = 0; b < plat_joystick_state[c].nr_axes; b++)
|
||||
plat_joystick_state[c].a[b] = SDL_JoystickGetAxis(sdl_joy[c], b);
|
||||
for (int button_nr = 0; button_nr < plat_joystick_state[js].nr_buttons; button_nr++)
|
||||
plat_joystick_state[js].b[button_nr] = SDL_JoystickGetButton(sdl_joy[js], button_nr);
|
||||
|
||||
for (b = 0; b < plat_joystick_state[c].nr_buttons; b++)
|
||||
plat_joystick_state[c].b[b] = SDL_JoystickGetButton(sdl_joy[c], b);
|
||||
for (int pov_nr = 0; pov_nr < plat_joystick_state[js].nr_povs; pov_nr++)
|
||||
plat_joystick_state[js].p[pov_nr] = SDL_JoystickGetHat(sdl_joy[js], pov_nr);
|
||||
|
||||
for (b = 0; b < plat_joystick_state[c].nr_povs; b++)
|
||||
plat_joystick_state[c].p[b] = SDL_JoystickGetHat(sdl_joy[c], b);
|
||||
// pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present);
|
||||
#if 0
|
||||
pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", js,
|
||||
joystick_state[js].x,
|
||||
joystick_state[js].y,
|
||||
joystick_state[js].b[0],
|
||||
joystick_state[js].b[1],
|
||||
joysticks_present);
|
||||
#endif
|
||||
}
|
||||
|
||||
for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) {
|
||||
if (joystick_state[c].plat_joystick_nr) {
|
||||
int joystick_nr = joystick_state[c].plat_joystick_nr - 1;
|
||||
for (int js = 0; js < joystick_get_max_joysticks(joystick_type); js++) {
|
||||
if (joystick_state[js].plat_joystick_nr) {
|
||||
int joystick_nr = joystick_state[js].plat_joystick_nr - 1;
|
||||
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
||||
joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]);
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
||||
joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]];
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++) {
|
||||
int x, y;
|
||||
double angle, magnitude;
|
||||
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++)
|
||||
joystick_state[js].axis[axis_nr] = joystick_get_axis(joystick_nr, joystick_state[js].axis_mapping[axis_nr]);
|
||||
|
||||
x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]);
|
||||
y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]);
|
||||
for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++)
|
||||
joystick_state[js].button[button_nr] = plat_joystick_state[joystick_nr].b[joystick_state[js].button_mapping[button_nr]];
|
||||
|
||||
angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI);
|
||||
magnitude = sqrt((double) x * (double) x + (double) y * (double) y);
|
||||
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) {
|
||||
int x = joystick_get_axis(joystick_nr, joystick_state[js].pov_mapping[pov_nr][0]);
|
||||
int y = joystick_get_axis(joystick_nr, joystick_state[js].pov_mapping[pov_nr][1]);
|
||||
double angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI);
|
||||
double magnitude = sqrt((double) x * (double) x + (double) y * (double) y);
|
||||
|
||||
if (magnitude < 16384)
|
||||
joystick_state[c].pov[d] = -1;
|
||||
joystick_state[js].pov[pov_nr] = -1;
|
||||
else
|
||||
joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360;
|
||||
joystick_state[js].pov[pov_nr] = ((int) angle + 90 + 360) % 360;
|
||||
}
|
||||
} else {
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
||||
joystick_state[c].axis[d] = 0;
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
||||
joystick_state[c].button[d] = 0;
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
|
||||
joystick_state[c].pov[d] = -1;
|
||||
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++)
|
||||
joystick_state[js].axis[axis_nr] = 0;
|
||||
|
||||
for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++)
|
||||
joystick_state[js].button[button_nr] = 0;
|
||||
|
||||
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++)
|
||||
joystick_state[js].pov[pov_nr] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -412,7 +412,7 @@ win_joystick_handle(PRAWINPUT raw)
|
||||
/* Read buttons */
|
||||
USAGE usage_list[128] = { 0 };
|
||||
ULONG usage_length = plat_joystick_state[j].nr_buttons;
|
||||
memset(plat_joystick_state[j].b, 0, 32 * sizeof(int));
|
||||
memset(plat_joystick_state[j].b, 0, MAX_JOY_BUTTONS * sizeof(int));
|
||||
|
||||
r = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usage_list, &usage_length,
|
||||
raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid);
|
||||
@@ -425,8 +425,8 @@ win_joystick_handle(PRAWINPUT raw)
|
||||
}
|
||||
|
||||
/* Read axes */
|
||||
for (int a = 0; a < plat_joystick_state[j].nr_axes; a++) {
|
||||
const struct raw_axis_t *axis = &raw_joystick_state[j].axis[a];
|
||||
for (int axis_nr = 0; axis_nr < plat_joystick_state[j].nr_axes; axis_nr++) {
|
||||
const struct raw_axis_t *axis = &raw_joystick_state[j].axis[axis_nr];
|
||||
ULONG uvalue = 0;
|
||||
LONG value = 0;
|
||||
LONG center = (axis->max - axis->min + 1) / 2;
|
||||
@@ -453,15 +453,15 @@ win_joystick_handle(PRAWINPUT raw)
|
||||
value = value * 32768 / center;
|
||||
}
|
||||
|
||||
plat_joystick_state[j].a[a] = value;
|
||||
plat_joystick_state[j].a[axis_nr] = value;
|
||||
#if 0
|
||||
joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]);
|
||||
joystick_log("%s %-06d ", plat_joystick_state[j].axis[axis_nr].name, plat_joystick_state[j].a[axis_nr]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* read povs */
|
||||
for (int p = 0; p < plat_joystick_state[j].nr_povs; p++) {
|
||||
const struct raw_pov_t *pov = &raw_joystick_state[j].pov[p];
|
||||
for (int pov_nr = 0; pov_nr < plat_joystick_state[j].nr_povs; pov_nr++) {
|
||||
const struct raw_pov_t *pov = &raw_joystick_state[j].pov[pov_nr];
|
||||
ULONG uvalue = 0;
|
||||
LONG value = -1;
|
||||
|
||||
@@ -474,10 +474,10 @@ win_joystick_handle(PRAWINPUT raw)
|
||||
value %= 36000;
|
||||
}
|
||||
|
||||
plat_joystick_state[j].p[p] = value;
|
||||
plat_joystick_state[j].p[pov_nr] = value;
|
||||
|
||||
#if 0
|
||||
joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]);
|
||||
joystick_log("%s %-3d ", plat_joystick_state[j].pov[pov_nr].name, plat_joystick_state[j].p[pov_nr]);
|
||||
#endif
|
||||
}
|
||||
#if 0
|
||||
@@ -508,44 +508,39 @@ joystick_get_axis(int joystick_nr, int mapping)
|
||||
void
|
||||
joystick_process(void)
|
||||
{
|
||||
int d;
|
||||
|
||||
if (joystick_type == JS_TYPE_NONE)
|
||||
return;
|
||||
|
||||
for (int c = 0; c < joystick_get_max_joysticks(joystick_type); c++) {
|
||||
if (joystick_state[c].plat_joystick_nr) {
|
||||
int joystick_nr = joystick_state[c].plat_joystick_nr - 1;
|
||||
for (int js = 0; js < joystick_get_max_joysticks(joystick_type); js++) {
|
||||
if (joystick_state[js].plat_joystick_nr) {
|
||||
int joystick_nr = joystick_state[js].plat_joystick_nr - 1;
|
||||
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
||||
joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]);
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
||||
joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]];
|
||||
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++)
|
||||
joystick_state[js].axis[axis_nr] = joystick_get_axis(joystick_nr, joystick_state[js].axis_mapping[axis_nr]);
|
||||
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++) {
|
||||
int x;
|
||||
int y;
|
||||
double angle;
|
||||
double magnitude;
|
||||
for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++)
|
||||
joystick_state[js].button[button_nr] = plat_joystick_state[joystick_nr].b[joystick_state[js].button_mapping[button_nr]];
|
||||
|
||||
x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]);
|
||||
y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]);
|
||||
|
||||
angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI);
|
||||
magnitude = sqrt((double) x * (double) x + (double) y * (double) y);
|
||||
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) {
|
||||
int x = joystick_get_axis(joystick_nr, joystick_state[js].pov_mapping[pov_nr][0]);
|
||||
int y = joystick_get_axis(joystick_nr, joystick_state[js].pov_mapping[pov_nr][1]);
|
||||
double angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI);
|
||||
double magnitude = sqrt((double) x * (double) x + (double) y * (double) y);
|
||||
|
||||
if (magnitude < 16384)
|
||||
joystick_state[c].pov[d] = -1;
|
||||
joystick_state[js].pov[pov_nr] = -1;
|
||||
else
|
||||
joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360;
|
||||
joystick_state[js].pov[pov_nr] = ((int) angle + 90 + 360) % 360;
|
||||
}
|
||||
} else {
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
||||
joystick_state[c].axis[d] = 0;
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
||||
joystick_state[c].button[d] = 0;
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
|
||||
joystick_state[c].pov[d] = -1;
|
||||
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++)
|
||||
joystick_state[js].axis[axis_nr] = 0;
|
||||
|
||||
for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++)
|
||||
joystick_state[js].button[button_nr] = 0;
|
||||
|
||||
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++)
|
||||
joystick_state[js].pov[pov_nr] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ plat_serpt_set_params(void *priv)
|
||||
const serial_passthrough_t *dev = (serial_passthrough_t *) priv;
|
||||
|
||||
if (dev->mode == SERPT_MODE_HOSTSER) {
|
||||
DCB serialattr = {};
|
||||
DCB serialattr = { 0 };
|
||||
GetCommState((HANDLE) dev->master_fd, &serialattr);
|
||||
#define BAUDRATE_RANGE(baud_rate, min, max) \
|
||||
if (baud_rate >= min && baud_rate < max) { \
|
||||
|
||||
@@ -1421,7 +1421,7 @@ static const device_config_t aha_154xcp_config[] = {
|
||||
.default_string = "v1_02_en",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 }, /*W1*/
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "Version 1.02 (English)", .internal_name = "v1_02_en", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 2, .local = 0, .size = 32768, .files = { "roms/scsi/adaptec/aha1542cp102.bin",
|
||||
|
||||
@@ -197,20 +197,30 @@ ncr5380_bus_read(ncr_t *ncr)
|
||||
phase = (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN);
|
||||
|
||||
if (phase == SCSI_PHASE_DATA_IN) {
|
||||
ncr->tx_data = dev->sc->temp_buffer[ncr->data_pos++];
|
||||
ncr->state = STATE_DATAIN;
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP;
|
||||
if ((ncr->dma_mode == DMA_IDLE) || ncr->dma_initiator_receive_ext || (ncr->wait_data_back == 1)) {
|
||||
ncr5380_log("Phase Data In.\n");
|
||||
if ((dev->sc != NULL) && (dev->sc->temp_buffer != NULL))
|
||||
ncr->tx_data = dev->sc->temp_buffer[ncr->data_pos++];
|
||||
|
||||
ncr->state = STATE_DATAIN;
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP;
|
||||
}
|
||||
} else if (phase == SCSI_PHASE_DATA_OUT) {
|
||||
if (ncr->new_phase & BUS_IDLE) {
|
||||
ncr->state = STATE_IDLE;
|
||||
ncr->cur_bus &= ~BUS_BSY;
|
||||
} else
|
||||
ncr->state = STATE_DATAOUT;
|
||||
} else {
|
||||
if ((ncr->dma_mode == DMA_IDLE) || ncr->dma_send_ext || (ncr->wait_data_back == 1))
|
||||
ncr->state = STATE_DATAOUT;
|
||||
}
|
||||
} else if (phase == SCSI_PHASE_STATUS) {
|
||||
ncr5380_log("Phase Status.\n");
|
||||
ncr->wait_data_back = 0;
|
||||
ncr->cur_bus |= BUS_REQ;
|
||||
ncr->state = STATE_STATUS;
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(dev->status) | BUS_DBP;
|
||||
} else if (phase == SCSI_PHASE_MESSAGE_IN) {
|
||||
ncr5380_log("Phase Message In.\n");
|
||||
ncr->state = STATE_MESSAGEIN;
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(0) | BUS_DBP;
|
||||
} else if (phase == SCSI_PHASE_MESSAGE_OUT) {
|
||||
@@ -335,19 +345,22 @@ ncr5380_bus_update(ncr_t *ncr, int bus)
|
||||
if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) {
|
||||
if (ncr->data_pos >= dev->buffer_length) {
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
ncr5380_log("CMD Phase1 DataIn.\n");
|
||||
scsi_device_command_phase1(dev);
|
||||
ncr->new_phase = SCSI_PHASE_STATUS;
|
||||
ncr->wait_data = 4;
|
||||
ncr->wait_complete = 8;
|
||||
} else {
|
||||
ncr->tx_data = dev->sc->temp_buffer[ncr->data_pos++];
|
||||
if ((dev->sc != NULL) && (dev->sc->temp_buffer != NULL))
|
||||
ncr->tx_data = dev->sc->temp_buffer[ncr->data_pos++];
|
||||
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP | BUS_REQ;
|
||||
if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/
|
||||
ncr->data_wait |= 1;
|
||||
ncr5380_log("DMA mode idle in\n");
|
||||
ncr5380_log("DMA mode idle IN=%d.\n", ncr->data_pos);
|
||||
ncr->timer(ncr->priv, ncr->period);
|
||||
} else {
|
||||
ncr5380_log("DMA mode IN.\n");
|
||||
ncr5380_log("DMA mode IN=%d.\n", ncr->data_pos);
|
||||
ncr->clear_req = 3;
|
||||
}
|
||||
|
||||
@@ -359,7 +372,8 @@ ncr5380_bus_update(ncr_t *ncr, int bus)
|
||||
case STATE_DATAOUT:
|
||||
dev = &scsi_devices[ncr->bus][ncr->target_id];
|
||||
if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) {
|
||||
dev->sc->temp_buffer[ncr->data_pos++] = BUS_GETDATA(bus);
|
||||
if ((dev->sc != NULL) && (dev->sc->temp_buffer != NULL))
|
||||
dev->sc->temp_buffer[ncr->data_pos++] = BUS_GETDATA(bus);
|
||||
|
||||
if (ncr->data_pos >= dev->buffer_length) {
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -439,12 +453,12 @@ ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr)
|
||||
|
||||
switch (port & 7) {
|
||||
case 0: /* Output data register */
|
||||
ncr5380_log("Write: Output data register, val = %02x\n", val);
|
||||
ncr5380_log("[%04X:%08X]: Write: Output data register, val=%02x\n", CS, cpu_state.pc, val);
|
||||
ncr->output_data = val;
|
||||
break;
|
||||
|
||||
case 1: /* Initiator Command Register */
|
||||
ncr5380_log("Write: Initiator command register\n");
|
||||
ncr5380_log("[%04X:%08X]: Write: Initiator command register, val=%02x.\n", CS, cpu_state.pc, val);
|
||||
if ((val & 0x80) && !(ncr->icr & 0x80)) {
|
||||
ncr5380_log("Resetting the 5380\n");
|
||||
ncr5380_reset(ncr);
|
||||
@@ -465,7 +479,7 @@ ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr)
|
||||
break;
|
||||
|
||||
case 3: /* Target Command Register */
|
||||
ncr5380_log("Write: Target Command register\n");
|
||||
ncr5380_log("Write: Target Command register, val=%02x.\n", val);
|
||||
ncr->tcr = val;
|
||||
break;
|
||||
|
||||
@@ -482,7 +496,7 @@ ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr)
|
||||
break;
|
||||
|
||||
case 7: /* start DMA Initiator Receive */
|
||||
ncr5380_log("Write: start DMA initiator receive register, dma? = %02x\n", ncr->mode & MODE_DMA);
|
||||
ncr5380_log("[%04X:%08X]: Write: start DMA initiator receive register, dma? = %02x\n", CS, cpu_state.pc, ncr->mode & MODE_DMA);
|
||||
/*a Read 6/10 has occurred, start the timer when the block count is loaded*/
|
||||
ncr->dma_mode = DMA_INITIATOR_RECEIVE;
|
||||
if (ncr->dma_initiator_receive_ext)
|
||||
@@ -510,13 +524,13 @@ ncr5380_read(uint16_t port, ncr_t *ncr)
|
||||
ncr5380_log("Read: Current SCSI data register\n");
|
||||
if (ncr->icr & ICR_DBP) {
|
||||
/*Return the data from the output register if on data bus phase from ICR*/
|
||||
ncr5380_log("Data Bus Phase, ret = %02x\n", ncr->output_data);
|
||||
ret = ncr->output_data;
|
||||
ncr5380_log("[%04X:%08X]: Data Bus Phase, ret=%02x, clearreq=%d, waitdata=%x.\n", CS, cpu_state.pc, ret, ncr->clear_req, ncr->wait_data);
|
||||
} else {
|
||||
/*Return the data from the SCSI bus*/
|
||||
ncr5380_bus_read(ncr);
|
||||
ncr5380_log("NCR GetData=%02x\n", BUS_GETDATA(ncr->cur_bus));
|
||||
ret = BUS_GETDATA(ncr->cur_bus);
|
||||
ncr5380_log("[%04X:%08X]: NCR Get SCSI bus data=%02x.\n", CS, cpu_state.pc, ret);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -595,7 +609,9 @@ ncr5380_read(uint16_t port, ncr_t *ncr)
|
||||
break;
|
||||
|
||||
case 6:
|
||||
ret = ncr->tx_data;
|
||||
ncr5380_log("Read: Input Data.\n");
|
||||
ncr5380_bus_read(ncr);
|
||||
ret = BUS_GETDATA(ncr->cur_bus);
|
||||
break;
|
||||
|
||||
case 7: /* reset Parity/Interrupt */
|
||||
|
||||
@@ -148,6 +148,12 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv)
|
||||
ncr400->busy = 1;
|
||||
if (!(ncr->mode & MODE_MONITOR_BUSY) && ((scsi_device_get_callback(dev) > 0.0)))
|
||||
timer_on_auto(&ncr400->timer, ncr->period / 250.0);
|
||||
else if ((ncr->mode & MODE_MONITOR_BUSY) && !ncr->wait_data) {
|
||||
if (scsi_device_get_callback(dev) > 0.0)
|
||||
timer_on_auto(&ncr400->timer, 100.0);
|
||||
else
|
||||
timer_on_auto(&ncr400->timer, 40.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -181,13 +187,15 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv)
|
||||
if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0)) {
|
||||
memset(ncr400->buffer, 0, MIN(128, dev->buffer_length));
|
||||
if (ncr->mode & MODE_MONITOR_BUSY)
|
||||
timer_on_auto(&ncr400->timer, ncr->period);
|
||||
timer_on_auto(&ncr400->timer, (ncr->period / 4.0) * 3.0);
|
||||
else if (scsi_device_get_callback(dev) > 0.0)
|
||||
timer_on_auto(&ncr400->timer, 40.0);
|
||||
else
|
||||
timer_on_auto(&ncr400->timer, ncr->period);
|
||||
|
||||
ncr53c400_log("DMA timer on=%02x, callback=%lf, scsi buflen=%d, waitdata=%d, waitcomplete=%d, clearreq=%d, datawait=%d, enabled=%d.\n", ncr->mode & MODE_MONITOR_BUSY, scsi_device_get_callback(dev), dev->buffer_length, ncr->wait_complete, ncr->wait_data, ncr->wait_complete, ncr->clear_req, ncr->data_wait, timer_is_enabled(&ncr400->timer));
|
||||
ncr->wait_data_back = ncr->wait_data;
|
||||
ncr53c400_log("DMA timer on=%02x, callback=%lf, scsi buflen=%d, waitdata=%d, waitcomplete=%d, clearreq=%d, datawait=%d, enabled=%d.\n",
|
||||
ncr->mode & MODE_MONITOR_BUSY, scsi_device_get_callback(dev), dev->buffer_length, ncr->wait_data, ncr->wait_complete, ncr->clear_req, ncr->data_wait, timer_is_enabled(&ncr400->timer));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -244,6 +252,12 @@ ncr53c400_read(uint32_t addr, void *priv)
|
||||
ncr53c400_log("Transfer busy read, status = %02x.\n", ncr400->status_ctrl);
|
||||
if (!(ncr->mode & MODE_MONITOR_BUSY) && (scsi_device_get_callback(dev) > 0.0))
|
||||
timer_on_auto(&ncr400->timer, ncr->period / 250.0);
|
||||
else if ((ncr->mode & MODE_MONITOR_BUSY) && !ncr->wait_data) {
|
||||
if (scsi_device_get_callback(dev) > 0.0)
|
||||
timer_on_auto(&ncr400->timer, 100.0);
|
||||
else
|
||||
timer_on_auto(&ncr400->timer, 40.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -397,16 +411,20 @@ t130b_in(uint16_t port, void *priv)
|
||||
}
|
||||
|
||||
static void
|
||||
ncr53c400_dma_mode_ext(void *priv, UNUSED(void *ext_priv))
|
||||
ncr53c400_dma_mode_ext(void *priv, void *ext_priv)
|
||||
{
|
||||
ncr_t *ncr = (ncr_t *) priv;
|
||||
ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv;
|
||||
ncr_t *ncr = (ncr_t *) priv;
|
||||
|
||||
/*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/
|
||||
if (!(ncr->mode & MODE_DMA)) {
|
||||
ncr53c400_log("No DMA mode\n");
|
||||
ncr->tcr &= ~TCR_LAST_BYTE_SENT;
|
||||
ncr->isr &= ~STATUS_END_OF_DMA;
|
||||
ncr->dma_mode = DMA_IDLE;
|
||||
ncr53c400_log("BlockCountLoaded=%d.\n", ncr400->block_count_loaded);
|
||||
if (!ncr400->block_count_loaded) {
|
||||
if (!(ncr->mode & MODE_DMA)) {
|
||||
ncr53c400_log("No DMA mode\n");
|
||||
ncr->tcr &= ~TCR_LAST_BYTE_SENT;
|
||||
ncr->isr &= ~STATUS_END_OF_DMA;
|
||||
ncr->dma_mode = DMA_IDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,6 +492,7 @@ ncr53c400_callback(void *priv)
|
||||
ncr400->block_count = (ncr400->block_count - 1) & 0xff;
|
||||
ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", ncr400->block_count);
|
||||
if (!ncr400->block_count) {
|
||||
ncr->dma_mode = DMA_IDLE;
|
||||
ncr400->block_count_loaded = 0;
|
||||
ncr53c400_log("IO End of write transfer\n");
|
||||
ncr->tcr |= TCR_LAST_BYTE_SENT;
|
||||
@@ -527,6 +546,7 @@ ncr53c400_callback(void *priv)
|
||||
ncr400->block_count = (ncr400->block_count - 1) & 0xff;
|
||||
ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", ncr400->block_count);
|
||||
if (!ncr400->block_count) {
|
||||
ncr->dma_mode = DMA_IDLE;
|
||||
ncr400->block_count_loaded = 0;
|
||||
ncr53c400_log("IO End of read transfer\n");
|
||||
ncr->isr |= STATUS_END_OF_DMA;
|
||||
@@ -544,6 +564,7 @@ ncr53c400_callback(void *priv)
|
||||
break;
|
||||
}
|
||||
|
||||
ncr53c400_log("Bus Read.\n");
|
||||
ncr5380_bus_read(ncr);
|
||||
|
||||
if (!(ncr->cur_bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) {
|
||||
@@ -841,7 +862,7 @@ static const device_config_t rt1000b_config[] = {
|
||||
.default_string = "v8_10r",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 }, /*W1*/
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "Version 8.10R", .internal_name = "v8_10r", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 8192, .files = { RT1000B_810R_ROM, "" } },
|
||||
|
||||
@@ -630,6 +630,7 @@ esp_hard_reset(esp_t *dev)
|
||||
fifo8_reset(&dev->fifo);
|
||||
fifo8_reset(&dev->cmdfifo);
|
||||
dev->dma = 0;
|
||||
dev->tchi_written = 0;
|
||||
dev->rregs[ESP_CFG1] = dev->mca ? dev->HostID : 7;
|
||||
esp_log("ESP Reset\n");
|
||||
|
||||
@@ -1346,7 +1347,7 @@ esp_reg_read(esp_t *dev, uint32_t saddr)
|
||||
if (dev->mca) {
|
||||
ret = dev->rregs[ESP_TCHI];
|
||||
} else {
|
||||
if (dev->rregs[ESP_CFG2] & 0x40)
|
||||
if (!dev->tchi_written)
|
||||
ret = TCHI_AM53C974;
|
||||
else
|
||||
ret = dev->rregs[ESP_TCHI];
|
||||
@@ -1369,6 +1370,8 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val)
|
||||
esp_log("Write reg %02x = %02x\n", saddr, val);
|
||||
switch (saddr) {
|
||||
case ESP_TCHI:
|
||||
dev->tchi_written = 1;
|
||||
fallthrough;
|
||||
case ESP_TCLO:
|
||||
case ESP_TCMID:
|
||||
esp_log("ESP TCW reg%02x = %02x.\n", saddr, val);
|
||||
|
||||
@@ -71,7 +71,7 @@ typedef struct
|
||||
const device_t *device;
|
||||
} MIDI_OUT_DEVICE, MIDI_IN_DEVICE;
|
||||
|
||||
static const MIDI_OUT_DEVICE devices[] = {
|
||||
static const MIDI_OUT_DEVICE midi_out_devices[] = {
|
||||
// clang-format off
|
||||
{ &device_none },
|
||||
#ifdef USE_FLUIDSYNTH
|
||||
@@ -106,8 +106,8 @@ static const MIDI_IN_DEVICE midi_in_devices[] = {
|
||||
int
|
||||
midi_out_device_available(int card)
|
||||
{
|
||||
if (devices[card].device)
|
||||
return device_available(devices[card].device);
|
||||
if (midi_out_devices[card].device)
|
||||
return device_available(midi_out_devices[card].device);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -115,21 +115,21 @@ midi_out_device_available(int card)
|
||||
const device_t *
|
||||
midi_out_device_getdevice(int card)
|
||||
{
|
||||
return devices[card].device;
|
||||
return midi_out_devices[card].device;
|
||||
}
|
||||
|
||||
int
|
||||
midi_out_device_has_config(int card)
|
||||
{
|
||||
if (!devices[card].device)
|
||||
if (!midi_out_devices[card].device)
|
||||
return 0;
|
||||
return devices[card].device->config ? 1 : 0;
|
||||
return midi_out_devices[card].device->config ? 1 : 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
midi_out_device_get_internal_name(int card)
|
||||
{
|
||||
return device_get_internal_name(devices[card].device);
|
||||
return device_get_internal_name(midi_out_devices[card].device);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -137,8 +137,8 @@ midi_out_device_get_from_internal_name(char *s)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
while (devices[c].device != NULL) {
|
||||
if (!strcmp(devices[c].device->internal_name, s))
|
||||
while (midi_out_devices[c].device != NULL) {
|
||||
if (!strcmp(midi_out_devices[c].device->internal_name, s))
|
||||
return c;
|
||||
c++;
|
||||
}
|
||||
@@ -149,8 +149,8 @@ midi_out_device_get_from_internal_name(char *s)
|
||||
void
|
||||
midi_out_device_init(void)
|
||||
{
|
||||
if ((midi_output_device_current > 0) && devices[midi_output_device_current].device)
|
||||
device_add(devices[midi_output_device_current].device);
|
||||
if ((midi_output_device_current > 0) && midi_out_devices[midi_output_device_current].device)
|
||||
device_add(midi_out_devices[midi_output_device_current].device);
|
||||
midi_output_device_last = midi_output_device_current;
|
||||
}
|
||||
|
||||
|
||||
@@ -330,8 +330,7 @@ static const device_config_t fluidsynth_config[] = {
|
||||
.name = "output_gain",
|
||||
.description = "Output Gain",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.spinner = {
|
||||
.min = 0,
|
||||
.max = 100
|
||||
},
|
||||
@@ -347,8 +346,7 @@ static const device_config_t fluidsynth_config[] = {
|
||||
.name = "chorus_voices",
|
||||
.description = "Chorus Voices",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.spinner = {
|
||||
.min = 0,
|
||||
.max = 99
|
||||
},
|
||||
@@ -358,8 +356,7 @@ static const device_config_t fluidsynth_config[] = {
|
||||
.name = "chorus_level",
|
||||
.description = "Chorus Level",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.spinner = {
|
||||
.min = 0,
|
||||
.max = 100
|
||||
},
|
||||
@@ -369,8 +366,7 @@ static const device_config_t fluidsynth_config[] = {
|
||||
.name = "chorus_speed",
|
||||
.description = "Chorus Speed",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.spinner = {
|
||||
.min = 10,
|
||||
.max = 500
|
||||
},
|
||||
@@ -380,8 +376,7 @@ static const device_config_t fluidsynth_config[] = {
|
||||
.name = "chorus_depth",
|
||||
.description = "Chorus Depth",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.spinner = {
|
||||
.min = 0,
|
||||
.max = 2560
|
||||
},
|
||||
@@ -391,8 +386,7 @@ static const device_config_t fluidsynth_config[] = {
|
||||
.name = "chorus_waveform",
|
||||
.description = "Chorus Waveform",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
.selection = {
|
||||
{
|
||||
.description = "Sine",
|
||||
.value = 0
|
||||
@@ -414,8 +408,7 @@ static const device_config_t fluidsynth_config[] = {
|
||||
.name = "reverb_room_size",
|
||||
.description = "Reverb Room Size",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.spinner = {
|
||||
.min = 0,
|
||||
.max = 100
|
||||
},
|
||||
@@ -425,8 +418,7 @@ static const device_config_t fluidsynth_config[] = {
|
||||
.name = "reverb_damping",
|
||||
.description = "Reverb Damping",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.spinner = {
|
||||
.min = 0,
|
||||
.max = 100
|
||||
},
|
||||
@@ -436,8 +428,7 @@ static const device_config_t fluidsynth_config[] = {
|
||||
.name = "reverb_width",
|
||||
.description = "Reverb Width",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.spinner = {
|
||||
.min = 0,
|
||||
.max = 1000
|
||||
},
|
||||
@@ -447,8 +438,7 @@ static const device_config_t fluidsynth_config[] = {
|
||||
.name = "reverb_level",
|
||||
.description = "Reverb Level",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.spinner = {
|
||||
.min = 0,
|
||||
.max = 100
|
||||
},
|
||||
@@ -458,8 +448,7 @@ static const device_config_t fluidsynth_config[] = {
|
||||
.name = "interpolation",
|
||||
.description = "Interpolation Method",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
.selection = {
|
||||
{
|
||||
.description = "None",
|
||||
.value = 0
|
||||
|
||||
@@ -24,7 +24,11 @@
|
||||
#define RESID_BRANCH_HINTS true
|
||||
|
||||
// Compiler specifics.
|
||||
#ifndef _MSC_VER
|
||||
#define HAVE_BUILTIN_EXPECT true
|
||||
#else
|
||||
#define HAVE_BUILTIN_EXPECT false
|
||||
#endif
|
||||
|
||||
// Branch prediction macros, lifted off the Linux kernel.
|
||||
#if RESID_BRANCH_HINTS && HAVE_BUILTIN_EXPECT
|
||||
|
||||
@@ -1238,7 +1238,7 @@ azt_init(const device_t *info)
|
||||
fm_driver_get(FM_YMF262, &azt2316a->sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&azt2316a->sb->dsp, 1);
|
||||
sb_dsp_init(&azt2316a->sb->dsp, SBPRO2, azt2316a->type, azt2316a);
|
||||
sb_dsp_init(&azt2316a->sb->dsp, SBPRO2_DSP_302, azt2316a->type, azt2316a);
|
||||
sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr);
|
||||
sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq);
|
||||
sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma);
|
||||
|
||||
@@ -497,7 +497,7 @@ cmi8x38_sb_mixer_write(uint16_t addr, uint8_t val, void *priv)
|
||||
/* Set TDMA channels if auto-detection is enabled. */
|
||||
if ((dev->io_regs[0x27] & 0x01) && (mixer->index == 0x81)) {
|
||||
dev->tdma_8 = dev->sb->dsp.sb_8_dmanum;
|
||||
if (dev->sb->dsp.sb_type >= SB16)
|
||||
if (dev->sb->dsp.sb_type >= SB16_DSP_404)
|
||||
dev->tdma_16 = dev->sb->dsp.sb_16_dmanum;
|
||||
}
|
||||
} else {
|
||||
@@ -879,7 +879,7 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv)
|
||||
dev->sb->dsp.sbleftright_default = !!(val & 0x02);
|
||||
|
||||
/* Enable or disable SB16 mode. */
|
||||
dev->sb->dsp.sb_type = (val & 0x01) ? SBPRO2 : SB16;
|
||||
dev->sb->dsp.sb_type = (val & 0x01) ? SBPRO2_DSP_302 : SB16_DSP_405;
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
|
||||
@@ -173,8 +173,8 @@ static const device_config_t opl2board_config[] = {
|
||||
.type = CONFIG_SERPORT,
|
||||
.default_string = "",
|
||||
.file_filter = NULL,
|
||||
.spinner = {},
|
||||
.selection = {}
|
||||
.spinner = { 0 },
|
||||
.selection = { { 0 } }
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
};
|
||||
|
||||
@@ -394,7 +394,7 @@ optimc_init(const device_t *info)
|
||||
optimc->fm_type = (info->local & OPTIMC_OPL4) ? FM_YMF278B : FM_YMF262;
|
||||
|
||||
sb_dsp_set_real_opl(&optimc->sb->dsp, optimc->fm_type != FM_YMF278B);
|
||||
sb_dsp_init(&optimc->sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, optimc);
|
||||
sb_dsp_init(&optimc->sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, optimc);
|
||||
sb_dsp_setaddr(&optimc->sb->dsp, optimc->cur_addr);
|
||||
sb_dsp_setirq(&optimc->sb->dsp, optimc->cur_irq);
|
||||
sb_dsp_setdma8(&optimc->sb->dsp, optimc->cur_dma);
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
* Copyright 2008-2024 Sarah Walker.
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
@@ -2314,7 +2315,7 @@ pas16_init(const device_t *info)
|
||||
pas16->has_scsi = (!pas16->type) || (pas16->type == 0x0f);
|
||||
fm_driver_get(FM_YMF262, &pas16->opl);
|
||||
sb_dsp_set_real_opl(&pas16->dsp, 1);
|
||||
sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16);
|
||||
sb_dsp_init(&pas16->dsp, SB_DSP_201, SB_SUBTYPE_DEFAULT, pas16);
|
||||
pas16->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
||||
memset(pas16->mpu, 0, sizeof(mpu_t));
|
||||
mpu401_init(pas16->mpu, 0, 0, M_UART, device_get_config_int("receive_input401"));
|
||||
|
||||
@@ -43,6 +43,10 @@
|
||||
#include <86box/snd_sb.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#define SB_1 0
|
||||
#define SB_15 1
|
||||
#define SB_2 2
|
||||
|
||||
#define SB_16_PNP_NOIDE 0
|
||||
#define SB_16_PNP_IDE 1
|
||||
|
||||
@@ -288,7 +292,7 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv)
|
||||
if (!sb->opl_enabled)
|
||||
return;
|
||||
|
||||
if (sb->dsp.sb_type == SBPRO) {
|
||||
if (sb->dsp.sb_type == SBPRO_DSP_300) {
|
||||
opl_buf = sb->opl.update(sb->opl.priv);
|
||||
opl2_buf = sb->opl2.update(sb->opl2.priv);
|
||||
} else
|
||||
@@ -300,7 +304,7 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv)
|
||||
out_l = 0.0;
|
||||
out_r = 0.0;
|
||||
|
||||
if (sb->dsp.sb_type == SBPRO) {
|
||||
if (sb->dsp.sb_type == SBPRO_DSP_300) {
|
||||
/* Two chips for LEFT and RIGHT channels.
|
||||
Each chip stores data into the LEFT channel only (no sample alternating.) */
|
||||
out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375;
|
||||
@@ -322,7 +326,7 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv)
|
||||
}
|
||||
|
||||
sb->opl.reset_buffer(sb->opl.priv);
|
||||
if (sb->dsp.sb_type == SBPRO)
|
||||
if (sb->dsp.sb_type == SBPRO_DSP_300)
|
||||
sb->opl2.reset_buffer(sb->opl2.priv);
|
||||
}
|
||||
|
||||
@@ -415,7 +419,7 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, const int len, void *priv)
|
||||
const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16;
|
||||
const int dsp_rec_pos = sb->dsp.record_pos_write;
|
||||
double bass_treble;
|
||||
const int32_t *opl_buf = NULL;
|
||||
const int32_t *opl_buf = NULL;
|
||||
|
||||
if (sb->opl_enabled)
|
||||
opl_buf = sb->opl.update(sb->opl.priv);
|
||||
@@ -1157,7 +1161,7 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0xff:
|
||||
if ((sb->dsp.sb_type > SBAWE32) && !sb->dsp.sb_16_dma_supported) {
|
||||
if ((sb->dsp.sb_type > SBAWE32_DSP_412) && !sb->dsp.sb_16_dma_supported) {
|
||||
/*
|
||||
Bit 5: High DMA channel enabled (0 = yes, 1 = no);
|
||||
Bit 2: ????;
|
||||
@@ -1341,7 +1345,7 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv)
|
||||
/* http://the.earth.li/~tfm/oldpage/sb_mixer.html - 0x10, 0x20, 0x80. */
|
||||
const uint8_t temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) |
|
||||
((sb->dsp.sb_irq401) ? 4 : 0);
|
||||
if (sb->dsp.sb_type >= SBAWE32)
|
||||
if (sb->dsp.sb_type >= SBAWE32_DSP_412)
|
||||
ret = temp | 0x80;
|
||||
else
|
||||
ret = temp | 0x40;
|
||||
@@ -1386,7 +1390,7 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv)
|
||||
- Register FF = FF: Volume playback normal.
|
||||
- Register FF = Not FF: Volume playback low unless
|
||||
bit 6 of 82h is set. */
|
||||
if (sb->dsp.sb_type > SBAWE32)
|
||||
if (sb->dsp.sb_type > SBAWE32_DSP_412)
|
||||
ret = mixer->regs[mixer->index];
|
||||
break;
|
||||
|
||||
@@ -1808,8 +1812,8 @@ sb_mcv_read(int port, void *priv)
|
||||
void
|
||||
sb_mcv_write(int port, uint8_t val, void *priv)
|
||||
{
|
||||
uint16_t addr;
|
||||
sb_t *sb = (sb_t *) priv;
|
||||
uint16_t addr = 0;
|
||||
sb_t *sb = (sb_t *) priv;
|
||||
|
||||
if (port < 0x102)
|
||||
return;
|
||||
@@ -1872,8 +1876,8 @@ sb_pro_mcv_read(int port, void *priv)
|
||||
static void
|
||||
sb_pro_mcv_write(int port, uint8_t val, void *priv)
|
||||
{
|
||||
uint16_t addr;
|
||||
sb_t *sb = (sb_t *) priv;
|
||||
uint16_t addr = 0;
|
||||
sb_t *sb = (sb_t *) priv;
|
||||
|
||||
if (port < 0x102)
|
||||
return;
|
||||
@@ -1943,8 +1947,8 @@ sb_16_reply_mca_read(int port, void *priv)
|
||||
static void
|
||||
sb_16_reply_mca_write(const int port, const uint8_t val, void *priv)
|
||||
{
|
||||
uint16_t addr;
|
||||
sb_t *sb = (sb_t *) priv;
|
||||
uint16_t addr = 0;
|
||||
sb_t *sb = (sb_t *) priv;
|
||||
|
||||
if (port < 0x102)
|
||||
return;
|
||||
@@ -2219,7 +2223,7 @@ sb_16_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void
|
||||
break;
|
||||
|
||||
case 2: /* Reserved (16) / WaveTable (32+) */
|
||||
if (sb->dsp.sb_type > SB16)
|
||||
if (sb->dsp.sb_type >= SBAWE32_DSP_412)
|
||||
emu8k_change_addr(&sb->emu8k, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0);
|
||||
break;
|
||||
|
||||
@@ -2812,182 +2816,62 @@ ess_chipchat_mca_write(int port, uint8_t val, void *priv)
|
||||
}
|
||||
|
||||
void *
|
||||
sb_1_init(UNUSED(const device_t *info))
|
||||
sb_init(UNUSED(const device_t *info))
|
||||
{
|
||||
/* SB1/2 port mappings, 210h to 260h in 10h steps
|
||||
2x0 to 2x3 -> CMS chip
|
||||
2x6, 2xA, 2xC, 2xE -> DSP chip
|
||||
2x8, 2x9, 388 and 389 FM chip */
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
const uint16_t addr = device_get_config_hex16("base");
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
|
||||
sb->opl_enabled = device_get_config_int("opl");
|
||||
if (sb->opl_enabled)
|
||||
fm_driver_get(FM_YM3812, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SB1, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||
/* DSP I/O handler is activated in sb_dsp_setaddr */
|
||||
if (sb->opl_enabled) {
|
||||
io_sethandler(addr + 8, 0x0002,
|
||||
sb->opl.read, NULL, NULL,
|
||||
sb->opl.write, NULL, NULL,
|
||||
sb->opl.priv);
|
||||
io_sethandler(0x0388, 0x0002,
|
||||
sb->opl.read, NULL, NULL,
|
||||
sb->opl.write, NULL, NULL,
|
||||
sb->opl.priv);
|
||||
}
|
||||
|
||||
sb->cms_enabled = 1;
|
||||
memset(&sb->cms, 0, sizeof(cms_t));
|
||||
io_sethandler(addr, 0x0004,
|
||||
cms_read, NULL, NULL,
|
||||
cms_write, NULL, NULL,
|
||||
&sb->cms);
|
||||
|
||||
sb->mixer_enabled = 0;
|
||||
sound_add_handler(sb_get_buffer_sb2, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sb2, sb);
|
||||
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
|
||||
|
||||
if (device_get_config_int("receive_input"))
|
||||
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
void *
|
||||
sb_15_init(UNUSED(const device_t *info))
|
||||
{
|
||||
/* SB1/2 port mappings, 210h to 260h in 10h steps
|
||||
2x0 to 2x3 -> CMS chip
|
||||
2x6, 2xA, 2xC, 2xE -> DSP chip
|
||||
2x8, 2x9, 388 and 389 FM chip */
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
const uint16_t addr = device_get_config_hex16("base");
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
|
||||
sb->opl_enabled = device_get_config_int("opl");
|
||||
if (sb->opl_enabled)
|
||||
fm_driver_get(FM_YM3812, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||
/* DSP I/O handler is activated in sb_dsp_setaddr */
|
||||
if (sb->opl_enabled) {
|
||||
io_sethandler(addr + 8, 0x0002,
|
||||
sb->opl.read, NULL, NULL,
|
||||
sb->opl.write, NULL, NULL,
|
||||
sb->opl.priv);
|
||||
io_sethandler(0x0388, 0x0002,
|
||||
sb->opl.read, NULL, NULL,
|
||||
sb->opl.write, NULL, NULL,
|
||||
sb->opl.priv);
|
||||
}
|
||||
|
||||
sb->cms_enabled = device_get_config_int("cms");
|
||||
if (sb->cms_enabled) {
|
||||
memset(&sb->cms, 0, sizeof(cms_t));
|
||||
io_sethandler(addr, 0x0004,
|
||||
cms_read, NULL, NULL,
|
||||
cms_write, NULL, NULL,
|
||||
&sb->cms);
|
||||
}
|
||||
|
||||
sb->mixer_enabled = 0;
|
||||
sound_add_handler(sb_get_buffer_sb2, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sb2, sb);
|
||||
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
|
||||
|
||||
if (device_get_config_int("receive_input"))
|
||||
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
void *
|
||||
sb_mcv_init(UNUSED(const device_t *info))
|
||||
{
|
||||
/* SB1/2 port mappings, 210h to 260h in 10h steps
|
||||
2x6, 2xA, 2xC, 2xE -> DSP chip
|
||||
2x8, 2x9, 388 and 389 FM chip */
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
|
||||
sb->opl_enabled = device_get_config_int("opl");
|
||||
if (sb->opl_enabled)
|
||||
fm_driver_get(FM_YM3812, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, 0);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||
|
||||
sb->mixer_enabled = 0;
|
||||
sound_add_handler(sb_get_buffer_sb2, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sb2, sb);
|
||||
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
|
||||
|
||||
/* I/O handlers activated in sb_mcv_write */
|
||||
mca_add(sb_mcv_read, sb_mcv_write, sb_mcv_feedb, NULL, sb);
|
||||
sb->pos_regs[0] = 0x84;
|
||||
sb->pos_regs[1] = 0x50;
|
||||
|
||||
if (device_get_config_int("receive_input"))
|
||||
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
void *
|
||||
sb_2_init(UNUSED(const device_t *info))
|
||||
{
|
||||
/* SB2 port mappings, 220h or 240h.
|
||||
2x0 to 2x3 -> CMS chip
|
||||
2x6, 2xA, 2xC, 2xE -> DSP chip
|
||||
2x8, 2x9, 388 and 389 FM chip
|
||||
"CD version" also uses 250h or 260h for
|
||||
2x0 to 2x3 -> CDROM interface
|
||||
2x4 to 2x5 -> Mixer interface */
|
||||
/* SB1.x port mappings, 210h to 260h in 10h steps:
|
||||
(SB2 port mappings are 220h or 240h)
|
||||
2x0 to 2x3 -> CMS chip
|
||||
2x6, 2xA, 2xC, 2xE -> DSP chip
|
||||
2x8, 2x9, 388 and 389 FM chip
|
||||
SB2 "CD version" also uses 250h or 260h:
|
||||
2x0 to 2x3 -> CDROM interface
|
||||
2x4 to 2x5 -> Mixer interface */
|
||||
/* My SB 2.0 mirrors the OPL2 at ports 2x0/2x1. Presumably this mirror is disabled when the
|
||||
CMS chips are present.
|
||||
This mirror may also exist on SB 1.5 & MCV, however I am unable to test this. It shouldn't
|
||||
exist on SB 1.0 as the CMS chips are always present there. Syndicate requires this mirror
|
||||
for music to play.*/
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
uint16_t addr = device_get_config_hex16("base");
|
||||
uint16_t mixer_addr = device_get_config_int("mixaddr");
|
||||
for music to play. */
|
||||
sb_t *sb = calloc(1, sizeof(sb_t));
|
||||
const uint16_t addr = device_get_config_hex16("base");
|
||||
uint16_t mixer_addr = 0x0000;
|
||||
uint8_t model = 0;
|
||||
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
switch (info->local) {
|
||||
default:
|
||||
case SB_1:
|
||||
model = SB_DSP_105;
|
||||
sb->cms_enabled = 1;
|
||||
break;
|
||||
|
||||
case SB_15:
|
||||
model = SB_DSP_200;
|
||||
sb->cms_enabled = device_get_config_int("cms");
|
||||
break;
|
||||
|
||||
case SB_2:
|
||||
model = SB_DSP_201;
|
||||
sb->cms_enabled = device_get_config_int("cms");
|
||||
mixer_addr = device_get_config_int("mixaddr");
|
||||
break;
|
||||
}
|
||||
|
||||
sb->opl_enabled = device_get_config_int("opl");
|
||||
if (sb->opl_enabled)
|
||||
fm_driver_get(FM_YM3812, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SB2, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_init(&sb->dsp, model, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||
if (mixer_addr > 0x000)
|
||||
|
||||
if (mixer_addr > 0x0000)
|
||||
sb_ct1335_mixer_reset(sb);
|
||||
|
||||
sb->cms_enabled = device_get_config_int("cms");
|
||||
/* DSP I/O handler is activated in sb_dsp_setaddr */
|
||||
if (sb->opl_enabled) {
|
||||
if (!sb->cms_enabled) {
|
||||
// TODO: See if this applies to the SB1.5 as well
|
||||
if ((!sb->cms_enabled) && ((model == SB_DSP_201) || (model == SB_DSP_202))) {
|
||||
io_sethandler(addr, 0x0002,
|
||||
sb->opl.read, NULL, NULL,
|
||||
sb->opl.write, NULL, NULL,
|
||||
@@ -3019,6 +2903,7 @@ sb_2_init(UNUSED(const device_t *info))
|
||||
sb);
|
||||
} else
|
||||
sb->mixer_enabled = 0;
|
||||
|
||||
sound_add_handler(sb_get_buffer_sb2, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sb2, sb);
|
||||
@@ -3030,6 +2915,41 @@ sb_2_init(UNUSED(const device_t *info))
|
||||
return sb;
|
||||
}
|
||||
|
||||
void *
|
||||
sb_mcv_init(UNUSED(const device_t *info))
|
||||
{
|
||||
/* SB1/2 port mappings, 210h to 260h in 10h steps
|
||||
2x6, 2xA, 2xC, 2xE -> DSP chip
|
||||
2x8, 2x9, 388 and 389 FM chip */
|
||||
sb_t *sb = calloc(1, sizeof(sb_t));
|
||||
|
||||
sb->opl_enabled = device_get_config_int("opl");
|
||||
if (sb->opl_enabled)
|
||||
fm_driver_get(FM_YM3812, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SB_DSP_105, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, 0);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||
|
||||
sb->mixer_enabled = 0;
|
||||
sound_add_handler(sb_get_buffer_sb2, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sb2, sb);
|
||||
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
|
||||
|
||||
/* I/O handlers activated in sb_mcv_write */
|
||||
mca_add(sb_mcv_read, sb_mcv_write, sb_mcv_feedb, NULL, sb);
|
||||
sb->pos_regs[0] = 0x84;
|
||||
sb->pos_regs[1] = 0x50;
|
||||
|
||||
if (device_get_config_int("receive_input"))
|
||||
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sb_pro_v1_opl_read(uint16_t port, void *priv)
|
||||
{
|
||||
@@ -3059,9 +2979,8 @@ sb_pro_v1_init(UNUSED(const device_t *info))
|
||||
2x6, 2xA, 2xC, 2xE -> DSP chip
|
||||
2x8, 2x9, 388 and 389 FM chip (9 voices)
|
||||
2x0+10 to 2x0+13 CDROM interface. */
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
sb_t *sb = calloc(1, sizeof(sb_t));
|
||||
uint16_t addr = device_get_config_hex16("base");
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
|
||||
sb->opl_enabled = device_get_config_int("opl");
|
||||
if (sb->opl_enabled) {
|
||||
@@ -3072,7 +2991,7 @@ sb_pro_v1_init(UNUSED(const device_t *info))
|
||||
}
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SBPRO, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_init(&sb->dsp, SBPRO_DSP_300, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||
@@ -3122,16 +3041,15 @@ sb_pro_v2_init(UNUSED(const device_t *info))
|
||||
2x6, 2xA, 2xC, 2xE -> DSP chip
|
||||
2x8, 2x9, 388 and 389 FM chip (9 voices)
|
||||
2x0+10 to 2x0+13 CDROM interface. */
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
sb_t *sb = calloc(1, sizeof(sb_t));
|
||||
uint16_t addr = device_get_config_hex16("base");
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
|
||||
sb->opl_enabled = device_get_config_int("opl");
|
||||
if (sb->opl_enabled)
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_init(&sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||
@@ -3176,14 +3094,13 @@ sb_pro_mcv_init(UNUSED(const device_t *info))
|
||||
2x4 to 2x5 -> Mixer interface
|
||||
2x6, 2xA, 2xC, 2xE -> DSP chip
|
||||
2x8, 2x9, 388 and 389 FM chip (9 voices) */
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
sb_t *sb = calloc(1, sizeof(sb_t));
|
||||
|
||||
sb->opl_enabled = 1;
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_init(&sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_ct1345_mixer_reset(sb);
|
||||
|
||||
sb->mixer_enabled = 1;
|
||||
@@ -3205,13 +3122,12 @@ sb_pro_mcv_init(UNUSED(const device_t *info))
|
||||
static void *
|
||||
sb_pro_compat_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
sb_t *sb = calloc(1, sizeof(sb_t));
|
||||
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_init(&sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_ct1345_mixer_reset(sb);
|
||||
|
||||
sb->mixer_enabled = 1;
|
||||
@@ -3219,8 +3135,7 @@ sb_pro_compat_init(UNUSED(const device_t *info))
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sbpro, sb);
|
||||
|
||||
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
||||
memset(sb->mpu, 0, sizeof(mpu_t));
|
||||
sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
|
||||
mpu401_init(sb->mpu, 0, 0, M_UART, 1);
|
||||
sb_dsp_set_mpu(&sb->dsp, sb->mpu);
|
||||
|
||||
@@ -3230,18 +3145,16 @@ sb_pro_compat_init(UNUSED(const device_t *info))
|
||||
static void *
|
||||
sb_16_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
sb_t *sb = calloc(1, sizeof(sb_t));
|
||||
const uint16_t addr = device_get_config_hex16("base");
|
||||
const uint16_t mpu_addr = device_get_config_hex16("base401");
|
||||
|
||||
memset(sb, 0x00, sizeof(sb_t));
|
||||
|
||||
sb->opl_enabled = device_get_config_int("opl");
|
||||
if (sb->opl_enabled)
|
||||
fm_driver_get((int) (intptr_t) info->local, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32PNP : SB16, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32_DSP_413 : SB16_DSP_405, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||
@@ -3277,8 +3190,7 @@ sb_16_init(UNUSED(const device_t *info))
|
||||
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
|
||||
|
||||
if (mpu_addr) {
|
||||
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
||||
memset(sb->mpu, 0, sizeof(mpu_t));
|
||||
sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
|
||||
mpu401_init(sb->mpu, device_get_config_hex16("base401"), 0, M_UART,
|
||||
device_get_config_int("receive_input401"));
|
||||
} else
|
||||
@@ -3298,14 +3210,13 @@ sb_16_init(UNUSED(const device_t *info))
|
||||
static void *
|
||||
sb_16_reply_mca_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
memset(sb, 0x00, sizeof(sb_t));
|
||||
sb_t *sb = calloc(1, sizeof(sb_t));
|
||||
|
||||
sb->opl_enabled = 1;
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_init(&sb->dsp, SB16_DSP_405, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setdma16_supported(&sb->dsp, 1);
|
||||
sb_dsp_setdma16_enabled(&sb->dsp, 1);
|
||||
sb_ct1745_mixer_reset(sb);
|
||||
@@ -3318,8 +3229,7 @@ sb_16_reply_mca_init(UNUSED(const device_t *info))
|
||||
if (device_get_config_int("control_pc_speaker"))
|
||||
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
|
||||
|
||||
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
||||
memset(sb->mpu, 0, sizeof(mpu_t));
|
||||
sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
|
||||
mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401"));
|
||||
sb_dsp_set_mpu(&sb->dsp, sb->mpu);
|
||||
|
||||
@@ -3353,15 +3263,14 @@ sb_16_pnp_ide_available(void)
|
||||
static void *
|
||||
sb_16_pnp_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
memset(sb, 0x00, sizeof(sb_t));
|
||||
sb_t *sb = calloc(1, sizeof(sb_t));
|
||||
|
||||
sb->pnp = 1;
|
||||
|
||||
sb->opl_enabled = 1;
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_init(&sb->dsp, SB16_DSP_405, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setdma16_supported(&sb->dsp, 1);
|
||||
sb_ct1745_mixer_reset(sb);
|
||||
|
||||
@@ -3373,8 +3282,7 @@ sb_16_pnp_init(UNUSED(const device_t *info))
|
||||
if (device_get_config_int("control_pc_speaker"))
|
||||
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
|
||||
|
||||
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
||||
memset(sb->mpu, 0, sizeof(mpu_t));
|
||||
sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
|
||||
mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401"));
|
||||
sb_dsp_set_mpu(&sb->dsp, sb->mpu);
|
||||
|
||||
@@ -3457,8 +3365,7 @@ sb_vibra16xv_available(void)
|
||||
static void *
|
||||
sb_vibra16_pnp_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
memset(sb, 0x00, sizeof(sb_t));
|
||||
sb_t *sb = calloc(1, sizeof(sb_t));
|
||||
|
||||
sb->pnp = 1;
|
||||
|
||||
@@ -3466,7 +3373,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info))
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, (info->local == SB_VIBRA16XV) ? SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_init(&sb->dsp, (info->local == SB_VIBRA16XV) ? SBAWE64_DSP_416 : SBAWE32_DSP_413, SB_SUBTYPE_DEFAULT, sb);
|
||||
/* The ViBRA 16XV does 16-bit DMA through 8-bit DMA. */
|
||||
sb_dsp_setdma16_supported(&sb->dsp, info->local != SB_VIBRA16XV);
|
||||
sb_ct1745_mixer_reset(sb);
|
||||
@@ -3479,8 +3386,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info))
|
||||
if (device_get_config_int("control_pc_speaker"))
|
||||
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
|
||||
|
||||
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
||||
memset(sb->mpu, 0, sizeof(mpu_t));
|
||||
sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
|
||||
mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401"));
|
||||
sb_dsp_set_mpu(&sb->dsp, sb->mpu);
|
||||
|
||||
@@ -3558,13 +3464,12 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info))
|
||||
static void *
|
||||
sb_16_compat_init(const device_t *info)
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
sb_t *sb = calloc(1, sizeof(sb_t));
|
||||
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_init(&sb->dsp, SB16_DSP_405, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setdma16_supported(&sb->dsp, 1);
|
||||
sb_dsp_setdma16_enabled(&sb->dsp, 1);
|
||||
sb_ct1745_mixer_reset(sb);
|
||||
@@ -3574,7 +3479,7 @@ sb_16_compat_init(const device_t *info)
|
||||
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
|
||||
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
|
||||
|
||||
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
||||
sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
|
||||
memset(sb->mpu, 0, sizeof(mpu_t));
|
||||
mpu401_init(sb->mpu, 0, 0, M_UART, (int) (intptr_t) info->local);
|
||||
sb_dsp_set_mpu(&sb->dsp, sb->mpu);
|
||||
@@ -3637,7 +3542,7 @@ sb_awe64_gold_available(void)
|
||||
static void *
|
||||
sb_awe32_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
sb_t *sb = calloc(1, sizeof(sb_t));
|
||||
uint16_t addr = device_get_config_hex16("base");
|
||||
uint16_t mpu_addr = device_get_config_hex16("base401");
|
||||
uint16_t emu_addr = device_get_config_hex16("emu_base");
|
||||
@@ -3650,7 +3555,7 @@ sb_awe32_init(UNUSED(const device_t *info))
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SBAWE32, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_init(&sb->dsp, SBAWE32_DSP_412, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||
@@ -3687,7 +3592,7 @@ sb_awe32_init(UNUSED(const device_t *info))
|
||||
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
|
||||
|
||||
if (mpu_addr) {
|
||||
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
||||
sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
|
||||
memset(sb->mpu, 0, sizeof(mpu_t));
|
||||
mpu401_init(sb->mpu, device_get_config_hex16("base401"), 0, M_UART,
|
||||
device_get_config_int("receive_input401"));
|
||||
@@ -3710,11 +3615,9 @@ sb_awe32_init(UNUSED(const device_t *info))
|
||||
static void *
|
||||
sb_goldfinch_init(const device_t *info)
|
||||
{
|
||||
goldfinch_t *goldfinch = malloc(sizeof(goldfinch_t));
|
||||
goldfinch_t *goldfinch = calloc(1, sizeof(goldfinch_t));
|
||||
int onboard_ram = device_get_config_int("onboard_ram");
|
||||
|
||||
memset(goldfinch, 0x00, sizeof(goldfinch_t));
|
||||
|
||||
wavetable_add_handler(sb_get_wavetable_buffer_goldfinch, goldfinch);
|
||||
|
||||
emu8k_init(&goldfinch->emu8k, 0, onboard_ram);
|
||||
@@ -3758,18 +3661,16 @@ sb_goldfinch_init(const device_t *info)
|
||||
static void *
|
||||
sb_awe32_pnp_init(const device_t *info)
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
sb_t *sb = calloc(1, sizeof(sb_t));
|
||||
int onboard_ram = device_get_config_int("onboard_ram");
|
||||
|
||||
memset(sb, 0x00, sizeof(sb_t));
|
||||
|
||||
sb->pnp = 1;
|
||||
|
||||
sb->opl_enabled = 1;
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_init(&sb->dsp, (info->local >= SB_AWE64_VALUE) ?
|
||||
SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb);
|
||||
SBAWE64_DSP_416 : SBAWE32_DSP_413, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setdma16_supported(&sb->dsp, 1);
|
||||
sb_ct1745_mixer_reset(sb);
|
||||
|
||||
@@ -3783,8 +3684,7 @@ sb_awe32_pnp_init(const device_t *info)
|
||||
if (device_get_config_int("control_pc_speaker"))
|
||||
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
|
||||
|
||||
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
||||
memset(sb->mpu, 0, sizeof(mpu_t));
|
||||
sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
|
||||
mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401"));
|
||||
sb_dsp_set_mpu(&sb->dsp, sb->mpu);
|
||||
|
||||
@@ -3903,7 +3803,7 @@ ess_x688_init(UNUSED(const device_t *info))
|
||||
fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&ess->dsp, 1);
|
||||
sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess);
|
||||
sb_dsp_init(&ess->dsp, SBPRO2_DSP_302, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess);
|
||||
sb_dsp_setaddr(&ess->dsp, addr);
|
||||
sb_dsp_setirq(&ess->dsp, device_get_config_int("irq"));
|
||||
sb_dsp_setdma8(&ess->dsp, device_get_config_int("dma"));
|
||||
@@ -4014,7 +3914,7 @@ ess_x688_pnp_init(UNUSED(const device_t *info))
|
||||
fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&ess->dsp, 1);
|
||||
sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess);
|
||||
sb_dsp_init(&ess->dsp, SBPRO2_DSP_302, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess);
|
||||
sb_dsp_setdma16_supported(&ess->dsp, 0);
|
||||
ess_mixer_reset(ess);
|
||||
|
||||
@@ -4100,7 +4000,7 @@ ess_x688_mca_init(UNUSED(const device_t *info))
|
||||
fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&ess->dsp, 1);
|
||||
sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess);
|
||||
sb_dsp_init(&ess->dsp, SBPRO2_DSP_302, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess);
|
||||
sb_dsp_setdma16_supported(&ess->dsp, 0);
|
||||
ess_mixer_reset(ess);
|
||||
|
||||
@@ -4211,7 +4111,8 @@ static const device_config_t sb_config[] = {
|
||||
},
|
||||
{
|
||||
.description = "0x260",
|
||||
.value = 0x260 },
|
||||
.value = 0x260
|
||||
},
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
@@ -4260,7 +4161,7 @@ static const device_config_t sb_config[] = {
|
||||
.description = "DMA 3",
|
||||
.value = 3
|
||||
},
|
||||
{ "" }
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -4314,8 +4215,7 @@ static const device_config_t sb15_config[] = {
|
||||
.description = "0x260",
|
||||
.value = 0x260
|
||||
},
|
||||
{
|
||||
.description = "" }
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -4408,10 +4308,6 @@ static const device_config_t sb2_config[] = {
|
||||
.description = "0x240",
|
||||
.value = 0x240
|
||||
},
|
||||
{
|
||||
.description = "0x260",
|
||||
.value = 0x260
|
||||
},
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
@@ -4428,14 +4324,6 @@ static const device_config_t sb2_config[] = {
|
||||
.description = "Disabled",
|
||||
.value = 0
|
||||
},
|
||||
{
|
||||
.description = "0x220",
|
||||
.value = 0x220
|
||||
},
|
||||
{
|
||||
.description = "0x240",
|
||||
.value = 0x240
|
||||
},
|
||||
{
|
||||
.description = "0x250",
|
||||
.value = 0x250
|
||||
@@ -5769,8 +5657,8 @@ const device_t sb_1_device = {
|
||||
.name = "Sound Blaster v1.0",
|
||||
.internal_name = "sb",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = sb_1_init,
|
||||
.local = SB_1,
|
||||
.init = sb_init,
|
||||
.close = sb_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
@@ -5783,8 +5671,8 @@ const device_t sb_15_device = {
|
||||
.name = "Sound Blaster v1.5",
|
||||
.internal_name = "sb1.5",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = sb_15_init,
|
||||
.local = SB_15,
|
||||
.init = sb_init,
|
||||
.close = sb_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
@@ -5811,8 +5699,8 @@ const device_t sb_2_device = {
|
||||
.name = "Sound Blaster v2.0",
|
||||
.internal_name = "sb2.0",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = sb_2_init,
|
||||
.local = SB_2,
|
||||
.init = sb_init,
|
||||
.close = sb_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
|
||||
@@ -77,13 +77,33 @@ static int sb_commands[256] = {
|
||||
-1, -1, 0, 0, -1, -1, -1, -1, -1, 1, 2, -1, -1, -1, -1, 0
|
||||
};
|
||||
|
||||
#if 0
|
||||
// Currently unused, here for reference if ever needed
|
||||
char sb202_copyright[] = "COPYRIGHT(C) CREATIVE TECHNOLOGY PTE. LTD. (1991) "
|
||||
#endif
|
||||
char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
|
||||
uint16_t sb_dsp_versions[] = { 0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x40c, 0x40d, 0x410 };
|
||||
uint16_t sb_dsp_versions[] = {
|
||||
0, /* Pad */
|
||||
0, /* SADLIB - No DSP */
|
||||
0x105, /* SB_DSP_105 - SB1/1.5, DSP v1.05 */
|
||||
0x200, /* SB_DSP_200 - SB1.5/2, DSP v2.00 */
|
||||
0x201, /* SB_DSP_201 - SB1.5/2, DSP v2.01 - needed for high-speed DMA */
|
||||
0x202, /* SB_DSP_202 - SB2, DSP v2.02 */
|
||||
0x300, /* SB_PRO_DSP_300 - SB Pro, DSP v3.00 */
|
||||
0x302, /* SBPRO2_DSP_302 - SB Pro 2, DSP v3.02 + OPL3 */
|
||||
0x404, /* SB16_DSP_404 - DSP v4.04 + OPL3 */
|
||||
0x405, /* SB16_405 - DSP v4.05 + OPL3 */
|
||||
0x406, /* SB16_406 - DSP v4.06 + OPL3 */
|
||||
0x40b, /* SB16_411 - DSP v4.11 + OPL3 */
|
||||
0x40c, /* SBAWE32 - DSP v4.12 + OPL3 */
|
||||
0x40d, /* SBAWE32PNP - DSP v4.13 + OPL3 */
|
||||
0x410 /* SBAWE64 - DSP v4.16 + OPL3 */
|
||||
};
|
||||
|
||||
/*These tables were 'borrowed' from DOSBox*/
|
||||
int8_t scaleMap4[64] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7,
|
||||
1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7,
|
||||
1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15,
|
||||
2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30,
|
||||
4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60
|
||||
};
|
||||
@@ -525,7 +545,7 @@ sb_doreset(sb_dsp_t *dsp)
|
||||
sb_commands[8] = 1;
|
||||
sb_commands[9] = 1;
|
||||
} else {
|
||||
if (dsp->sb_type >= SB16)
|
||||
if (dsp->sb_type >= SB16_DSP_404)
|
||||
sb_commands[8] = 1;
|
||||
else
|
||||
sb_commands[8] = -1;
|
||||
@@ -1206,7 +1226,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
|
||||
/* Update 8051 ram with the current DSP command.
|
||||
See https://github.com/joncampbell123/dosbox-x/issues/1044 */
|
||||
if (dsp->sb_type >= SB16) {
|
||||
if (dsp->sb_type >= SB16_DSP_404) {
|
||||
dsp->sb_8051_ram[0x20] = dsp->sb_command;
|
||||
}
|
||||
|
||||
@@ -1232,15 +1252,15 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
|
||||
switch (dsp->sb_command) {
|
||||
case 0x01: /* ???? */
|
||||
if (dsp->sb_type >= SB16)
|
||||
if (dsp->sb_type >= SB16_DSP_404)
|
||||
dsp->asp_data_len = dsp->sb_data[0] + (dsp->sb_data[1] << 8) + 1;
|
||||
break;
|
||||
case 0x03: /* ASP status */
|
||||
if (dsp->sb_type >= SB16)
|
||||
if (dsp->sb_type >= SB16_DSP_404)
|
||||
sb_add_data(dsp, 0);
|
||||
break;
|
||||
case 0x04: /* ASP set mode register */
|
||||
if (dsp->sb_type >= SB16) {
|
||||
if (dsp->sb_type >= SB16_DSP_404) {
|
||||
dsp->sb_asp_mode = dsp->sb_data[0];
|
||||
if (dsp->sb_asp_mode & 4)
|
||||
dsp->sb_asp_ram_index = 0;
|
||||
@@ -1248,7 +1268,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
} /* else DSP Status (Obsolete) */
|
||||
break;
|
||||
case 0x05: /* ASP set codec parameter */
|
||||
if (dsp->sb_type >= SB16) {
|
||||
if (dsp->sb_type >= SB16_DSP_404) {
|
||||
sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]);
|
||||
}
|
||||
break;
|
||||
@@ -1278,9 +1298,9 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
sb_dsp_log("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); /* 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen */
|
||||
break;
|
||||
}
|
||||
if (dsp->sb_type == SBAWE64) /* AWE64 has no ASP or a socket for it */
|
||||
if (dsp->sb_type == SBAWE64_DSP_416) /* AWE64 has no ASP or a socket for it */
|
||||
sb_add_data(dsp, 0xFF);
|
||||
else if (dsp->sb_type >= SB16)
|
||||
else if (dsp->sb_type >= SB16_DSP_404)
|
||||
sb_add_data(dsp, 0x18);
|
||||
break;
|
||||
case 0x09: /* AZTECH mode set */
|
||||
@@ -1296,7 +1316,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
}
|
||||
break;
|
||||
case 0x0E: /* ASP set register */
|
||||
if (dsp->sb_type >= SB16) {
|
||||
if (dsp->sb_type >= SB16_DSP_404) {
|
||||
dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1];
|
||||
|
||||
if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory write */
|
||||
@@ -1315,7 +1335,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
}
|
||||
break;
|
||||
case 0x0F: /* ASP get register */
|
||||
if (dsp->sb_type >= SB16) {
|
||||
if (dsp->sb_type >= SB16_DSP_404) {
|
||||
if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory read */
|
||||
if (dsp->sb_asp_mode & 8)
|
||||
dsp->sb_asp_ram_index = 0;
|
||||
@@ -1359,11 +1379,11 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
}
|
||||
break;
|
||||
case 0x1C: /* 8-bit autoinit DMA output */
|
||||
if (dsp->sb_type >= SB15)
|
||||
if (dsp->sb_type >= SB_DSP_200)
|
||||
sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen);
|
||||
break;
|
||||
case 0x1F: /* 2-bit ADPCM autoinit output */
|
||||
if (dsp->sb_type >= SB15) {
|
||||
if (dsp->sb_type >= SB_DSP_200) {
|
||||
sb_start_dma(dsp, 1, 1, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
|
||||
dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv);
|
||||
dsp->sb_8_length--;
|
||||
@@ -1388,7 +1408,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
case 0x28: /* Direct ADC, 8-bit (Burst) */
|
||||
break;
|
||||
case 0x2C: /* 8-bit autoinit DMA input */
|
||||
if (dsp->sb_type >= SB15)
|
||||
if (dsp->sb_type >= SB_DSP_200)
|
||||
sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
|
||||
break;
|
||||
case 0x30: /* MIDI Polling mode input */
|
||||
@@ -1405,7 +1425,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
case 0x33: /* MIDI Read Timestamp Interrupt */
|
||||
break;
|
||||
case 0x34: /* MIDI In poll */
|
||||
if (dsp->sb_type < SB2)
|
||||
if (dsp->sb_type < SB_DSP_200)
|
||||
break;
|
||||
sb_dsp_log("MIDI poll in\n");
|
||||
dsp->midi_in_poll = 1;
|
||||
@@ -1413,7 +1433,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
dsp->uart_irq = 0;
|
||||
break;
|
||||
case 0x35: /* MIDI In irq */
|
||||
if (dsp->sb_type < SB2)
|
||||
if (dsp->sb_type < SB_DSP_200)
|
||||
break;
|
||||
sb_dsp_log("MIDI irq in\n");
|
||||
dsp->midi_in_poll = 0;
|
||||
@@ -1432,7 +1452,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
temp = 256 - dsp->sb_data[0];
|
||||
temp = 1000000 / temp;
|
||||
sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho);
|
||||
if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16))
|
||||
if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16_DSP_404))
|
||||
recalc_sb16_filter(0, temp);
|
||||
dsp->sb_freq = temp;
|
||||
if (IS_ESS(dsp)) {
|
||||
@@ -1441,7 +1461,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
break;
|
||||
case 0x41: /* Set output sampling rate */
|
||||
case 0x42: /* Set input sampling rate */
|
||||
if (dsp->sb_type >= SB16) {
|
||||
if (dsp->sb_type >= SB16_DSP_404) {
|
||||
dsp->sblatcho = (double) ((double) TIMER_USEC * (1000000.0 / (double) (dsp->sb_data[1] + (dsp->sb_data[0] << 8))));
|
||||
sb_dsp_log("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho);
|
||||
temp = dsp->sb_freq;
|
||||
@@ -1459,7 +1479,8 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
case 0x47: /* Continue Auto-Initialize DMA, 16-bit */
|
||||
break;
|
||||
case 0x48: /* Set DSP block transfer size */
|
||||
dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8);
|
||||
if (dsp->sb_type >= SB_DSP_200)
|
||||
dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8);
|
||||
break;
|
||||
case 0x65: /* 4-bit ESPCM output with reference */
|
||||
case 0x64: /* 4-bit ESPCM output */
|
||||
@@ -1534,7 +1555,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
}
|
||||
break;
|
||||
case 0x7D: /* 4-bit ADPCM autoinit output */
|
||||
if (dsp->sb_type >= SB15) {
|
||||
if (dsp->sb_type >= SB_DSP_200) {
|
||||
sb_start_dma(dsp, 1, 1, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
|
||||
dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv);
|
||||
dsp->sb_8_length--;
|
||||
@@ -1542,7 +1563,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
}
|
||||
break;
|
||||
case 0x7F: /* 2.6-bit ADPCM autoinit output */
|
||||
if (dsp->sb_type >= SB15) {
|
||||
if (dsp->sb_type >= SB_DSP_200) {
|
||||
sb_start_dma(dsp, 1, 1, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
|
||||
dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv);
|
||||
dsp->sb_8_length--;
|
||||
@@ -1555,24 +1576,24 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
timer_set_delay_u64(&dsp->output_timer, (uint64_t) trunc(dsp->sblatcho));
|
||||
break;
|
||||
case 0x90: /* High speed 8-bit autoinit DMA output */
|
||||
if (dsp->sb_type >= SB2)
|
||||
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
|
||||
sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen);
|
||||
break;
|
||||
case 0x91: /* High speed 8-bit single cycle DMA output */
|
||||
if (dsp->sb_type >= SB2)
|
||||
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
|
||||
sb_start_dma(dsp, 1, 0, 0, dsp->sb_8_autolen);
|
||||
break;
|
||||
case 0x98: /* High speed 8-bit autoinit DMA input */
|
||||
if (dsp->sb_type >= SB2)
|
||||
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
|
||||
sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_8_autolen);
|
||||
break;
|
||||
case 0x99: /* High speed 8-bit single cycle DMA input */
|
||||
if (dsp->sb_type >= SB2)
|
||||
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
|
||||
sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_8_autolen);
|
||||
break;
|
||||
case 0xA0: /* Set input mode to mono */
|
||||
case 0xA8: /* Set input mode to stereo */
|
||||
if ((dsp->sb_type < SB2) || (dsp->sb_type > SBPRO2))
|
||||
if ((dsp->sb_type < SBPRO_DSP_300) || (dsp->sb_type > SBPRO2_DSP_302))
|
||||
break;
|
||||
/* TODO: Implement. 3.xx-only command. */
|
||||
break;
|
||||
@@ -1584,7 +1605,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
case 0xB5:
|
||||
case 0xB6:
|
||||
case 0xB7: /* 16-bit DMA output */
|
||||
if (dsp->sb_type >= SB16) {
|
||||
if (dsp->sb_type >= SB16_DSP_404) {
|
||||
sb_start_dma(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0],
|
||||
dsp->sb_data[1] + (dsp->sb_data[2] << 8));
|
||||
dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
|
||||
@@ -1598,7 +1619,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
case 0xBD:
|
||||
case 0xBE:
|
||||
case 0xBF: /* 16-bit DMA input */
|
||||
if (dsp->sb_type >= SB16) {
|
||||
if (dsp->sb_type >= SB16_DSP_404) {
|
||||
sb_start_dma_i(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0],
|
||||
dsp->sb_data[1] + (dsp->sb_data[2] << 8));
|
||||
dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
|
||||
@@ -1612,7 +1633,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
case 0xC5:
|
||||
case 0xC6:
|
||||
case 0xC7: /* 8-bit DMA output */
|
||||
if (dsp->sb_type >= SB16) {
|
||||
if (dsp->sb_type >= SB16_DSP_404) {
|
||||
sb_start_dma(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0],
|
||||
dsp->sb_data[1] + (dsp->sb_data[2] << 8));
|
||||
dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
|
||||
@@ -1626,7 +1647,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
case 0xCD:
|
||||
case 0xCE:
|
||||
case 0xCF: /* 8-bit DMA input */
|
||||
if (dsp->sb_type >= SB16) {
|
||||
if (dsp->sb_type >= SB16_DSP_404) {
|
||||
sb_start_dma_i(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0],
|
||||
dsp->sb_data[1] + (dsp->sb_data[2] << 8));
|
||||
dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
|
||||
@@ -1638,20 +1659,20 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
break;
|
||||
case 0xD1: /* Speaker on */
|
||||
if (IS_NOT_ESS(dsp)) {
|
||||
if (dsp->sb_type < SB15) {
|
||||
if (dsp->sb_type < SB_DSP_200) {
|
||||
dsp->sb_8_pause = 1;
|
||||
sb_stop_dma(dsp);
|
||||
} else if (dsp->sb_type < SB16)
|
||||
} else if (dsp->sb_type < SB16_DSP_404)
|
||||
dsp->muted = 0;
|
||||
}
|
||||
dsp->sb_speaker = 1;
|
||||
break;
|
||||
case 0xD3: /* Speaker off */
|
||||
if (IS_NOT_ESS(dsp)) {
|
||||
if (dsp->sb_type < SB15) {
|
||||
if (dsp->sb_type < SB_DSP_201) {
|
||||
dsp->sb_8_pause = 1;
|
||||
sb_stop_dma(dsp);
|
||||
} else if (dsp->sb_type < SB16)
|
||||
} else if (dsp->sb_type < SB16_DSP_404)
|
||||
dsp->muted = 1;
|
||||
}
|
||||
dsp->sb_speaker = 0;
|
||||
@@ -1661,26 +1682,28 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
sb_resume_dma(dsp, 1);
|
||||
break;
|
||||
case 0xD5: /* Pause 16-bit DMA */
|
||||
if (dsp->sb_type >= SB16) {
|
||||
if (dsp->sb_type >= SB16_DSP_404) {
|
||||
dsp->sb_16_pause = 1;
|
||||
sb_stop_dma(dsp);
|
||||
}
|
||||
break;
|
||||
case 0xD6: /* Continue 16-bit DMA */
|
||||
if (dsp->sb_type >= SB16) {
|
||||
if (dsp->sb_type >= SB16_DSP_404) {
|
||||
dsp->sb_16_pause = 0;
|
||||
sb_resume_dma(dsp, 1);
|
||||
}
|
||||
break;
|
||||
case 0xD8: /* Get speaker status */
|
||||
sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0);
|
||||
if (dsp->sb_type >= SB_DSP_200)
|
||||
sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0);
|
||||
break;
|
||||
case 0xD9: /* Exit 16-bit auto-init mode */
|
||||
if (dsp->sb_type >= SB16)
|
||||
if (dsp->sb_type >= SB16_DSP_404)
|
||||
dsp->sb_16_autoinit = 0;
|
||||
break;
|
||||
case 0xDA: /* Exit 8-bit auto-init mode */
|
||||
dsp->sb_8_autoinit = 0;
|
||||
if (dsp->sb_type >= SB_DSP_200)
|
||||
dsp->sb_8_autoinit = 0;
|
||||
break;
|
||||
case 0xE0: /* DSP identification */
|
||||
sb_add_data(dsp, ~dsp->sb_data[0]);
|
||||
@@ -1721,7 +1744,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
sb_add_data(dsp, dsp->sbe2);
|
||||
break;
|
||||
case 0xE3: /* DSP copyright */
|
||||
if (dsp->sb_type >= SB16) {
|
||||
if (dsp->sb_type >= SB16_DSP_404) {
|
||||
c = 0;
|
||||
while (sb16_copyright[c])
|
||||
sb_add_data(dsp, sb16_copyright[c++]);
|
||||
@@ -1782,15 +1805,15 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
timer_set_delay_u64(&dsp->irq16_timer, (10ULL * TIMER_USEC));
|
||||
break;
|
||||
case 0xF8:
|
||||
if (dsp->sb_type < SB16)
|
||||
if (dsp->sb_type < SB16_DSP_404)
|
||||
sb_add_data(dsp, 0);
|
||||
break;
|
||||
case 0xF9: /* SB16 8051 RAM read */
|
||||
if (dsp->sb_type >= SB16)
|
||||
if (dsp->sb_type >= SB16_DSP_404)
|
||||
sb_add_data(dsp, dsp->sb_8051_ram[dsp->sb_data[0]]);
|
||||
break;
|
||||
case 0xFA: /* SB16 8051 RAM write */
|
||||
if (dsp->sb_type >= SB16)
|
||||
if (dsp->sb_type >= SB16_DSP_404)
|
||||
dsp->sb_8051_ram[dsp->sb_data[0]] = dsp->sb_data[1];
|
||||
break;
|
||||
case 0xFF: /* No, that's not how you program auto-init DMA */
|
||||
@@ -1800,11 +1823,24 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
* http://the.earth.li/~tfm/oldpage/sb_dsp.html
|
||||
* http://www.synchrondata.com/pheaven/www/area19.htm
|
||||
* http://www.dcee.net/Files/Programm/Sound/
|
||||
* 0E3h DSP Copyright SBPro2???
|
||||
* 0F0h Sine Generator SB
|
||||
* 0F1h DSP Auxiliary Status (Obsolete) SB-Pro2
|
||||
* 0F2h IRQ Request, 8-bit SB
|
||||
* https://github.com/schlae/sb-firmware/blob/master/sbv202.asm
|
||||
* 008h Halt (Infinate Loop) SB2???
|
||||
* 018h DMA playback with auto init DMA. SB2???
|
||||
* 028h Auto-init direct ADC SB2???
|
||||
* 036h (Timestamp) SB???
|
||||
* 037h (Timestamp) SB???
|
||||
* 050h Stops playback of SRAM samples SB???
|
||||
* 051h Plays back samples stored in SRAM. SB???
|
||||
* 058h Load data into SRAM SB???
|
||||
* 059h Fetches the samples and then immediately plays them back. SB???
|
||||
* 078h Auto-init DMA ADPCM SB2???
|
||||
* 07Ah 2.6-bit ADPCM SB???
|
||||
* 0E3h DSP Copyright SBPro2??? (SBPRO2_DSP_302)
|
||||
* 0F0h Sine Generator SB (SB_DSP_105, DSP20x)
|
||||
* 0F1h DSP Auxiliary Status (Obsolete) SB-Pro2 (DSP20x, SBPRO2_DSP_302)
|
||||
* 0F2h IRQ Request, 8-bit SB (SB_DSP_105, DSP20x)
|
||||
* 0F3h IRQ Request, 16-bit SB16
|
||||
* 0F4h Perform ROM checksum SB (SB_DSP_105, DSP20x)
|
||||
* 0FBh DSP Status SB16
|
||||
* 0FCh DSP Auxiliary Status SB16
|
||||
* 0FDh DSP Command Status SB16
|
||||
@@ -1817,7 +1853,7 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
|
||||
/* Update 8051 ram with the last DSP command.
|
||||
See https://github.com/joncampbell123/dosbox-x/issues/1044 */
|
||||
if (dsp->sb_type >= SB16)
|
||||
if (dsp->sb_type >= SB16_DSP_404)
|
||||
dsp->sb_8051_ram[0x30] = dsp->sb_command;
|
||||
}
|
||||
|
||||
@@ -1836,31 +1872,31 @@ sb_do_reset(sb_dsp_t *dsp, const uint8_t v)
|
||||
}
|
||||
|
||||
void
|
||||
sb_write(uint16_t a, uint8_t v, void *priv)
|
||||
sb_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
sb_dsp_t *dsp = (sb_dsp_t *) priv;
|
||||
|
||||
sb_dsp_log("[%04X:%08X] DSP: [W] %04X = %02X\n", CS, cpu_state.pc, a, v);
|
||||
sb_dsp_log("[%04X:%08X] DSP: [W] %04X = %02X\n", CS, cpu_state.pc, addr, val);
|
||||
|
||||
/* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */
|
||||
if ((dsp->sb_type < SB16) && (IS_NOT_ESS(dsp) || ((a & 0xF) != 0xE)))
|
||||
a &= 0xfffe;
|
||||
if ((dsp->sb_type < SB16_DSP_404) && (IS_NOT_ESS(dsp) || ((addr & 0xF) != 0xE)))
|
||||
addr &= 0xfffe;
|
||||
|
||||
switch (a & 0xF) {
|
||||
switch (addr & 0xF) {
|
||||
case 6: /* Reset */
|
||||
sb_do_reset(dsp, v);
|
||||
sb_do_reset(dsp, val);
|
||||
|
||||
if (!(v & 2) && (dsp->espcm_fifo_reset & 2)) {
|
||||
if (!(val & 2) && (dsp->espcm_fifo_reset & 2)) {
|
||||
fifo_reset(dsp->espcm_fifo);
|
||||
}
|
||||
dsp->espcm_fifo_reset = v;
|
||||
dsp->espcm_fifo_reset = val;
|
||||
dsp->uart_midi = 0;
|
||||
dsp->uart_irq = 0;
|
||||
dsp->onebyte_midi = 0;
|
||||
return;
|
||||
case 0xC: /* Command/data write */
|
||||
if (dsp->uart_midi || dsp->onebyte_midi) {
|
||||
midi_raw_out_byte(v);
|
||||
midi_raw_out_byte(val);
|
||||
dsp->onebyte_midi = 0;
|
||||
return;
|
||||
}
|
||||
@@ -1873,8 +1909,8 @@ sb_write(uint16_t a, uint8_t v, void *priv)
|
||||
return;
|
||||
}
|
||||
if (dsp->sb_data_stat == -1) {
|
||||
dsp->sb_command = v;
|
||||
if (v == 0x01)
|
||||
dsp->sb_command = val;
|
||||
if (val == 0x01)
|
||||
sb_add_data(dsp, 0);
|
||||
dsp->sb_data_stat++;
|
||||
if (IS_AZTECH(dsp)) {
|
||||
@@ -1901,7 +1937,7 @@ sb_write(uint16_t a, uint8_t v, void *priv)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dsp->sb_data[dsp->sb_data_stat++] = v;
|
||||
dsp->sb_data[dsp->sb_data_stat++] = val;
|
||||
}
|
||||
if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1) {
|
||||
sb_exec_command(dsp);
|
||||
@@ -1920,17 +1956,17 @@ sb_write(uint16_t a, uint8_t v, void *priv)
|
||||
}
|
||||
|
||||
uint8_t
|
||||
sb_read(uint16_t a, void *priv)
|
||||
sb_read(uint16_t addr, void *priv)
|
||||
{
|
||||
sb_dsp_t *dsp = (sb_dsp_t *) priv;
|
||||
uint8_t ret = 0x00;
|
||||
|
||||
/* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */
|
||||
if ((dsp->sb_type < SB16) && (IS_NOT_ESS(dsp) || ((a & 0xF) != 0xF)))
|
||||
if ((dsp->sb_type < SB16_DSP_404) && (IS_NOT_ESS(dsp) || ((addr & 0xF) != 0xF)))
|
||||
/* Exception: ESS AudioDrive does not alias port base+0xf */
|
||||
a &= 0xfffe;
|
||||
addr &= 0xfffe;
|
||||
|
||||
switch (a & 0xf) {
|
||||
switch (addr & 0xf) {
|
||||
case 0x6:
|
||||
if (IS_ESS(dsp)) {
|
||||
ret = (dsp->espcm_fifo_reset & 0x03) | 0x08 | (dsp->activity & 0xe0);
|
||||
@@ -1968,7 +2004,7 @@ sb_read(uint16_t a, void *priv)
|
||||
if (dsp->state == DSP_S_RESET_WAIT)
|
||||
dsp->state = DSP_S_NORMAL;
|
||||
if ((dsp->state == DSP_S_NORMAL) || IS_ESS(dsp)) {
|
||||
if (dsp->sb_8_enable || dsp->sb_type >= SB16)
|
||||
if (dsp->sb_8_enable || dsp->sb_type >= SB16_DSP_404)
|
||||
dsp->busy_count = (dsp->busy_count + 1) & 3;
|
||||
else
|
||||
dsp->busy_count = 0;
|
||||
@@ -1993,7 +2029,7 @@ sb_read(uint16_t a, void *priv)
|
||||
ret = 0x80;
|
||||
} else {
|
||||
sb_dsp_log("SB Write Data Creative read 0xff\n");
|
||||
if ((dsp->sb_type >= SB2) && (dsp->sb_type < SB16) && IS_NOT_ESS(dsp))
|
||||
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404) && IS_NOT_ESS(dsp))
|
||||
ret = 0xaa;
|
||||
else
|
||||
ret = 0xff;
|
||||
@@ -2003,7 +2039,7 @@ sb_read(uint16_t a, void *priv)
|
||||
ret = 0x00;
|
||||
} else {
|
||||
sb_dsp_log("SB Write Data Creative read 0x7f\n");
|
||||
if ((dsp->sb_type >= SB2) && (dsp->sb_type < SB16) && IS_NOT_ESS(dsp))
|
||||
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404) && IS_NOT_ESS(dsp))
|
||||
ret = 0x2a;
|
||||
else
|
||||
ret = 0x7f;
|
||||
@@ -2027,7 +2063,7 @@ sb_read(uint16_t a, void *priv)
|
||||
ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80;
|
||||
} else {
|
||||
sb_dsp_log("SB Read Data Creative read %02X\n", (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff);
|
||||
if ((dsp->sb_type < SB16) && IS_NOT_ESS(dsp))
|
||||
if ((dsp->sb_type < SB16_DSP_404) && IS_NOT_ESS(dsp))
|
||||
ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x2a : 0xaa;
|
||||
else
|
||||
ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff;
|
||||
@@ -2138,11 +2174,11 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent)
|
||||
/* Default values. Use sb_dsp_setxxx() methods to change. */
|
||||
dsp->sb_irqnum = 7;
|
||||
dsp->sb_8_dmanum = 1;
|
||||
if (type >= SB16)
|
||||
if (type >= SB16_DSP_404)
|
||||
dsp->sb_16_dmanum = 5;
|
||||
else
|
||||
dsp->sb_16_dmanum = 0xff;
|
||||
if ((type >= SB16) || IS_ESS(dsp))
|
||||
if ((type >= SB16_DSP_404) || IS_ESS(dsp))
|
||||
dsp->sb_16_8_dmanum = 0x1;
|
||||
dsp->mpu = NULL;
|
||||
|
||||
@@ -2174,7 +2210,7 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent)
|
||||
a set frequency command is sent. */
|
||||
recalc_sb16_filter(0, 3200 * 2);
|
||||
}
|
||||
if (IS_ESS(dsp) || (dsp->sb_type >= SBPRO2)) {
|
||||
if (IS_ESS(dsp) || (dsp->sb_type >= SBPRO2_DSP_302)) {
|
||||
/* OPL3 or dual OPL2 is stereo. */
|
||||
if (dsp->sb_has_real_opl)
|
||||
recalc_opl_filter(FREQ_49716 * 2);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/nv/vid_nv_rivatimer.h>
|
||||
|
||||
uint64_t TIMER_USEC;
|
||||
uint32_t timer_target;
|
||||
@@ -168,6 +169,9 @@ timer_init(void)
|
||||
timer_target = 0ULL;
|
||||
tsc = 0;
|
||||
|
||||
/* Initialise the CPU-independent timer */
|
||||
rivatimer_init();
|
||||
|
||||
timer_inited = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -134,9 +134,14 @@ plat_cdrom_get_last_block(void *local)
|
||||
}
|
||||
|
||||
int
|
||||
plat_cdrom_ext_medium_changed(void *local)
|
||||
plat_cdrom_ext_medium_changed(UNUSED(void *local))
|
||||
{
|
||||
#if 0
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
#endif
|
||||
|
||||
int ret = 0;
|
||||
|
||||
dummy_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret);
|
||||
|
||||
@@ -27,7 +27,9 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c
|
||||
vid_tkd8001_ramdac.c vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c
|
||||
vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c
|
||||
vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c
|
||||
vid_bochs_vbe.c)
|
||||
vid_bochs_vbe.c
|
||||
nv/nv_rivatimer.c
|
||||
)
|
||||
|
||||
if(G100)
|
||||
target_compile_definitions(vid PRIVATE USE_G100)
|
||||
|
||||
274
src/video/nv/nv_rivatimer.c
Normal file
274
src/video/nv/nv_rivatimer.c
Normal file
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Fast, high-frequency, CPU-independent timer.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Connor Hyde, <mario64crashed@gmail.com> I need a better email address ;^)
|
||||
*
|
||||
* Copyright 2024-2025 starfrost
|
||||
*/
|
||||
|
||||
/* See vid_nv_rivatimer.h comments for rationale behind not using the regular timer system
|
||||
|
||||
Notes applicable to this file:
|
||||
Since Windows XP, QueryPerformanceCounter and QueryPerformanceFrequency cannot fail so they are not checked.
|
||||
|
||||
*/
|
||||
|
||||
#include <86box/nv/vid_nv_rivatimer.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER performance_frequency;
|
||||
#endif
|
||||
|
||||
rivatimer_t* rivatimer_head; // The head of the rivatimer list.
|
||||
rivatimer_t* rivatimer_tail; // The tail of the rivatimer list.
|
||||
|
||||
/* Functions only used in this translation unit */
|
||||
bool rivatimer_really_exists(rivatimer_t* rivatimer); // Determine if a rivatimer really exists in the linked list.
|
||||
|
||||
void rivatimer_init(void)
|
||||
{
|
||||
// Destroy all the rivatimers.
|
||||
rivatimer_t* rivatimer_ptr = rivatimer_head;
|
||||
|
||||
if (!rivatimer_ptr)
|
||||
return;
|
||||
|
||||
while (rivatimer_ptr)
|
||||
{
|
||||
// since we are destroing it
|
||||
rivatimer_t* old_next = rivatimer_ptr->next;
|
||||
rivatimer_destroy(rivatimer_ptr);
|
||||
|
||||
rivatimer_ptr = old_next;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
// Query the performance frequency.
|
||||
QueryPerformanceFrequency(&performance_frequency);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Creates a rivatimer.
|
||||
rivatimer_t* rivatimer_create(double period, void (*callback)(double real_time))
|
||||
{
|
||||
rivatimer_t* new_rivatimer = NULL;
|
||||
|
||||
// See i
|
||||
if (period <= 0
|
||||
|| !callback)
|
||||
{
|
||||
fatal("Invalid rivatimer_create call: period <= 0 or no callback");
|
||||
}
|
||||
|
||||
// If there are no rivatimers, create one
|
||||
if (!rivatimer_head)
|
||||
{
|
||||
rivatimer_head = calloc(1, sizeof(rivatimer_t));
|
||||
rivatimer_head->prev = NULL; // indicate this is the first in the list even if we don't strictly need to
|
||||
rivatimer_tail = rivatimer_head;
|
||||
new_rivatimer = rivatimer_head;
|
||||
}
|
||||
else // Otherwise add a new one to the list
|
||||
{
|
||||
rivatimer_tail->next = calloc(1, sizeof(rivatimer_t));
|
||||
rivatimer_tail = rivatimer_tail->next;
|
||||
new_rivatimer = rivatimer_tail;
|
||||
}
|
||||
|
||||
// sanity check
|
||||
if (new_rivatimer)
|
||||
{
|
||||
new_rivatimer->running = false;
|
||||
new_rivatimer->period = period;
|
||||
new_rivatimer->next = NULL; // indicate this is the last in the list
|
||||
new_rivatimer->callback = callback;
|
||||
}
|
||||
|
||||
return new_rivatimer;
|
||||
}
|
||||
|
||||
// Determines if a rivatimer really exists.
|
||||
bool rivatimer_really_exists(rivatimer_t* rivatimer)
|
||||
{
|
||||
rivatimer_t* current = rivatimer_head;
|
||||
|
||||
if (!current)
|
||||
return false;
|
||||
|
||||
while (current)
|
||||
{
|
||||
if (current == rivatimer)
|
||||
return true;
|
||||
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Destroy a rivatimer.
|
||||
void rivatimer_destroy(rivatimer_t* rivatimer_ptr)
|
||||
{
|
||||
if (!rivatimer_really_exists(rivatimer_ptr))
|
||||
fatal("rivatimer_destroy: The timer was already destroyed, or never existed in the first place.");
|
||||
|
||||
// Case: We are destroying the head
|
||||
if (rivatimer_ptr == rivatimer_head)
|
||||
{
|
||||
// This is the only rivatimer
|
||||
if (rivatimer_ptr->next == NULL)
|
||||
{
|
||||
rivatimer_head = NULL;
|
||||
rivatimer_tail = NULL;
|
||||
}
|
||||
// This is not the only rivatimer
|
||||
else
|
||||
{
|
||||
rivatimer_head = rivatimer_ptr->next;
|
||||
rivatimer_head->prev = NULL;
|
||||
// This is the only rivatimer and now there is only one
|
||||
if (!rivatimer_head->next)
|
||||
rivatimer_tail = rivatimer_head;
|
||||
}
|
||||
}
|
||||
// Case: We are destroying the tail
|
||||
else if (rivatimer_ptr == rivatimer_tail)
|
||||
{
|
||||
// We already covered the case where there is only one item above
|
||||
rivatimer_tail = rivatimer_ptr->prev;
|
||||
rivatimer_tail->next = NULL;
|
||||
}
|
||||
// Case: This is not the first or last rivatimer, so we don't need to set the head or tail
|
||||
else
|
||||
{
|
||||
// Fix the break in the chain that this
|
||||
if (rivatimer_ptr->next)
|
||||
rivatimer_ptr->prev->next = rivatimer_ptr->next;
|
||||
if (rivatimer_ptr->prev)
|
||||
rivatimer_ptr->next->prev = rivatimer_ptr->prev;
|
||||
}
|
||||
|
||||
free(rivatimer_ptr);
|
||||
rivatimer_ptr = NULL; //explicitly set to null
|
||||
}
|
||||
|
||||
void rivatimer_update_all(void)
|
||||
{
|
||||
rivatimer_t* rivatimer_ptr = rivatimer_head;
|
||||
|
||||
if (!rivatimer_ptr)
|
||||
return;
|
||||
|
||||
while (rivatimer_ptr)
|
||||
{
|
||||
// if it's not running skip it
|
||||
if (!rivatimer_ptr->running)
|
||||
{
|
||||
rivatimer_ptr = rivatimer_ptr->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER current_time;
|
||||
|
||||
QueryPerformanceCounter(¤t_time);
|
||||
|
||||
double microseconds = ((double)current_time.QuadPart / 1000000.0) - (rivatimer_ptr->starting_time.QuadPart / 1000000.0);
|
||||
#else
|
||||
struct timespec current_time;
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, ¤t_time);
|
||||
|
||||
double microseconds = ((double)current_time.tv_sec * 1000000.0) + ((double)current_time.tv_nsec / 1000.0);
|
||||
#endif
|
||||
|
||||
rivatimer_ptr->time += microseconds;
|
||||
|
||||
// Reset the current time so we can actually restart
|
||||
#ifdef _WIN32
|
||||
QueryPerformanceCounter(&rivatimer_ptr->starting_time);
|
||||
#else
|
||||
clock_gettime(CLOCK_REALTIME, &rivatimer_ptr->starting_time);
|
||||
#endif
|
||||
|
||||
// Time to fire
|
||||
if (microseconds > rivatimer_ptr->period)
|
||||
{
|
||||
if (!rivatimer_ptr->callback)
|
||||
{
|
||||
pclog("Eh? No callback in RivaTimer?");
|
||||
continue;
|
||||
}
|
||||
|
||||
rivatimer_ptr->callback(microseconds);
|
||||
}
|
||||
|
||||
rivatimer_ptr = rivatimer_ptr->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void rivatimer_start(rivatimer_t* rivatimer_ptr)
|
||||
{
|
||||
if (!rivatimer_really_exists(rivatimer_ptr))
|
||||
fatal("rivatimer_start: The timer has been destroyed, or never existed in the first place.");
|
||||
|
||||
if (rivatimer_ptr->period <= 0)
|
||||
fatal("rivatimer_start: Zero period!");
|
||||
|
||||
rivatimer_ptr->running = true;
|
||||
|
||||
// Start off so rivatimer_update_all can actually update.
|
||||
#ifdef _WIN32
|
||||
QueryPerformanceCounter(&rivatimer_ptr->starting_time);
|
||||
#else
|
||||
clock_gettime(CLOCK_REALTIME, &rivatimer_ptr->starting_time);
|
||||
#endif
|
||||
}
|
||||
|
||||
void rivatimer_stop(rivatimer_t* rivatimer_ptr)
|
||||
{
|
||||
if (!rivatimer_really_exists(rivatimer_ptr))
|
||||
fatal("rivatimer_stop: The timer has been destroyed, or never existed in the first place.");
|
||||
|
||||
rivatimer_ptr->running = false;
|
||||
rivatimer_ptr->time = 0;
|
||||
}
|
||||
|
||||
// Get the current time value of a rivatimer
|
||||
double rivatimer_get_time(rivatimer_t* rivatimer_ptr)
|
||||
{
|
||||
if (!rivatimer_really_exists(rivatimer_ptr))
|
||||
fatal("rivatimer_get_time: The timer has been destroyed, or never existed in the first place.");
|
||||
|
||||
return rivatimer_ptr->time;
|
||||
}
|
||||
|
||||
void rivatimer_set_callback(rivatimer_t* rivatimer_ptr, void (*callback)(double real_time))
|
||||
{
|
||||
if (!rivatimer_really_exists(rivatimer_ptr))
|
||||
fatal("rivatimer_set_callback: The timer has been destroyed, or never existed in the first place.");
|
||||
|
||||
if (!callback)
|
||||
fatal("rivatimer_set_callback: No callback!");
|
||||
|
||||
rivatimer_ptr->callback = callback;
|
||||
}
|
||||
|
||||
void rivatimer_set_period(rivatimer_t* rivatimer_ptr, double period)
|
||||
{
|
||||
if (!rivatimer_really_exists(rivatimer_ptr))
|
||||
fatal("rivatimer_set_period: The timer has been destroyed, or never existed in the first place.");
|
||||
|
||||
rivatimer_ptr->period = period;
|
||||
}
|
||||
@@ -43,6 +43,11 @@
|
||||
#include <86box/vid_ati_mach8.h>
|
||||
#include "cpu.h"
|
||||
|
||||
#ifdef CLAMP
|
||||
# undef CLAMP
|
||||
#endif
|
||||
|
||||
|
||||
#define BIOS_MACH8_ROM_PATH "roms/video/mach8/11301113140_4k.BIN"
|
||||
|
||||
static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *priv);
|
||||
@@ -68,6 +73,17 @@ ibm8514_log(const char *fmt, ...)
|
||||
# define ibm8514_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static int16_t
|
||||
CLAMP(int16_t in, int16_t min, int16_t max)
|
||||
{
|
||||
if (in < min)
|
||||
return min;
|
||||
if (in > max)
|
||||
return max;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
#define WRITE8(addr, var, val) \
|
||||
switch ((addr) & 1) { \
|
||||
case 0: \
|
||||
@@ -416,14 +432,6 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len)
|
||||
if (len == 2) {
|
||||
dev->accel.short_stroke = val;
|
||||
|
||||
dev->accel.cx = dev->accel.cur_x;
|
||||
if (dev->accel.cur_x >= 0x600)
|
||||
dev->accel.cx |= ~0x5ff;
|
||||
|
||||
dev->accel.cy = dev->accel.cur_y;
|
||||
if (dev->accel.cur_y >= 0x600)
|
||||
dev->accel.cy |= ~0x5ff;
|
||||
|
||||
if (dev->accel.cmd & 0x1000) {
|
||||
ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len);
|
||||
ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len);
|
||||
@@ -969,6 +977,7 @@ ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t
|
||||
dev->accel.ssv_len = ssv & 0x0f;
|
||||
dev->accel.ssv_dir = ssv & 0xe0;
|
||||
dev->accel.ssv_draw = ssv & 0x10;
|
||||
dev->accel.ssv_len_back = dev->accel.ssv_len;
|
||||
|
||||
if (ibm8514_cpu_src(svga)) {
|
||||
dev->data_available = 0;
|
||||
@@ -1006,6 +1015,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
uint16_t bkgd_color = dev->accel.bkgd_color;
|
||||
uint32_t old_mix_dat;
|
||||
int and3 = dev->accel.cur_x & 3;
|
||||
int poly_src;
|
||||
|
||||
if (!dev->bpp) {
|
||||
compare &= 0xff;
|
||||
@@ -1121,13 +1131,24 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
|
||||
old_mix_dat = mix_dat;
|
||||
|
||||
if (cmd == 5 || cmd == 1 || (cmd == 2 && (dev->accel.multifunc[0x0a] & 0x06)))
|
||||
ibm8514_log("CMD=%d, full=%04x, pixcntl=%d, filling=%02x.\n", cmd, dev->accel.cmd, pixcntl, dev->accel.multifunc[0x0a] & 0x06);
|
||||
|
||||
/*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled.
|
||||
When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on
|
||||
the NOP command)*/
|
||||
switch (cmd) {
|
||||
case 0: /*NOP (Short Stroke Vectors)*/
|
||||
if (dev->accel.ssv_state == 0)
|
||||
if (dev->accel.ssv_state == 0) {
|
||||
dev->accel.cx = dev->accel.cur_x;
|
||||
if (dev->accel.cur_x >= 0x600)
|
||||
dev->accel.cx |= ~0x5ff;
|
||||
|
||||
dev->accel.cy = dev->accel.cur_y;
|
||||
if (dev->accel.cur_y >= 0x600)
|
||||
dev->accel.cy |= ~0x5ff;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->accel.cmd & 0x08) {
|
||||
while (count-- && dev->accel.ssv_len >= 0) {
|
||||
@@ -1289,7 +1310,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
else
|
||||
dev->accel.cy--;
|
||||
|
||||
if (dev->accel.err_term >= 0) {
|
||||
if (dev->accel.err_term >= dev->accel.ssv_len_back) {
|
||||
dev->accel.err_term += dev->accel.destx_distp;
|
||||
if (dev->accel.cmd & 0x20)
|
||||
dev->accel.cx++;
|
||||
@@ -1303,7 +1324,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
else
|
||||
dev->accel.cx--;
|
||||
|
||||
if (dev->accel.err_term >= 0) {
|
||||
if (dev->accel.err_term >= dev->accel.ssv_len_back) {
|
||||
dev->accel.err_term += dev->accel.destx_distp;
|
||||
if (dev->accel.cmd & 0x80)
|
||||
dev->accel.cy++;
|
||||
@@ -1454,6 +1475,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
|
||||
if (!dev->accel.sy) {
|
||||
dev->accel.cmd_back = 1;
|
||||
if (!cpu_input) {
|
||||
dev->accel.cur_x = dev->accel.cx;
|
||||
dev->accel.cur_y = dev->accel.cy;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1505,8 +1530,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
|
||||
dev->accel.sy--;
|
||||
}
|
||||
dev->accel.cur_x = dev->accel.cx;
|
||||
dev->accel.cur_y = dev->accel.cy;
|
||||
dev->accel.x_count = 0;
|
||||
dev->accel.output = 0;
|
||||
} else { /*Bresenham Line*/
|
||||
@@ -1580,7 +1603,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
else
|
||||
dev->accel.cy--;
|
||||
|
||||
if (dev->accel.err_term >= 0) {
|
||||
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) {
|
||||
dev->accel.err_term += dev->accel.destx_distp;
|
||||
if (dev->accel.cmd & 0x20)
|
||||
dev->accel.cx++;
|
||||
@@ -1594,7 +1617,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
else
|
||||
dev->accel.cx--;
|
||||
|
||||
if (dev->accel.err_term >= 0) {
|
||||
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) {
|
||||
dev->accel.err_term += dev->accel.destx_distp;
|
||||
if (dev->accel.cmd & 0x80)
|
||||
dev->accel.cy++;
|
||||
@@ -1673,6 +1696,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
|
||||
if (!dev->accel.sy) {
|
||||
dev->accel.cmd_back = 1;
|
||||
if (!cpu_input) {
|
||||
dev->accel.cur_x = dev->accel.cx;
|
||||
dev->accel.cur_y = dev->accel.cy;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1682,7 +1709,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
else
|
||||
dev->accel.cy--;
|
||||
|
||||
if (dev->accel.err_term >= 0) {
|
||||
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) {
|
||||
dev->accel.err_term += dev->accel.destx_distp;
|
||||
if (dev->accel.cmd & 0x20)
|
||||
dev->accel.cx++;
|
||||
@@ -1696,7 +1723,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
else
|
||||
dev->accel.cx--;
|
||||
|
||||
if (dev->accel.err_term >= 0) {
|
||||
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) {
|
||||
dev->accel.err_term += dev->accel.destx_distp;
|
||||
if (dev->accel.cmd & 0x80)
|
||||
dev->accel.cy++;
|
||||
@@ -1709,8 +1736,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
|
||||
dev->accel.sy--;
|
||||
}
|
||||
}
|
||||
dev->accel.cur_x = dev->accel.cx;
|
||||
dev->accel.cur_y = dev->accel.cy;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2283,35 +2308,62 @@ skip_nibble_rect_write:
|
||||
}
|
||||
}
|
||||
} else if ((dev->accel.multifunc[0x0a] & 0x06) == 0x04) { /*Polygon Draw Type A*/
|
||||
ibm8514_log("Polygon Draw Type A: Clipping: L=%d, R=%d, T=%d, B=%d, C(%d,%d), sx=%d, sy=%d.\n", clip_l, clip_r, clip_t, clip_b, dev->accel.cx, dev->accel.cy, dev->accel.sx, dev->accel.sy);
|
||||
while (count-- && (dev->accel.sy >= 0)) {
|
||||
if ((dev->accel.cx >= clip_l) &&
|
||||
(dev->accel.cx <= clip_r) &&
|
||||
(dev->accel.cy >= clip_t) &&
|
||||
(dev->accel.cy <= clip_b)) {
|
||||
READ(dev->accel.dest + dev->accel.cx, mix_dat);
|
||||
if ((mix_dat & rd_mask_polygon) == rd_mask_polygon)
|
||||
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
|
||||
case 0:
|
||||
src_dat = bkgd_color;
|
||||
break;
|
||||
case 1:
|
||||
src_dat = frgd_color;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
src_dat = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
READ(dev->accel.dest + dev->accel.cx, poly_src);
|
||||
if ((poly_src & rd_mask_polygon) == rd_mask_polygon)
|
||||
dev->accel.fill_state ^= 1;
|
||||
|
||||
READ(dev->accel.dest + dev->accel.cx, dest_dat);
|
||||
|
||||
old_dest_dat = dest_dat;
|
||||
if (dev->accel.fill_state) {
|
||||
if (!(rd_mask_polygon & 0x01) && (wrt_mask & 0x01)) {
|
||||
MIX(mix_dat ^ rd_mask_polygon, dest_dat, mix_dat);
|
||||
ibm8514_log("Filling c(%d,%d) without bit 0 of rdmask=%02x, wrtmask=%02x, mixdat=%02x, dest=%02x, old=%02x.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask, mix_dat, dest_dat, old_dest_dat);
|
||||
dest_dat &= ~rd_mask_polygon;
|
||||
} else if ((rd_mask_polygon & 0x01) && (wrt_mask & 0x01)) {
|
||||
ibm8514_log("Filling c(%d,%d) with bit 0 of rdmask=%02x, wrtmask=%02x.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask);
|
||||
dest_dat &= ~(rd_mask_polygon & wrt_mask);
|
||||
if (rd_mask_polygon & 0x01) {
|
||||
if (wrt_mask & 0x01) {
|
||||
dest_dat &= ~(rd_mask_polygon & wrt_mask); /*Fill State On, Write Mask 1, Read Mask 1.*/
|
||||
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
|
||||
}
|
||||
} else {
|
||||
if (wrt_mask & 0x01) {
|
||||
MIX(mix_dat & mix_mask, dest_dat, src_dat);
|
||||
dest_dat &= ~rd_mask_polygon; /*Fill State On, Write Mask 1, Read Mask 0.*/
|
||||
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!(rd_mask_polygon & 0x01) && (wrt_mask & 0x01))
|
||||
dest_dat &= ~rd_mask_polygon;
|
||||
else if ((rd_mask_polygon & 0x01) && (wrt_mask & 0x01))
|
||||
dest_dat &= ~(rd_mask_polygon & wrt_mask);
|
||||
if (rd_mask_polygon & 0x01) {
|
||||
if (wrt_mask & 0x01) {
|
||||
dest_dat &= ~(rd_mask_polygon & wrt_mask); /*Fill State Off, Write Mask 1, Read Mask 1.*/
|
||||
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
|
||||
}
|
||||
} else {
|
||||
if (wrt_mask & 0x01) {
|
||||
dest_dat &= ~rd_mask_polygon; /*Fill State Off, Write Mask 1, Read Mask 0.*/
|
||||
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
|
||||
|
||||
if ((compare_mode == 0) ||
|
||||
((compare_mode == 0x10) && (dest_dat >= compare)) ||
|
||||
((compare_mode == 0x18) && (dest_dat < compare)) ||
|
||||
@@ -2322,7 +2374,11 @@ skip_nibble_rect_write:
|
||||
ibm8514_log("Results c(%d,%d):rdmask=%02x, wrtmask=%02x, mix=%02x, destdat=%02x, nowrite=%d.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask, mix_dat, dest_dat, dev->accel.cx_back);
|
||||
WRITE(dev->accel.dest + dev->accel.cx, dest_dat);
|
||||
}
|
||||
}
|
||||
} else
|
||||
ibm8514_log("Out of bounds DrawA C(%d,%d).\n", dev->accel.cx, dev->accel.cy);
|
||||
|
||||
mix_dat <<= 1;
|
||||
mix_dat |= 1;
|
||||
|
||||
if (dev->accel.cmd & 0x20)
|
||||
dev->accel.cx++;
|
||||
@@ -2356,6 +2412,8 @@ skip_nibble_rect_write:
|
||||
if (dev->accel.sy < 0) {
|
||||
ibm8514_log(".\n");
|
||||
dev->accel.cmd_back = 1;
|
||||
dev->accel.cur_x = dev->accel.cx;
|
||||
dev->accel.cur_y = dev->accel.cy;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2468,7 +2526,7 @@ skip_nibble_rect_write:
|
||||
else
|
||||
dev->accel.oldcy = dev->accel.cy - 1;
|
||||
|
||||
ibm8514_log("Polygon Boundary activated=%04x, len=%d, cur(%d,%d), frgdmix=%02x, err=%d, clipping: l=%d, r=%d, t=%d, b=%d, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.sy, dev->accel.cx, dev->accel.cy, dev->accel.frgd_mix & 0x1f, dev->accel.err_term, dev->accel.multifunc[2], dev->accel.multifunc[4], dev->accel.clip_top, clip_b, dev->accel.multifunc[0x0a]);
|
||||
ibm8514_log("Polygon Boundary activated=%04x, len=%d, cur(%d,%d), frgdmix=%02x, err=%d, clipping: l=%d, r=%d, t=%d, b=%d, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.sy, dev->accel.cx, dev->accel.cy, dev->accel.frgd_mix & 0x1f, dev->accel.err_term, clip_l, clip_r, clip_t, clip_b, dev->accel.multifunc[0x0a]);
|
||||
|
||||
if (ibm8514_cpu_src(svga)) {
|
||||
dev->data_available = 0;
|
||||
@@ -2483,8 +2541,7 @@ skip_nibble_rect_write:
|
||||
|
||||
if (dev->accel.cmd & 0x08) { /*Vectored Boundary Line*/
|
||||
while (count-- && (dev->accel.sy >= 0)) {
|
||||
if (dev->accel.cx < clip_l)
|
||||
dev->accel.cx = clip_l;
|
||||
dev->accel.cx = CLAMP(dev->accel.cx, clip_l, clip_r);
|
||||
|
||||
if ((dev->accel.cx >= clip_l) &&
|
||||
(dev->accel.cx <= clip_r) &&
|
||||
@@ -2591,11 +2648,10 @@ skip_nibble_rect_write:
|
||||
}
|
||||
} else { /*Vectored Bresenham*/
|
||||
while (count-- && (dev->accel.sy >= 0)) {
|
||||
if (dev->accel.cx < clip_l)
|
||||
dev->accel.cx = clip_l;
|
||||
dev->accel.cx = CLAMP(dev->accel.cx, clip_l, clip_r);
|
||||
|
||||
if ((dev->accel.cx >= clip_l) &&
|
||||
(dev->accel.cx <= clip_r) &&
|
||||
(dev->accel.cx < clip_r) &&
|
||||
(dev->accel.cy >= clip_t) &&
|
||||
(dev->accel.cy <= clip_b)) {
|
||||
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
|
||||
@@ -2658,7 +2714,7 @@ skip_nibble_rect_write:
|
||||
else
|
||||
dev->accel.cy--;
|
||||
|
||||
if (dev->accel.err_term >= 0) {
|
||||
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt_no_limit) {
|
||||
dev->accel.err_term += dev->accel.destx_distp;
|
||||
if (dev->accel.cmd & 0x20)
|
||||
dev->accel.cx++;
|
||||
@@ -2673,7 +2729,7 @@ skip_nibble_rect_write:
|
||||
dev->accel.cx--;
|
||||
|
||||
dev->accel.oldcy = dev->accel.cy;
|
||||
if (dev->accel.err_term >= 0) {
|
||||
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt_no_limit) {
|
||||
dev->accel.err_term += dev->accel.destx_distp;
|
||||
if (dev->accel.cmd & 0x80)
|
||||
dev->accel.cy++;
|
||||
|
||||
@@ -1361,7 +1361,7 @@ gd54xx_in(uint16_t addr, void *priv)
|
||||
32-bit (Pre-5434)/64-bit (5434 and up) DRAM data bus width
|
||||
for 2M of memory
|
||||
*/
|
||||
ret |= (gd54xx_is_5434(svga)) ? 0x98 : 0x18;
|
||||
ret |= 0x18;
|
||||
break;
|
||||
case 4096:
|
||||
ret |= 0x98; /*64-bit (5434 and up) DRAM data bus width for 4M of memory*/
|
||||
@@ -2281,6 +2281,9 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
|
||||
if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest &&
|
||||
!(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) {
|
||||
if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY))
|
||||
val = (val >> 8) | (val << 8);
|
||||
|
||||
gd54xx_write(addr, val, gd54xx);
|
||||
gd54xx_write(addr + 1, val >> 8, gd54xx);
|
||||
return;
|
||||
@@ -2308,6 +2311,9 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *priv)
|
||||
|
||||
if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest &&
|
||||
!(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) {
|
||||
if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY))
|
||||
val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24);
|
||||
|
||||
gd54xx_write(addr, val, gd54xx);
|
||||
gd54xx_write(addr + 1, val >> 8, gd54xx);
|
||||
gd54xx_write(addr + 2, val >> 16, gd54xx);
|
||||
@@ -3661,9 +3667,6 @@ gd54xx_mem_sys_src(gd54xx_t *gd54xx, uint32_t cpu_dat, uint32_t count)
|
||||
mask_shift = 31 - byte_pos;
|
||||
if (!(gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND))
|
||||
cpu_dat >>= byte_pos;
|
||||
else if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
|
||||
cpu_dat = ((cpu_dat & 0xff000000) >> 24) | ((cpu_dat & 0x00ff0000) >> 8) |
|
||||
((cpu_dat & 0x0000ff00) << 8) | ((cpu_dat & 0x000000ff) << 24);
|
||||
} else
|
||||
mask_shift = 7;
|
||||
|
||||
|
||||
@@ -548,17 +548,20 @@ et3000_available(void)
|
||||
}
|
||||
|
||||
static const device_config_t et3000_config[] = {
|
||||
{ .name = "memory",
|
||||
.description = "Memory size",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_int = 512,
|
||||
.selection = {
|
||||
{ .description = "256 KB",
|
||||
.value = 256 },
|
||||
{ .description = "512 KB",
|
||||
.value = 512 },
|
||||
{ .description = "" } } },
|
||||
// clang-format off
|
||||
{
|
||||
.name = "memory",
|
||||
.description = "Memory size",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_int = 512,
|
||||
.selection = {
|
||||
{ .description = "256 KB", .value = 256 },
|
||||
{ .description = "512 KB", .value = 512 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{ .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t et3000_isa_device = {
|
||||
|
||||
@@ -972,7 +972,7 @@ static const device_config_t et4000_tc6058af_config[] = {
|
||||
.default_string = "v1_10",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 }, /*W1*/
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "Version 1.10", .internal_name = "v1_10", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 32768, .files = { TC6058AF_BIOS_ROM_PATH, "" } },
|
||||
@@ -1019,7 +1019,7 @@ static const device_config_t et4000_bios_config[] = {
|
||||
.default_string = "v8_01",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 }, /*W1*/
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "Version 8.01", .internal_name = "v8_01", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 32768, .files = { BIOS_ROM_PATH, "" } },
|
||||
|
||||
@@ -1701,52 +1701,37 @@ ht216_force_redraw(void *priv)
|
||||
ht216->svga.fullchange = changeframecount;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
static const device_config_t v7_vga_1024i_config[] = {
|
||||
{ .name = "memory",
|
||||
.description = "Memory size",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_int = 512,
|
||||
.selection = {
|
||||
{ .description = "256 KB",
|
||||
.value = 256 },
|
||||
{ .description = "512 KB",
|
||||
.value = 512 },
|
||||
{ .description = "" } } },
|
||||
{
|
||||
.name = "memory",
|
||||
.description = "Memory size",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_int = 512,
|
||||
.selection = {
|
||||
{ .description = "256 KB", .value = 256 },
|
||||
{ .description = "512 KB", .value = 512 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{ .type = CONFIG_END }
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
static const device_config_t ht216_32_standalone_config[] = {
|
||||
{
|
||||
.name = "monitor_type",
|
||||
.name = "monitor_type",
|
||||
.description = "Monitor type",
|
||||
.type = CONFIG_SELECTION,
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_int = 0x18,
|
||||
.selection = {
|
||||
{
|
||||
.description = "Mono Interlaced",
|
||||
.value = 0x00
|
||||
},
|
||||
{
|
||||
.description = "Mono Non-Interlaced",
|
||||
.value = 0x08
|
||||
},
|
||||
{
|
||||
.description = "Color Interlaced",
|
||||
.value = 0x10
|
||||
},
|
||||
{
|
||||
.description = "Color Non-Interlaced",
|
||||
.value = 0x18
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
.selection = {
|
||||
{ .description = "Mono Interlaced", .value = 0x00 },
|
||||
{ .description = "Mono Non-Interlaced", .value = 0x08 },
|
||||
{ .description = "Color Interlaced", .value = 0x10 },
|
||||
{ .description = "Color Non-Interlaced", .value = 0x18 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{
|
||||
.type = CONFIG_END
|
||||
}
|
||||
{ .type = CONFIG_END }
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -6851,8 +6851,7 @@ static const device_config_t mystique_config[] = {
|
||||
.name = "memory",
|
||||
.description = "Memory size",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
.selection = {
|
||||
{
|
||||
.description = "2 MB",
|
||||
.value = 2
|
||||
@@ -6865,15 +6864,11 @@ static const device_config_t mystique_config[] = {
|
||||
.description = "8 MB",
|
||||
.value = 8
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
{ .description = "" }
|
||||
},
|
||||
.default_int = 8
|
||||
},
|
||||
{
|
||||
.type = CONFIG_END
|
||||
}
|
||||
{ .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
@@ -6883,8 +6878,7 @@ static const device_config_t millennium_ii_config[] = {
|
||||
.name = "memory",
|
||||
.description = "Memory size",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
.selection = {
|
||||
{
|
||||
.description = "4 MB",
|
||||
.value = 4
|
||||
@@ -6897,15 +6891,11 @@ static const device_config_t millennium_ii_config[] = {
|
||||
.description = "16 MB",
|
||||
.value = 16
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
{ .description = "" }
|
||||
},
|
||||
.default_int = 8
|
||||
},
|
||||
{
|
||||
.type = CONFIG_END
|
||||
}
|
||||
{ .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@ typedef struct s3_t {
|
||||
int dat_count;
|
||||
int b2e8_pix, temp_cnt;
|
||||
int ssv_len;
|
||||
int ssv_len_back;
|
||||
uint8_t ssv_dir;
|
||||
uint8_t ssv_draw;
|
||||
uint8_t dat_buf_16bit;
|
||||
@@ -511,7 +512,7 @@ s3_update_irqs(s3_t *s3)
|
||||
}
|
||||
|
||||
void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, void *priv);
|
||||
void s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv);
|
||||
void s3_short_stroke_start(s3_t *s3, uint8_t ssv);
|
||||
static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3);
|
||||
|
||||
#define WRITE8(addr, var, val) \
|
||||
@@ -922,15 +923,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
|
||||
s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8);
|
||||
s3->accel.ssv_state = 1;
|
||||
|
||||
s3->accel.cx = s3->accel.cur_x & 0xfff;
|
||||
s3->accel.cy = s3->accel.cur_y & 0xfff;
|
||||
|
||||
if (s3->accel.cmd & 0x1000) {
|
||||
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff);
|
||||
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8);
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff);
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke >> 8);
|
||||
} else {
|
||||
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8);
|
||||
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff);
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke >> 8);
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1787,15 +1785,12 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val)
|
||||
s3->accel.short_stroke = val;
|
||||
s3->accel.ssv_state = 1;
|
||||
|
||||
s3->accel.cx = s3->accel.cur_x & 0xfff;
|
||||
s3->accel.cy = s3->accel.cur_y & 0xfff;
|
||||
|
||||
if (s3->accel.cmd & 0x1000) {
|
||||
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff);
|
||||
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8);
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff);
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke >> 8);
|
||||
} else {
|
||||
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8);
|
||||
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff);
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke >> 8);
|
||||
s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7823,19 +7818,16 @@ s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3)
|
||||
}
|
||||
|
||||
void
|
||||
s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv)
|
||||
s3_short_stroke_start(s3_t *s3, uint8_t ssv)
|
||||
{
|
||||
if (!cpu_input) {
|
||||
s3->accel.ssv_len = ssv & 0x0f;
|
||||
s3->accel.ssv_dir = ssv & 0xe0;
|
||||
s3->accel.ssv_draw = ssv & 0x10;
|
||||
s3->accel.ssv_len = ssv & 0x0f;
|
||||
s3->accel.ssv_dir = ssv & 0xe0;
|
||||
s3->accel.ssv_draw = !!(ssv & 0x10);
|
||||
|
||||
if (s3_cpu_src(s3)) {
|
||||
return; /*Wait for data from CPU*/
|
||||
}
|
||||
}
|
||||
if (s3_cpu_src(s3))
|
||||
return; /*Wait for data from CPU*/
|
||||
|
||||
s3->accel_start(count, cpu_input, mix_dat, cpu_dat, s3);
|
||||
s3->accel_start(-1, 0, -1, 0, s3);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -7978,11 +7970,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
|
||||
|
||||
switch (cmd) {
|
||||
case 0: /*NOP (Short Stroke Vectors)*/
|
||||
if (s3->accel.ssv_state == 0)
|
||||
if (s3->accel.ssv_state == 0) {
|
||||
s3->accel.cx = s3->accel.cur_x & 0xfff;
|
||||
s3->accel.cy = s3->accel.cur_y & 0xfff;
|
||||
break;
|
||||
}
|
||||
|
||||
if (s3->accel.cmd & 0x08) /*Radial*/
|
||||
{
|
||||
if (s3->accel.cmd & 0x08) { /*Radial*/
|
||||
while (count-- && s3->accel.ssv_len >= 0) {
|
||||
if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) {
|
||||
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
|
||||
@@ -8036,8 +8030,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
|
||||
else
|
||||
cpu_dat >>= 16;
|
||||
|
||||
if (!s3->accel.ssv_len)
|
||||
if (!s3->accel.ssv_len) {
|
||||
s3->accel.cur_x = s3->accel.cx & 0xfff;
|
||||
s3->accel.cur_y = s3->accel.cy & 0xfff;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (s3->accel.ssv_dir & 0xe0) {
|
||||
case 0x00:
|
||||
@@ -8077,9 +8074,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
|
||||
s3->accel.cx &= 0xfff;
|
||||
s3->accel.cy &= 0xfff;
|
||||
}
|
||||
|
||||
s3->accel.cur_x = s3->accel.cx & 0xfff;
|
||||
s3->accel.cur_y = s3->accel.cy & 0xfff;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -8270,7 +8264,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
|
||||
else
|
||||
s3->accel.cy--;
|
||||
|
||||
if (s3->accel.err_term >= 0) {
|
||||
if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) {
|
||||
s3->accel.err_term += s3->accel.destx_distp;
|
||||
if (s3->accel.cmd & 0x20)
|
||||
s3->accel.cx++;
|
||||
@@ -8284,7 +8278,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
|
||||
else
|
||||
s3->accel.cx--;
|
||||
|
||||
if (s3->accel.err_term >= 0) {
|
||||
if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) {
|
||||
s3->accel.err_term += s3->accel.destx_distp;
|
||||
if (s3->accel.cmd & 0x80)
|
||||
s3->accel.cy++;
|
||||
|
||||
Reference in New Issue
Block a user