mirror of
https://github.com/86Box/86Box.git
synced 2026-02-24 02:18:20 -07:00
Merge branch '86Box:master' into master
This commit is contained in:
@@ -184,15 +184,11 @@ endif()
|
||||
# Option Description Def. Condition Otherwise
|
||||
# ------ ----------- ---- ------------ ---------
|
||||
cmake_dependent_option(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(AN430TX "Intel AN430TX" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(CDROM_MITSUMI "Mitsumi CDROM" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(G100 "Matrox Productiva G100" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(GUSMAX "Gravis UltraSound MAX" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(PCL "Generic PCL5e Printer" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
add_library(chipset OBJECT
|
||||
82c100.c
|
||||
acc2168.c
|
||||
cs8220.c
|
||||
cs8230.c
|
||||
ali1429.c
|
||||
ali1435.c
|
||||
@@ -42,6 +43,7 @@ add_library(chipset OBJECT
|
||||
isa486c.c
|
||||
../ioapic.c
|
||||
neat.c
|
||||
olivetti_eva.c
|
||||
opti283.c
|
||||
opti291.c
|
||||
opti391.c
|
||||
@@ -85,7 +87,3 @@ add_library(chipset OBJECT
|
||||
vl82c480.c
|
||||
wd76c10.c
|
||||
)
|
||||
|
||||
if(OLIVETTI)
|
||||
target_sources(chipset PRIVATE olivetti_eva.c)
|
||||
endif()
|
||||
|
||||
@@ -61,91 +61,238 @@ ali1409_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct ali_1409_t {
|
||||
uint8_t is_g;
|
||||
uint8_t index;
|
||||
uint8_t cfg_locked;
|
||||
uint8_t reg_57h;
|
||||
uint8_t regs[256];
|
||||
uint8_t shadow[4];
|
||||
uint8_t last_reg;
|
||||
} ali1409_t;
|
||||
|
||||
/*
|
||||
This here is because from the two BIOS'es I used to reverse engineer this,
|
||||
it is unclear which of the two interpretations of the shadow RAM register
|
||||
operation is correct.
|
||||
The 16 kB interpretation appears to work fine right now but it may be wrong,
|
||||
so I left the 32 kB interpretation in as well.
|
||||
*/
|
||||
#ifdef INTERPRETATION_32KB
|
||||
#define SHADOW_SIZE 0x00008000
|
||||
#else
|
||||
#define SHADOW_SIZE 0x00004000
|
||||
#endif
|
||||
|
||||
static void
|
||||
ali1409_shadow_recalc(ali1409_t *dev)
|
||||
{
|
||||
uint32_t base = 0x000c0000;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
uint8_t reg = 0x08 + i;
|
||||
|
||||
#ifdef INTERPRETATION_32KB
|
||||
for (uint8_t j = 0; j < 4; j += 2) {
|
||||
uint8_t mask = (0x03 << j);
|
||||
#else
|
||||
for (uint8_t j = 0; j < 4; j++) {
|
||||
uint8_t mask = (0x01 << j);
|
||||
#endif
|
||||
uint8_t r_on = dev->regs[reg] & 0x10;
|
||||
uint8_t w_on = dev->regs[reg] & 0x20;
|
||||
uint8_t val = dev->regs[reg] & mask;
|
||||
uint8_t xor = (dev->shadow[i] ^ dev->regs[reg]) & (mask | 0x30);
|
||||
int read = r_on ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
int write = w_on ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
|
||||
if (xor) {
|
||||
#ifdef INTERPRETATION_32KB
|
||||
switch (val >> j) {
|
||||
case 0x00:
|
||||
mem_set_mem_state_both(base, SHADOW_SIZE, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 0x01:
|
||||
mem_set_mem_state_both(base, SHADOW_SIZE, MEM_READ_EXTANY | write);
|
||||
break;
|
||||
case 0x02:
|
||||
mem_set_mem_state_both(base, SHADOW_SIZE, read | write);
|
||||
break;
|
||||
case 0x03:
|
||||
mem_set_mem_state_both(base, SHADOW_SIZE, read | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
switch (val >> j) {
|
||||
case 0x00:
|
||||
mem_set_mem_state_both(base, SHADOW_SIZE, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 0x01:
|
||||
mem_set_mem_state_both(base, SHADOW_SIZE, read | write);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
base += SHADOW_SIZE;
|
||||
}
|
||||
|
||||
dev->shadow[i] = dev->regs[reg];
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
ali1409_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1409_t *dev = (ali1409_t *) priv;
|
||||
ali1409_log ("INPUT:addr %02x ,Value %02x \n" , addr , val);
|
||||
ali1409_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, addr, val);
|
||||
|
||||
if (addr & 1) {
|
||||
if (dev->cfg_locked) {
|
||||
if (dev->last_reg == 0x14 && val == 0x09)
|
||||
dev->cfg_locked = 0;
|
||||
if (addr & 0x0001) {
|
||||
if (dev->cfg_locked) {
|
||||
if ((dev->last_reg == 0x14) && (val == 0x09))
|
||||
dev->cfg_locked = 0;
|
||||
|
||||
dev->last_reg = val;
|
||||
return;
|
||||
}
|
||||
dev->last_reg = val;
|
||||
return;
|
||||
}
|
||||
|
||||
if (dev->index == 0xff && val == 0xff)
|
||||
dev->cfg_locked = 1;
|
||||
else {
|
||||
ali1409_log("Write reg %02x %02x %08x\n", dev->index, val, cs);
|
||||
dev->regs[dev->index] = val;
|
||||
/* It appears writing anything at all to register 0xFF locks it again. */
|
||||
if (dev->index == 0xff)
|
||||
dev->cfg_locked = 1;
|
||||
else if (dev->index < 0x44) {
|
||||
ali1409_log("[%04X:%08X] [W] Register %02X = %02X\n", CS, cpu_state.pc, dev->index, val);
|
||||
|
||||
switch (dev->index) {
|
||||
case 0xa:
|
||||
switch ((val >> 4) & 3) {
|
||||
case 0:
|
||||
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
}
|
||||
if (dev->index < 0x10) {
|
||||
dev->regs[dev->index] = val;
|
||||
|
||||
/*
|
||||
There are still a lot of unknown here, but unfortunately, this is
|
||||
as far as I have been able to come with two BIOS'es that are
|
||||
available (the Acer 100T and an AMI Color dated 07/07/91).
|
||||
*/
|
||||
switch (dev->index) {
|
||||
case 0x02:
|
||||
/*
|
||||
- Bit 7: The RAS address hold time:
|
||||
- 0: 1/2 T;
|
||||
- 1: 1 T.
|
||||
- Bits 6-4: The RAS precharge time:
|
||||
- 0, 0, 0: 1.5 T;
|
||||
- 0, 0, 1: 2 T;
|
||||
- 0, 1, 0: 2.5 T;
|
||||
- 0, 1, 1: 3 T;
|
||||
- 1, 0, 0: 3.5 T;
|
||||
- 1, 0, 1: 4 T;
|
||||
- 1, 1, 0: Reserved;
|
||||
- 1, 1, 1: Reserved.
|
||||
- Bit 3: Early miss cycle:
|
||||
- 0: Disabled;
|
||||
- 1: Enabled.
|
||||
*/
|
||||
break;
|
||||
case 0x03:
|
||||
/*
|
||||
- Bit 6: CAS pulse for read cycle:
|
||||
- 0: 1 T;
|
||||
- 1: 1.5 T or 2 T.
|
||||
I can not get the 2.5 T or 3 T setting to apply so
|
||||
I have no idea what bit governs that.
|
||||
- Bits 5, 4: CAS pulse for write cycle:
|
||||
- 0, 0: 0.5 T or 1 T;
|
||||
- 0, 1: 1.5 T or 2 T;
|
||||
- 1, 0: 2.5 T or 3 T;
|
||||
- 1, 1: Reserved.
|
||||
- Bit 3: CAS active for read cycle:
|
||||
- 0: Disabled;
|
||||
- 1: Enabled.
|
||||
- Bit 2: CAS active for write cycle:
|
||||
- 0: Disabled;
|
||||
- 1: Enabled.
|
||||
*/
|
||||
break;
|
||||
case 0x06:
|
||||
/*
|
||||
- Bits 6-4: Clock divider:
|
||||
- 0, 0, 0: / 2;
|
||||
- 0, 0, 1: / 4;
|
||||
- 0, 1, 0: / 8;
|
||||
- 0, 1, 1: Reserved;
|
||||
- 1, 0, 0: / 3;
|
||||
- 1, 0, 1: / 6;
|
||||
- 1, 1, 0: / 5;
|
||||
- 1, 1, 1: / 10.
|
||||
*/
|
||||
switch ((val >> 4) & 7) {
|
||||
default:
|
||||
case 3: /* Reserved */
|
||||
cpu_set_isa_speed(7159091);
|
||||
break;
|
||||
case 0xb:
|
||||
switch ((val >> 4) & 3) {
|
||||
case 0:
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY| MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0:
|
||||
cpu_set_isa_speed(cpu_busspeed / 2);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
cpu_set_isa_speed(cpu_busspeed / 4);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
cpu_set_isa_speed(cpu_busspeed / 8);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
cpu_set_isa_speed(cpu_busspeed / 3);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
cpu_set_isa_speed(cpu_busspeed / 6);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
cpu_set_isa_speed(cpu_busspeed / 5);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
cpu_set_isa_speed(cpu_busspeed / 10);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x08 ... 0x0b:
|
||||
ali1409_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x0c:
|
||||
/*
|
||||
This appears to be turbo in bit 4 (1 = on, 0 = off),
|
||||
and bus speed in the rest of the bits.
|
||||
*/
|
||||
break;
|
||||
case 0x0d:
|
||||
cpu_cache_ext_enabled = !!(val & 0x08);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
}
|
||||
} else
|
||||
dev->index = val;
|
||||
}
|
||||
}
|
||||
} else
|
||||
dev->index = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ali1409_read(uint16_t addr, void *priv)
|
||||
{
|
||||
ali1409_log ("reading at %02X\n",addr);
|
||||
const ali1409_t *dev = (ali1409_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (dev->cfg_locked)
|
||||
ret = 0xff;
|
||||
if (addr & 1) {
|
||||
if ((dev->index >= 0xc0 || dev->index == 0x20) && cpu_iscyrix)
|
||||
ret = 0xff;
|
||||
else if (addr & 0x0001) {
|
||||
if (dev->index < 0x44)
|
||||
ret = dev->regs[dev->index];
|
||||
} else
|
||||
ret = dev->index;
|
||||
} else
|
||||
ret = dev->index;
|
||||
|
||||
ali1409_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -166,17 +313,16 @@ ali1409_init(UNUSED(const device_t *info))
|
||||
|
||||
dev->cfg_locked = 1;
|
||||
|
||||
/* M1409 Ports:
|
||||
22h Index Port
|
||||
23h Data Port
|
||||
*/
|
||||
|
||||
ali1409_log ("Bus speed: %i", cpu_busspeed);
|
||||
|
||||
ali1409_log("Bus speed: %i\n", cpu_busspeed);
|
||||
|
||||
io_sethandler(0x0022, 0x0002, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev);
|
||||
io_sethandler(0x037f, 0x0001, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev);
|
||||
io_sethandler(0x03f3, 0x0001, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev);
|
||||
|
||||
dev->regs[0x0f] = 0x08;
|
||||
|
||||
cpu_set_isa_speed(7159091);
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
289
src/chipset/cs8220.c
Normal file
289
src/chipset/cs8220.c
Normal file
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* 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 C&T CS8220 ("PC/AT") chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2025 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t virt;
|
||||
uint32_t phys;
|
||||
|
||||
uint32_t size;
|
||||
|
||||
mem_mapping_t mapping;
|
||||
} ram_bank_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t regs[3];
|
||||
|
||||
ram_bank_t ram_banks[3];
|
||||
} cs8220_t;
|
||||
|
||||
static uint8_t
|
||||
cs8220_mem_read(uint32_t addr, void *priv)
|
||||
{
|
||||
ram_bank_t *dev = (ram_bank_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ret = ram[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
cs8220_mem_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
ram_bank_t *dev = (ram_bank_t *) priv;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ret = *(uint16_t *) &(ram[addr]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
cs8220_mem_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ram_bank_t *dev = (ram_bank_t *) priv;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ram[addr] = val;
|
||||
}
|
||||
|
||||
static void
|
||||
cs8220_mem_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
ram_bank_t *dev = (ram_bank_t *) priv;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
*(uint16_t *) &(ram[addr]) = val;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
cs8220_in(uint16_t port, void *priv) {
|
||||
cs8220_t *dev = (cs8220_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port) {
|
||||
case 0x00a4 ... 0x00a5:
|
||||
ret = dev->regs[port & 0x0001];
|
||||
break;
|
||||
case 0x00ab:
|
||||
ret = dev->regs[2];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
cs8220_out(uint16_t port, uint8_t val, void *priv) {
|
||||
cs8220_t *dev = (cs8220_t *) priv;
|
||||
|
||||
switch (port) {
|
||||
case 0x00a4:
|
||||
dev->regs[0] = val;
|
||||
mem_a20_alt = val & 0x40;
|
||||
mem_a20_recalc();
|
||||
break;
|
||||
case 0x00a5:
|
||||
dev->regs[1] = val;
|
||||
if (val & 0x01) {
|
||||
mem_mapping_set_addr(&dev->ram_banks[0].mapping, 0, 0x000040000);
|
||||
mem_mapping_disable(&dev->ram_banks[1].mapping);
|
||||
mem_mapping_disable(&dev->ram_banks[2].mapping);
|
||||
} else {
|
||||
mem_mapping_set_addr(&dev->ram_banks[0].mapping, 0, dev->ram_banks[0].size);
|
||||
mem_mapping_enable(&dev->ram_banks[1].mapping);
|
||||
mem_mapping_enable(&dev->ram_banks[2].mapping);
|
||||
}
|
||||
break;
|
||||
case 0x00ab:
|
||||
dev->regs[2] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cs8220_close(void *priv)
|
||||
{
|
||||
cs8220_t *dev = (cs8220_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
cs8220_init(UNUSED(const device_t *info))
|
||||
{
|
||||
cs8220_t *dev = (cs8220_t *) calloc(1, sizeof(cs8220_t));
|
||||
|
||||
mem_mapping_disable(&ram_low_mapping);
|
||||
mem_mapping_disable(&ram_mid_mapping);
|
||||
mem_mapping_disable(&ram_high_mapping);
|
||||
|
||||
/*
|
||||
Dell System 200: 640 kB soldered on-board, any other RAM is expansion.
|
||||
*/
|
||||
if (!strcmp(machine_get_internal_name(), "dells200")) switch (mem_size) {
|
||||
default:
|
||||
dev->ram_banks[2].virt = 0x00100000;
|
||||
dev->ram_banks[2].phys = 0x000a0000;
|
||||
dev->ram_banks[2].size = (mem_size << 10) - 0x000a0000;
|
||||
fallthrough;
|
||||
case 640:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00080000;
|
||||
dev->ram_banks[1].virt = 0x00080000;
|
||||
dev->ram_banks[1].phys = 0x00080000;
|
||||
dev->ram_banks[1].size = 0x00020000;
|
||||
break;
|
||||
/*
|
||||
We are limited to steps of equal size, so we have to simulate some
|
||||
memory expansions to work around the chipset's limits.
|
||||
*/
|
||||
} else switch (mem_size) {
|
||||
case 256:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00020000;
|
||||
dev->ram_banks[1].virt = 0x00020000;
|
||||
dev->ram_banks[1].phys = 0x00020000;
|
||||
dev->ram_banks[1].size = 0x00020000;
|
||||
break;
|
||||
case 384:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00020000;
|
||||
/* Pretend there's a 128k expansion. */
|
||||
dev->ram_banks[2].virt = 0x00020000;
|
||||
dev->ram_banks[2].phys = 0x00020000;
|
||||
dev->ram_banks[2].size = 0x00040000;
|
||||
break;
|
||||
case 512:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00080000;
|
||||
break;
|
||||
default:
|
||||
dev->ram_banks[2].virt = 0x00100000;
|
||||
dev->ram_banks[2].phys = 0x000a0000;
|
||||
dev->ram_banks[2].size = (mem_size << 10) - 0x000a0000;
|
||||
fallthrough;
|
||||
case 640:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00080000;
|
||||
dev->ram_banks[1].virt = 0x00080000;
|
||||
dev->ram_banks[1].phys = 0x00080000;
|
||||
dev->ram_banks[1].size = 0x00020000;
|
||||
break;
|
||||
case 768:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00080000;
|
||||
dev->ram_banks[1].virt = 0x00080000;
|
||||
dev->ram_banks[1].phys = 0x00080000;
|
||||
dev->ram_banks[1].size = 0x00020000;
|
||||
/* Pretend there's a 128k expansion. */
|
||||
dev->ram_banks[2].virt = 0x00100000;
|
||||
dev->ram_banks[2].phys = 0x00080000;
|
||||
dev->ram_banks[2].size = 0x00020000;
|
||||
break;
|
||||
case 896:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00080000;
|
||||
dev->ram_banks[1].virt = 0x00080000;
|
||||
dev->ram_banks[1].phys = 0x00080000;
|
||||
dev->ram_banks[1].size = 0x00020000;
|
||||
/* Pretend there's a 256k expansion. */
|
||||
dev->ram_banks[2].virt = 0x00100000;
|
||||
dev->ram_banks[2].phys = 0x00080000;
|
||||
dev->ram_banks[2].size = 0x00040000;
|
||||
break;
|
||||
case 1024:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00080000;
|
||||
dev->ram_banks[1].virt = 0x00100000;
|
||||
dev->ram_banks[1].phys = 0x00080000;
|
||||
dev->ram_banks[1].size = 0x00080000;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->ram_banks[0].size > 0x00000000)
|
||||
mem_mapping_add(&dev->ram_banks[0].mapping, dev->ram_banks[0].virt, dev->ram_banks[0].size,
|
||||
cs8220_mem_read, cs8220_mem_readw, NULL,
|
||||
cs8220_mem_write, cs8220_mem_writew, NULL,
|
||||
ram + dev->ram_banks[0].phys, MEM_MAPPING_INTERNAL, &(dev->ram_banks[0]));
|
||||
|
||||
if (dev->ram_banks[1].size > 0x00000000)
|
||||
mem_mapping_add(&dev->ram_banks[1].mapping, dev->ram_banks[1].virt, dev->ram_banks[1].size,
|
||||
cs8220_mem_read, cs8220_mem_readw, NULL,
|
||||
cs8220_mem_write, cs8220_mem_writew, NULL,
|
||||
ram + dev->ram_banks[1].phys, MEM_MAPPING_INTERNAL, &(dev->ram_banks[1]));
|
||||
|
||||
if (dev->ram_banks[2].size > 0x00000000)
|
||||
mem_mapping_add(&dev->ram_banks[2].mapping, dev->ram_banks[2].virt, dev->ram_banks[2].size,
|
||||
cs8220_mem_read, cs8220_mem_readw, NULL,
|
||||
cs8220_mem_write, cs8220_mem_writew, NULL,
|
||||
ram + dev->ram_banks[2].phys, MEM_MAPPING_INTERNAL, &(dev->ram_banks[2]));
|
||||
|
||||
io_sethandler(0x00a4, 0x0002,
|
||||
cs8220_in, NULL, NULL, cs8220_out, NULL, NULL, dev);
|
||||
io_sethandler(0x00ab, 0x0001,
|
||||
cs8220_in, NULL, NULL, cs8220_out, NULL, NULL, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t cs8220_device = {
|
||||
.name = "C&T CS8220 (PC/AT)",
|
||||
.internal_name = "cs8220",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = cs8220_init,
|
||||
.close = cs8220_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -1013,7 +1013,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
case INTEL_430TX:
|
||||
if (!dev->smram_locked) {
|
||||
i4x0_smram_handler_phase0(dev);
|
||||
regs[0x71] = (regs[0x71] & 0x20) | (val & 0xdf);
|
||||
regs[0x71] = (regs[0x71] & 0x60) | (val & 0x9f);
|
||||
regs[0x71] &= (val & 0x40);
|
||||
i4x0_smram_handler_phase1(dev);
|
||||
}
|
||||
break;
|
||||
@@ -1041,9 +1042,11 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
regs[0x72] = (val & 0x7f);
|
||||
else
|
||||
regs[0x72] = (regs[0x72] & 0x87) | (val & 0x78);
|
||||
dev->smram_locked = (val & 0x10);
|
||||
if (dev->smram_locked)
|
||||
regs[0x72] &= 0xbf;
|
||||
if (val & 0x08) {
|
||||
dev->smram_locked = (val & 0x10);
|
||||
if (dev->smram_locked)
|
||||
regs[0x72] &= 0xbf;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (dev->smram_locked)
|
||||
@@ -1577,6 +1580,8 @@ i4x0_reset(void *priv)
|
||||
dev->regs[0x68 + i] = 0x00;
|
||||
}
|
||||
|
||||
dev->smram_locked = 0;
|
||||
|
||||
if (dev->type >= INTEL_430FX) {
|
||||
dev->regs[0x72] &= 0xef; /* Forcibly unlock the SMRAM register. */
|
||||
i4x0_write(0, 0x72, 0x02, priv);
|
||||
|
||||
@@ -73,26 +73,24 @@ olivetti_eva_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 0x069:
|
||||
dev->reg_069 = val;
|
||||
/*
|
||||
* Unfortunately, if triggered, the BIOS remapping function fails causing
|
||||
* a fatal error. Therefore, this code section is currently commented.
|
||||
*/
|
||||
#if 0
|
||||
if (val & 1) {
|
||||
mem_remap_top(0);
|
||||
if (val == 0x01) {
|
||||
/*
|
||||
* Set the register to 7 or above for the BIOS to trigger the
|
||||
* memory remapping function if shadowing is active.
|
||||
*/
|
||||
dev->reg_069 = 0x7;
|
||||
dev->reg_069 = 0x07;
|
||||
}
|
||||
if (val & 8) {
|
||||
if (val & 0x08) {
|
||||
/*
|
||||
* Activate shadowing for region e0000-fffff
|
||||
*/
|
||||
mem_remap_top(256);
|
||||
mem_set_mem_state_both(0xa0000, 0x60000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else {
|
||||
mem_remap_top(384);
|
||||
mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -143,7 +141,7 @@ olivetti_eva_init(UNUSED(const device_t *info))
|
||||
dev->reg_067 = 0x00;
|
||||
|
||||
/* RAM enable registers */
|
||||
dev->reg_069 = 0x0;
|
||||
dev->reg_069 = 0x00;
|
||||
|
||||
io_sethandler(0x0065, 0x0001, olivetti_eva_read, NULL, NULL, olivetti_eva_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0067, 0x0001, olivetti_eva_read, NULL, NULL, olivetti_eva_write, NULL, NULL, dev);
|
||||
@@ -152,13 +150,6 @@ olivetti_eva_init(UNUSED(const device_t *info))
|
||||
/* When shadowing is not enabled in BIOS, all upper memory is available as XMS */
|
||||
mem_remap_top(384);
|
||||
|
||||
/*
|
||||
* Default settings when NVRAM is cleared activate shadowing.
|
||||
* Thus, to avoid boot errors, remap only 256k from UMB to XMS.
|
||||
* Remove this block once BIOS memory remapping works.
|
||||
*/
|
||||
mem_remap_top(256);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
@@ -1177,7 +1177,7 @@ scamp_init(UNUSED(const device_t *info))
|
||||
dev->mem_flags[i] = MEM_FLAG_READ | MEM_FLAG_WRITE;
|
||||
scamp_mem_update_state(dev, i * EMS_PGSIZE, EMS_PGSIZE, 0x00, MEM_FMASK_RW);
|
||||
|
||||
if (i >= 60)
|
||||
if (i >= 56)
|
||||
scamp_mem_update_state(dev, i * EMS_PGSIZE, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,6 +270,8 @@ hb4_smram(hb4_t *dev)
|
||||
}
|
||||
|
||||
umc_smram_recalc(dev->smram_base >> 12, 1);
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -398,55 +400,6 @@ hb4_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
ims8848_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
hb4_t *dev = (hb4_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x23:
|
||||
if (((val & 0x0f) == ((dev->idx >> 4) & 0x0f)) && ((val & 0xf0) == ((dev->idx << 4) & 0xf0)))
|
||||
dev->access_data = 1;
|
||||
break;
|
||||
case 0x24:
|
||||
if (dev->access_data)
|
||||
dev->access_data = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
ims8848_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
hb4_t *dev = (hb4_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
ret = dev->idx;
|
||||
break;
|
||||
case 0x23:
|
||||
ret = (dev->idx >> 4) | (dev->idx << 4);
|
||||
break;
|
||||
case 0x24:
|
||||
if (dev->access_data) {
|
||||
ret = dev->pci_conf[dev->idx];
|
||||
dev->access_data = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *
|
||||
hb4_init(UNUSED(const device_t *info))
|
||||
{
|
||||
@@ -463,8 +416,6 @@ hb4_init(UNUSED(const device_t *info))
|
||||
dev->smram_base = 0x000a0000;
|
||||
hb4_reset(dev);
|
||||
|
||||
io_sethandler(0x0022, 0x0003, ims8848_read, NULL, NULL, ims8848_write, NULL, NULL, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
@@ -4264,7 +4264,7 @@ cpu_write(uint16_t addr, uint8_t val, UNUSED(void *priv))
|
||||
cyrix_addr = val;
|
||||
else if (addr < 0xf1) switch (cyrix_addr) {
|
||||
default:
|
||||
if (cyrix_addr >= 0xc0)
|
||||
if ((cyrix_addr >= 0xc0) && (cyrix_addr != 0xff))
|
||||
fatal("Writing unimplemented Cyrix register %02X\n", cyrix_addr);
|
||||
break;
|
||||
|
||||
|
||||
@@ -830,7 +830,9 @@ write_p2(atkbc_t *dev, uint8_t val)
|
||||
softresetx86(); /* Pulse reset! */
|
||||
cpu_set_edx();
|
||||
flushmmucache();
|
||||
if ((kbc_ven == KBC_VEN_ALI) || !strcmp(machine_get_internal_name(), "spc7700plw"))
|
||||
if ((kbc_ven == KBC_VEN_ALI) ||
|
||||
!strcmp(machine_get_internal_name(), "spc7700plw") ||
|
||||
!strcmp(machine_get_internal_name(), "pl4600c"))
|
||||
smbase = 0x00030000;
|
||||
|
||||
/* Yes, this is a hack, but until someone gets ahold of the real PCD-2L
|
||||
@@ -1077,7 +1079,14 @@ write_cmd_generic(void *priv, uint8_t val)
|
||||
/* The SMM handlers of Intel AMI Pentium BIOS'es expect bit 6 to be set. */
|
||||
if ((kbc_ven == KBC_VEN_AMI) && ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_GREEN))
|
||||
fixed_bits |= 0x40;
|
||||
if (kbc_ven == KBC_VEN_IBM_PS1) {
|
||||
if (!strcmp(machine_get_internal_name(), "dells333sl")) {
|
||||
/*
|
||||
Dell System 333s/L:
|
||||
- Bit 5: Stuck in reboot loop if clear.
|
||||
*/
|
||||
uint8_t p1 = 0x20 | (video_is_mda() ? 0x40 : 0x00);
|
||||
kbc_delay_to_ob(dev, p1, 0, 0x00);
|
||||
} else if (kbc_ven == KBC_VEN_IBM_PS1) {
|
||||
current_drive = fdc_get_current_drive();
|
||||
/* (B0 or F0) | (fdd_is_525(current_drive) on bit 6) */
|
||||
kbc_delay_to_ob(dev, dev->p1 | fixed_bits | (fdd_is_525(current_drive) ? 0x40 : 0x00),
|
||||
@@ -1112,7 +1121,7 @@ write_cmd_generic(void *priv, uint8_t val)
|
||||
Dell 466/NP:
|
||||
- Bit 2: Keyboard fuse (must be set);
|
||||
- Bit 4: Password disable jumper (must be clear);
|
||||
- Bit 5: Manufacturing jumper (must be set);
|
||||
- Bit 5: Manufacturing jumper (must be set).
|
||||
*/
|
||||
uint8_t p1 = 0x24;
|
||||
kbc_delay_to_ob(dev, p1, 0, 0x00);
|
||||
@@ -1121,7 +1130,7 @@ write_cmd_generic(void *priv, uint8_t val)
|
||||
Dell OptiPlex GXL/GXM:
|
||||
- Bit 3: Password disable jumper (must be clear);
|
||||
- Bit 4: Keyboard fuse (must be set);
|
||||
- Bit 5: Manufacturing jumper (must be set);
|
||||
- Bit 5: Manufacturing jumper (must be set).
|
||||
*/
|
||||
uint8_t p1 = 0x30;
|
||||
kbc_delay_to_ob(dev, p1, 0, 0x00);
|
||||
|
||||
@@ -87,6 +87,14 @@ pci_bridge_set_ctl(void *priv, uint8_t ctl)
|
||||
dev->ctl = ctl;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
pci_bridge_get_bus_index(void *priv)
|
||||
{
|
||||
pci_bridge_t *dev = (pci_bridge_t *) priv;
|
||||
|
||||
return dev->bus_index;
|
||||
}
|
||||
|
||||
static void
|
||||
pci_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -513,11 +521,9 @@ static void *
|
||||
pci_bridge_init(const device_t *info)
|
||||
{
|
||||
uint8_t interrupts[4];
|
||||
uint8_t interrupt_count;
|
||||
uint8_t interrupt_mask;
|
||||
uint8_t add_type;
|
||||
uint8_t slot_count;
|
||||
uint8_t dell_slots[3] = { 0x09, 0x0a, 0x0b };
|
||||
uint8_t dell_interrupts[3][4] = { { 1, 2, 3, 4 }, { 4, 2, 1, 3 }, { 1, 3, 4, 2 } };
|
||||
|
||||
pci_bridge_t *dev = (pci_bridge_t *) calloc(1, sizeof(pci_bridge_t));
|
||||
|
||||
@@ -527,40 +533,35 @@ pci_bridge_init(const device_t *info)
|
||||
|
||||
pci_bridge_reset(dev);
|
||||
|
||||
if (info->local == PCI_BRIDGE_DEC_21152)
|
||||
pci_add_card(PCI_ADD_BRIDGE, pci_bridge_read, pci_bridge_write, dev, &dev->slot);
|
||||
else
|
||||
pci_add_bridge(AGP_BRIDGE(dev->local), pci_bridge_read, pci_bridge_write, dev, &dev->slot);
|
||||
|
||||
interrupt_count = sizeof(interrupts);
|
||||
interrupt_mask = interrupt_count - 1;
|
||||
interrupt_mask = sizeof(interrupts) - 1;
|
||||
if (dev->slot < 32) {
|
||||
for (uint8_t i = 0; i < interrupt_count; i++)
|
||||
for (uint8_t i = 0; i <= interrupt_mask; i++)
|
||||
interrupts[i] = pci_get_int(dev->slot, PCI_INTA + i);
|
||||
}
|
||||
pci_bridge_log("PCI Bridge %d: upstream bus %02X slot %02X interrupts %02X %02X %02X %02X\n",
|
||||
dev->bus_index, (dev->slot >> 5) & 0xff, dev->slot & 31, interrupts[0],
|
||||
interrupts[1], interrupts[2], interrupts[3]);
|
||||
|
||||
if (info->local == PCI_BRIDGE_DEC_21150)
|
||||
if (info->local == PCI_BRIDGE_DEC_21150) {
|
||||
slot_count = 9; /* 9 bus masters */
|
||||
else if (info->local == PCI_BRIDGE_DEC_21152)
|
||||
slot_count = 3; /* 3 bus masters */
|
||||
else
|
||||
add_type = PCI_ADD_NORMAL;
|
||||
} else if (info->local == PCI_BRIDGE_DEC_21152) {
|
||||
slot_count = 0; /* 4 bus masters, but slots are added by the Dell machines */
|
||||
add_type = PCI_ADD_BRIDGE;
|
||||
} else {
|
||||
slot_count = 1; /* AGP bridges always have 1 slot */
|
||||
add_type = PCI_ADD_AGPBRIDGE;
|
||||
}
|
||||
|
||||
pci_add_bridge(add_type, pci_bridge_read, pci_bridge_write, dev, &dev->slot);
|
||||
|
||||
for (uint8_t i = 0; i < slot_count; i++) {
|
||||
uint8_t slot = i;
|
||||
if (info->local == PCI_BRIDGE_DEC_21152) {
|
||||
slot = dell_slots[i];
|
||||
memcpy(interrupts, dell_interrupts[i], 4);
|
||||
}
|
||||
/* Interrupts for bridge slots are assigned in round-robin: ABCD, BCDA, CDAB and so on. */
|
||||
pci_bridge_log("PCI Bridge %d: downstream slot %02X interrupts %02X %02X %02X %02X\n",
|
||||
dev->bus_index, slot, interrupts[i & interrupt_mask],
|
||||
dev->bus_index, i, interrupts[i & interrupt_mask],
|
||||
interrupts[(i + 1) & interrupt_mask], interrupts[(i + 2) & interrupt_mask],
|
||||
interrupts[(i + 3) & interrupt_mask]);
|
||||
pci_register_bus_slot(dev->bus_index, slot, AGP_BRIDGE(dev->local) ? PCI_CARD_AGP : PCI_CARD_NORMAL,
|
||||
pci_register_bus_slot(dev->bus_index, i, AGP_BRIDGE(dev->local) ? PCI_CARD_AGP : PCI_CARD_NORMAL,
|
||||
interrupts[i & interrupt_mask],
|
||||
interrupts[(i + 1) & interrupt_mask],
|
||||
interrupts[(i + 2) & interrupt_mask],
|
||||
|
||||
@@ -36,6 +36,7 @@ static uint16_t postcard_port;
|
||||
static uint8_t postcard_written[POSTCARDS_NUM];
|
||||
static uint8_t postcard_ports_num = 1;
|
||||
static uint8_t postcard_prev_codes[POSTCARDS_NUM];
|
||||
static uint8_t postcard_dell_mode = 0;
|
||||
static char postcard_prev_diags[5] = { 0 };
|
||||
#define UISTR_LEN 32
|
||||
static char postcard_str[UISTR_LEN]; /* UI output string */
|
||||
@@ -99,30 +100,23 @@ postcard_setui(void)
|
||||
ps[1][0], ps[1][1], ps[1][2], ps[1][3]);
|
||||
break;
|
||||
}
|
||||
} else if (strstr(machines[machine].name, " Dell ") &&
|
||||
(machine_get_chipset(machine) >= MACHINE_CHIPSET_INTEL_430FX)) {
|
||||
char dell_diags[10] = { 0 };
|
||||
|
||||
if (!postcard_written[1])
|
||||
snprintf(dell_diags, sizeof(dell_diags), "---- ----");
|
||||
else if (postcard_written[1] == 1)
|
||||
snprintf(dell_diags, sizeof(dell_diags), "%s ----", postcard_diags);
|
||||
else
|
||||
snprintf(dell_diags, sizeof(dell_diags), "%s %s", postcard_diags, postcard_prev_diags);
|
||||
|
||||
if (!postcard_written[0])
|
||||
snprintf(postcard_str, sizeof(postcard_str), "POST: -- -- %s", dell_diags);
|
||||
else if (postcard_written[0] == 1)
|
||||
snprintf(postcard_str, sizeof(postcard_str), "POST: %02X -- %s", postcard_codes[0], dell_diags);
|
||||
else
|
||||
snprintf(postcard_str, sizeof(postcard_str), "POST: %02X %02X %s", postcard_codes[0], postcard_prev_codes[0], dell_diags);
|
||||
} else {
|
||||
char dell_diags[11] = { 0 };
|
||||
if (postcard_dell_mode) {
|
||||
if (!postcard_written[1])
|
||||
snprintf(dell_diags, sizeof(dell_diags), " ---- ----");
|
||||
else if (postcard_written[1] == 1)
|
||||
snprintf(dell_diags, sizeof(dell_diags), " %s ----", postcard_diags);
|
||||
else
|
||||
snprintf(dell_diags, sizeof(dell_diags), " %s %s", postcard_diags, postcard_prev_diags);
|
||||
}
|
||||
|
||||
if (!postcard_written[0])
|
||||
snprintf(postcard_str, sizeof(postcard_str), "POST: -- --");
|
||||
snprintf(postcard_str, sizeof(postcard_str), "POST: -- --%s", dell_diags);
|
||||
else if (postcard_written[0] == 1)
|
||||
snprintf(postcard_str, sizeof(postcard_str), "POST: %02X --", postcard_codes[0]);
|
||||
snprintf(postcard_str, sizeof(postcard_str), "POST: %02X --%s", postcard_codes[0], dell_diags);
|
||||
else
|
||||
snprintf(postcard_str, sizeof(postcard_str), "POST: %02X %02X", postcard_codes[0], postcard_prev_codes[0]);
|
||||
snprintf(postcard_str, sizeof(postcard_str), "POST: %02X %02X%s", postcard_codes[0], postcard_prev_codes[0], dell_diags);
|
||||
}
|
||||
|
||||
ui_sb_bugui(postcard_str);
|
||||
@@ -224,9 +218,10 @@ postcard_init(UNUSED(const device_t *info))
|
||||
io_sethandler(postcard_port, postcard_ports_num,
|
||||
NULL, NULL, NULL, postcard_write, NULL, NULL, NULL);
|
||||
|
||||
if (strstr(machines[machine].name, " Dell ") &&
|
||||
(machine_get_chipset(machine) >= MACHINE_CHIPSET_INTEL_430FX))
|
||||
io_sethandler(0x00e0, 0x0001,
|
||||
postcard_dell_mode = strstr(machines[machine].name, " Dell ") &&
|
||||
(machine_get_chipset(machine) >= MACHINE_CHIPSET_INTEL_430FX);
|
||||
if (postcard_dell_mode)
|
||||
io_sethandler(is486 ? 0x00e0 : 0x00e4, 0x0001,
|
||||
NULL, NULL, NULL, NULL, NULL, postcard_writel, NULL);
|
||||
|
||||
return postcard_write;
|
||||
|
||||
@@ -55,6 +55,7 @@ extern const device_t neat_sx_device;
|
||||
extern const device_t scat_device;
|
||||
extern const device_t scat_4_device;
|
||||
extern const device_t scat_sx_device;
|
||||
extern const device_t cs8220_device;
|
||||
extern const device_t cs8230_device;
|
||||
extern const device_t cs4031_device;
|
||||
|
||||
@@ -112,6 +113,9 @@ extern const device_t slc90e66_device;
|
||||
|
||||
extern const device_t ioapic_device;
|
||||
|
||||
/* Olivetti */
|
||||
extern const device_t olivetti_eva_device;
|
||||
|
||||
/* OPTi */
|
||||
extern const device_t opti283_device;
|
||||
extern const device_t opti291_device;
|
||||
@@ -203,8 +207,4 @@ extern const device_t nec_mate_unk_device;
|
||||
|
||||
extern const device_t phoenix_486_jumper_device;
|
||||
extern const device_t phoenix_486_jumper_pci_device;
|
||||
|
||||
#ifdef USE_OLIVETTI
|
||||
extern const device_t olivetti_eva_device;
|
||||
#endif /* USE_OLIVETTI */
|
||||
#endif /*EMU_CHIPSET_H*/
|
||||
|
||||
@@ -211,6 +211,7 @@ enum {
|
||||
MACHINE_CHIPSET_SCAT_SX,
|
||||
MACHINE_CHIPSET_NEAT,
|
||||
MACHINE_CHIPSET_NEAT_SX,
|
||||
MACHINE_CHIPSET_CT_AT,
|
||||
MACHINE_CHIPSET_CT_386,
|
||||
MACHINE_CHIPSET_CT_CS4031,
|
||||
MACHINE_CHIPSET_CONTAQ_82C596,
|
||||
@@ -447,9 +448,6 @@ extern int machine_at_pb286_init(const machine_t *);
|
||||
extern int machine_at_siemens_init(const machine_t *); // Siemens PCD-2L. N82330 discrete machine. It segfaults in some places
|
||||
|
||||
extern int machine_at_wellamerastar_init(const machine_t *); // Wells American A*Star with custom award BIOS
|
||||
#ifdef USE_OPEN_AT
|
||||
extern int machine_at_openat_init(const machine_t *);
|
||||
#endif /* USE_OPEN_AT */
|
||||
|
||||
/* m_at_286_386sx.c */
|
||||
extern int machine_at_tg286m_init(const machine_t *);
|
||||
@@ -475,19 +473,19 @@ extern int machine_at_spc4216p_init(const machine_t *);
|
||||
extern int machine_at_spc4620p_init(const machine_t *);
|
||||
extern int machine_at_kmxc02_init(const machine_t *);
|
||||
extern int machine_at_deskmaster286_init(const machine_t *);
|
||||
extern int machine_at_dells200_init(const machine_t *);
|
||||
|
||||
extern int machine_at_pc8_init(const machine_t *);
|
||||
extern int machine_at_3302_init(const machine_t *);
|
||||
|
||||
#ifdef USE_OLIVETTI
|
||||
extern int machine_at_m290_init(const machine_t *);
|
||||
#endif /* USE_OLIVETTI */
|
||||
|
||||
extern int machine_at_shuttle386sx_init(const machine_t *);
|
||||
extern int machine_at_adi386sx_init(const machine_t *);
|
||||
extern int machine_at_cmdsl386sx16_init(const machine_t *);
|
||||
extern int machine_at_cmdsl386sx25_init(const machine_t *);
|
||||
extern int machine_at_dataexpert386sx_init(const machine_t *);
|
||||
extern int machine_at_dells333sl_init(const machine_t *);
|
||||
extern int machine_at_if386sx_init(const machine_t *);
|
||||
extern int machine_at_spc6033p_init(const machine_t *);
|
||||
extern int machine_at_wd76c10_init(const machine_t *);
|
||||
@@ -515,7 +513,7 @@ extern int machine_at_ga486l_init(const machine_t *);
|
||||
extern int machine_at_cougar_init(const machine_t *);
|
||||
|
||||
extern int machine_at_acc386_init(const machine_t *);
|
||||
extern int machine_at_asus386_3364k_init(const machine_t *);
|
||||
extern int machine_at_asus3863364k_init(const machine_t *);
|
||||
extern int machine_at_asus386_init(const machine_t *);
|
||||
extern int machine_at_ecs386_init(const machine_t *);
|
||||
extern int machine_at_spc6000a_init(const machine_t *);
|
||||
@@ -673,7 +671,7 @@ extern int machine_at_tek932_init(const machine_t *);
|
||||
|
||||
extern int machine_at_acerv30_init(const machine_t *);
|
||||
extern int machine_at_apollo_init(const machine_t *);
|
||||
extern int machine_at_optiplex_gxl_init(const machine_t *);
|
||||
extern int machine_at_optiplexgxl_init(const machine_t *);
|
||||
extern int machine_at_zappa_init(const machine_t *);
|
||||
extern int machine_at_powermatev_init(const machine_t *);
|
||||
extern int machine_at_hawk_init(const machine_t *);
|
||||
@@ -724,6 +722,8 @@ extern int machine_at_vectra54_init(const machine_t *);
|
||||
extern int machine_at_5sbm2_init(const machine_t *);
|
||||
|
||||
/* m_at_socket7.c */
|
||||
extern void machine_at_optiplex_21152_init(void);
|
||||
|
||||
extern int machine_at_acerv35n_init(const machine_t *);
|
||||
extern int machine_at_p55t2p4_init(const machine_t *);
|
||||
extern int machine_at_m7shi_init(const machine_t *);
|
||||
@@ -753,12 +753,10 @@ extern int machine_at_gw2kte_init(const machine_t *);
|
||||
extern int machine_at_ma23c_init(const machine_t *);
|
||||
extern int machine_at_nupro592_init(const machine_t *);
|
||||
extern int machine_at_tx97_init(const machine_t *);
|
||||
extern int machine_at_optiplex_gn_init(const machine_t *);
|
||||
#ifdef USE_AN430TX
|
||||
extern int machine_at_an430tx_init(const machine_t *);
|
||||
#endif /* USE_AN430TX */
|
||||
extern int machine_at_optiplexgn_init(const machine_t *);
|
||||
extern int machine_at_ym430tx_init(const machine_t *);
|
||||
extern int machine_at_thunderbolt_init(const machine_t *);
|
||||
extern int machine_at_an430tx_init(const machine_t *);
|
||||
extern int machine_at_mb540n_init(const machine_t *);
|
||||
extern int machine_at_56a5_init(const machine_t *);
|
||||
extern int machine_at_p5mms98_init(const machine_t *);
|
||||
@@ -824,7 +822,7 @@ extern int machine_at_p65up5_cpknd_init(const machine_t *);
|
||||
extern int machine_at_kn97_init(const machine_t *);
|
||||
|
||||
extern int machine_at_lx6_init(const machine_t *);
|
||||
extern int machine_at_optiplex_gxa_init(const machine_t *);
|
||||
extern int machine_at_optiplexgxa_init(const machine_t *);
|
||||
extern int machine_at_spitfire_init(const machine_t *);
|
||||
extern int machine_at_ma30d_init(const machine_t *);
|
||||
|
||||
|
||||
@@ -283,6 +283,7 @@ extern void pci_init(int flags);
|
||||
|
||||
/* PCI bridge stuff. */
|
||||
extern void pci_bridge_set_ctl(void *priv, uint8_t ctl);
|
||||
extern uint8_t pci_bridge_get_bus_index(void *priv);
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t dec21150_device;
|
||||
|
||||
42
src/include/86box/snd_mmb.h
Normal file
42
src/include/86box/snd_mmb.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Mindscape Music Board emulation.
|
||||
*
|
||||
* Authors: Roy Baer, <https://pcem-emulator.co.uk/>
|
||||
* Jasmine Iwanek, <jriwanek@gmail.com>
|
||||
*
|
||||
* Copyright 2025 Roy Baer.
|
||||
* Copyright 2025 Jasmine Iwanek.
|
||||
*/
|
||||
#ifndef _SOUND_SND_MMB_H_
|
||||
#define _SOUND_SND_MMB_H_
|
||||
|
||||
#define MMB_FREQ FREQ_48000
|
||||
|
||||
/* NOTE:
|
||||
* The constant clock rate is a deviation from the real hardware which has
|
||||
* the design flaw that the clock rate is always half the ISA bus clock.
|
||||
*/
|
||||
#define MMB_CLOCK 2386364
|
||||
|
||||
typedef struct ay_3_891x_s {
|
||||
uint8_t index;
|
||||
uint8_t regs[16];
|
||||
struct ayumi chip;
|
||||
} ay_3_891x_t;
|
||||
|
||||
typedef struct mmb_s {
|
||||
ay_3_891x_t first;
|
||||
ay_3_891x_t second;
|
||||
|
||||
int16_t buffer[SOUNDBUFLEN * 2];
|
||||
int pos;
|
||||
} mmb_t;
|
||||
|
||||
#endif /* _SOUND_SND_MMB_H_ */
|
||||
@@ -197,6 +197,7 @@ extern const device_t ct5880_onboard_device;
|
||||
|
||||
/* Gravis UltraSound and UltraSound Max */
|
||||
extern const device_t gus_device;
|
||||
extern const device_t gus_max_device;
|
||||
|
||||
/* IBM PS/1 Audio Card */
|
||||
extern const device_t ps1snd_device;
|
||||
@@ -205,6 +206,9 @@ extern const device_t ps1snd_device;
|
||||
extern const device_t ssi2001_device;
|
||||
extern const device_t entertainer_device;
|
||||
|
||||
/* Mindscape Music Board */
|
||||
extern const device_t mmb_device;
|
||||
|
||||
/* Pro Audio Spectrum Plus, 16, and 16D */
|
||||
extern const device_t pasplus_device;
|
||||
extern const device_t pas16_device;
|
||||
|
||||
@@ -36,6 +36,10 @@ using atomic_int = std::atomic_int;
|
||||
#define getcolg(color) (((color) >> 8) & 0xFF)
|
||||
#define getcolb(color) ((color) & 0xFF)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
VID_NONE = 0,
|
||||
VID_INTERNAL
|
||||
@@ -49,10 +53,6 @@ enum {
|
||||
FULLSCR_SCALE_INT43
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
VIDEO_ISA = 0,
|
||||
VIDEO_MCA,
|
||||
@@ -71,6 +71,11 @@ enum {
|
||||
|
||||
#define VIDEO_FLAG_TYPE_SECONDARY VIDEO_FLAG_TYPE_SPECIAL
|
||||
|
||||
#define FONT_IBM_MDA_437_PATH "roms/video/mda/mda.rom"
|
||||
#define FONT_IBM_MDA_437_NORDIC_PATH "roms/video/mda/4733197.bin"
|
||||
#define FONT_KAM_PATH "roms/video/mda/kam.bin"
|
||||
#define FONT_KAMCL16_PATH "roms/video/mda/kamcl16.bin"
|
||||
|
||||
typedef struct video_timings_t {
|
||||
int type;
|
||||
int write_b;
|
||||
@@ -189,15 +194,15 @@ extern uint32_t pal_lookup[256];
|
||||
#endif
|
||||
extern int video_fullscreen;
|
||||
extern int video_fullscreen_scale;
|
||||
extern uint8_t fontdat[2048][8];
|
||||
extern uint8_t fontdatm[2048][16];
|
||||
extern uint8_t fontdat2[2048][8];
|
||||
extern uint8_t fontdatm2[2048][16];
|
||||
extern uint8_t fontdatw[512][32];
|
||||
extern uint8_t fontdat8x12[256][16];
|
||||
extern uint8_t fontdat12x18[256][36];
|
||||
extern dbcs_font_t *fontdatksc5601;
|
||||
extern dbcs_font_t *fontdatksc5601_user;
|
||||
extern uint8_t fontdat[2048][8]; /* IBM CGA font */
|
||||
extern uint8_t fontdatm[2048][16]; /* IBM MDA font */
|
||||
extern uint8_t fontdat2[2048][8]; /* IBM CGA 2nd instance font */
|
||||
extern uint8_t fontdatm2[2048][16]; /* IBM MDA 2nd instance font */
|
||||
extern uint8_t fontdatw[512][32]; /* Wyse700 font */
|
||||
extern uint8_t fontdat8x12[256][16]; /* MDSI Genius font */
|
||||
extern uint8_t fontdat12x18[256][36]; /* IM1024 font */
|
||||
extern dbcs_font_t *fontdatksc5601; /* Korean KSC-5601 font */
|
||||
extern dbcs_font_t *fontdatksc5601_user; /* Korean KSC-5601 user defined font */
|
||||
extern uint32_t *video_6to8;
|
||||
extern uint32_t *video_8togs;
|
||||
extern uint32_t *video_8to32;
|
||||
@@ -277,8 +282,8 @@ extern uint8_t video_force_resize_get_monitor(int monitor_index);
|
||||
extern void video_force_resize_set_monitor(uint8_t res, int monitor_index);
|
||||
extern void video_update_timing(void);
|
||||
|
||||
extern void loadfont_ex(char *s, int format, int offset);
|
||||
extern void loadfont(char *s, int format);
|
||||
extern void loadfont_ex(char *fn, int format, int offset);
|
||||
extern void loadfont(char *fn, int format);
|
||||
|
||||
extern int get_actual_size_x(void);
|
||||
extern int get_actual_size_y(void);
|
||||
@@ -351,6 +356,7 @@ extern const device_t gd5401_isa_device;
|
||||
extern const device_t gd5402_isa_device;
|
||||
extern const device_t gd5402_onboard_device;
|
||||
extern const device_t gd5420_isa_device;
|
||||
extern const device_t gd5420_onboard_device;
|
||||
extern const device_t gd5422_isa_device;
|
||||
extern const device_t gd5424_vlb_device;
|
||||
extern const device_t gd5426_isa_device;
|
||||
|
||||
@@ -56,19 +56,3 @@ add_library(mch OBJECT
|
||||
m_at_socket370.c
|
||||
m_at_misc.c
|
||||
)
|
||||
|
||||
if(AN430TX)
|
||||
target_compile_definitions(mch PRIVATE USE_AN430TX)
|
||||
endif()
|
||||
|
||||
if(DESKPRO386)
|
||||
target_compile_definitions(mch PRIVATE USE_DESKPRO386)
|
||||
endif()
|
||||
|
||||
if(OLIVETTI)
|
||||
target_compile_definitions(mch PRIVATE USE_OLIVETTI)
|
||||
endif()
|
||||
|
||||
if(OPEN_AT)
|
||||
target_compile_definitions(mch PRIVATE USE_OPEN_AT)
|
||||
endif()
|
||||
|
||||
@@ -2936,7 +2936,7 @@ machine_amstrad_init(const machine_t *model, int type)
|
||||
break;
|
||||
|
||||
case AMS_PC1640:
|
||||
loadfont("roms/video/mda/mda.rom", 0);
|
||||
loadfont(FONT_IBM_MDA_437_PATH, 0);
|
||||
device_context(&vid_1640_device);
|
||||
ams->language = device_get_config_int("language");
|
||||
vid_init_1640(ams);
|
||||
|
||||
@@ -388,21 +388,3 @@ machine_at_wellamerastar_init(const machine_t *model)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef USE_OPEN_AT
|
||||
int
|
||||
machine_at_openat_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/openat/bios.bin",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_ibm_common_init(model);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* USE_OPEN_AT */
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/port_6x.h>
|
||||
#define USE_SIO_DETECT
|
||||
#include <86box/sio.h>
|
||||
#include <86box/serial.h>
|
||||
#include <86box/video.h>
|
||||
@@ -261,6 +262,30 @@ machine_at_px286_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_dells200_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_interleaved("roms/machines/dells200/dellL200256_LO_@DIP28.BIN",
|
||||
"roms/machines/dells200/Dell200256_HI_@DIP28.BIN",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&cs8220_device);
|
||||
|
||||
if (fdc_current[0] == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
device_add(&keyboard_at_phoenix_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_micronics386_init(const machine_t *model)
|
||||
{
|
||||
@@ -736,6 +761,75 @@ machine_at_cmdsl386sx25_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const device_config_t dells333sl_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "dells333sl",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "J01 (Jostens Learning Corporation OEM)", .internal_name = "dells333sl_j01", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/dells333sl/DELL386.BIN", "" } },
|
||||
{ .name = "A02", .internal_name = "dells333sl", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/dells333sl/Dell_386SX_30807_UBIOS_B400_VLSI_VL82C311_Cirrus_Logic_GD5420.bin", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t dells333sl_device = {
|
||||
.name = "Dell System 333s/L",
|
||||
.internal_name = "dells333sl_device",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = dells333sl_config
|
||||
};
|
||||
|
||||
int
|
||||
machine_at_dells333sl_init(const machine_t *model)
|
||||
{
|
||||
int ret = 0;
|
||||
const char* fn;
|
||||
|
||||
/* No ROMs available */
|
||||
if (!device_available(model->device))
|
||||
return ret;
|
||||
|
||||
device_context(model->device);
|
||||
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0);
|
||||
ret = bios_load_linear(fn, 0x000e0000, 262144, 0);
|
||||
memcpy(rom, &(rom[0x00020000]), 131072);
|
||||
mem_mapping_set_addr(&bios_mapping, 0x0c0000, 0x40000);
|
||||
mem_mapping_set_exec(&bios_mapping, rom);
|
||||
device_context_restore();
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
device_add(&ide_isa_device);
|
||||
|
||||
device_add(&pc87311_device);
|
||||
device_add(&vl82c113_device); /* The keyboard controller is part of the VL82c113. */
|
||||
|
||||
device_add(&vlsi_scamp_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_dataexpert386sx_init(const machine_t *model)
|
||||
{
|
||||
@@ -1045,7 +1139,6 @@ machine_at_pc916sx_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef USE_OLIVETTI
|
||||
int
|
||||
machine_at_m290_init(const machine_t *model)
|
||||
{
|
||||
@@ -1057,15 +1150,16 @@ machine_at_m290_init(const machine_t *model)
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init_ex(model, 4);
|
||||
device_add(&keyboard_at_olivetti_device);
|
||||
machine_at_common_init_ex(model, 6);
|
||||
device_add(&amstrad_megapc_nvr_device);
|
||||
|
||||
device_add(&olivetti_eva_device);
|
||||
device_add(&port_6x_olivetti_device);
|
||||
|
||||
if (fdc_current[0] == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
device_add(&olivetti_eva_device);
|
||||
device_add(&keyboard_at_olivetti_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* USE_OLIVETTI */
|
||||
|
||||
@@ -73,11 +73,11 @@ machine_at_acc386_init(const machine_t *model)
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_asus386_3364k_init(const machine_t *model)
|
||||
machine_at_asus3863364k_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/asus386_3364k/am27c512dip28-64b53c26be3d8160533563.bin",
|
||||
ret = bios_load_linear("roms/machines/asus3863364k/am27c512dip28-64b53c26be3d8160533563.bin",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
|
||||
@@ -151,11 +151,11 @@ machine_at_lx6_init(const machine_t *model)
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_optiplex_gxa_init(const machine_t *model)
|
||||
machine_at_optiplexgxa_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/optiplex_gxa/DELL.ROM",
|
||||
ret = bios_load_linear("roms/machines/optiplexgxa/DELL.ROM",
|
||||
0x000c0000, 262144, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
@@ -170,14 +170,14 @@ machine_at_optiplex_gxa_init(const machine_t *model)
|
||||
pci_register_slot(0x11, PCI_CARD_NETWORK, 4, 0, 0, 0);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 2, 1);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 1, 3, 4);
|
||||
pci_register_slot(0x0F, PCI_CARD_BRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0F, PCI_CARD_BRIDGE, 0, 0, 0, 0);
|
||||
|
||||
if (sound_card_current[0] == SOUND_INTERNAL)
|
||||
device_add(machine_get_snd_device(machine));
|
||||
|
||||
device_add(&i440lx_device);
|
||||
device_add(&piix4_device);
|
||||
device_add(&dec21152_device);
|
||||
machine_at_optiplex_21152_init();
|
||||
device_add_params(&pc87307_device, (void *) (PCX730X_PHOENIX_42 | PCX7307_PC87307));
|
||||
device_add(&intel_flash_bxt_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
|
||||
|
||||
@@ -238,11 +238,11 @@ machine_at_apollo_init(const machine_t *model)
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_optiplex_gxl_init(const machine_t *model)
|
||||
machine_at_optiplexgxl_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/optiplex_gxl/DELL.ROM",
|
||||
ret = bios_load_linear("roms/machines/optiplexgxl/DELL.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
|
||||
@@ -46,6 +46,15 @@
|
||||
#include <86box/network.h>
|
||||
#include <86box/pci.h>
|
||||
|
||||
void
|
||||
machine_at_optiplex_21152_init(void)
|
||||
{
|
||||
uint8_t bus_index = pci_bridge_get_bus_index(device_add(&dec21152_device));
|
||||
pci_register_bus_slot(bus_index, 0x09, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_bus_slot(bus_index, 0x0a, PCI_CARD_NORMAL, 4, 2, 1, 3);
|
||||
pci_register_bus_slot(bus_index, 0x0b, PCI_CARD_NORMAL, 1, 3, 4, 2);
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_acerv35n_init(const machine_t *model)
|
||||
{
|
||||
@@ -970,11 +979,11 @@ machine_at_tx97_init(const machine_t *model)
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_optiplex_gn_init(const machine_t *model)
|
||||
machine_at_optiplexgn_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/optiplex_gn/DELL.ROM",
|
||||
ret = bios_load_linear("roms/machines/optiplexgn/DELL.ROM",
|
||||
0x000c0000, 262144, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
@@ -989,7 +998,7 @@ machine_at_optiplex_gn_init(const machine_t *model)
|
||||
pci_register_slot(0x10, PCI_CARD_VIDEO, 4, 0, 0, 0); /* Trio64V2/GX, temporarily Trio64V2/DX is given */
|
||||
pci_register_slot(0x11, PCI_CARD_NETWORK, 4, 0, 0, 0); /* 3C905, not yet emulated */
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4);
|
||||
pci_register_slot(0x0F, PCI_CARD_BRIDGE, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0F, PCI_CARD_BRIDGE, 0, 0, 0, 0);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(machine_get_vid_device(machine));
|
||||
@@ -999,7 +1008,7 @@ machine_at_optiplex_gn_init(const machine_t *model)
|
||||
|
||||
device_add(&i430tx_device);
|
||||
device_add(&piix4_device);
|
||||
device_add(&dec21152_device);
|
||||
machine_at_optiplex_21152_init();
|
||||
device_add_params(&pc87307_device, (void *) (PCX730X_PHOENIX_42 | PCX7307_PC87307));
|
||||
device_add(&intel_flash_bxt_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
|
||||
@@ -1007,27 +1016,17 @@ machine_at_optiplex_gn_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef USE_AN430TX
|
||||
int
|
||||
machine_at_an430tx_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
# if 1
|
||||
ret = bios_load_linear_combined2("roms/machines/an430tx/P10-0095.BIO",
|
||||
"roms/machines/an430tx/P10-0095.BI1",
|
||||
"roms/machines/an430tx/P10-0095.BI2",
|
||||
"roms/machines/an430tx/P10-0095.BI3",
|
||||
"roms/machines/an430tx/P10-0095.RCV",
|
||||
ret = bios_load_linear_combined2("roms/machines/an430tx/ANP0911A.BIO",
|
||||
"roms/machines/an430tx/ANP0911A.BI1",
|
||||
"roms/machines/an430tx/ANP0911A.BI2",
|
||||
"roms/machines/an430tx/ANP0911A.BI3",
|
||||
"roms/machines/an430tx/ANP0911A.RCV",
|
||||
0x3a000, 160);
|
||||
# else
|
||||
ret = bios_load_linear_combined2("roms/machines/an430tx/P06-0062.BIO",
|
||||
"roms/machines/an430tx/P06-0062.BI1",
|
||||
"roms/machines/an430tx/P06-0062.BI2",
|
||||
"roms/machines/an430tx/P06-0062.BI3",
|
||||
"roms/machines/an430tx/P10-0095.RCV",
|
||||
0x3a000, 160);
|
||||
# endif
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
@@ -1036,21 +1035,25 @@ machine_at_an430tx_init(const machine_t *model)
|
||||
|
||||
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); /* PIIX4 */
|
||||
// pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); /* PIIX4 */
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
|
||||
device_add(&i430tx_device);
|
||||
device_add(&piix4_device);
|
||||
#ifdef FOLLOW_THE_SPECIFICATION
|
||||
device_add_params(&pc87307_device, (void *) (PCX730X_PHOENIX_42I | PCX7307_PC97307));
|
||||
#else
|
||||
/* The technical specification says Phoenix, a real machnine HWINFO dump says AMI '5'. */
|
||||
device_add_params(&pc87307_device, (void *) (PCX730X_AMI | PCX7307_PC97307));
|
||||
#endif
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x3, 128);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* USE_AN430TX */
|
||||
|
||||
int
|
||||
machine_at_ym430tx_init(const machine_t *model)
|
||||
|
||||
@@ -1541,7 +1541,7 @@ machine_pcjr_init(UNUSED(const machine_t *model))
|
||||
|
||||
/* Initialize the video controller. */
|
||||
video_reset(gfxcard[0]);
|
||||
loadfont("roms/video/mda/mda.rom", 0);
|
||||
loadfont(FONT_IBM_MDA_437_PATH, 0);
|
||||
device_context(&pcjr_device);
|
||||
pcjr_vid_init(pcjr);
|
||||
device_context_restore();
|
||||
|
||||
@@ -8,17 +8,12 @@
|
||||
*
|
||||
* Handling of the emulated machines.
|
||||
*
|
||||
* NOTES: OpenAT wip for 286-class machine with open BIOS.
|
||||
* PS2_M80-486 wip, pending receipt of TRM's for machine.
|
||||
*
|
||||
*
|
||||
*
|
||||
* 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 2016-2025 Miran Grca.
|
||||
* Copyright 2017-2025 Fred N. van Kempen.
|
||||
* Copyright 2025 Jasmine Iwanek.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
@@ -71,6 +66,7 @@ extern const device_t vendex_device;
|
||||
extern const device_t c5sbm2_device;
|
||||
extern const device_t sb486pv_device;
|
||||
extern const device_t ap5s_device;
|
||||
extern const device_t dells333sl_device;
|
||||
|
||||
const machine_filter_t machine_types[] = {
|
||||
{ "None", MACHINE_TYPE_NONE },
|
||||
@@ -117,11 +113,12 @@ const machine_filter_t machine_chipsets[] = {
|
||||
{ "ALi ALADDiN IV+", MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS },
|
||||
{ "ALi ALADDiN V", MACHINE_CHIPSET_ALI_ALADDIN_V },
|
||||
{ "ALi ALADDiN-PRO II", MACHINE_CHIPSET_ALI_ALADDIN_PRO_II },
|
||||
{ "C&T PC/AT", MACHINE_CHIPSET_CT_AT },
|
||||
{ "C&T 386/AT", MACHINE_CHIPSET_CT_386 },
|
||||
{ "C&T 82C235 SCAT", MACHINE_CHIPSET_SCAT },
|
||||
{ "C&T 82C236 SCATsx", MACHINE_CHIPSET_SCAT_SX },
|
||||
{ "C&T CS8221 NEAT", MACHINE_CHIPSET_NEAT },
|
||||
{ "C&T CS8281 NEATsx", MACHINE_CHIPSET_NEAT_SX },
|
||||
{ "C&T 386", MACHINE_CHIPSET_CT_386 },
|
||||
{ "C&T CS4031", MACHINE_CHIPSET_CT_CS4031 },
|
||||
{ "Contaq 82C596", MACHINE_CHIPSET_CONTAQ_82C596 },
|
||||
{ "Contaq 82C597", MACHINE_CHIPSET_CONTAQ_82C597 },
|
||||
@@ -3095,7 +3092,6 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
#ifdef USE_OLIVETTI
|
||||
/* Has Olivetti KBC firmware. */
|
||||
{
|
||||
.name = "[ISA] Olivetti M290",
|
||||
@@ -3136,49 +3132,6 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
#endif /* USE_OLIVETTI */
|
||||
#ifdef USE_OPEN_AT
|
||||
/* Has IBM AT KBC firmware. */
|
||||
{
|
||||
.name = "[ISA] OpenAT",
|
||||
.internal_name = "openat",
|
||||
.type = MACHINE_TYPE_286,
|
||||
.chipset = MACHINE_CHIPSET_DISCRETE,
|
||||
.init = machine_at_openat_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_286,
|
||||
.block = CPU_BLOCK_NONE,
|
||||
.min_bus = 0,
|
||||
.max_bus = 0,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_AT,
|
||||
.flags = MACHINE_FLAGS_NONE,
|
||||
.ram = {
|
||||
.min = 256,
|
||||
.max = 15872,
|
||||
.step = 128
|
||||
},
|
||||
.nvrmask = 63,
|
||||
.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
|
||||
},
|
||||
#endif /* USE_OPEN_AT */
|
||||
/* Has IBM AT KBC firmware. */
|
||||
{
|
||||
.name = "[ISA] Phoenix IBM AT",
|
||||
@@ -3419,6 +3372,47 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC
|
||||
firmware. */
|
||||
{
|
||||
.name = "[C&T PC/AT] Dell System 200",
|
||||
.internal_name = "dells200",
|
||||
.type = MACHINE_TYPE_286,
|
||||
.chipset = MACHINE_CHIPSET_CT_AT,
|
||||
.init = machine_at_dells200_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_286,
|
||||
.block = CPU_BLOCK_NONE,
|
||||
.min_bus = 6000000,
|
||||
.max_bus = 12000000,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_AT,
|
||||
.flags = MACHINE_FLAGS_NONE,
|
||||
.ram = {
|
||||
.min = 640,
|
||||
.max = 16384,
|
||||
.step = 128
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.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
|
||||
},
|
||||
/* Has Quadtel KBC firmware. */
|
||||
{
|
||||
.name = "[GC103] Quadtel 286 clone",
|
||||
@@ -4463,7 +4457,7 @@ const machine_t machines[] = {
|
||||
.net_device = NULL
|
||||
},
|
||||
{
|
||||
.name = "[ALI M1409] Acer 100T",
|
||||
.name = "[ALi M1409] Acer 100T",
|
||||
.internal_name = "acer100t",
|
||||
.type = MACHINE_TYPE_386SX,
|
||||
.chipset = MACHINE_CHIPSET_ALI_M1409,
|
||||
@@ -4949,6 +4943,47 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC
|
||||
firmware. */
|
||||
{
|
||||
.name = "[SCAMP] Dell System 333s/L",
|
||||
.internal_name = "dells333sl",
|
||||
.type = MACHINE_TYPE_386SX,
|
||||
.chipset = MACHINE_CHIPSET_VLSI_SCAMP,
|
||||
.init = machine_at_dells333sl_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_386SX,
|
||||
.block = CPU_BLOCK_NONE,
|
||||
.min_bus = 10000000,
|
||||
.max_bus = 33333333,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_PS2,
|
||||
.flags = MACHINE_IDE | MACHINE_VIDEO,
|
||||
.ram = {
|
||||
.min = 1024,
|
||||
.max = 16384,
|
||||
.step = 128
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = &dells333sl_device,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = &gd5420_onboard_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has IBM PS/2 Type 1 KBC firmware. */
|
||||
{
|
||||
.name = "[SCAMP] Samsung SPC-6033P",
|
||||
@@ -5239,7 +5274,7 @@ const machine_t machines[] = {
|
||||
},
|
||||
/* Has an AMI Keyboard BIOS PLUS KBC firmware ('8'). */
|
||||
{
|
||||
.name = "[C&T 386] ECS 386/32",
|
||||
.name = "[C&T 386/AT] ECS 386/32",
|
||||
.internal_name = "ecs386",
|
||||
.type = MACHINE_TYPE_386DX,
|
||||
.chipset = MACHINE_CHIPSET_CT_386,
|
||||
@@ -5279,7 +5314,7 @@ const machine_t machines[] = {
|
||||
},
|
||||
/* Has IBM AT KBC firmware. */
|
||||
{
|
||||
.name = "[C&T 386] Samsung SPC-6000A",
|
||||
.name = "[C&T 386/AT] Samsung SPC-6000A",
|
||||
.internal_name = "spc6000a",
|
||||
.type = MACHINE_TYPE_386DX,
|
||||
.chipset = MACHINE_CHIPSET_CT_386,
|
||||
@@ -5678,10 +5713,10 @@ const machine_t machines[] = {
|
||||
/* Has Award KBC firmware. */
|
||||
{
|
||||
.name = "[SiS 310] ASUS 386/33-64K",
|
||||
.internal_name = "asus386_3364k",
|
||||
.internal_name = "asus3863364k",
|
||||
.type = MACHINE_TYPE_386DX,
|
||||
.chipset = MACHINE_CHIPSET_SIS_310,
|
||||
.init = machine_at_asus386_3364k_init,
|
||||
.init = machine_at_asus3863364k_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
@@ -9429,7 +9464,7 @@ const machine_t machines[] = {
|
||||
.max_multi = 2.0
|
||||
},
|
||||
.bus_flags = MACHINE_PS2_PCI,
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal video: ST STPC Atlas */
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_PCI_INTERNAL, /* Machine has internal video: ST STPC Atlas */
|
||||
.ram = {
|
||||
.min = 32768,
|
||||
.max = 163840,
|
||||
@@ -9470,7 +9505,7 @@ const machine_t machines[] = {
|
||||
.max_multi = 2.0
|
||||
},
|
||||
.bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB,
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal video: ST STPC Atlas */
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_PCI_INTERNAL | MACHINE_USB, /* Machine has internal video: ST STPC Atlas */
|
||||
.ram = {
|
||||
.min = 32768,
|
||||
.max = 163840,
|
||||
@@ -9511,7 +9546,7 @@ const machine_t machines[] = {
|
||||
.max_multi = 2.0
|
||||
},
|
||||
.bus_flags = MACHINE_PS2,
|
||||
.flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal video: ST STPC Atlas and NIC: Realtek RTL8139C+ */
|
||||
.flags = MACHINE_IDE | MACHINE_APM | MACHINE_PCI_INTERNAL, /* Machine has internal video: ST STPC Atlas and NIC: Realtek RTL8139C+ */
|
||||
.ram = {
|
||||
.min = 32768,
|
||||
.max = 131072,
|
||||
@@ -9552,7 +9587,7 @@ const machine_t machines[] = {
|
||||
.max_multi = 2.0
|
||||
},
|
||||
.bus_flags = MACHINE_PS2_PCI,
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM,
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_PCI_INTERNAL,
|
||||
.ram = {
|
||||
.min = 32768,
|
||||
.max = 98304,
|
||||
@@ -9593,7 +9628,7 @@ const machine_t machines[] = {
|
||||
.max_multi = 2.0
|
||||
},
|
||||
.bus_flags = MACHINE_PS2_PCI,
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM,
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_PCI_INTERNAL,
|
||||
.ram = {
|
||||
.min = 32768,
|
||||
.max = 131072,
|
||||
@@ -10556,10 +10591,10 @@ const machine_t machines[] = {
|
||||
/* Has a National Semiconductor PC87332VLJ Super I/O with AMIKey 'F' KBC firmware. */
|
||||
{
|
||||
.name = "[i430FX] Dell OptiPlex GXL/GXM",
|
||||
.internal_name = "optiplex_gxl",
|
||||
.internal_name = "optiplexgxl",
|
||||
.type = MACHINE_TYPE_SOCKET5,
|
||||
.chipset = MACHINE_CHIPSET_INTEL_430FX,
|
||||
.init = machine_at_optiplex_gxl_init,
|
||||
.init = machine_at_optiplexgxl_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
@@ -13154,10 +13189,10 @@ const machine_t machines[] = {
|
||||
*/
|
||||
{
|
||||
.name = "[i430TX] Dell OptiPlex GN+",
|
||||
.internal_name = "optiplex_gn",
|
||||
.internal_name = "optiplexgn",
|
||||
.type = MACHINE_TYPE_SOCKET7,
|
||||
.chipset = MACHINE_CHIPSET_INTEL_430TX,
|
||||
.init = machine_at_optiplex_gn_init,
|
||||
.init = machine_at_optiplexgn_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
@@ -13233,49 +13268,6 @@ const machine_t machines[] = {
|
||||
.snd_device = &cs4236b_device,
|
||||
.net_device = &pcnet_am79c973_onboard_device
|
||||
},
|
||||
#ifdef USE_AN430TX
|
||||
/* This has the Phoenix MultiKey KBC firmware. */
|
||||
{
|
||||
.name = "[i430TX] Intel AN430TX (Anchorage)",
|
||||
.internal_name = "an430tx",
|
||||
.type = MACHINE_TYPE_SOCKET7,
|
||||
.chipset = MACHINE_CHIPSET_INTEL_430TX,
|
||||
.init = machine_at_an430tx_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_SOCKET5_7,
|
||||
.block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P,
|
||||
CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L),
|
||||
.min_bus = 60000000,
|
||||
.max_bus = 66666667,
|
||||
.min_voltage = 2800,
|
||||
.max_voltage = 3520,
|
||||
.min_multi = 1.5,
|
||||
.max_multi = 3.5
|
||||
},
|
||||
.bus_flags = MACHINE_PS2_PCI,
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI,
|
||||
.ram = {
|
||||
.min = 8192,
|
||||
.max = 262144,
|
||||
.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
|
||||
},
|
||||
#endif /* USE_AN430TX */
|
||||
/* This has the AMIKey KBC firmware, which is an updated 'F' type. */
|
||||
{
|
||||
.name = "[i430TX] Intel YM430TX (Yamamoto)",
|
||||
@@ -13317,9 +13309,13 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* PhoenixBIOS 4.0 Rel 6.0 for 430TX, has onboard Yamaha YMF701 which is not emulated yet. */
|
||||
/* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix
|
||||
MultiKey/42 (version 1.38) KBC firmware. */
|
||||
/*
|
||||
PhoenixBIOS 4.0 Rel 6.0 for 430TX, has onboard Yamaha YMF701 which
|
||||
is not emulated yet.
|
||||
|
||||
Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix
|
||||
MultiKey/42 (version 1.38) KBC firmware.
|
||||
*/
|
||||
{
|
||||
.name = "[i430TX] Micronics Thunderbolt",
|
||||
.internal_name = "thunderbolt",
|
||||
@@ -13341,7 +13337,8 @@ const machine_t machines[] = {
|
||||
.max_multi = 3.5
|
||||
},
|
||||
.bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB,
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Yamaha YMF701-S */
|
||||
/* Machine has internal sound: Yamaha YMF701-S */
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB,
|
||||
.ram = {
|
||||
.min = 8192,
|
||||
.max = 262144,
|
||||
@@ -13400,6 +13397,47 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* This has the Phoenix MultiKey KBC firmware. */
|
||||
{
|
||||
.name = "[i430TX] Packard Bell PB790",
|
||||
.internal_name = "an430tx",
|
||||
.type = MACHINE_TYPE_SOCKET7,
|
||||
.chipset = MACHINE_CHIPSET_INTEL_430TX,
|
||||
.init = machine_at_an430tx_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_SOCKET5_7,
|
||||
.block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P,
|
||||
CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L),
|
||||
.min_bus = 60000000,
|
||||
.max_bus = 66666667,
|
||||
.min_voltage = 2800,
|
||||
.max_voltage = 3520,
|
||||
.min_multi = 1.5,
|
||||
.max_multi = 3.5
|
||||
},
|
||||
.bus_flags = MACHINE_PS2_PCI,
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI,
|
||||
.ram = {
|
||||
.min = 8192,
|
||||
.max = 262144,
|
||||
.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
|
||||
},
|
||||
/* The BIOS sends KBC command BB and expects it to output a byte, which is AMI KBC behavior.
|
||||
A picture shows a VIA VT82C42N KBC though, so it could be a case of that KBC with AMI firmware. */
|
||||
{
|
||||
@@ -14424,7 +14462,7 @@ const machine_t machines[] = {
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.snd_device = &cs4235_device,
|
||||
.snd_device = &cs4235_onboard_device,
|
||||
.net_device = NULL
|
||||
},
|
||||
|
||||
@@ -15214,10 +15252,10 @@ const machine_t machines[] = {
|
||||
firmwares: AMI '5' MegaKey, Phoenix MultiKey/42 1.37, or Phoenix MultiKey/42i 4.16. */
|
||||
{
|
||||
.name = "[i440LX] Dell OptiPlex GXa",
|
||||
.internal_name = "optiplex_gxa",
|
||||
.internal_name = "optiplexgxa",
|
||||
.type = MACHINE_TYPE_SLOT1,
|
||||
.chipset = MACHINE_CHIPSET_INTEL_440LX,
|
||||
.init = machine_at_optiplex_gxa_init,
|
||||
.init = machine_at_optiplexgxa_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
|
||||
@@ -2994,10 +2994,12 @@ mem_init(void)
|
||||
}
|
||||
|
||||
static void
|
||||
umc_page_recalc(uint32_t c, int set)
|
||||
umc_page_recalc(uint32_t c, uint32_t phys, int set)
|
||||
{
|
||||
uint32_t target = set ? phys : c;
|
||||
|
||||
if (set) {
|
||||
pages[c].mem = &ram[(c & 0xff) << 12];
|
||||
pages[c].mem = &ram[(target & 0xff) << 12];
|
||||
pages[c].write_b = mem_write_ramb_page;
|
||||
pages[c].write_w = mem_write_ramw_page;
|
||||
pages[c].write_l = mem_write_raml_page;
|
||||
@@ -3010,8 +3012,8 @@ umc_page_recalc(uint32_t c, int set)
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
pages[c].evict_prev = EVICT_NOT_IN_LIST;
|
||||
pages[c].byte_dirty_mask = &byte_dirty_mask[(c & 0xff) * 64];
|
||||
pages[c].byte_code_present_mask = &byte_code_present_mask[(c & 0xff) * 64];
|
||||
pages[c].byte_dirty_mask = &byte_dirty_mask[(target & 0xff) * 64];
|
||||
pages[c].byte_code_present_mask = &byte_code_present_mask[(target & 0xff) * 64];
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3019,7 +3021,7 @@ void
|
||||
umc_smram_recalc(uint32_t start, int set)
|
||||
{
|
||||
for (uint32_t c = start; c < (start + 0x0020); c++)
|
||||
umc_page_recalc(c, set);
|
||||
umc_page_recalc(c, c - start + 0x000a0000, set);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -59,9 +59,12 @@ smram_read(uint32_t addr, void *priv)
|
||||
const smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
if (new_addr >= (1 << 30))
|
||||
return mem_read_ram_2gb(new_addr, priv);
|
||||
else if (!use_separate_smram || (new_addr >= 0xa0000))
|
||||
else
|
||||
#endif
|
||||
if (!use_separate_smram || (new_addr >= 0xa0000))
|
||||
return mem_read_ram(new_addr, priv);
|
||||
else
|
||||
return dev->mapping.exec[addr - dev->host_base];
|
||||
@@ -73,9 +76,12 @@ smram_readw(uint32_t addr, void *priv)
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
if (new_addr >= (1 << 30))
|
||||
return mem_read_ram_2gbw(new_addr, priv);
|
||||
else if (!use_separate_smram || (new_addr >= 0xa0000))
|
||||
else
|
||||
#endif
|
||||
if (!use_separate_smram || (new_addr >= 0xa0000))
|
||||
return mem_read_ramw(new_addr, priv);
|
||||
else
|
||||
return *(uint16_t *) &(dev->mapping.exec[addr - dev->host_base]);
|
||||
@@ -87,9 +93,12 @@ smram_readl(uint32_t addr, void *priv)
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
if (new_addr >= (1 << 30))
|
||||
return mem_read_ram_2gbl(new_addr, priv);
|
||||
else if (!use_separate_smram || (new_addr >= 0xa0000))
|
||||
else
|
||||
#endif
|
||||
if (!use_separate_smram || (new_addr >= 0xa0000))
|
||||
return mem_read_raml(new_addr, priv);
|
||||
else
|
||||
return *(uint32_t *) &(dev->mapping.exec[addr - dev->host_base]);
|
||||
|
||||
@@ -855,10 +855,10 @@ pci_register_card(int pci_card)
|
||||
|
||||
/* Add an instance of the PCI bridge. */
|
||||
void
|
||||
pci_add_bridge(uint8_t agp, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, uint8_t *slot)
|
||||
pci_add_bridge(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, uint8_t *slot)
|
||||
{
|
||||
pci_card_t *card;
|
||||
uint8_t bridge_slot = agp ? pci_find_slot(PCI_ADD_AGPBRIDGE, 0xff) : last_normal_pci_card_id;
|
||||
uint8_t bridge_slot = (add_type == PCI_ADD_NORMAL) ? last_normal_pci_card_id : pci_find_slot(add_type, 0xff);
|
||||
|
||||
if (bridge_slot != PCI_CARD_INVALID) {
|
||||
card = &pci_cards[bridge_slot];
|
||||
|
||||
@@ -199,7 +199,7 @@ HarddiskDialog::on_comboBoxFormat_currentIndexChanged(int index)
|
||||
* than a tenth of a percent change in size.
|
||||
*/
|
||||
static void
|
||||
adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *vhd_geometry)
|
||||
adjust_86box_geometry_for_vhd(_86BoxGeom *_86box_geometry, MVHDGeom *vhd_geometry)
|
||||
{
|
||||
if (_86box_geometry->cyl <= 65535) {
|
||||
vhd_geometry->cyl = _86box_geometry->cyl;
|
||||
@@ -226,10 +226,10 @@ adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *vhd_geometry)
|
||||
}
|
||||
|
||||
static HarddiskDialog *callbackPtr = nullptr;
|
||||
static MVHDGeom
|
||||
create_drive_vhd_fixed(const QString &fileName, HarddiskDialog *p, uint16_t cyl, uint8_t heads, uint8_t spt)
|
||||
static _86BoxGeom
|
||||
create_drive_vhd_fixed(const QString &fileName, HarddiskDialog *p, uint32_t cyl, uint32_t heads, uint32_t spt)
|
||||
{
|
||||
MVHDGeom _86box_geometry = {
|
||||
_86BoxGeom _86box_geometry = {
|
||||
.cyl = cyl,
|
||||
.heads = heads,
|
||||
.spt = spt
|
||||
@@ -256,10 +256,10 @@ create_drive_vhd_fixed(const QString &fileName, HarddiskDialog *p, uint16_t cyl,
|
||||
return _86box_geometry;
|
||||
}
|
||||
|
||||
static MVHDGeom
|
||||
create_drive_vhd_dynamic(const QString &fileName, uint16_t cyl, uint8_t heads, uint8_t spt, int blocksize)
|
||||
static _86BoxGeom
|
||||
create_drive_vhd_dynamic(const QString &fileName, uint32_t cyl, uint32_t heads, uint32_t spt, int blocksize)
|
||||
{
|
||||
MVHDGeom _86box_geometry = {
|
||||
_86BoxGeom _86box_geometry = {
|
||||
.cyl = cyl,
|
||||
.heads = heads,
|
||||
.spt = spt
|
||||
@@ -287,7 +287,7 @@ create_drive_vhd_dynamic(const QString &fileName, uint16_t cyl, uint8_t heads, u
|
||||
return _86box_geometry;
|
||||
}
|
||||
|
||||
static MVHDGeom
|
||||
static _86BoxGeom
|
||||
create_drive_vhd_diff(const QString &fileName, const QString &parentFileName, int blocksize)
|
||||
{
|
||||
int vhd_error = 0;
|
||||
@@ -299,25 +299,31 @@ create_drive_vhd_diff(const QString &fileName, const QString &parentFileName, in
|
||||
options.parent_path = parentFilenameBytes.data();
|
||||
options.type = MVHD_TYPE_DIFF;
|
||||
|
||||
MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error);
|
||||
MVHDGeom vhd_geometry;
|
||||
MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error);
|
||||
MVHDGeom vhd_geometry;
|
||||
_86BoxGeom _86box_geometry;
|
||||
if (vhd == NULL) {
|
||||
vhd_geometry.cyl = 0;
|
||||
vhd_geometry.heads = 0;
|
||||
vhd_geometry.spt = 0;
|
||||
_86box_geometry.cyl = 0;
|
||||
_86box_geometry.heads = 0;
|
||||
_86box_geometry.spt = 0;
|
||||
} else {
|
||||
vhd_geometry = mvhd_get_geometry(vhd);
|
||||
|
||||
if (vhd_geometry.spt > 63) {
|
||||
vhd_geometry.cyl = mvhd_calc_size_sectors(&vhd_geometry) / (16 * 63);
|
||||
vhd_geometry.heads = 16;
|
||||
vhd_geometry.spt = 63;
|
||||
_86box_geometry.cyl = mvhd_calc_size_sectors(&vhd_geometry) / (16 * 63);
|
||||
_86box_geometry.heads = 16;
|
||||
_86box_geometry.spt = 63;
|
||||
} else {
|
||||
_86box_geometry.cyl = vhd_geometry.cyl;
|
||||
_86box_geometry.heads = vhd_geometry.heads;
|
||||
_86box_geometry.spt = vhd_geometry.spt;
|
||||
}
|
||||
|
||||
|
||||
mvhd_close(vhd);
|
||||
}
|
||||
|
||||
return vhd_geometry;
|
||||
return _86box_geometry;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -409,7 +415,7 @@ HarddiskDialog::onCreateNewFile()
|
||||
} else if (img_format >= IMG_FMT_VHD_FIXED) { /* VHD file */
|
||||
file.close();
|
||||
|
||||
MVHDGeom _86box_geometry {};
|
||||
_86BoxGeom _86box_geometry {};
|
||||
int block_size = ui->comboBoxBlockSize->currentIndex() == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL;
|
||||
switch (img_format) {
|
||||
case IMG_FMT_VHD_FIXED:
|
||||
@@ -493,10 +499,14 @@ HarddiskDialog::onCreateNewFile()
|
||||
}
|
||||
|
||||
static void
|
||||
adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry)
|
||||
adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry, _86BoxGeom *_86box_geometry)
|
||||
{
|
||||
if (vhd_geometry->spt <= 63)
|
||||
if (vhd_geometry->spt <= 63) {
|
||||
_86box_geometry->cyl = vhd_geometry->cyl;
|
||||
_86box_geometry->heads = vhd_geometry->heads;
|
||||
_86box_geometry->spt = vhd_geometry->spt;
|
||||
return;
|
||||
}
|
||||
|
||||
int desired_sectors = vhd_geometry->cyl * vhd_geometry->heads * vhd_geometry->spt;
|
||||
if (desired_sectors > 267321600)
|
||||
@@ -506,9 +516,9 @@ adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry)
|
||||
if (remainder > 0)
|
||||
desired_sectors -= remainder;
|
||||
|
||||
vhd_geometry->cyl = desired_sectors / (16 * 63);
|
||||
vhd_geometry->heads = 16;
|
||||
vhd_geometry->spt = 63;
|
||||
_86box_geometry->cyl = desired_sectors / (16 * 63);
|
||||
_86box_geometry->heads = 16;
|
||||
_86box_geometry->spt = 63;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -602,11 +612,12 @@ HarddiskDialog::onExistingFileSelected(const QString &fileName, bool precheck)
|
||||
}
|
||||
}
|
||||
|
||||
MVHDGeom vhd_geom = mvhd_get_geometry(vhd);
|
||||
adjust_vhd_geometry_for_86box(&vhd_geom);
|
||||
cylinders = vhd_geom.cyl;
|
||||
heads = vhd_geom.heads;
|
||||
sectors = vhd_geom.spt;
|
||||
MVHDGeom vhd_geom = mvhd_get_geometry(vhd);
|
||||
_86BoxGeom _86box_geom;
|
||||
adjust_vhd_geometry_for_86box(&vhd_geom, &_86box_geom);
|
||||
cylinders = _86box_geom.cyl;
|
||||
heads = _86box_geom.heads;
|
||||
sectors = _86box_geom.spt;
|
||||
size = static_cast<uint64_t>(cylinders * heads * sectors * 512);
|
||||
mvhd_close(vhd);
|
||||
} else {
|
||||
|
||||
@@ -64,4 +64,10 @@ private:
|
||||
void recalcSelection();
|
||||
};
|
||||
|
||||
typedef struct _86BoxGeom {
|
||||
uint32_t cyl;
|
||||
uint32_t heads;
|
||||
uint32_t spt;
|
||||
} _86BoxGeom;
|
||||
|
||||
#endif // QT_HARDDISKDIALOG_HPP
|
||||
|
||||
@@ -47,11 +47,12 @@ sio_detect_write(uint16_t port, uint8_t val, void *priv)
|
||||
static uint8_t
|
||||
sio_detect_read(uint16_t port, void *priv)
|
||||
{
|
||||
const sio_detect_t *dev = (sio_detect_t *) priv;
|
||||
/*const sio_detect_t *dev = (sio_detect_t *) priv*/;
|
||||
uint8_t ret = 0xff /*dev->regs[port & 1]*/;
|
||||
|
||||
pclog("sio_detect_read : port=%04x = %02X\n", port, dev->regs[port & 1]);
|
||||
pclog("sio_detect_read : port=%04x = %02X\n", port, ret);
|
||||
|
||||
return 0xff /*dev->regs[port & 1]*/;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -41,6 +41,7 @@ add_library(snd OBJECT
|
||||
snd_sb.c
|
||||
snd_sb_dsp.c
|
||||
snd_emu8k.c
|
||||
snd_mmb.c
|
||||
snd_mpu401.c
|
||||
snd_pas16.c
|
||||
snd_sn76489.c
|
||||
@@ -48,8 +49,6 @@ add_library(snd OBJECT
|
||||
snd_wss.c
|
||||
snd_ym7128.c
|
||||
snd_optimc.c
|
||||
esfmu/esfm.c
|
||||
esfmu/esfm_registers.c
|
||||
snd_opl_esfm.c
|
||||
)
|
||||
|
||||
@@ -177,20 +176,22 @@ if(MUNT)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_subdirectory(ayumi)
|
||||
target_link_libraries(86Box ayumi)
|
||||
|
||||
add_subdirectory(esfmu)
|
||||
target_link_libraries(86Box esfmu)
|
||||
|
||||
add_subdirectory(ymfm)
|
||||
target_link_libraries(86Box ymfm)
|
||||
|
||||
if(GUSMAX)
|
||||
target_compile_definitions(snd PRIVATE USE_GUSMAX)
|
||||
endif()
|
||||
|
||||
if(OPL4ML)
|
||||
target_compile_definitions(snd PRIVATE USE_OPL4ML)
|
||||
target_sources(snd PRIVATE midi_opl4.c midi_opl4_yrw801.c)
|
||||
endif()
|
||||
|
||||
find_package(PkgConfig )
|
||||
pkg_check_modules(SERIALPORT libserialport)
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(SERIALPORT libserialport)
|
||||
|
||||
if(SERIALPORT_FOUND OR DEFINED LIBSERIALPORT_ROOT)
|
||||
add_compile_definitions(USE_LIBSERIALPORT=1)
|
||||
|
||||
14
src/sound/ayumi/CMakeLists.txt
Normal file
14
src/sound/ayumi/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# CMake build script.
|
||||
#
|
||||
|
||||
add_library(ayumi STATIC
|
||||
ayumi.c
|
||||
)
|
||||
21
src/sound/ayumi/LICENSE
Normal file
21
src/sound/ayumi/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) Peter Sovietov, http://sovietov.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
338
src/sound/ayumi/ayumi.c
Normal file
338
src/sound/ayumi/ayumi.c
Normal file
@@ -0,0 +1,338 @@
|
||||
/* Author: Peter Sovietov */
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "ayumi.h"
|
||||
|
||||
static const double AY_dac_table[] = {
|
||||
0.0, 0.0,
|
||||
0.00999465934234, 0.00999465934234,
|
||||
0.0144502937362, 0.0144502937362,
|
||||
0.0210574502174, 0.0210574502174,
|
||||
0.0307011520562, 0.0307011520562,
|
||||
0.0455481803616, 0.0455481803616,
|
||||
0.0644998855573, 0.0644998855573,
|
||||
0.107362478065, 0.107362478065,
|
||||
0.126588845655, 0.126588845655,
|
||||
0.20498970016, 0.20498970016,
|
||||
0.292210269322, 0.292210269322,
|
||||
0.372838941024, 0.372838941024,
|
||||
0.492530708782, 0.492530708782,
|
||||
0.635324635691, 0.635324635691,
|
||||
0.805584802014, 0.805584802014,
|
||||
1.0, 1.0
|
||||
};
|
||||
|
||||
static const double YM_dac_table[] = {
|
||||
0.0, 0.0,
|
||||
0.00465400167849, 0.00772106507973,
|
||||
0.0109559777218, 0.0139620050355,
|
||||
0.0169985503929, 0.0200198367285,
|
||||
0.024368657969, 0.029694056611,
|
||||
0.0350652323186, 0.0403906309606,
|
||||
0.0485389486534, 0.0583352407111,
|
||||
0.0680552376593, 0.0777752346075,
|
||||
0.0925154497597, 0.111085679408,
|
||||
0.129747463188, 0.148485542077,
|
||||
0.17666895552, 0.211551079576,
|
||||
0.246387426566, 0.281101701381,
|
||||
0.333730067903, 0.400427252613,
|
||||
0.467383840696, 0.53443198291,
|
||||
0.635172045472, 0.75800717174,
|
||||
0.879926756695, 1.0
|
||||
};
|
||||
|
||||
static void reset_segment(struct ayumi* ay);
|
||||
|
||||
static int update_tone(struct ayumi* ay, int index) {
|
||||
struct tone_channel* ch = &ay->channels[index];
|
||||
ch->tone_counter += 1;
|
||||
if (ch->tone_counter >= ch->tone_period) {
|
||||
ch->tone_counter = 0;
|
||||
ch->tone ^= 1;
|
||||
}
|
||||
return ch->tone;
|
||||
}
|
||||
|
||||
static int update_noise(struct ayumi* ay) {
|
||||
int bit0x3;
|
||||
ay->noise_counter += 1;
|
||||
if (ay->noise_counter >= (ay->noise_period << 1)) {
|
||||
ay->noise_counter = 0;
|
||||
bit0x3 = ((ay->noise ^ (ay->noise >> 3)) & 1);
|
||||
ay->noise = (ay->noise >> 1) | (bit0x3 << 16);
|
||||
}
|
||||
return ay->noise & 1;
|
||||
}
|
||||
|
||||
static void slide_up(struct ayumi* ay) {
|
||||
ay->envelope += 1;
|
||||
if (ay->envelope > 31) {
|
||||
ay->envelope_segment ^= 1;
|
||||
reset_segment(ay);
|
||||
}
|
||||
}
|
||||
|
||||
static void slide_down(struct ayumi* ay) {
|
||||
ay->envelope -= 1;
|
||||
if (ay->envelope < 0) {
|
||||
ay->envelope_segment ^= 1;
|
||||
reset_segment(ay);
|
||||
}
|
||||
}
|
||||
|
||||
static void hold_top(struct ayumi* ay) {
|
||||
(void) ay;
|
||||
}
|
||||
|
||||
static void hold_bottom(struct ayumi* ay) {
|
||||
(void) ay;
|
||||
}
|
||||
|
||||
static void (* const Envelopes[][2])(struct ayumi*) = {
|
||||
{slide_down, hold_bottom},
|
||||
{slide_down, hold_bottom},
|
||||
{slide_down, hold_bottom},
|
||||
{slide_down, hold_bottom},
|
||||
{slide_up, hold_bottom},
|
||||
{slide_up, hold_bottom},
|
||||
{slide_up, hold_bottom},
|
||||
{slide_up, hold_bottom},
|
||||
{slide_down, slide_down},
|
||||
{slide_down, hold_bottom},
|
||||
{slide_down, slide_up},
|
||||
{slide_down, hold_top},
|
||||
{slide_up, slide_up},
|
||||
{slide_up, hold_top},
|
||||
{slide_up, slide_down},
|
||||
{slide_up, hold_bottom}
|
||||
};
|
||||
|
||||
static void reset_segment(struct ayumi* ay) {
|
||||
if (Envelopes[ay->envelope_shape][ay->envelope_segment] == slide_down
|
||||
|| Envelopes[ay->envelope_shape][ay->envelope_segment] == hold_top) {
|
||||
ay->envelope = 31;
|
||||
return;
|
||||
}
|
||||
ay->envelope = 0;
|
||||
}
|
||||
|
||||
int update_envelope(struct ayumi* ay) {
|
||||
ay->envelope_counter += 1;
|
||||
if (ay->envelope_counter >= ay->envelope_period) {
|
||||
ay->envelope_counter = 0;
|
||||
Envelopes[ay->envelope_shape][ay->envelope_segment](ay);
|
||||
}
|
||||
return ay->envelope;
|
||||
}
|
||||
|
||||
static void update_mixer(struct ayumi* ay) {
|
||||
int i;
|
||||
int out;
|
||||
int noise = update_noise(ay);
|
||||
int envelope = update_envelope(ay);
|
||||
ay->left = 0;
|
||||
ay->right = 0;
|
||||
for (i = 0; i < TONE_CHANNELS; i += 1) {
|
||||
out = (update_tone(ay, i) | ay->channels[i].t_off) & (noise | ay->channels[i].n_off);
|
||||
out *= ay->channels[i].e_on ? envelope : ay->channels[i].volume * 2 + 1;
|
||||
ay->left += ay->dac_table[out] * ay->channels[i].pan_left;
|
||||
ay->right += ay->dac_table[out] * ay->channels[i].pan_right;
|
||||
}
|
||||
}
|
||||
|
||||
int ayumi_configure(struct ayumi* ay, int is_ym, double clock_rate, int sr) {
|
||||
int i;
|
||||
memset(ay, 0, sizeof(struct ayumi));
|
||||
ay->step = clock_rate / (sr * 8 * DECIMATE_FACTOR);
|
||||
ay->dac_table = is_ym ? YM_dac_table : AY_dac_table;
|
||||
ay->noise = 1;
|
||||
ayumi_set_envelope(ay, 1);
|
||||
for (i = 0; i < TONE_CHANNELS; i += 1) {
|
||||
ayumi_set_tone(ay, i, 1);
|
||||
}
|
||||
return ay->step < 1;
|
||||
}
|
||||
|
||||
void ayumi_set_pan(struct ayumi* ay, int index, double pan, int is_eqp) {
|
||||
if (is_eqp) {
|
||||
ay->channels[index].pan_left = sqrt(1 - pan);
|
||||
ay->channels[index].pan_right = sqrt(pan);
|
||||
} else {
|
||||
ay->channels[index].pan_left = 1 - pan;
|
||||
ay->channels[index].pan_right = pan;
|
||||
}
|
||||
}
|
||||
|
||||
void ayumi_set_tone(struct ayumi* ay, int index, int period) {
|
||||
period &= 0xfff;
|
||||
ay->channels[index].tone_period = (period == 0) | period;
|
||||
}
|
||||
|
||||
void ayumi_set_noise(struct ayumi* ay, int period) {
|
||||
period &= 0x1f;
|
||||
ay->noise_period = (period == 0) | period;
|
||||
}
|
||||
|
||||
void ayumi_set_mixer(struct ayumi* ay, int index, int t_off, int n_off, int e_on) {
|
||||
ay->channels[index].t_off = t_off & 1;
|
||||
ay->channels[index].n_off = n_off & 1;
|
||||
ay->channels[index].e_on = e_on;
|
||||
}
|
||||
|
||||
void ayumi_set_volume(struct ayumi* ay, int index, int volume) {
|
||||
ay->channels[index].volume = volume & 0xf;
|
||||
}
|
||||
|
||||
void ayumi_set_envelope(struct ayumi* ay, int period) {
|
||||
period &= 0xffff;
|
||||
ay->envelope_period = (period == 0) | period;
|
||||
}
|
||||
|
||||
void ayumi_set_envelope_shape(struct ayumi* ay, int shape) {
|
||||
ay->envelope_shape = shape & 0xf;
|
||||
ay->envelope_counter = 0;
|
||||
ay->envelope_segment = 0;
|
||||
reset_segment(ay);
|
||||
}
|
||||
|
||||
static double decimate(double* x) {
|
||||
double y = -0.0000046183113992051936 * (x[1] + x[191]) +
|
||||
-0.00001117761640887225 * (x[2] + x[190]) +
|
||||
-0.000018610264502005432 * (x[3] + x[189]) +
|
||||
-0.000025134586135631012 * (x[4] + x[188]) +
|
||||
-0.000028494281690666197 * (x[5] + x[187]) +
|
||||
-0.000026396828793275159 * (x[6] + x[186]) +
|
||||
-0.000017094212558802156 * (x[7] + x[185]) +
|
||||
0.000023798193576966866 * (x[9] + x[183]) +
|
||||
0.000051281160242202183 * (x[10] + x[182]) +
|
||||
0.00007762197826243427 * (x[11] + x[181]) +
|
||||
0.000096759426664120416 * (x[12] + x[180]) +
|
||||
0.00010240229300393402 * (x[13] + x[179]) +
|
||||
0.000089344614218077106 * (x[14] + x[178]) +
|
||||
0.000054875700118949183 * (x[15] + x[177]) +
|
||||
-0.000069839082210680165 * (x[17] + x[175]) +
|
||||
-0.0001447966132360757 * (x[18] + x[174]) +
|
||||
-0.00021158452917708308 * (x[19] + x[173]) +
|
||||
-0.00025535069106550544 * (x[20] + x[172]) +
|
||||
-0.00026228714374322104 * (x[21] + x[171]) +
|
||||
-0.00022258805927027799 * (x[22] + x[170]) +
|
||||
-0.00013323230495695704 * (x[23] + x[169]) +
|
||||
0.00016182578767055206 * (x[25] + x[167]) +
|
||||
0.00032846175385096581 * (x[26] + x[166]) +
|
||||
0.00047045611576184863 * (x[27] + x[165]) +
|
||||
0.00055713851457530944 * (x[28] + x[164]) +
|
||||
0.00056212565121518726 * (x[29] + x[163]) +
|
||||
0.00046901918553962478 * (x[30] + x[162]) +
|
||||
0.00027624866838952986 * (x[31] + x[161]) +
|
||||
-0.00032564179486838622 * (x[33] + x[159]) +
|
||||
-0.00065182310286710388 * (x[34] + x[158]) +
|
||||
-0.00092127787309319298 * (x[35] + x[157]) +
|
||||
-0.0010772534348943575 * (x[36] + x[156]) +
|
||||
-0.0010737727700273478 * (x[37] + x[155]) +
|
||||
-0.00088556645390392634 * (x[38] + x[154]) +
|
||||
-0.00051581896090765534 * (x[39] + x[153]) +
|
||||
0.00059548767193795277 * (x[41] + x[151]) +
|
||||
0.0011803558710661009 * (x[42] + x[150]) +
|
||||
0.0016527320270369871 * (x[43] + x[149]) +
|
||||
0.0019152679330965555 * (x[44] + x[148]) +
|
||||
0.0018927324805381538 * (x[45] + x[147]) +
|
||||
0.0015481870327877937 * (x[46] + x[146]) +
|
||||
0.00089470695834941306 * (x[47] + x[145]) +
|
||||
-0.0010178225878206125 * (x[49] + x[143]) +
|
||||
-0.0020037400552054292 * (x[50] + x[142]) +
|
||||
-0.0027874356824117317 * (x[51] + x[141]) +
|
||||
-0.003210329988021943 * (x[52] + x[140]) +
|
||||
-0.0031540624117984395 * (x[53] + x[139]) +
|
||||
-0.0025657163651900345 * (x[54] + x[138]) +
|
||||
-0.0014750752642111449 * (x[55] + x[137]) +
|
||||
0.0016624165446378462 * (x[57] + x[135]) +
|
||||
0.0032591192839069179 * (x[58] + x[134]) +
|
||||
0.0045165685815867747 * (x[59] + x[133]) +
|
||||
0.0051838984346123896 * (x[60] + x[132]) +
|
||||
0.0050774264697459933 * (x[61] + x[131]) +
|
||||
0.0041192521414141585 * (x[62] + x[130]) +
|
||||
0.0023628575417966491 * (x[63] + x[129]) +
|
||||
-0.0026543507866759182 * (x[65] + x[127]) +
|
||||
-0.0051990251084333425 * (x[66] + x[126]) +
|
||||
-0.0072020238234656924 * (x[67] + x[125]) +
|
||||
-0.0082672928192007358 * (x[68] + x[124]) +
|
||||
-0.0081033739572956287 * (x[69] + x[123]) +
|
||||
-0.006583111539570221 * (x[70] + x[122]) +
|
||||
-0.0037839040415292386 * (x[71] + x[121]) +
|
||||
0.0042781252851152507 * (x[73] + x[119]) +
|
||||
0.0084176358598320178 * (x[74] + x[118]) +
|
||||
0.01172566057463055 * (x[75] + x[117]) +
|
||||
0.013550476647788672 * (x[76] + x[116]) +
|
||||
0.013388189369997496 * (x[77] + x[115]) +
|
||||
0.010979501242341259 * (x[78] + x[114]) +
|
||||
0.006381274941685413 * (x[79] + x[113]) +
|
||||
-0.007421229604153888 * (x[81] + x[111]) +
|
||||
-0.01486456304340213 * (x[82] + x[110]) +
|
||||
-0.021143584622178104 * (x[83] + x[109]) +
|
||||
-0.02504275058758609 * (x[84] + x[108]) +
|
||||
-0.025473530942547201 * (x[85] + x[107]) +
|
||||
-0.021627310017882196 * (x[86] + x[106]) +
|
||||
-0.013104323383225543 * (x[87] + x[105]) +
|
||||
0.017065133989980476 * (x[89] + x[103]) +
|
||||
0.036978919264451952 * (x[90] + x[102]) +
|
||||
0.05823318062093958 * (x[91] + x[101]) +
|
||||
0.079072012081405949 * (x[92] + x[100]) +
|
||||
0.097675998716952317 * (x[93] + x[99]) +
|
||||
0.11236045936950932 * (x[94] + x[98]) +
|
||||
0.12176343577287731 * (x[95] + x[97]) +
|
||||
0.125 * x[96];
|
||||
memcpy(&x[FIR_SIZE - DECIMATE_FACTOR], x, DECIMATE_FACTOR * sizeof(double));
|
||||
return y;
|
||||
}
|
||||
|
||||
void ayumi_process(struct ayumi* ay) {
|
||||
int i;
|
||||
double y1;
|
||||
double* c_left = ay->interpolator_left.c;
|
||||
double* y_left = ay->interpolator_left.y;
|
||||
double* c_right = ay->interpolator_right.c;
|
||||
double* y_right = ay->interpolator_right.y;
|
||||
double* fir_left = &ay->fir_left[FIR_SIZE - ay->fir_index * DECIMATE_FACTOR];
|
||||
double* fir_right = &ay->fir_right[FIR_SIZE - ay->fir_index * DECIMATE_FACTOR];
|
||||
ay->fir_index = (ay->fir_index + 1) % (FIR_SIZE / DECIMATE_FACTOR - 1);
|
||||
for (i = DECIMATE_FACTOR - 1; i >= 0; i -= 1) {
|
||||
ay->x += ay->step;
|
||||
if (ay->x >= 1) {
|
||||
ay->x -= 1;
|
||||
y_left[0] = y_left[1];
|
||||
y_left[1] = y_left[2];
|
||||
y_left[2] = y_left[3];
|
||||
y_right[0] = y_right[1];
|
||||
y_right[1] = y_right[2];
|
||||
y_right[2] = y_right[3];
|
||||
update_mixer(ay);
|
||||
y_left[3] = ay->left;
|
||||
y_right[3] = ay->right;
|
||||
y1 = y_left[2] - y_left[0];
|
||||
c_left[0] = 0.5 * y_left[1] + 0.25 * (y_left[0] + y_left[2]);
|
||||
c_left[1] = 0.5 * y1;
|
||||
c_left[2] = 0.25 * (y_left[3] - y_left[1] - y1);
|
||||
y1 = y_right[2] - y_right[0];
|
||||
c_right[0] = 0.5 * y_right[1] + 0.25 * (y_right[0] + y_right[2]);
|
||||
c_right[1] = 0.5 * y1;
|
||||
c_right[2] = 0.25 * (y_right[3] - y_right[1] - y1);
|
||||
}
|
||||
fir_left[i] = (c_left[2] * ay->x + c_left[1]) * ay->x + c_left[0];
|
||||
fir_right[i] = (c_right[2] * ay->x + c_right[1]) * ay->x + c_right[0];
|
||||
}
|
||||
ay->left = decimate(fir_left);
|
||||
ay->right = decimate(fir_right);
|
||||
}
|
||||
|
||||
static double dc_filter(struct dc_filter* dc, int index, double x) {
|
||||
dc->sum += -dc->delay[index] + x;
|
||||
dc->delay[index] = x;
|
||||
return x - dc->sum / DC_FILTER_SIZE;
|
||||
}
|
||||
|
||||
void ayumi_remove_dc(struct ayumi* ay) {
|
||||
ay->left = dc_filter(&ay->dc_left, ay->dc_index, ay->left);
|
||||
ay->right = dc_filter(&ay->dc_right, ay->dc_index, ay->right);
|
||||
ay->dc_index = (ay->dc_index + 1) & (DC_FILTER_SIZE - 1);
|
||||
}
|
||||
71
src/sound/ayumi/ayumi.h
Normal file
71
src/sound/ayumi/ayumi.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* Author: Peter Sovietov */
|
||||
|
||||
#ifndef AYUMI_H
|
||||
#define AYUMI_H
|
||||
|
||||
enum {
|
||||
TONE_CHANNELS = 3,
|
||||
DECIMATE_FACTOR = 8,
|
||||
FIR_SIZE = 192,
|
||||
DC_FILTER_SIZE = 1024
|
||||
};
|
||||
|
||||
struct tone_channel {
|
||||
int tone_period;
|
||||
int tone_counter;
|
||||
int tone;
|
||||
int t_off;
|
||||
int n_off;
|
||||
int e_on;
|
||||
int volume;
|
||||
double pan_left;
|
||||
double pan_right;
|
||||
};
|
||||
|
||||
struct interpolator {
|
||||
double c[4];
|
||||
double y[4];
|
||||
};
|
||||
|
||||
struct dc_filter {
|
||||
double sum;
|
||||
double delay[DC_FILTER_SIZE];
|
||||
};
|
||||
|
||||
struct ayumi {
|
||||
struct tone_channel channels[TONE_CHANNELS];
|
||||
int noise_period;
|
||||
int noise_counter;
|
||||
int noise;
|
||||
int envelope_counter;
|
||||
int envelope_period;
|
||||
int envelope_shape;
|
||||
int envelope_segment;
|
||||
int envelope;
|
||||
const double* dac_table;
|
||||
double step;
|
||||
double x;
|
||||
struct interpolator interpolator_left;
|
||||
struct interpolator interpolator_right;
|
||||
double fir_left[FIR_SIZE * 2];
|
||||
double fir_right[FIR_SIZE * 2];
|
||||
int fir_index;
|
||||
struct dc_filter dc_left;
|
||||
struct dc_filter dc_right;
|
||||
int dc_index;
|
||||
double left;
|
||||
double right;
|
||||
};
|
||||
|
||||
int ayumi_configure(struct ayumi* ay, int is_ym, double clock_rate, int sr);
|
||||
void ayumi_set_pan(struct ayumi* ay, int index, double pan, int is_eqp);
|
||||
void ayumi_set_tone(struct ayumi* ay, int index, int period);
|
||||
void ayumi_set_noise(struct ayumi* ay, int period);
|
||||
void ayumi_set_mixer(struct ayumi* ay, int index, int t_off, int n_off, int e_on);
|
||||
void ayumi_set_volume(struct ayumi* ay, int index, int volume);
|
||||
void ayumi_set_envelope(struct ayumi* ay, int period);
|
||||
void ayumi_set_envelope_shape(struct ayumi* ay, int shape);
|
||||
void ayumi_process(struct ayumi* ay);
|
||||
void ayumi_remove_dc(struct ayumi* ay);
|
||||
|
||||
#endif
|
||||
15
src/sound/esfmu/CMakeLists.txt
Normal file
15
src/sound/esfmu/CMakeLists.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# CMake build script.
|
||||
#
|
||||
|
||||
add_library(esfmu STATIC
|
||||
esfm.c
|
||||
esfm_registers.c
|
||||
)
|
||||
@@ -650,15 +650,7 @@ cs423x_pnp_enable(cs423x_t *dev, uint8_t update_rom, uint8_t update_hwconfig)
|
||||
isapnp_update_card_rom(dev->pnp_card, &dev->ram_data[dev->pnp_offset], dev->pnp_size);
|
||||
|
||||
/* Disable PnP key if the PKD bit is set, or if it was disabled by command 0x55. */
|
||||
/* But wait! The TriGem Delhi-III BIOS sends command 0x55, and its behavior doesn't
|
||||
line up with real hardware (still listed in the POST summary and seen by software).
|
||||
Disable the PnP key disabling mechanism until someone figures something out. */
|
||||
#if 0
|
||||
isapnp_enable_card(dev->pnp_card, ((dev->ram_data[0x4002] & 0x20) || !dev->pnp_enable) ? ISAPNP_CARD_NO_KEY : ISAPNP_CARD_ENABLE);
|
||||
#else
|
||||
if ((dev->ram_data[0x4002] & 0x20) || !dev->pnp_enable)
|
||||
pclog("CS423x: Attempted to disable PnP key\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Update some register bits based on the config data in RAM if requested. */
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
#include <86box/sound.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#ifdef USE_GUSMAX
|
||||
# include <86box/snd_ad1848.h>
|
||||
#endif /*USE_GUSMAX */
|
||||
#include <86box/snd_ad1848.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
@@ -145,11 +143,9 @@ typedef struct gus_t {
|
||||
|
||||
uint8_t usrr;
|
||||
|
||||
#ifdef USE_GUSMAX
|
||||
uint8_t max_ctrl;
|
||||
|
||||
ad1848_t ad1848;
|
||||
#endif /*USE_GUSMAX */
|
||||
} gus_t;
|
||||
|
||||
static int gus_gf1_irqs[8] = { -1, 2, 5, 3, 7, 11, 12, 15 };
|
||||
@@ -257,9 +253,7 @@ writegus(uint16_t addr, uint8_t val, void *priv)
|
||||
int d;
|
||||
int old;
|
||||
uint16_t port;
|
||||
#ifdef USE_GUSMAX
|
||||
uint16_t csioport;
|
||||
#endif /*USE_GUSMAX */
|
||||
|
||||
if ((addr == 0x388) || (addr == 0x389))
|
||||
port = addr;
|
||||
@@ -607,10 +601,9 @@ writegus(uint16_t addr, uint8_t val, void *priv)
|
||||
gus->irq_midi = gus->irq;
|
||||
} else
|
||||
gus->irq_midi = gus_midi_irqs[(val >> 3) & 7];
|
||||
#ifdef USE_GUSMAX
|
||||
|
||||
if (gus->type == GUS_MAX)
|
||||
ad1848_setirq(&gus->ad1848, gus->irq);
|
||||
#endif /*USE_GUSMAX */
|
||||
|
||||
gus->sb_nmi = val & 0x80;
|
||||
} else {
|
||||
@@ -623,10 +616,9 @@ writegus(uint16_t addr, uint8_t val, void *priv)
|
||||
gus->dma2 = gus->dma;
|
||||
} else
|
||||
gus->dma2 = gus_dmas[(val >> 3) & 7];
|
||||
#ifdef USE_GUSMAX
|
||||
|
||||
if (gus->type == GUS_MAX)
|
||||
ad1848_setdma(&gus->ad1848, gus->dma2);
|
||||
#endif /*USE_GUSMAX */
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
@@ -684,7 +676,6 @@ writegus(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 0x306:
|
||||
case 0x706:
|
||||
#ifdef USE_GUSMAX
|
||||
if (gus->type == GUS_MAX) {
|
||||
if (gus->dma >= 4)
|
||||
val |= 0x10;
|
||||
@@ -704,7 +695,6 @@ writegus(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /*USE_GUSMAX */
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -756,11 +746,9 @@ readgus(uint16_t addr, void *priv)
|
||||
return val;
|
||||
|
||||
case 0x20F:
|
||||
#ifdef USE_GUSMAX
|
||||
if (gus->type == GUS_MAX)
|
||||
val = 0x02;
|
||||
else
|
||||
#endif /*USE_GUSMAX */
|
||||
val = 0x00;
|
||||
break;
|
||||
|
||||
@@ -879,11 +867,9 @@ readgus(uint16_t addr, void *priv)
|
||||
break;
|
||||
case 0x306:
|
||||
case 0x706:
|
||||
#ifdef USE_GUSMAX
|
||||
if (gus->type == GUS_MAX)
|
||||
val = 0x0a; /* GUS MAX */
|
||||
else
|
||||
#endif /*USE_GUSMAX */
|
||||
val = 0xff; /*Pre 3.7 - no mixer*/
|
||||
break;
|
||||
|
||||
@@ -1183,24 +1169,20 @@ gus_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
gus_t *gus = (gus_t *) priv;
|
||||
|
||||
#ifdef USE_GUSMAX
|
||||
if ((gus->type == GUS_MAX) && (gus->max_ctrl))
|
||||
ad1848_update(&gus->ad1848);
|
||||
#endif /*USE_GUSMAX */
|
||||
|
||||
gus_update(gus);
|
||||
|
||||
for (int c = 0; c < len * 2; c++) {
|
||||
#ifdef USE_GUSMAX
|
||||
if ((gus->type == GUS_MAX) && (gus->max_ctrl))
|
||||
buffer[c] += (int32_t) (gus->ad1848.buffer[c] / 2);
|
||||
#endif /*USE_GUSMAX */
|
||||
buffer[c] += (int32_t) gus->buffer[c & 1][c >> 1];
|
||||
}
|
||||
|
||||
#ifdef USE_GUSMAX
|
||||
if ((gus->type == GUS_MAX) && (gus->max_ctrl))
|
||||
gus->ad1848.pos = 0;
|
||||
#endif /*USE_GUSMAX */
|
||||
|
||||
gus->pos = 0;
|
||||
}
|
||||
|
||||
@@ -1333,9 +1315,7 @@ gus_reset(void *priv)
|
||||
|
||||
gus->usrr = 0;
|
||||
|
||||
#ifdef USE_GUSMAX
|
||||
gus->max_ctrl = 0;
|
||||
#endif /*USE_GUSMAX */
|
||||
|
||||
gus->irq_state = 0;
|
||||
gus->midi_irq_state = 0;
|
||||
@@ -1373,7 +1353,7 @@ gus_init(UNUSED(const device_t *info))
|
||||
|
||||
gus->uart_out = 1;
|
||||
|
||||
gus->type = device_get_config_int("type");
|
||||
gus->type = info->local;
|
||||
|
||||
gus->base = device_get_config_hex16("base");
|
||||
|
||||
@@ -1382,7 +1362,6 @@ gus_init(UNUSED(const device_t *info))
|
||||
io_sethandler(0x0506 + gus->base, 0x0001, readgus, NULL, NULL, writegus, NULL, NULL, gus);
|
||||
io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL, gus);
|
||||
|
||||
#ifdef USE_GUSMAX
|
||||
if (gus->type == GUS_MAX) {
|
||||
ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231);
|
||||
ad1848_setirq(&gus->ad1848, 5);
|
||||
@@ -1390,7 +1369,6 @@ gus_init(UNUSED(const device_t *info))
|
||||
io_sethandler(0x10C + gus->base, 4,
|
||||
ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &gus->ad1848);
|
||||
}
|
||||
#endif /*USE_GUSMAX */
|
||||
|
||||
timer_add(&gus->samp_timer, gus_poll_wave, gus, 1);
|
||||
timer_add(&gus->timer_1, gus_poll_timer_1, gus, 1);
|
||||
@@ -1423,31 +1401,12 @@ gus_speed_changed(void *priv)
|
||||
else
|
||||
gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14]));
|
||||
|
||||
#ifdef USE_GUSMAX
|
||||
if ((gus->type == GUS_MAX) && (gus->max_ctrl))
|
||||
ad1848_speed_changed(&gus->ad1848);
|
||||
#endif /*USE_GUSMAX */
|
||||
}
|
||||
|
||||
static const device_config_t gus_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "type",
|
||||
.description = "GUS type",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Classic", .value = GUS_CLASSIC },
|
||||
#ifdef USE_GUSMAX
|
||||
{ .description = "MAX", .value = GUS_MAX },
|
||||
#endif /*USE_GUSMAX */
|
||||
{ NULL }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "base",
|
||||
.description = "Address",
|
||||
@@ -1502,7 +1461,21 @@ const device_t gus_device = {
|
||||
.name = "Gravis UltraSound",
|
||||
.internal_name = "gus",
|
||||
.flags = DEVICE_ISA16,
|
||||
.local = 0,
|
||||
.local = GUS_CLASSIC,
|
||||
.init = gus_init,
|
||||
.close = gus_close,
|
||||
.reset = gus_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = gus_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = gus_config
|
||||
};
|
||||
|
||||
const device_t gus_max_device = {
|
||||
.name = "Gravis UltraSound MAX",
|
||||
.internal_name = "gus",
|
||||
.flags = DEVICE_ISA16,
|
||||
.local = GUS_MAX,
|
||||
.init = gus_init,
|
||||
.close = gus_close,
|
||||
.reset = gus_reset,
|
||||
|
||||
339
src/sound/snd_mmb.c
Normal file
339
src/sound/snd_mmb.c
Normal file
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Mindscape Music Board emulation.
|
||||
*
|
||||
* Authors: Roy Baer, <https://pcem-emulator.co.uk/>
|
||||
* Jasmine Iwanek, <jriwanek@gmail.com>
|
||||
*
|
||||
* Copyright 2025 Roy Baer.
|
||||
* Copyright 2025 Jasmine Iwanek.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/sound.h>
|
||||
//#i nclude "cpu.h"
|
||||
#include "ayumi/ayumi.h"
|
||||
#include <86box/snd_mmb.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#ifdef ENABLE_MMB_LOG
|
||||
int mmb_do_log = ENABLE_MMB_LOG;
|
||||
|
||||
static void
|
||||
mmb_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (mmb_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define mmb_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
void
|
||||
mmb_update(mmb_t *mmb)
|
||||
{
|
||||
for (; mmb->pos < sound_pos_global; mmb->pos++) {
|
||||
ayumi_process(&mmb->first.chip);
|
||||
ayumi_process(&mmb->second.chip);
|
||||
|
||||
ayumi_remove_dc(&mmb->first.chip);
|
||||
ayumi_remove_dc(&mmb->second.chip);
|
||||
|
||||
mmb->buffer[mmb->pos << 1] = (mmb->first.chip.left + mmb->second.chip.left) * 16000;
|
||||
mmb->buffer[(mmb->pos << 1) + 1] = (mmb->first.chip.right + mmb->second.chip.right) * 16000;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mmb_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
mmb_t *mmb = (mmb_t *) priv;
|
||||
|
||||
mmb_update(mmb);
|
||||
|
||||
for (int c = 0; c < len * 2; c++)
|
||||
buffer[c] += mmb->buffer[c];
|
||||
|
||||
mmb->pos = 0;
|
||||
}
|
||||
|
||||
void
|
||||
mmb_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
mmb_t *mmb = (mmb_t *) priv;
|
||||
|
||||
mmb_update(mmb);
|
||||
|
||||
mmb_log("mmb_write(%04X): activity now: %02X\n", addr, val);
|
||||
|
||||
switch (addr & 3) {
|
||||
case 0:
|
||||
mmb->first.index = val;
|
||||
break;
|
||||
case 2:
|
||||
mmb->second.index = val;
|
||||
break;
|
||||
case 1:
|
||||
case 3:
|
||||
{
|
||||
ay_3_891x_t *ay = ((addr & 2) == 0) ? &mmb->first : &mmb->second;
|
||||
|
||||
switch (ay->index) {
|
||||
case 0:
|
||||
ay->regs[0] = val;
|
||||
ayumi_set_tone(&ay->chip, 0, (ay->regs[1] << 8) | ay->regs[0]);
|
||||
break;
|
||||
case 1:
|
||||
ay->regs[1] = val & 0xf;
|
||||
ayumi_set_tone(&ay->chip, 0, (ay->regs[1] << 8) | ay->regs[0]);
|
||||
break;
|
||||
case 2:
|
||||
ay->regs[2] = val;
|
||||
ayumi_set_tone(&ay->chip, 1, (ay->regs[3] << 8) | ay->regs[2]);
|
||||
break;
|
||||
case 3:
|
||||
ay->regs[3] = val & 0xf;
|
||||
ayumi_set_tone(&ay->chip, 1, (ay->regs[3] << 8) | ay->regs[2]);
|
||||
break;
|
||||
case 4:
|
||||
ay->regs[4] = val;
|
||||
ayumi_set_tone(&ay->chip, 2, (ay->regs[5] << 8) | ay->regs[4]);
|
||||
break;
|
||||
case 5:
|
||||
ay->regs[5] = val & 0xf;
|
||||
ayumi_set_tone(&ay->chip, 2, (ay->regs[5] << 8) | ay->regs[4]);
|
||||
break;
|
||||
case 6:
|
||||
ay->regs[6] = val & 0x1f;
|
||||
ayumi_set_noise(&ay->chip, ay->regs[6]);
|
||||
break;
|
||||
case 7:
|
||||
ay->regs[7] = val;
|
||||
ayumi_set_mixer(&ay->chip, 0, val & 1, (val >> 3) & 1, (ay->regs[8] >> 4) & 1);
|
||||
ayumi_set_mixer(&ay->chip, 1, (val >> 1) & 1, (val >> 4) & 1, (ay->regs[9] >> 4) & 1);
|
||||
ayumi_set_mixer(&ay->chip, 2, (val >> 2) & 1, (val >> 5) & 1, (ay->regs[10] >> 4) & 1);
|
||||
break;
|
||||
case 8:
|
||||
ay->regs[8] = val;
|
||||
ayumi_set_volume(&ay->chip, 0, val & 0xf);
|
||||
ayumi_set_mixer(&ay->chip, 0, ay->regs[7] & 1, (ay->regs[7] >> 3) & 1, (val >> 4) & 1);
|
||||
break;
|
||||
case 9:
|
||||
ay->regs[9] = val;
|
||||
ayumi_set_volume(&ay->chip, 1, val & 0xf);
|
||||
ayumi_set_mixer(&ay->chip, 1, (ay->regs[7] >> 1) & 1, (ay->regs[7] >> 4) & 1, (val >> 4) & 1);
|
||||
break;
|
||||
case 10:
|
||||
ay->regs[10] = val;
|
||||
ayumi_set_volume(&ay->chip, 2, val & 0xf);
|
||||
ayumi_set_mixer(&ay->chip, 2, (ay->regs[7] >> 2) & 1, (ay->regs[7] >> 5) & 1, (val >> 4) & 1);
|
||||
break;
|
||||
case 11:
|
||||
ay->regs[11] = val;
|
||||
ayumi_set_envelope(&ay->chip, (ay->regs[12] >> 8) | ay->regs[11]);
|
||||
break;
|
||||
case 12:
|
||||
ay->regs[12] = val;
|
||||
ayumi_set_envelope(&ay->chip, (ay->regs[12] >> 8) | ay->regs[11]);
|
||||
break;
|
||||
case 13:
|
||||
ay->regs[13] = val;
|
||||
ayumi_set_envelope_shape(&ay->chip, val & 0xf);
|
||||
break;
|
||||
case 14:
|
||||
ay->regs[14] = val;
|
||||
break;
|
||||
case 15:
|
||||
ay->regs[15] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
mmb_read(uint16_t addr, void *priv)
|
||||
{
|
||||
mmb_t *mmb = (mmb_t *) priv;
|
||||
ay_3_891x_t *ay = ((addr & 2) == 0) ? &mmb->first : &mmb->second;
|
||||
uint8_t ret = 0;
|
||||
|
||||
switch (ay->index) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
ret = ay->regs[ay->index];
|
||||
break;
|
||||
case 14:
|
||||
if (ay->regs[7] & 0x40)
|
||||
ret = ay->regs[14];
|
||||
break;
|
||||
case 15:
|
||||
if (ay->regs[7] & 0x80)
|
||||
ret = ay->regs[15];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
mmb_log("mmb_read(%04X): activity now: %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *
|
||||
mmb_init(UNUSED(const device_t *info))
|
||||
{
|
||||
mmb_t *mmb = calloc(1, sizeof(mmb_t));
|
||||
# if 0
|
||||
uint16_t addr = (device_get_config_int("addr96") << 6) | (device_get_config_int("addr52") << 2);
|
||||
#else
|
||||
uint16_t addr = 0x300;
|
||||
|
||||
#endif
|
||||
sound_add_handler(mmb_get_buffer, mmb);
|
||||
|
||||
ayumi_configure(&mmb->first.chip, 0, MMB_CLOCK, MMB_FREQ);
|
||||
ayumi_configure(&mmb->second.chip, 0, MMB_CLOCK, MMB_FREQ);
|
||||
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
ayumi_set_pan(&mmb->first.chip, i, 0.5, 1);
|
||||
ayumi_set_pan(&mmb->second.chip, i, 0.5, 1);
|
||||
}
|
||||
|
||||
io_sethandler(addr, 0x0004,
|
||||
mmb_read, NULL, NULL,
|
||||
mmb_write, NULL, NULL,
|
||||
mmb);
|
||||
|
||||
return mmb;
|
||||
}
|
||||
|
||||
void
|
||||
mmb_close(void *priv)
|
||||
{
|
||||
mmb_t *mmb = (mmb_t *) priv;
|
||||
|
||||
free(mmb);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
#if 0
|
||||
static device_config_t mmb_config[] = {
|
||||
{
|
||||
.name = "addr96",
|
||||
.description = "Base address A9...A6",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 12,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "0000", .value = 0 },
|
||||
{ .description = "0001", .value = 1 },
|
||||
{ .description = "0010", .value = 2 },
|
||||
{ .description = "0011", .value = 3 },
|
||||
{ .description = "0100", .value = 4 },
|
||||
{ .description = "0101", .value = 5 },
|
||||
{ .description = "0110", .value = 6 },
|
||||
{ .description = "0111", .value = 7 },
|
||||
{ .description = "1000", .value = 8 },
|
||||
{ .description = "1001", .value = 9 },
|
||||
{ .description = "1010", .value = 10 },
|
||||
{ .description = "1011", .value = 11 },
|
||||
{ .description = "1100", .value = 12 },
|
||||
{ .description = "1101", .value = 13 },
|
||||
{ .description = "1110", .value = 14 },
|
||||
{ .description = "1111", .value = 15 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "addr52",
|
||||
.description = "Base address A5...A2",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "0000", .value = 0 },
|
||||
{ .description = "0001", .value = 1 },
|
||||
{ .description = "0010", .value = 2 },
|
||||
{ .description = "0011", .value = 3 },
|
||||
{ .description = "0100", .value = 4 },
|
||||
{ .description = "0101", .value = 5 },
|
||||
{ .description = "0110", .value = 6 },
|
||||
{ .description = "0111", .value = 7 },
|
||||
{ .description = "1000", .value = 8 },
|
||||
{ .description = "1001", .value = 9 },
|
||||
{ .description = "1010", .value = 10 },
|
||||
{ .description = "1011", .value = 11 },
|
||||
{ .description = "1100", .value = 12 },
|
||||
{ .description = "1101", .value = 13 },
|
||||
{ .description = "1110", .value = 14 },
|
||||
{ .description = "1111", .value = 15 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{ .type = CONFIG_END }
|
||||
};
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
const device_t mmb_device = {
|
||||
.name = "Mindscape Music Board",
|
||||
.internal_name = "mmb",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = mmb_init,
|
||||
.close = mmb_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
#if 0
|
||||
.config = mmb_config
|
||||
#else
|
||||
.config = NULL
|
||||
#endif
|
||||
};
|
||||
@@ -115,6 +115,7 @@ static const SOUND_CARD sound_cards[] = {
|
||||
{ &ess_ess0102_pnp_device },
|
||||
{ &ess_ess0968_pnp_device },
|
||||
{ &gus_device },
|
||||
{ &gus_max_device },
|
||||
{ &sb_1_device },
|
||||
{ &sb_15_device },
|
||||
{ &sb_2_device },
|
||||
@@ -137,6 +138,7 @@ static const SOUND_CARD sound_cards[] = {
|
||||
{ &sb_vibra16xv_device },
|
||||
{ &ssi2001_device },
|
||||
{ &entertainer_device },
|
||||
{ &mmb_device },
|
||||
{ &pasplus_device },
|
||||
{ &pas16_device },
|
||||
{ &pas16d_device },
|
||||
|
||||
@@ -4247,7 +4247,10 @@ gd54xx_init(const device_t *info)
|
||||
break;
|
||||
|
||||
case CIRRUS_ID_CLGD5420:
|
||||
romfn = BIOS_GD5420_PATH;
|
||||
if (info->local & 0x200)
|
||||
romfn = NULL;
|
||||
else
|
||||
romfn = BIOS_GD5420_PATH;
|
||||
break;
|
||||
|
||||
case CIRRUS_ID_CLGD5422:
|
||||
@@ -4978,6 +4981,20 @@ const device_t gd5420_isa_device = {
|
||||
.config = gd542x_config,
|
||||
};
|
||||
|
||||
const device_t gd5420_onboard_device = {
|
||||
.name = "Cirrus Logic GD5420 (ISA)",
|
||||
.internal_name = "cl_gd5420_isa",
|
||||
.flags = DEVICE_ISA16,
|
||||
.local = CIRRUS_ID_CLGD5420 | 0x200,
|
||||
.init = gd54xx_init,
|
||||
.close = gd54xx_close,
|
||||
.reset = gd54xx_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = gd54xx_speed_changed,
|
||||
.force_redraw = gd54xx_force_redraw,
|
||||
.config = gd542x_config,
|
||||
};
|
||||
|
||||
const device_t gd5422_isa_device = {
|
||||
.name = "Cirrus Logic GD5422 (ISA)",
|
||||
.internal_name = "cl_gd5422_isa",
|
||||
|
||||
@@ -543,14 +543,33 @@ hercules_init(UNUSED(const device_t *info))
|
||||
|
||||
dev->vram = (uint8_t *) malloc(0x10000);
|
||||
|
||||
switch(device_get_config_int("font")) {
|
||||
case 0:
|
||||
loadfont(FONT_IBM_MDA_437_PATH, 0);
|
||||
break;
|
||||
case 1:
|
||||
loadfont(FONT_IBM_MDA_437_NORDIC_PATH, 0);
|
||||
break;
|
||||
case 2:
|
||||
loadfont(FONT_KAM_PATH, 0);
|
||||
break;
|
||||
case 3:
|
||||
loadfont(FONT_KAMCL16_PATH, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
timer_add(&dev->timer, hercules_poll, dev, 1);
|
||||
|
||||
mem_mapping_add(&dev->mapping, 0xb0000, 0x08000,
|
||||
hercules_read, NULL, NULL, hercules_write, NULL, NULL,
|
||||
NULL /*dev->vram*/, MEM_MAPPING_EXTERNAL, dev);
|
||||
hercules_read, NULL, NULL,
|
||||
hercules_write, NULL, NULL,
|
||||
NULL /*dev->vram*/, MEM_MAPPING_EXTERNAL,
|
||||
dev);
|
||||
|
||||
io_sethandler(0x03b0, 16,
|
||||
hercules_in, NULL, NULL, hercules_out, NULL, NULL, dev);
|
||||
io_sethandler(0x03b0, 0x0010,
|
||||
hercules_in, NULL, NULL,
|
||||
hercules_out, NULL, NULL,
|
||||
dev);
|
||||
|
||||
for (uint16_t c = 0; c < 256; c++) {
|
||||
dev->cols[c][0][0] = dev->cols[c][1][0] = dev->cols[c][1][1] = 16;
|
||||
@@ -642,6 +661,23 @@ static const device_config_t hercules_config[] = {
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "font",
|
||||
.description = "Font",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "US (CP 437)", .value = 0 },
|
||||
{ .description = "IBM Nordic (CP 437-Nordic)", .value = 1 },
|
||||
{ .description = "Czech Kamenicky (CP 895) #1", .value = 2 },
|
||||
{ .description = "Czech Kamenicky (CP 895) #2", .value = 3 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
@@ -317,8 +317,32 @@ mda_standalone_init(UNUSED(const device_t *info))
|
||||
|
||||
mda->vram = malloc(0x1000);
|
||||
|
||||
mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, mda);
|
||||
io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda);
|
||||
switch(device_get_config_int("font")) {
|
||||
case 0:
|
||||
loadfont(FONT_IBM_MDA_437_PATH, 0);
|
||||
break;
|
||||
case 1:
|
||||
loadfont(FONT_IBM_MDA_437_NORDIC_PATH, 0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
loadfont(FONT_KAM_PATH, 0);
|
||||
break;
|
||||
case 3:
|
||||
loadfont(FONT_KAMCL16_PATH, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
mem_mapping_add(&mda->mapping, 0xb0000, 0x08000,
|
||||
mda_read, NULL, NULL,
|
||||
mda_write, NULL, NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL,
|
||||
mda);
|
||||
|
||||
io_sethandler(0x03b0, 0x0010,
|
||||
mda_in, NULL, NULL,
|
||||
mda_out, NULL, NULL,
|
||||
mda);
|
||||
|
||||
mda_init(mda);
|
||||
|
||||
@@ -369,6 +393,23 @@ static const device_config_t mda_config[] = {
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "font",
|
||||
.description = "Font",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "US (CP 437)", .value = 0 },
|
||||
{ .description = "IBM Nordic (CP 437-Nordic)", .value = 1 },
|
||||
{ .description = "Czech Kamenicky (CP 895) #1", .value = 2 },
|
||||
{ .description = "Czech Kamenicky (CP 895) #2", .value = 3 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
@@ -332,7 +332,7 @@ video_reset(int card)
|
||||
card, machine_has_flags(machine, MACHINE_VIDEO) ? 1 : 0);
|
||||
|
||||
monitor_index_global = 0;
|
||||
loadfont("roms/video/mda/mda.rom", 0);
|
||||
loadfont(FONT_IBM_MDA_437_PATH, 0);
|
||||
|
||||
for (uint8_t i = 1; i < GFXCARD_MAX; i ++) {
|
||||
if ((card != VID_NONE) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY) &&
|
||||
|
||||
@@ -1006,76 +1006,73 @@ video_force_resize_set_monitor(uint8_t res, int monitor_index)
|
||||
}
|
||||
|
||||
void
|
||||
loadfont_common(FILE *f, int format)
|
||||
loadfont_common(FILE *fp, int format)
|
||||
{
|
||||
int c;
|
||||
int d;
|
||||
|
||||
switch (format) {
|
||||
case 0: /* MDA */
|
||||
for (c = 0; c < 256; c++)
|
||||
for (d = 0; d < 8; d++)
|
||||
fontdatm[c][d] = fgetc(f) & 0xff;
|
||||
for (c = 0; c < 256; c++)
|
||||
for (d = 0; d < 8; d++)
|
||||
fontdatm[c][d + 8] = fgetc(f) & 0xff;
|
||||
(void) fseek(f, 4096 + 2048, SEEK_SET);
|
||||
for (c = 0; c < 256; c++)
|
||||
for (d = 0; d < 8; d++)
|
||||
fontdat[c][d] = fgetc(f) & 0xff;
|
||||
for (uint16_t c = 0; c < 256; c++) /* 8x14 MDA in 8x8 cell (lines 0-7) */
|
||||
for (uint8_t d = 0; d < 8; d++)
|
||||
fontdatm[c][d] = fgetc(fp) & 0xff;
|
||||
for (uint16_t c = 0; c < 256; c++) /* 8x14 MDA in 8x8 cell (lines 8-13 + padding lines) */
|
||||
for (uint8_t d = 0; d < 8; d++)
|
||||
fontdatm[c][d + 8] = fgetc(fp) & 0xff;
|
||||
(void) fseek(fp, 4096 + 2048, SEEK_SET);
|
||||
for (uint16_t c = 0; c < 256; c++)
|
||||
for (uint8_t d = 0; d < 8; d++) /* 8x8 CGA (thick, primary) */
|
||||
fontdat[c][d] = fgetc(fp) & 0xff;
|
||||
break;
|
||||
|
||||
case 1: /* PC200 */
|
||||
for (d = 0; d < 4; d++) {
|
||||
for (uint8_t d = 0; d < 4; d++) {
|
||||
/* There are 4 fonts in the ROM */
|
||||
for (c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */
|
||||
(void) !fread(&fontdatm[256 * d + c][0], 1, 16, f);
|
||||
for (c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */
|
||||
(void) !fread(&fontdat[256 * d + c][0], 1, 8, f);
|
||||
fseek(f, 8, SEEK_CUR);
|
||||
for (uint16_t c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */
|
||||
(void) !fread(&fontdatm[256 * d + c][0], 1, 16, fp);
|
||||
for (uint16_t c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */
|
||||
(void) !fread(&fontdat[256 * d + c][0], 1, 8, fp);
|
||||
fseek(fp, 8, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case 2: /* CGA */
|
||||
for (c = 0; c < 256; c++)
|
||||
for (d = 0; d < 8; d++)
|
||||
fontdat[c][d] = fgetc(f) & 0xff;
|
||||
for (uint16_t c = 0; c < 256; c++)
|
||||
for (uint8_t d = 0; d < 8; d++)
|
||||
fontdat[c][d] = fgetc(fp) & 0xff;
|
||||
break;
|
||||
|
||||
case 3: /* Wyse 700 */
|
||||
for (c = 0; c < 512; c++)
|
||||
for (d = 0; d < 32; d++)
|
||||
fontdatw[c][d] = fgetc(f) & 0xff;
|
||||
for (uint16_t c = 0; c < 512; c++)
|
||||
for (uint8_t d = 0; d < 32; d++)
|
||||
fontdatw[c][d] = fgetc(fp) & 0xff;
|
||||
break;
|
||||
|
||||
case 4: /* MDSI Genius */
|
||||
for (c = 0; c < 256; c++)
|
||||
for (d = 0; d < 16; d++)
|
||||
fontdat8x12[c][d] = fgetc(f) & 0xff;
|
||||
for (uint16_t c = 0; c < 256; c++)
|
||||
for (uint8_t d = 0; d < 16; d++)
|
||||
fontdat8x12[c][d] = fgetc(fp) & 0xff;
|
||||
break;
|
||||
|
||||
case 5: /* Toshiba 3100e */
|
||||
for (d = 0; d < 2048; d += 512) { /* Four languages... */
|
||||
for (c = d; c < d + 256; c++) {
|
||||
(void) !fread(&fontdatm[c][8], 1, 8, f);
|
||||
case 5: /* Toshiba 3100e */
|
||||
for (uint16_t d = 0; d < 2048; d += 512) { /* Four languages... */
|
||||
for (uint16_t c = d; c < d + 256; c++) {
|
||||
(void) !fread(&fontdatm[c][8], 1, 8, fp);
|
||||
}
|
||||
for (c = d + 256; c < d + 512; c++) {
|
||||
(void) !fread(&fontdatm[c][8], 1, 8, f);
|
||||
for (uint16_t c = d + 256; c < d + 512; c++) {
|
||||
(void) !fread(&fontdatm[c][8], 1, 8, fp);
|
||||
}
|
||||
for (c = d; c < d + 256; c++) {
|
||||
(void) !fread(&fontdatm[c][0], 1, 8, f);
|
||||
for (uint16_t c = d; c < d + 256; c++) {
|
||||
(void) !fread(&fontdatm[c][0], 1, 8, fp);
|
||||
}
|
||||
for (c = d + 256; c < d + 512; c++) {
|
||||
(void) !fread(&fontdatm[c][0], 1, 8, f);
|
||||
for (uint16_t c = d + 256; c < d + 512; c++) {
|
||||
(void) !fread(&fontdatm[c][0], 1, 8, fp);
|
||||
}
|
||||
fseek(f, 4096, SEEK_CUR); /* Skip blank section */
|
||||
for (c = d; c < d + 256; c++) {
|
||||
(void) !fread(&fontdat[c][0], 1, 8, f);
|
||||
fseek(fp, 4096, SEEK_CUR); /* Skip blank section */
|
||||
for (uint16_t c = d; c < d + 256; c++) {
|
||||
(void) !fread(&fontdat[c][0], 1, 8, fp);
|
||||
}
|
||||
for (c = d + 256; c < d + 512; c++) {
|
||||
(void) !fread(&fontdat[c][0], 1, 8, f);
|
||||
for (uint16_t c = d + 256; c < d + 512; c++) {
|
||||
(void) !fread(&fontdat[c][0], 1, 8, fp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1087,65 +1084,64 @@ loadfont_common(FILE *f, int format)
|
||||
if (!fontdatksc5601_user)
|
||||
fontdatksc5601_user = malloc(192 * sizeof(dbcs_font_t));
|
||||
|
||||
for (c = 0; c < 16384; c++) {
|
||||
for (d = 0; d < 32; d++)
|
||||
fontdatksc5601[c].chr[d] = fgetc(f) & 0xff;
|
||||
for (uint32_t c = 0; c < 16384; c++) {
|
||||
for (uint8_t d = 0; d < 32; d++)
|
||||
fontdatksc5601[c].chr[d] = fgetc(fp) & 0xff;
|
||||
}
|
||||
break;
|
||||
|
||||
case 7: /* Sigma Color 400 */
|
||||
/* The first 4k of the character ROM holds an 8x8 font */
|
||||
for (c = 0; c < 256; c++) {
|
||||
(void) !fread(&fontdat[c][0], 1, 8, f);
|
||||
fseek(f, 8, SEEK_CUR);
|
||||
for (uint16_t c = 0; c < 256; c++) {
|
||||
(void) !fread(&fontdat[c][0], 1, 8, fp);
|
||||
fseek(fp, 8, SEEK_CUR);
|
||||
}
|
||||
/* The second 4k holds an 8x16 font */
|
||||
for (c = 0; c < 256; c++) {
|
||||
if (fread(&fontdatm[c][0], 1, 16, f) != 16)
|
||||
for (uint16_t c = 0; c < 256; c++) {
|
||||
if (fread(&fontdatm[c][0], 1, 16, fp) != 16)
|
||||
fatal("loadfont(): Error reading 8x16 font in Sigma Color 400 mode, c = %i\n", c);
|
||||
}
|
||||
break;
|
||||
|
||||
case 8: /* Amstrad PC1512, Toshiba T1000/T1200 */
|
||||
for (c = 0; c < 2048; c++) /* Allow up to 2048 chars */
|
||||
for (d = 0; d < 8; d++)
|
||||
fontdat[c][d] = fgetc(f) & 0xff;
|
||||
case 8: /* Amstrad PC1512, Toshiba T1000/T1200 */
|
||||
for (uint16_t c = 0; c < 2048; c++) /* Allow up to 2048 chars */
|
||||
for (uint8_t d = 0; d < 8; d++)
|
||||
fontdat[c][d] = fgetc(fp) & 0xff;
|
||||
break;
|
||||
|
||||
case 9: /* Image Manager 1024 native font */
|
||||
for (c = 0; c < 256; c++)
|
||||
(void) !fread(&fontdat12x18[c][0], 1, 36, f);
|
||||
for (uint16_t c = 0; c < 256; c++)
|
||||
(void) !fread(&fontdat12x18[c][0], 1, 36, fp);
|
||||
break;
|
||||
|
||||
case 10: /* Pravetz */
|
||||
for (c = 0; c < 1024; c++) /* Allow up to 1024 chars */
|
||||
for (d = 0; d < 8; d++)
|
||||
fontdat[c][d] = fgetc(f) & 0xff;
|
||||
case 10: /* Pravetz */
|
||||
for (uint16_t c = 0; c < 1024; c++) /* Allow up to 1024 chars */
|
||||
for (uint8_t d = 0; d < 8; d++)
|
||||
fontdat[c][d] = fgetc(fp) & 0xff;
|
||||
break;
|
||||
|
||||
|
||||
case 11: /* PC200 */
|
||||
for (d = 0; d < 4; d++) {
|
||||
for (uint8_t d = 0; d < 4; d++) {
|
||||
/* There are 4 fonts in the ROM */
|
||||
for (c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */
|
||||
(void) !fread(&fontdatm2[256 * d + c][0], 1, 16, f);
|
||||
for (c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */
|
||||
(void) !fread(&fontdat2[256 * d + c][0], 1, 8, f);
|
||||
fseek(f, 8, SEEK_CUR);
|
||||
for (uint16_t c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */
|
||||
(void) !fread(&fontdatm2[256 * d + c][0], 1, 16, fp);
|
||||
for (uint16_t c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */
|
||||
(void) !fread(&fontdat2[256 * d + c][0], 1, 8, fp);
|
||||
fseek(fp, 8, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
(void) fclose(f);
|
||||
(void) fclose(fp);
|
||||
}
|
||||
|
||||
void
|
||||
loadfont_ex(char *s, int format, int offset)
|
||||
loadfont_ex(char *fn, int format, int offset)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = rom_fopen(s, "rb");
|
||||
fp = rom_fopen(fn, "rb");
|
||||
if (fp == NULL)
|
||||
return;
|
||||
|
||||
@@ -1154,9 +1150,9 @@ loadfont_ex(char *s, int format, int offset)
|
||||
}
|
||||
|
||||
void
|
||||
loadfont(char *s, int format)
|
||||
loadfont(char *fn, int format)
|
||||
{
|
||||
loadfont_ex(s, format, 0);
|
||||
loadfont_ex(fn, format, 0);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
||||
Reference in New Issue
Block a user