Merge remote-tracking branch 'upstream/master' into feature/mtrr

This commit is contained in:
Jasmine Iwanek
2022-11-05 21:26:58 -04:00
66 changed files with 2066 additions and 411 deletions

View File

@@ -1,4 +1,4 @@
name: MinGW64 Makefile
name: MSYS2 Makefile
on:
@@ -16,7 +16,7 @@ on:
jobs:
build:
name: ${{ matrix.environment.msystem }} Makefile build (DEV_BUILD=${{ matrix.dev-build }}, NEW_DYNAREC=${{ matrix.new-dynarec }})
name: MSYS2 Makefile build ${{ matrix.build.name }} ${{ matrix.dynarec.name }} build (${{ matrix.environment.msystem }})
runs-on: windows-latest
@@ -27,8 +27,22 @@ jobs:
strategy:
fail-fast: true
matrix:
dev-build: ['y', 'n']
new-dynarec: ['y', 'n']
build:
- name: Debug
debug: y
dev: n
slug: -Debug
- name: Dev
debug: y
dev: y
slug: -Dev
dynarec:
- name: ODR
new: n
slug: -ODR
- name: NDR
new: y
slug: -NDR
environment:
- msystem: MINGW32
prefix: mingw-w64-i686
@@ -54,5 +68,9 @@ jobs:
${{ matrix.environment.prefix }}-rtmidi
- uses: actions/checkout@v3
- name: make
run: make -fwin/makefile.mingw -j DEV_BUILD=${{ matrix.dev-build }} NEW_DYNAREC=${{ matrix.new-dynarec }} X64=${{ matrix.environment.x64 }} VNC=n
run: make -fwin/makefile.mingw -j DEV_BUILD=${{ matrix.build.dev }} DEBUG=${{ matrix.build.debug }} NEW_DYNAREC=${{ matrix.dynarec.new }} X64=${{ matrix.environment.x64 }} VNC=n
working-directory: ./src
- uses: actions/upload-artifact@v3
with:
name: '86Box${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}'
path: src/86Box.exe

View File

@@ -1362,6 +1362,36 @@ set_screen_size_monitor(int x, int y, int monitor_index)
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x << 1);
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y << 1);
break;
case 4: /* 300% */
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 3);
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 3);
break;
case 5: /* 400% */
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x << 2);
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y << 2);
break;
case 6: /* 500% */
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 5);
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 5);
break;
case 7: /* 600% */
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 6);
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 6);
break;
case 8: /* 700% */
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 7);
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 7);
break;
case 9: /* 800% */
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x << 3);
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y << 3);
break;
}
plat_resize_request(monitors[monitor_index].mon_scrnsz_x, monitors[monitor_index].mon_scrnsz_y, monitor_index);

View File

@@ -13,4 +13,4 @@
# Copyright 2020,2021 David Hrdlička.
#
add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image_viso.c cdrom_image.c)
add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image_viso.c cdrom_image.c cdrom_mitsumi.c)

View File

@@ -322,13 +322,13 @@ cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len)
}
static __inline int
bin2bcd (int x)
bin2bcd(int x)
{
return (x % 10) | ((x / 10) << 4);
}
static __inline int
bcd2bin (int x)
bcd2bin(int x)
{
return (x >> 4) * 10 + (x & 0x0f);
}
@@ -385,9 +385,9 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf)
} else
pos = MSFtoLBA(m, s, f) - 150;
m = (len >> 16) & 0xff;
s = (len >> 8) & 0xff;
f = len & 0xff;
m = (len >> 16) & 0xff;
s = (len >> 8) & 0xff;
f = len & 0xff;
/* NEC CDR-260 speaks BCD. */
if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early)
@@ -524,7 +524,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
b[pos++] = subc.index;
if (msf) {
b[pos] = 0;
b[pos] = 0;
/* NEC CDR-260 speaks BCD. */
if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early) {
@@ -543,7 +543,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
pos += 4;
b[pos] = 0;
b[pos] = 0;
/* NEC CDR-260 speaks BCD. */
if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early) {
@@ -803,7 +803,7 @@ cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type, unsigned char start_tra
return len;
}
/* A new API call for Mitsumi CD-ROM. */
/* New API calls for Mitsumi CD-ROM. */
void
cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf)
{
@@ -827,6 +827,64 @@ cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf)
memset(buf, 0x00, 9);
}
void
cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode)
{
track_info_t ti;
int first_track, last_track;
if (dev != NULL) {
dev->ops->get_tracks(dev, &first_track, &last_track);
dev->ops->get_track_info(dev, *curtoctrk, 0, &ti);
buf[0] = (ti.attr << 4) & 0xf0;
buf[1] = ti.number;
buf[2] = CD_BCD(*curtoctrk + 1);
buf[3] = ti.m;
buf[4] = ti.s;
buf[5] = ti.f;
buf[6] = 0x00;
dev->ops->get_track_info(dev, 1, 0, &ti);
buf[7] = ti.m;
buf[8] = ti.s;
buf[9] = ti.f;
if (*curtoctrk >= (last_track + 1))
*curtoctrk = 0;
else if (mode)
*curtoctrk = *curtoctrk + 1;
} else
memset(buf, 0x00, 10);
}
uint8_t
cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len)
{
track_info_t ti;
if (dev->cd_status == CD_STATUS_DATA_ONLY)
return 0;
cdrom_log("CD-ROM 0: Play Mitsumi audio - %08X %08X\n", pos, len);
dev->ops->get_track_info(dev, pos, 0, &ti);
pos = MSFtoLBA(ti.m, ti.s, ti.f) - 150;
dev->ops->get_track_info(dev, len, 1, &ti);
len = MSFtoLBA(ti.m, ti.s, ti.f) - 150;
/* Do this at this point, since it's at this point that we know the
actual LBA position to start playing from. */
if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) {
cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos);
cdrom_stop(dev);
return 0;
}
dev->seek_pos = pos;
dev->cd_end = len;
dev->cd_status = CD_STATUS_PLAYING;
dev->cd_buflen = 0;
return 1;
}
void
cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type)
{

443
src/cdrom/cdrom_mitsumi.c Normal file
View File

@@ -0,0 +1,443 @@
/*
* 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.
*
* Mitsumi CD-ROM emulation for the ISA bus.
*
*
*
* Author: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2022 Miran Grca.
*/
#include <inttypes.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/io.h>
#include <86box/pic.h>
#include <86box/dma.h>
#include <86box/cdrom.h>
#include <86box/cdrom_mitsumi.h>
#include <86box/plat.h>
#include <86box/sound.h>
#define RAW_SECTOR_SIZE 2352
#define COOKED_SECTOR_SIZE 2048
enum {
STAT_CMD_CHECK = 0x01,
STAT_PLAY_CDDA = 0x02,
STAT_ERROR = 0x04,
STAT_DISK_CDDA = 0x08,
STAT_SPIN = 0x10,
STAT_CHANGE = 0x20,
STAT_READY = 0x40,
STAT_OPEN = 0x80
};
enum {
CMD_GET_INFO = 0x10,
CMD_GET_Q = 0x20,
CMD_GET_STAT = 0x40,
CMD_SET_MODE = 0x50,
CMD_SOFT_RESET = 0x60,
CMD_STOPCDDA = 0x70,
CMD_CONFIG = 0x90,
CMD_SET_VOL = 0xae,
CMD_READ1X = 0xc0,
CMD_READ2X = 0xc1,
CMD_GET_VER = 0xdc,
CMD_STOP = 0xf0,
CMD_EJECT = 0xf6,
CMD_LOCK = 0xfe
};
enum {
MODE_MUTE = 0x01,
MODE_GET_TOC = 0x04,
MODE_STOP = 0x08,
MODE_ECC = 0x20,
MODE_DATA = 0x40
};
enum {
DRV_MODE_STOP,
DRV_MODE_READ,
DRV_MODE_CDDA
};
enum {
FLAG_NODATA = 2,
FLAG_NOSTAT = 4,
FLAG_UNK = 8, //??
FLAG_OPEN = 16
};
enum {
IRQ_DATAREADY = 1,
IRQ_DATACOMP = 2,
IRQ_ERROR = 4
};
typedef struct {
int dma, irq;
int change;
int data;
uint8_t stat;
uint8_t buf[RAW_SECTOR_SIZE];
int buf_count;
int buf_idx;
uint8_t cmdbuf[16];
int cmdbuf_count;
int cmdrd_count;
int cmdbuf_idx;
uint8_t mode;
uint8_t cmd;
uint8_t conf;
uint8_t enable_irq;
uint8_t enable_dma;
uint16_t dmalen;
uint32_t readmsf;
uint32_t readcount;
int locked;
int drvmode;
int cur_toc_track;
int pos;
} mcd_t;
/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong:
there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start
of the audio while audio still plays. With an absolute conversion, the counter is fine. */
#undef MSFtoLBA
#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
#define CD_BCD(x) (((x) % 10) | (((x) / 10) << 4))
#define CD_DCB(x) ((((x) &0xf0) >> 4) * 10 + ((x) &0x0f))
#ifdef ENABLE_MITSUMI_CDROM_LOG
int mitsumi_cdrom_do_log = ENABLE_MITSUMI_CDROM_LOG;
void
mitsumi_cdrom_log(const char *fmt, ...)
{
va_list ap;
if (mitsumi_cdrom_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define mitsumi_cdrom_log(fmt, ...)
#endif
static void
mitsumi_cdrom_reset(mcd_t *dev)
{
cdrom_t *cdrom = &cdrom[0];
dev->stat = cdrom->host_drive ? (STAT_READY | STAT_CHANGE) : 0;
dev->cmdrd_count = 0;
dev->cmdbuf_count = 0;
dev->buf_count = 0;
dev->cur_toc_track = 0;
dev->enable_dma = 0;
dev->enable_irq = 0;
dev->conf = 0;
dev->dmalen = COOKED_SECTOR_SIZE;
dev->locked = 0;
dev->change = 1;
dev->data = 0;
}
static int
mitsumi_cdrom_read_sector(mcd_t *dev, int first)
{
cdrom_t *cdrom = &cdrom[0];
uint8_t status;
int ret;
if (cdrom == NULL)
return 0;
if (dev->drvmode == DRV_MODE_CDDA) {
status = cdrom_mitsumi_audio_play(cdrom, dev->readmsf, dev->readcount);
if (status == 1)
return status;
else
dev->drvmode = DRV_MODE_READ;
}
if ((dev->enable_irq & IRQ_DATACOMP) && !first) {
picint(1 << dev->irq);
}
if (!dev->readcount) {
dev->data = 0;
return 0;
}
cdrom_stop(cdrom);
ret = cdrom_readsector_raw(cdrom, dev->buf, cdrom->seek_pos, 0, 2, 0x10, &dev->readcount);
if (!ret)
return 0;
if (dev->mode & 0x40) {
dev->buf[12] = CD_BCD((dev->readmsf >> 16) & 0xff);
dev->buf[13] = CD_BCD((dev->readmsf >> 8) & 0xff);
}
dev->readmsf = cdrom_lba_to_msf_accurate(cdrom->seek_pos + 1);
dev->buf_count = dev->dmalen + 1;
dev->buf_idx = 0;
dev->data = 1;
if (dev->enable_dma) {
while (dev->pos < dev->readcount) {
dma_channel_write(dev->dma, dev->buf[dev->pos]);
dev->pos++;
}
dev->pos = 0;
}
dev->readcount--;
if ((dev->enable_irq & IRQ_DATAREADY) && first)
picint(1 << dev->irq);
return 1;
}
static uint8_t
mitsumi_cdrom_in(uint16_t port, void *priv)
{
mcd_t *dev = (mcd_t *) priv;
uint8_t ret;
switch (port & 1) {
case 0:
if (dev->cmdbuf_count) {
dev->cmdbuf_count--;
return dev->cmdbuf[dev->cmdbuf_idx++];
} else if (dev->buf_count) {
ret = (dev->buf_idx < RAW_SECTOR_SIZE) ? dev->buf[dev->buf_idx] : 0;
dev->buf_idx++;
dev->buf_count--;
if (!dev->buf_count)
mitsumi_cdrom_read_sector(dev, 0);
return ret;
}
return dev->stat;
case 1:
ret = 0;
picintc(1 << dev->irq);
if (!dev->buf_count || !dev->data || dev->enable_dma)
ret |= FLAG_NODATA;
if (!dev->cmdbuf_count)
ret |= FLAG_NOSTAT;
return ret | FLAG_UNK;
}
return (0xff);
}
static void
mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
{
mcd_t *dev = (mcd_t *) priv;
cdrom_t *cdrom = &cdrom[0];
switch (port & 1) {
case 0:
if (dev->cmdrd_count) {
dev->cmdrd_count--;
switch (dev->cmd) {
case CMD_SET_MODE:
dev->mode = val;
dev->cmdbuf[1] = 0;
dev->cmdbuf_count = 2;
break;
case CMD_LOCK:
dev->locked = val & 1;
dev->cmdbuf[1] = 0;
dev->cmdbuf[2] = 0;
dev->cmdbuf_count = 3;
break;
case CMD_CONFIG:
switch (dev->cmdrd_count) {
case 0:
switch (dev->conf) {
case 0x01:
dev->dmalen |= val;
break;
case 0x02:
dev->enable_dma = val;
break;
case 0x10:
dev->enable_irq = val;
break;
}
dev->cmdbuf[1] = 0;
dev->cmdbuf_count = 2;
dev->conf = 0;
break;
case 1:
if (dev->conf == 1) {
dev->dmalen = val << 8;
break;
}
dev->conf = val;
if (dev->conf == 1)
dev->cmdrd_count++;
break;
}
break;
case CMD_READ1X:
case CMD_READ2X:
switch (dev->cmdrd_count) {
case 0:
dev->readcount |= val;
mitsumi_cdrom_read_sector(dev, 1);
dev->cmdbuf_count = 1;
dev->cmdbuf[0] = STAT_SPIN | STAT_READY;
break;
case 1:
dev->readcount |= (val << 8);
break;
case 2:
dev->readcount = (val << 16);
break;
case 5:
dev->readmsf = 0;
case 4:
case 3:
dev->readmsf |= CD_DCB(val) << ((dev->cmdrd_count - 3) << 3);
break;
}
break;
}
if (!dev->cmdrd_count)
dev->stat = cdrom->host_drive ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0;
return;
}
dev->cmd = val;
dev->cmdbuf_idx = 0;
dev->cmdrd_count = 0;
dev->cmdbuf_count = 1;
dev->cmdbuf[0] = cdrom->host_drive ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0;
dev->data = 0;
switch (val) {
case CMD_GET_INFO:
if (cdrom->host_drive) {
cdrom_get_track_buffer(cdrom, &(dev->cmdbuf[1]));
dev->cmdbuf_count = 10;
dev->readcount = 0;
} else {
dev->cmdbuf_count = 1;
dev->cmdbuf[0] = STAT_CMD_CHECK;
}
break;
case CMD_GET_Q:
if (cdrom->host_drive) {
cdrom_get_q(cdrom, &(dev->cmdbuf[1]), &dev->cur_toc_track, dev->mode & MODE_GET_TOC);
dev->cmdbuf_count = 11;
dev->readcount = 0;
} else {
dev->cmdbuf_count = 1;
dev->cmdbuf[0] = STAT_CMD_CHECK;
}
break;
case CMD_GET_STAT:
dev->change = 0;
break;
case CMD_SET_MODE:
dev->cmdrd_count = 1;
break;
case CMD_STOPCDDA:
case CMD_STOP:
cdrom_stop(cdrom);
dev->drvmode = DRV_MODE_STOP;
dev->cur_toc_track = 0;
break;
case CMD_CONFIG:
dev->cmdrd_count = 2;
break;
case CMD_READ1X:
case CMD_READ2X:
if (cdrom->host_drive) {
dev->readcount = 0;
dev->drvmode = (val == CMD_READ1X) ? DRV_MODE_CDDA : DRV_MODE_READ;
dev->cmdrd_count = 6;
} else {
dev->cmdbuf_count = 1;
dev->cmdbuf[0] = STAT_CMD_CHECK;
}
break;
case CMD_GET_VER:
dev->cmdbuf[1] = 1;
dev->cmdbuf[2] = 'D';
dev->cmdbuf[3] = 0;
dev->cmdbuf_count = 4;
break;
case CMD_EJECT:
cdrom_stop(cdrom);
cdrom_eject(0);
dev->readcount = 0;
break;
case CMD_LOCK:
dev->cmdrd_count = 1;
break;
default:
dev->cmdbuf[0] = dev->stat | STAT_CMD_CHECK;
break;
}
break;
case 1:
mitsumi_cdrom_reset(dev);
break;
}
}
static void *
mitsumi_cdrom_init(const device_t *info)
{
mcd_t *dev;
dev = malloc(sizeof(mcd_t));
memset(dev, 0x00, sizeof(mcd_t));
dev->irq = 5;
dev->dma = 5;
io_sethandler(0x310, 2,
mitsumi_cdrom_in, NULL, NULL, mitsumi_cdrom_out, NULL, NULL, dev);
mitsumi_cdrom_reset(dev);
return dev;
}
static void
mitsumi_cdrom_close(void *priv)
{
mcd_t *dev = (mcd_t *) priv;
if (dev) {
free(dev);
dev = NULL;
}
}
const device_t mitsumi_cdrom_device = {
"Mitsumi CD-ROM interface",
"mcd",
DEVICE_ISA | DEVICE_AT,
0,
mitsumi_cdrom_init,
mitsumi_cdrom_close,
NULL,
{ NULL },
NULL,
NULL,
NULL
};

View File

@@ -34,7 +34,8 @@
typedef struct
{
uint8_t idx, regs[16];
uint8_t idx, is_pci,
regs[16];
} opti5x7_t;
#ifdef ENABLE_OPTI5X7_LOG
@@ -75,11 +76,20 @@ opti5x7_shadow_map(int cur_reg, opti5x7_t *dev)
0 1 Read from DRAM (write protected)
*/
if (cur_reg == 0x06) {
mem_set_mem_state_both(0xe0000, 0x10000, ((dev->regs[6] & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
mem_set_mem_state_both(0xf0000, 0x10000, ((dev->regs[6] & 4) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 8) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
if (dev->is_pci) {
mem_set_mem_state_cpu_both(0xe0000, 0x10000, ((dev->regs[6] & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
mem_set_mem_state_cpu_both(0xf0000, 0x10000, ((dev->regs[6] & 4) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 8) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
} else {
mem_set_mem_state_both(0xe0000, 0x10000, ((dev->regs[6] & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
mem_set_mem_state_both(0xf0000, 0x10000, ((dev->regs[6] & 4) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & 8) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
}
} else {
for (int i = 0; i < 4; i++)
mem_set_mem_state_both(0xc0000 + ((cur_reg & 1) << 16) + (i << 14), 0x4000, ((dev->regs[cur_reg] & (1 << (2 * i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[cur_reg] & (2 << (2 * i))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
for (int i = 0; i < 4; i++) {
if (dev->is_pci)
mem_set_mem_state_cpu_both(0xc0000 + ((cur_reg & 1) << 16) + (i << 14), 0x4000, ((dev->regs[cur_reg] & (1 << (2 * i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[cur_reg] & (2 << (2 * i))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
else
mem_set_mem_state_both(0xc0000 + ((cur_reg & 1) << 16) + (i << 14), 0x4000, ((dev->regs[cur_reg] & (1 << (2 * i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[cur_reg] & (2 << (2 * i))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
}
}
flushmmucache_nopc();
@@ -161,6 +171,8 @@ opti5x7_init(const device_t *info)
opti5x7_t *dev = (opti5x7_t *) malloc(sizeof(opti5x7_t));
memset(dev, 0, sizeof(opti5x7_t));
dev->is_pci = info->local;
io_sethandler(0x0022, 0x0001, opti5x7_read, NULL, NULL, opti5x7_write, NULL, NULL, dev);
io_sethandler(0x0024, 0x0001, opti5x7_read, NULL, NULL, opti5x7_write, NULL, NULL, dev);
@@ -182,3 +194,17 @@ const device_t opti5x7_device = {
.force_redraw = NULL,
.config = NULL
};
const device_t opti5x7_pci_device = {
.name = "OPTi 82C5x6/82C5x7 (PCI)",
.internal_name = "opti5x7_pci",
.flags = 0,
.local = 1,
.init = opti5x7_init,
.close = opti5x7_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -6,14 +6,15 @@
*
* This file is part of the 86Box distribution.
*
* Implementation of the OPTi 82C822 VESA Local Bus to PCI Bridge Interface.
* Implementation of the OPTi 82C822 VESA Local Bus to PCI
* Bridge Interface.
*
*
* Authors: Tiseno100,
*
* Copyright 2021 Tiseno100.
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2022 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -22,22 +23,30 @@
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/io.h>
#include <86box/apm.h>
#include <86box/dma.h>
#include <86box/mem.h>
#include <86box/smram.h>
#include <86box/pci.h>
#include <86box/timer.h>
#include <86box/pic.h>
#include <86box/pit.h>
#include <86box/port_92.h>
#include <86box/hdc_ide.h>
#include <86box/hdc.h>
#include <86box/machine.h>
#include <86box/chipset.h>
#include <86box/spd.h>
/* Shadow RAM */
#define SYSTEM_READ ((dev->pci_conf[0x44] & 2) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
#define SYSTEM_WRITE ((dev->pci_conf[0x44] & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)
#define SHADOW_READ ((dev->pci_conf[cur_reg] & (1 << (4 + i))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
#define SHADOW_WRITE ((dev->pci_conf[cur_reg] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)
typedef struct
{
uint8_t irq_convert,
pci_regs[256];
} opti822_t;
// #define ENABLE_OPTI822_LOG 1
#ifdef ENABLE_OPTI822_LOG
int opti822_do_log = ENABLE_OPTI822_LOG;
@@ -47,247 +56,321 @@ opti822_log(const char *fmt, ...)
va_list ap;
if (opti822_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define opti822_log(fmt, ...)
#define opti822_log(fmt, ...)
#endif
typedef struct opti822_t {
uint8_t pci_conf[256];
} opti822_t;
int opti822_irq_routing[7] = { 5, 9, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f };
void
opti822_shadow(int cur_reg, opti822_t *dev)
/* NOTE: We currently cheat and pass all PCI shadow RAM accesses to ISA as well.
This is because we currently do not have separate access mappings for
PCI and ISA at all. */
static void
opti822_recalc(opti822_t *dev)
{
if (cur_reg == 0x44)
mem_set_mem_state_both(0xf0000, 0x10000, SYSTEM_READ | SYSTEM_WRITE);
else
for (int i = 0; i < 4; i++)
mem_set_mem_state_both(0xe0000 - (((cur_reg & 3) - 1) << 16) + (i << 14), 0x4000, SHADOW_READ | SHADOW_WRITE);
int i, reg, bit_r, bit_w;
int state;
uint32_t base;
flushmmucache_nopc();
for (i = 0; i < 12; i++) {
base = 0x000c0000 + (i << 14);
reg = 0x44 + ((i >> 2) ^ 3);
bit_w = (i & 3);
bit_r = bit_w + 4;
bit_w = 1 << bit_w;
bit_r = 1 << bit_r;
state = (dev->pci_regs[reg] & bit_w) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
state |= (dev->pci_regs[reg] & bit_r) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
mem_set_mem_state_bus_both(base, 0x00004000, state);
}
state = (dev->pci_regs[0x44] & 0x01) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
state |= (dev->pci_regs[0x44] & 0x02) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
mem_set_mem_state_bus_both(0x000f0000, 0x00010000, state);
}
/* NOTE: We cheat here. The real ALi M1435 uses a level to edge triggered IRQ converter
when the most siginificant bit is set. We work around that by manipulating the
emulated PIC's ELCR register. */
static void
opti822_update_irqs(opti822_t *dev, int set)
{
uint8_t val;
int i, reg;
int shift, irq;
int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 };
pic_t *temp_pic;
// dev->irq_convert = (dev->pci_regs[0x53] & 0x08);
dev->irq_convert = 1;
for (i = 0; i < 16; i++) {
reg = 0x88 + (i >> 1);
shift = (i & 1) << 2;
val = (dev->pci_regs[reg] >> shift) & 0x0f;
irq = irq_map[val & 0x07];
if (irq == -1)
continue;
temp_pic = (irq >= 8) ? &pic2 : &pic;
irq &= 7;
if (dev->irq_convert && set && (val & 0x08))
temp_pic->elcr |= (1 << irq);
else
temp_pic->elcr &= ~(1 << irq);
}
}
static void
opti822_write(int func, int addr, uint8_t val, void *priv)
opti822_pci_write(int func, int addr, uint8_t val, void *priv)
{
opti822_t *dev = (opti822_t *) priv;
int irq, irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 };
int pin, slot;
switch (func) {
case 0x04: /* Command Register */
dev->pci_conf[addr] = val & 0x40;
opti822_log("opti822_write(%02X, %02X, %02X)\n", func, addr, val);
if (func > 0)
return;
switch (addr) {
/* Command Register */
case 0x04:
dev->pci_regs[addr] = (val & 0x40) | 0x07;
break;
case 0x05: /* Command Register */
dev->pci_conf[addr] = val & 1;
/* Status Register */
case 0x06:
if (!(dev->pci_regs[0x52] & 0x04))
dev->pci_regs[addr] = (val & 0x80);
break;
case 0x07:
dev->pci_regs[addr] &= ~(val & 0xf9);
break;
case 0x06: /* Status Register */
dev->pci_conf[addr] |= val & 0xc0;
break;
case 0x07: /* Status Register */
dev->pci_conf[addr] = val & 0xa9;
/* Master Latency Timer Register */
case 0x0d:
dev->pci_regs[addr] = val;
break;
case 0x40:
dev->pci_conf[addr] = val & 0xc0;
dev->pci_regs[addr] = (val & 0xc0) | 0x01;
break;
case 0x41:
dev->pci_conf[addr] = val & 0xcf;
/* TODO: Bit 15th enable the PCI Bridge when 1. */
dev->pci_regs[addr] = val & 0xcf;
break;
case 0x42:
dev->pci_conf[addr] = val & 0xf8;
dev->pci_regs[addr] = val & 0xf8;
break;
case 0x43:
dev->pci_conf[addr] = val;
dev->pci_regs[addr] = val;
break;
case 0x44: /* Shadow RAM */
case 0x45:
case 0x46:
case 0x47:
dev->pci_conf[addr] = (addr == 0x44) ? (val & 0xcb) : val;
opti822_shadow(addr, dev);
case 0x44:
dev->pci_regs[addr] = val & 0xcb;
opti822_recalc(dev);
break;
case 0x45 ... 0x47:
dev->pci_regs[addr] = val;
opti822_recalc(dev);
break;
/* Memory hole stuff. */
case 0x48 ... 0x51:
dev->pci_regs[addr] = val;
break;
case 0x48:
case 0x49:
case 0x4a:
case 0x4b:
case 0x4c:
case 0x4d:
case 0x4e:
case 0x4f:
case 0x50:
case 0x51:
case 0x52:
dev->pci_regs[addr] = val;
break;
case 0x53:
case 0x54:
case 0x55:
case 0x56:
case 0x57:
dev->pci_conf[addr] = val;
dev->pci_regs[addr] = val;
opti822_update_irqs(dev, 0);
opti822_update_irqs(dev, 1);
break;
case 0x54 ... 0x57:
dev->pci_regs[addr] = val;
break;
case 0x58:
dev->pci_conf[addr] = val & 0xfc;
dev->pci_regs[addr] = val & 0xfc;
break;
case 0x59 ... 0x5b:
dev->pci_regs[addr] = val;
break;
case 0x59:
case 0x5a:
case 0x5b:
case 0x5c:
case 0x5d:
case 0x5e:
case 0x5f:
dev->pci_conf[addr] = val;
case 0x5c ... 0x5f:
dev->pci_regs[addr] = val;
break;
case 0x60:
dev->pci_conf[addr] = val & 0xfc;
dev->pci_regs[addr] = val & 0xfc;
break;
case 0x61 ... 0x63:
dev->pci_regs[addr] = val;
break;
case 0x61:
case 0x62:
case 0x63:
case 0x64:
case 0x65:
case 0x66:
case 0x67:
dev->pci_conf[addr] = val;
case 0x64 ... 0x67:
dev->pci_regs[addr] = val;
break;
case 0x68:
dev->pci_conf[addr] = val & 0xfc;
dev->pci_regs[addr] = val & 0xfc;
break;
case 0x69 ... 0x6b:
dev->pci_regs[addr] = val;
break;
case 0x69:
case 0x6a:
case 0x6b:
case 0x6c:
case 0x6d:
case 0x6e:
case 0x6f:
dev->pci_conf[addr] = val;
case 0x6c ... 0x6f:
dev->pci_regs[addr] = val;
break;
case 0x70:
dev->pci_conf[addr] = val & 0xfc;
dev->pci_regs[addr] = val & 0xfc;
break;
case 0x71:
case 0x72:
case 0x73:
dev->pci_conf[addr] = val;
case 0x71 ... 0x73:
dev->pci_regs[addr] = val;
break;
case 0x74:
dev->pci_conf[addr] = val & 0xfc;
dev->pci_regs[addr] = val & 0xf8;
break;
/* ROMCS# and NVMCS# stuff. */
case 0x75:
dev->pci_regs[addr] = val;
break;
case 0x76:
dev->pci_conf[addr] = val;
dev->pci_regs[addr] = val;
break;
case 0x77:
dev->pci_conf[addr] = val & 0xe7;
dev->pci_regs[addr] = val;
break;
/* Enabling of memory blocks at ISA bus. */
case 0x78:
dev->pci_conf[addr] = val;
dev->pci_regs[addr] = val;
break;
case 0x79:
dev->pci_conf[addr] = val & 0xfc;
dev->pci_regs[addr] = val & 0xfc;
break;
case 0x7a:
case 0x7b:
case 0x7c:
case 0x7d:
case 0x7e:
dev->pci_conf[addr] = val;
dev->pci_regs[addr] = val;
break;
case 0x7b ... 0x7c:
dev->pci_regs[addr] = val;
break;
case 0x7d ... 0x7e:
dev->pci_regs[addr] = val;
break;
case 0x7f:
dev->pci_conf[addr] = val & 3;
dev->pci_regs[addr] = val & 0x03;
break;
case 0x80:
case 0x81:
case 0x80 ... 0x81:
dev->pci_regs[addr] = val;
break;
case 0x82:
case 0x84:
case 0x85:
dev->pci_regs[addr] = val;
break;
case 0x84 ... 0x85:
dev->pci_regs[addr] = val;
break;
case 0x86:
dev->pci_conf[addr] = val;
dev->pci_regs[addr] = val;
break;
case 0x88: /* PCI IRQ Routing */
case 0x89: /* Very hacky implementation. Needs surely a rewrite after */
case 0x8a: /* a PCI rework happens. */
case 0x8b:
case 0x8c:
case 0x8d:
case 0x8e:
case 0x8f:
dev->pci_conf[addr] = val;
if (addr % 2) {
pci_set_irq_routing(PCI_INTB, ((val & 0x0f) != 0) ? opti822_irq_routing[(val & 7) - 1] : PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTA, (((val >> 4) & 0x0f) != 0) ? opti822_irq_routing[((val >> 4) & 7) - 1] : PCI_IRQ_DISABLED);
} else {
pci_set_irq_routing(PCI_INTD, ((val & 0x0f) != 0) ? opti822_irq_routing[(val & 7) - 1] : PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTC, (((val >> 4) & 0x0f) != 0) ? opti822_irq_routing[((val >> 4) & 7) - 1] : PCI_IRQ_DISABLED);
}
break;
case 0x88 ... 0x8f:
dev->pci_regs[addr] = val;
opti822_update_irqs(dev, 0);
irq = irq_map[val & 0x07];
pin = 4 - ((addr & 0x01) << 1);
slot = ((addr & 0x06) >> 1);
if (irq >= 0) {
opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq);
pci_set_irq_routing(pin + (slot << 2), irq);
pci_set_irq_level(pin + (slot << 2), !!(val & 0x07));
} else {
opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31);
pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED);
}
irq = irq_map[(val >> 4) & 0x07];
pin = 3 - ((addr & 0x01) << 1);
slot = ((addr & 0x06) >> 1);
if (irq >= 0) {
opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq);
pci_set_irq_routing(pin + (slot << 2), irq);
pci_set_irq_level(pin + (slot << 2), !!((val >> 4) & 0x07));
} else {
opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31);
pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED);
}
opti822_update_irqs(dev, 1);
break;
}
opti822_log("OPTI822: dev->pci_conf[%02x] = %02x\n", addr, dev->pci_conf[addr]);
}
static uint8_t
opti822_read(int func, int addr, void *priv)
opti822_pci_read(int func, int addr, void *priv)
{
opti822_t *dev = (opti822_t *) priv;
return dev->pci_conf[addr];
uint8_t ret;
ret = 0xff;
if (func == 0)
ret = dev->pci_regs[addr];
opti822_log("opti822_read(%02X, %02X) = %02X\n", func, addr, ret);
return ret;
}
static void
opti822_reset(void *priv)
{
opti822_t *dev = (opti822_t *) priv;
int i;
dev->pci_conf[0x00] = 0x45;
dev->pci_conf[0x01] = 0x10;
dev->pci_conf[0x02] = 0x22;
dev->pci_conf[0x03] = 0xc8;
dev->pci_conf[0x04] = 7;
dev->pci_conf[0x06] = 0x40;
dev->pci_conf[0x07] = 1;
dev->pci_conf[0x08] = 1;
dev->pci_conf[0x0b] = 6;
dev->pci_conf[0x0d] = 0x20;
dev->pci_conf[0x40] = 1;
dev->pci_conf[0x43] = 0x20;
dev->pci_conf[0x52] = 6;
dev->pci_conf[0x53] = 0x90;
memset(dev->pci_regs, 0, 256);
dev->pci_regs[0x00] = 0x45; dev->pci_regs[0x01] = 0x10; /*OPTi*/
dev->pci_regs[0x02] = 0x22; dev->pci_regs[0x03] = 0xc8; /*82C822 PCIB*/
dev->pci_regs[0x04] = 0x07;
dev->pci_regs[0x06] = 0x80;
dev->pci_regs[0x07] = 0x02;
dev->pci_regs[0x08] = 0x01;
dev->pci_regs[0x0b] = 0x06;
dev->pci_regs[0x0d] = 0x20;
dev->pci_regs[0x40] = 0x01; dev->pci_regs[0x41] = 0x0c;
dev->pci_regs[0x43] = 0x02;
dev->pci_regs[0x52] = 0x06;
dev->pci_regs[0x53] = 0x90;
dev->irq_convert = 1 /*0*/;
for (i = 0; i < 16; i++)
pci_set_irq_routing(PCI_INTA + i, PCI_IRQ_DISABLED);
}
static void
opti822_close(void *priv)
opti822_close(void *p)
{
opti822_t *dev = (opti822_t *) priv;
opti822_t *dev = (opti822_t *)p;
free(dev);
}
@@ -298,7 +381,7 @@ opti822_init(const device_t *info)
opti822_t *dev = (opti822_t *) malloc(sizeof(opti822_t));
memset(dev, 0, sizeof(opti822_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_read, opti822_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_pci_read, opti822_pci_write, dev);
opti822_reset(dev);

View File

@@ -35,6 +35,7 @@
typedef struct
{
uint8_t idx, forced_green,
is_pci,
regs[256],
scratch[2];
@@ -78,7 +79,10 @@ opti895_recalc(opti895_t *dev)
shflags = MEM_READ_INTERNAL | MEM_WRITE_DISABLED;
}
mem_set_mem_state_both(0xf0000, 0x10000, shflags);
if (dev->is_pci)
mem_set_mem_state_cpu_both(0xf0000, 0x10000, shflags);
else
mem_set_mem_state_both(0xf0000, 0x10000, shflags);
for (i = 0; i < 8; i++) {
base = 0xd0000 + (i << 14);
@@ -98,7 +102,10 @@ opti895_recalc(opti895_t *dev)
}
}
mem_set_mem_state_both(base, 0x4000, shflags);
if (dev->is_pci)
mem_set_mem_state_cpu_both(base, 0x4000, shflags);
else
mem_set_mem_state_both(base, 0x4000, shflags);
}
for (i = 0; i < 4; i++) {
@@ -119,7 +126,10 @@ opti895_recalc(opti895_t *dev)
}
}
mem_set_mem_state_both(base, 0x4000, shflags);
if (dev->is_pci)
mem_set_mem_state_cpu_both(base, 0x4000, shflags);
else
mem_set_mem_state_both(base, 0x4000, shflags);
}
flushmmucache_nopc();
@@ -232,6 +242,8 @@ opti895_init(const device_t *info)
io_sethandler(0x0022, 0x0003, opti895_read, NULL, NULL, opti895_write, NULL, NULL, dev);
dev->is_pci = info->local;
dev->scratch[0] = dev->scratch[1] = 0xff;
dev->regs[0x01] = 0xc0;
@@ -276,6 +288,20 @@ const device_t opti802g_device = {
.config = NULL
};
const device_t opti802g_pci_device = {
.name = "OPTi 82C802G (PCI)",
.internal_name = "opti802g_pci",
.flags = 0,
.local = 1,
.init = opti895_init,
.close = opti895_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t opti895_device = {
.name = "OPTi 82C895",
.internal_name = "opti895",

View File

@@ -123,8 +123,8 @@ load_general(void)
force_43 = !!ini_section_get_int(cat, "force_43", 0);
scale = ini_section_get_int(cat, "scale", 1);
if (scale > 3)
scale = 3;
if (scale > 9)
scale = 9;
dpi_scale = ini_section_get_int(cat, "dpi_scale", 1);
enable_overscan = !!ini_section_get_int(cat, "enable_overscan", 0);

View File

@@ -568,7 +568,8 @@ reset_808x(int hard)
load_cs(0xFFFF);
cpu_state.pc = 0;
cpu_state.flags |= MD_FLAG;
if (is_nec)
cpu_state.flags |= MD_FLAG;
rammask = 0xfffff;
prefetching = 1;
@@ -963,7 +964,7 @@ interrupt(uint16_t addr)
pfq_clear();
ovr_seg = NULL;
access(39, 16);
tempf = cpu_state.flags & ((is_nec && cpu_state.inside_emulation_mode) ? 0x8fd7 : 0x0fd7);
tempf = cpu_state.flags & (is_nec ? 0x8fd7 : 0x0fd7);
push(&tempf);
cpu_state.flags &= ~(I_FLAG | T_FLAG);
access(40, 16);
@@ -1003,7 +1004,7 @@ custom_nmi(void)
pfq_clear();
ovr_seg = NULL;
access(39, 16);
tempf = cpu_state.flags & 0x0fd7;
tempf = cpu_state.flags & (is_nec ? 0x8fd7 : 0x0fd7);
push(&tempf);
cpu_state.flags &= ~(I_FLAG | T_FLAG);
access(40, 16);
@@ -1083,7 +1084,10 @@ rep_action(int bits)
if (irq_pending() && (repeating != 0)) {
access(71, bits);
pfq_clear();
set_ip(cpu_state.pc - 2);
if (is_nec && (ovr_seg != NULL))
set_ip(cpu_state.pc - 3);
else
set_ip(cpu_state.pc - 2);
t = 0;
}
if (t == 0) {
@@ -2743,12 +2747,18 @@ execx86(int cycs)
break;
case 0x9C: /*PUSHF*/
access(33, 16);
tempw = cpu_state.flags & ((is_nec && cpu_state.inside_emulation_mode) ? (MD_FLAG | 0x0fd7) : 0x0fd7);
if (is_nec)
tempw = (cpu_state.flags & 0x8fd7) | 0x7000;
else
tempw = (cpu_state.flags & 0x0fd7) | 0xf000;
push(&tempw);
break;
case 0x9D: /*POPF*/
access(25, 16);
cpu_state.flags = pop() | 2;
if (is_nec)
cpu_state.flags = pop() | 0x8002;
else
cpu_state.flags = pop() | 0x0002;
wait(1, 0);
break;
case 0x9E: /*SAHF*/
@@ -3015,7 +3025,10 @@ execx86(int cycs)
access(62, 8);
set_ip(new_ip);
access(45, 8);
cpu_state.flags = pop() | 2 | (!is_nec ? 0 : (!cpu_state.inside_emulation_mode ? MD_FLAG : 0));
if (is_nec)
cpu_state.flags = pop() | 0x8002;
else
cpu_state.flags = pop() | 0x0002;
wait(5, 0);
noint = 1;
nmi_enable = 1;

View File

@@ -293,11 +293,11 @@ static int opPOPFD(uint32_t fetchdat)
else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2;
else cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2;
templ &= (is486) ? 0x3c0000 : 0;
templ &= (is486 || isibm486) ? 0x3c0000 : 0;
templ |= ((cpu_state.eflags&3) << 16);
if (cpu_CR4_mask & CR4_VME) cpu_state.eflags = (templ >> 16) & 0x3f;
else if (CPUID) cpu_state.eflags = (templ >> 16) & 0x27;
else if (is486) cpu_state.eflags = (templ >> 16) & 7;
else if (is486 || isibm486) cpu_state.eflags = (templ >> 16) & 7;
else cpu_state.eflags = (templ >> 16) & 3;
flags_extract();

View File

@@ -87,6 +87,19 @@
#include <86box/hdc.h>
#include <86box/hdd.h>
#define ST506_XT_TYPE_XEBEC 0
#define ST506_XT_TYPE_DTC_5150X 1
#define ST506_XT_TYPE_ST11M 11
#define ST506_XT_TYPE_ST11R 12
#define ST506_XT_TYPE_WD1002A_WX1 21
#define ST506_XT_TYPE_WD1002A_WX1_NOBIOS 22
#define ST506_XT_TYPE_WD1002A_27X 23
#define ST506_XT_TYPE_WD1004A_WX1 24
#define ST506_XT_TYPE_WD1004_27X 25
#define ST506_XT_TYPE_WD1004A_27X 26
#define ST506_XT_TYPE_VICTOR_V86P 27
#define ST506_XT_TYPE_TOSHIBA_T1200 28
#define XEBEC_BIOS_FILE "roms/hdd/st506/ibm_xebec_62x0822_1985.bin"
#define DTC_BIOS_FILE "roms/hdd/st506/dtc_cxd21a.bin"
#define ST11_BIOS_FILE_OLD "roms/hdd/st506/st11_bios_vers_1.7.bin"
@@ -394,7 +407,7 @@ get_chs(hdc_t *dev, drive_t *drive)
/* 6 bits are used for the sector number even on the IBM PC controller. */
dev->sector = dev->command[2] & 0x3f;
dev->count = dev->command[4];
if (((dev->type == 11) || (dev->type == 12)) && (dev->command[0] >= 0xf0))
if (((dev->type == ST506_XT_TYPE_ST11M) || (dev->type == ST506_XT_TYPE_ST11R)) && (dev->command[0] >= 0xf0))
dev->cylinder = 0;
else {
dev->cylinder = dev->command[3] | ((dev->command[2] & 0xc0) << 2);
@@ -565,7 +578,7 @@ st506_callback(void *priv)
break;
case CMD_FORMAT_ST11: /* This is really "Format cylinder 0" */
if ((dev->type < 11) || (dev->type > 12)) {
if ((dev->type < ST506_XT_TYPE_ST11M) || (dev->type > ST506_XT_TYPE_ST11R)) {
st506_error(dev, ERR_BAD_COMMAND);
st506_complete(dev);
break;
@@ -608,7 +621,7 @@ st506_callback(void *priv)
break;
case CMD_GET_GEOMETRY_ST11: /* "Get geometry" is really "Read cylinder 0" */
if ((dev->type < 11) || (dev->type > 12)) {
if ((dev->type < ST506_XT_TYPE_ST11M) || (dev->type > ST506_XT_TYPE_ST11R)) {
st506_error(dev, ERR_BAD_COMMAND);
st506_complete(dev);
break;
@@ -700,11 +713,11 @@ st506_callback(void *priv)
break;
case CMD_SET_GEOMETRY_ST11: /* "Set geometry" is really "Write cylinder 0" */
if (dev->type == 1) {
if (dev->type == ST506_XT_TYPE_DTC_5150X) {
/* DTC sends this... */
st506_complete(dev);
break;
} else if ((dev->type < 11) || (dev->type > 12)) {
} else if ((dev->type < ST506_XT_TYPE_ST11M) || (dev->type > ST506_XT_TYPE_ST11R)) {
st506_error(dev, ERR_BAD_COMMAND);
st506_complete(dev);
break;
@@ -821,7 +834,7 @@ st506_callback(void *priv)
/* For a 615/4/26 we get 666/2/31 geometry. */
st506_xt_log("ST506: drive%i: cyls=%i, heads=%i\n",
dev->drive_sel, drive->cfg_cyl, drive->cfg_hpc);
if ((dev->type >= 23) && (drive->cfg_hpc == 2)) {
if ((dev->type >= ST506_XT_TYPE_VICTOR_V86P) && (drive->cfg_hpc == 2)) {
/*
* On Victor V86P, there's a disagreement between
* the physical geometry, what the controller
@@ -950,7 +963,7 @@ st506_callback(void *priv)
break;
case CMD_INQUIRY_ST11:
if (dev->type == 11 || dev->type == 12)
if (dev->type == ST506_XT_TYPE_ST11M || dev->type == ST506_XT_TYPE_ST11R)
switch (dev->state) {
case STATE_START_COMMAND:
st506_xt_log("ST506: INQUIRY (type=%i)\n", dev->type);
@@ -975,7 +988,7 @@ st506_callback(void *priv)
break;
case CMD_V86P_POWEROFF:
if (dev->type >= 23) {
if (dev->type >= ST506_XT_TYPE_VICTOR_V86P) {
/*
* Main BIOS (not the option ROM on disk) issues this.
* Not much we can do, since we don't have a physical disk
@@ -1017,10 +1030,10 @@ st506_callback(void *priv)
break;
case CMD_SET_STEP_RATE_DTC:
if (dev->type == 1) {
if (dev->type == ST506_XT_TYPE_DTC_5150X) {
/* For DTC, we are done. */
st506_complete(dev);
} else if (dev->type == 11 || dev->type == 12) {
} else if (dev->type == ST506_XT_TYPE_ST11M || dev->type == ST506_XT_TYPE_ST11R) {
/*
* For Seagate ST-11, this is WriteGeometry.
*
@@ -1259,8 +1272,8 @@ mem_write(uint32_t addr, uint8_t val, void *priv)
addr -= dev->bios_addr;
switch (dev->type) {
case 11: /* ST-11M */
case 12: /* ST-11R */
case ST506_XT_TYPE_ST11M: /* ST-11M */
case ST506_XT_TYPE_ST11R: /* ST-11R */
mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */
break;
@@ -1290,7 +1303,7 @@ mem_read(uint32_t addr, void *priv)
addr -= dev->bios_addr;
switch (dev->type) {
case 0: /* Xebec */
case ST506_XT_TYPE_XEBEC: /* Xebec */
if (addr >= 0x001000) {
#ifdef ENABLE_ST506_XT_LOG
st506_xt_log("ST506: Xebec ROM access(0x%06lx)\n", addr);
@@ -1299,7 +1312,7 @@ mem_read(uint32_t addr, void *priv)
}
break;
case 1: /* DTC */
case ST506_XT_TYPE_DTC_5150X: /* DTC */
default:
if (addr >= 0x002000) {
#ifdef ENABLE_ST506_XT_LOG
@@ -1309,8 +1322,8 @@ mem_read(uint32_t addr, void *priv)
}
break;
case 11: /* ST-11M */
case 12: /* ST-11R */
case ST506_XT_TYPE_ST11M: /* ST-11M */
case ST506_XT_TYPE_ST11R: /* ST-11R */
mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */
break;
@@ -1468,20 +1481,20 @@ st506_init(const device_t *info)
dev->nr_err = ERR_NOT_READY;
switch (dev->type) {
case 0: /* Xebec (MFM) */
case ST506_XT_TYPE_XEBEC: /* Xebec (MFM) */
fn = XEBEC_BIOS_FILE;
break;
case 1: /* DTC5150 (MFM) */
case ST506_XT_TYPE_DTC_5150X: /* DTC5150 (MFM) */
fn = DTC_BIOS_FILE;
dev->switches = 0xff;
break;
case 12: /* Seagate ST-11R (RLL) */
case ST506_XT_TYPE_ST11R: /* Seagate ST-11R (RLL) */
dev->spt = RLL_SECTORS;
/*FALLTHROUGH*/
case 11: /* Seagate ST-11M (MFM) */
case ST506_XT_TYPE_ST11M: /* Seagate ST-11M (MFM) */
dev->nr_err = ERR_NOT_AVAILABLE;
dev->switches = 0x01; /* fixed */
dev->misc = device_get_config_int("revision");
@@ -1511,7 +1524,7 @@ st506_init(const device_t *info)
dev->cyl_off = 1;
break;
case 21: /* Western Digital WD1002A-WX1 (MFM) */
case ST506_XT_TYPE_WD1002A_WX1: /* Western Digital WD1002A-WX1 (MFM) */
dev->nr_err = ERR_NOT_AVAILABLE;
fn = WD1002A_WX1_BIOS_FILE;
/* The switches are read in reverse: 0 = closed, 1 = open.
@@ -1524,7 +1537,33 @@ st506_init(const device_t *info)
dev->bios_addr = device_get_config_hex20("bios_addr");
break;
case 22: /* Western Digital WD1002A-27X (RLL) */
case ST506_XT_TYPE_WD1002A_WX1_NOBIOS: /* Western Digital WD1002A-WX1 (MFM, No BIOS) */
dev->nr_err = ERR_NOT_AVAILABLE;
fn = NULL;
/* The switches are read in reverse: 0 = closed, 1 = open.
Both open means MFM, 17 sectors per track. */
dev->switches = 0x30; /* autobios */
dev->base = device_get_config_hex16("base");
dev->irq = device_get_config_int("irq");
if (dev->irq == 2)
dev->switches |= 0x40;
dev->bios_addr = device_get_config_hex20("bios_addr");
break;
case ST506_XT_TYPE_WD1004A_WX1: /* Western Digital WD1004A-WX1 (MFM) */
dev->nr_err = ERR_NOT_AVAILABLE;
fn = WD1004A_WX1_BIOS_FILE;
/* The switches are read in reverse: 0 = closed, 1 = open.
Both open means MFM, 17 sectors per track. */
dev->switches = 0x10; /* autobios */
dev->base = device_get_config_hex16("base");
dev->irq = device_get_config_int("irq");
if (dev->irq == 2)
dev->switches |= 0x40;
dev->bios_addr = device_get_config_hex20("bios_addr");
break;
case ST506_XT_TYPE_WD1002A_27X: /* Western Digital WD1002A-27X (RLL) */
dev->nr_err = ERR_NOT_AVAILABLE;
fn = WD1002A_27X_BIOS_FILE;
/* The switches are read in reverse: 0 = closed, 1 = open.
@@ -1539,11 +1578,41 @@ st506_init(const device_t *info)
dev->bios_addr = device_get_config_hex20("bios_addr");
break;
case 23: /* Victor V86P (RLL) */
case ST506_XT_TYPE_WD1004_27X: /* Western Digital WD1004-27X (RLL) */
dev->nr_err = ERR_NOT_AVAILABLE;
fn = WD1004_27X_BIOS_FILE;
/* The switches are read in reverse: 0 = closed, 1 = open.
Both closed means translate 26 sectors per track to 17,
SW6 closed, SW5 open means 26 sectors per track. */
dev->switches = device_get_config_int("translate") ? 0x00 : 0x10; /* autobios */
dev->spt = RLL_SECTORS;
dev->base = device_get_config_hex16("base");
dev->irq = device_get_config_int("irq");
if (dev->irq == 2)
dev->switches |= 0x40;
dev->bios_addr = device_get_config_hex20("bios_addr");
break;
case ST506_XT_TYPE_WD1004A_27X: /* Western Digital WD1004A-27X (RLL) */
dev->nr_err = ERR_NOT_AVAILABLE;
fn = WD1004A_27X_BIOS_FILE;
/* The switches are read in reverse: 0 = closed, 1 = open.
Both closed means translate 26 sectors per track to 17,
SW6 closed, SW5 open means 26 sectors per track. */
dev->switches = device_get_config_int("translate") ? 0x00 : 0x10; /* autobios */
dev->spt = RLL_SECTORS;
dev->base = device_get_config_hex16("base");
dev->irq = device_get_config_int("irq");
if (dev->irq == 2)
dev->switches |= 0x40;
dev->bios_addr = device_get_config_hex20("bios_addr");
break;
case ST506_XT_TYPE_VICTOR_V86P: /* Victor V86P (RLL) */
fn = VICTOR_V86P_BIOS_FILE;
break;
case 24: /* Toshiba T1200 */
case ST506_XT_TYPE_TOSHIBA_T1200: /* Toshiba T1200 */
fn = NULL;
dev->base = 0x01f0;
dev->switches = 0x0c;
@@ -1580,7 +1649,7 @@ st506_init(const device_t *info)
st506_xt_log("ST506: %i disks loaded.\n", c);
/* For the Xebec, set the switches now. */
if (dev->type == 0)
if (dev->type == ST506_XT_TYPE_XEBEC)
set_switches(dev);
/* Initial "active" drive parameters. */
@@ -1807,6 +1876,38 @@ static const device_config_t wd_config[] = {
{ .name = "", .description = "", .type = CONFIG_END }
};
static const device_config_t wd_nobios_config[] = {
{
.name = "base",
.description = "Address",
.type = CONFIG_HEX16,
.default_string = "",
.default_int = 0x0320,
.file_filter = "",
.spinner = { 0 },
.selection = {
{ .description = "320H", .value = 0x0320 },
{ .description = "324H", .value = 0x0324 },
{ .description = "" }
}
},
{
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 5,
.file_filter = "",
.spinner = { 0 },
.selection = {
{ .description = "IRQ 2", .value = 2 },
{ .description = "IRQ 5", .value = 5 },
{ .description = "" }
}
},
{ .name = "", .description = "", .type = CONFIG_END }
};
static const device_config_t wd_rll_config[] = {
{
.name = "bios_addr",
@@ -1984,7 +2085,7 @@ const device_t st506_xt_xebec_device = {
.name = "IBM PC Fixed Disk Adapter (MFM)",
.internal_name = "st506_xt",
.flags = DEVICE_ISA,
.local = (HDD_BUS_MFM << 8) | 0,
.local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_XEBEC,
.init = st506_init,
.close = st506_close,
.reset = NULL,
@@ -1998,7 +2099,7 @@ const device_t st506_xt_dtc5150x_device = {
.name = "DTC 5150X MFM Fixed Disk Adapter",
.internal_name = "st506_xt_dtc5150x",
.flags = DEVICE_ISA,
.local = (HDD_BUS_MFM << 8) | 1,
.local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_DTC_5150X,
.init = st506_init,
.close = st506_close,
.reset = NULL,
@@ -2012,7 +2113,7 @@ const device_t st506_xt_st11_m_device = {
.name = "ST-11M MFM Fixed Disk Adapter",
.internal_name = "st506_xt_st11_m",
.flags = DEVICE_ISA,
.local = (HDD_BUS_MFM << 8) | 11,
.local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_ST11M,
.init = st506_init,
.close = st506_close,
.reset = NULL,
@@ -2026,7 +2127,7 @@ const device_t st506_xt_st11_r_device = {
.name = "ST-11R RLL Fixed Disk Adapter",
.internal_name = "st506_xt_st11_r",
.flags = DEVICE_ISA,
.local = (HDD_BUS_MFM << 8) | 12,
.local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_ST11R,
.init = st506_init,
.close = st506_close,
.reset = NULL,
@@ -2040,7 +2141,7 @@ const device_t st506_xt_wd1002a_wx1_device = {
.name = "WD1002A-WX1 MFM Fixed Disk Adapter",
.internal_name = "st506_xt_wd1002a_wx1",
.flags = DEVICE_ISA,
.local = (HDD_BUS_MFM << 8) | 21,
.local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1002A_WX1,
.init = st506_init,
.close = st506_close,
.reset = NULL,
@@ -2050,11 +2151,25 @@ const device_t st506_xt_wd1002a_wx1_device = {
.config = wd_config
};
const device_t st506_xt_wd1002a_wx1_nobios_device = {
.name = "WD1002A-WX1 MFM Fixed Disk Adapter (No BIOS)",
.internal_name = "st506_xt_wd1002a_wx1",
.flags = DEVICE_ISA,
.local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1002A_WX1_NOBIOS,
.init = st506_init,
.close = st506_close,
.reset = NULL,
{ .available = wd1002a_wx1_available },
.speed_changed = NULL,
.force_redraw = NULL,
.config = wd_nobios_config
};
const device_t st506_xt_wd1002a_27x_device = {
.name = "WD1002A-27X RLL Fixed Disk Adapter",
.internal_name = "st506_xt_wd1002a_27x",
.flags = DEVICE_ISA,
.local = (HDD_BUS_MFM << 8) | 22,
.local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1002A_27X,
.init = st506_init,
.close = st506_close,
.reset = NULL,
@@ -2068,11 +2183,11 @@ const device_t st506_xt_wd1004a_wx1_device = {
.name = "WD1004A-WX1 MFM Fixed Disk Adapter",
.internal_name = "st506_xt_wd1004a_wx1",
.flags = DEVICE_ISA,
.local = (HDD_BUS_MFM << 8) | 21,
.local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1004A_WX1,
.init = st506_init,
.close = st506_close,
.reset = NULL,
{ wd1004a_wx1_available },
{ .available = wd1004a_wx1_available },
.speed_changed = NULL,
.force_redraw = NULL,
.config = wd1004a_config
@@ -2082,7 +2197,7 @@ const device_t st506_xt_wd1004_27x_device = {
.name = "WD1004-27X RLL Fixed Disk Adapter",
.internal_name = "st506_xt_wd1004_27x",
.flags = DEVICE_ISA,
.local = (HDD_BUS_MFM << 8) | 22,
.local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1004_27X,
.init = st506_init,
.close = st506_close,
.reset = NULL,
@@ -2096,7 +2211,7 @@ const device_t st506_xt_wd1004a_27x_device = {
.name = "WD1004a-27X RLL Fixed Disk Adapter",
.internal_name = "st506_xt_wd1004a_27x",
.flags = DEVICE_ISA,
.local = (HDD_BUS_MFM << 8) | 22,
.local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_WD1004A_27X,
.init = st506_init,
.close = st506_close,
.reset = NULL,
@@ -2110,7 +2225,7 @@ const device_t st506_xt_victor_v86p_device = {
.name = "Victor V86P RLL Fixed Disk Adapter",
.internal_name = "st506_xt_victor_v86p",
.flags = DEVICE_ISA,
.local = (HDD_BUS_MFM << 8) | 23,
.local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_VICTOR_V86P,
.init = st506_init,
.close = st506_close,
.reset = NULL,
@@ -2124,7 +2239,7 @@ const device_t st506_xt_toshiba_t1200_device = {
.name = "Toshiba T1200 RLL Fixed Disk Adapter",
.internal_name = "st506_xt_toshiba_t1200",
.flags = DEVICE_ISA,
.local = (HDD_BUS_MFM << 8) | 24,
.local = (HDD_BUS_MFM << 8) | ST506_XT_TYPE_TOSHIBA_T1200,
.init = st506_init,
.close = st506_close,
.reset = NULL,

View File

@@ -56,6 +56,7 @@ enum {
CDROM_BUS_DISABLED = 0,
CDROM_BUS_ATAPI = 5,
CDROM_BUS_SCSI,
CDROM_BUS_MITSUMI,
CDROM_BUS_USB
};
@@ -145,6 +146,8 @@ extern uint8_t cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b);
extern int cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type,
unsigned char start_track, int msf, int max_len);
extern void cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf);
extern void cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode);
extern uint8_t cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len);
extern int cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf,
int cdrom_sector_type, int cdrom_sector_flags, int *len);
extern void cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type);

View File

@@ -0,0 +1,22 @@
/*
* 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.
*
* Mitsumi CD-ROM emulation for the ISA bus.
*
*
*
* Author: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2022 Miran Grca.
*/
#ifndef CDROM_MITSUMI_H
#define CDROM_MITSUMI_H
extern const device_t mitsumi_cdrom_device;
#endif /*CDROM_MITSUMI_H*/

View File

@@ -108,10 +108,12 @@ extern const device_t opti291_device;
extern const device_t opti493_device;
extern const device_t opti495_device;
extern const device_t opti802g_device;
extern const device_t opti802g_pci_device;
extern const device_t opti822_device;
extern const device_t opti895_device;
extern const device_t opti5x7_device;
extern const device_t opti5x7_pci_device;
/* SiS */
extern const device_t rabbit_device;

View File

@@ -795,6 +795,7 @@ extern int machine_xt_v20xt_init(const machine_t *);
extern int machine_xt_iskra3104_init(const machine_t *);
extern int machine_xt_pravetz16_imko4_init(const machine_t *);
extern int machine_xt_micoms_xl7turbo_init(const machine_t *);
/* m_xt_compaq.c */
extern int machine_xt_compaq_deskpro_init(const machine_t *);

View File

@@ -27,9 +27,10 @@
#define PCI_COMMAND_IO 0x01
#define PCI_COMMAND_MEM 0x02
#define PCI_NO_IRQ_STEERING 0x8000
#define PCI_CAN_SWITCH_TYPE 0x10000
#define PCI_NO_BRIDGES 0x20000
#define PCI_NO_IRQ_STEERING 0x8000
#define PCI_CAN_SWITCH_TYPE 0x10000
#define PCI_NO_BRIDGES 0x20000
#define PCI_ALWAYS_EXPOSE_DEV0 0x40000
#define PCI_CONFIG_TYPE_1 1
#define PCI_CONFIG_TYPE_2 2

View File

@@ -32,6 +32,13 @@
#define TEX_CACHE_MAX 64
#ifdef __cplusplus
#include <atomic>
using atomic_int = std::atomic<int>;
#else
#include <stdatomic.h>
#endif
enum {
VOODOO_1 = 0,
VOODOO_SB50,
@@ -170,13 +177,13 @@ typedef struct voodoo_params_t {
} voodoo_params_t;
typedef struct texture_t {
uint32_t base;
uint32_t tLOD;
volatile int refcount, refcount_r[4];
int is16;
uint32_t palette_checksum;
uint32_t addr_start[4], addr_end[4];
uint32_t *data;
uint32_t base;
uint32_t tLOD;
atomic_int refcount, refcount_r[4];
int is16;
uint32_t palette_checksum;
uint32_t addr_start[4], addr_end[4];
uint32_t *data;
} texture_t;
typedef struct vert_t {
@@ -299,19 +306,19 @@ typedef struct voodoo_t {
int type;
fifo_entry_t fifo[FIFO_SIZE];
volatile int fifo_read_idx, fifo_write_idx;
volatile int cmd_read, cmd_written, cmd_written_fifo;
atomic_int fifo_read_idx, fifo_write_idx;
atomic_int cmd_read, cmd_written, cmd_written_fifo;
voodoo_params_t params_buffer[PARAM_SIZE];
volatile int params_read_idx[4], params_write_idx;
atomic_int params_read_idx[4], params_write_idx;
uint32_t cmdfifo_base, cmdfifo_end, cmdfifo_size;
int cmdfifo_rp, cmdfifo_ret_addr;
int cmdfifo_in_sub;
volatile int cmdfifo_depth_rd, cmdfifo_depth_wr;
volatile int cmdfifo_enabled;
uint32_t cmdfifo_amin, cmdfifo_amax;
int cmdfifo_holecount;
uint32_t cmdfifo_base, cmdfifo_end, cmdfifo_size;
int cmdfifo_rp, cmdfifo_ret_addr;
int cmdfifo_in_sub;
atomic_int cmdfifo_depth_rd, cmdfifo_depth_wr;
atomic_int cmdfifo_enabled;
uint32_t cmdfifo_amin, cmdfifo_amax;
int cmdfifo_holecount;
uint32_t sSetupMode;
vert_t verts[4];

View File

@@ -33,7 +33,8 @@ static const uint32_t texture_offset[LOD_MAX + 3] = {
256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2 + 1 * 1 + 1
};
void voodoo_recalc_tex(voodoo_t *voodoo, int tmu);
void voodoo_recalc_tex12(voodoo_t *voodoo, int tmu);
void voodoo_recalc_tex3(voodoo_t *voodoo, int tmu);
void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu);
void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p);
void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu);

View File

@@ -632,12 +632,15 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
device_add(&opti802g_device);
device_add(&opti802g_pci_device);
device_add(&opti822_device);
device_add(&keyboard_ps2_device);
device_add(&fdc37c665_device);

View File

@@ -385,12 +385,16 @@ machine_at_p5vl_init(const machine_t *model)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
device_add(&opti5x7_device);
pci_register_slot(0x12, PCI_CARD_NORMAL, 5, 6, 7, 8);
pci_register_slot(0x13, PCI_CARD_NORMAL, 9, 10, 11, 12);
pci_register_slot(0x14, PCI_CARD_NORMAL, 13, 14, 15, 16);
device_add(&opti5x7_pci_device);
device_add(&opti822_device);
device_add(&sst_flash_29ee010_device);
device_add(&keyboard_at_ami_device);

View File

@@ -335,12 +335,15 @@ machine_at_hot543_init(const machine_t *model)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
device_add(&opti5x7_device);
device_add(&opti5x7_pci_device);
device_add(&opti822_device);
device_add(&sst_flash_29ee010_device);
device_add(&keyboard_at_device);

View File

@@ -334,25 +334,24 @@ machine_xt_pravetz16_imko4_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/pravetz16/BIOS_IMKO4_FE00.bin",
ret = bios_load_linear("roms/machines/pravetz16/BIOS_IMKO4_FE00.BIN",
0x000fe000, 65536, 0);
if (ret) {
ret = bios_load_aux_linear("roms/machines/pravetz16/IMKO4-D34_SGS-M2764ADIP28.BIN",
0x000f4000, 8192, 0);
if (ret)
{
bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_F400.BIN",
0x000f4000, 8192, 0);
if (ret) {
bios_load_aux_linear("roms/machines/pravetz16/1.bin",
bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_F600.BIN",
0x000f6000, 8192, 0);
bios_load_aux_linear("roms/machines/pravetz16/2.bin",
bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_FA00.BIN",
0x000fa000, 8192, 0);
bios_load_aux_linear("roms/machines/pravetz16/5.bin",
bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_F800.BIN",
0x000f8000, 8192, 0);
bios_load_aux_linear("roms/machines/pravetz16/6.bin",
bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_FC00.BIN",
0x000fc000, 8192, 0);
}
}
if (bios_only || !ret)
@@ -365,6 +364,21 @@ machine_xt_pravetz16_imko4_init(const machine_t *model)
return ret;
}
int
machine_xt_micoms_xl7turbo_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/mxl7t/XL7_TURBO.BIN",
0x000fe000, 8192, 0);
if (bios_only || !ret)
return ret;
machine_xt_init_ex(model);
return ret;
}
int
machine_xt_pc4i_init(const machine_t *model)
{

View File

@@ -888,7 +888,7 @@ machine_xt_t1000_init(const machine_t *model)
machine_common_init(model);
pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt);
device_add(&keyboard_xt_device);
device_add(&keyboard_xt_t1x00_device);
t1000.fdc = device_add(&fdc_xt_device);
nmi_init();
@@ -948,7 +948,7 @@ machine_xt_t1200_init(const machine_t *model)
NULL, MEM_MAPPING_EXTERNAL, &t1000);
pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt);
device_add(&keyboard_xt_device);
device_add(&keyboard_xt_t1x00_device);
t1000.fdc = device_add(&fdc_xt_t1x00_device);
nmi_init();

View File

@@ -923,6 +923,42 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
{
.name = "[8088] Micoms XL-7 Turbo",
.internal_name = "mxl7t",
.type = MACHINE_TYPE_8088,
.chipset = MACHINE_CHIPSET_DISCRETE,
.init = machine_xt_micoms_xl7turbo_init,
.pad = 0,
.pad0 = 0,
.pad1 = MACHINE_AVAILABLE,
.pad2 = 0,
.cpu = {
.package = CPU_PKG_8088,
.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_PC,
.flags = MACHINE_FLAGS_NONE,
.ram = {
.min = 64,
.max = 640,
.step = 64
},
.nvrmask = 0,
.kbc = KBC_IBM_PC_XT,
.kbc_p1 = 0xff00,
.gpio = 0xffffffff,
.device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
{
.name = "[8088] NCR PC4i",
.internal_name = "pc4i",
@@ -4389,7 +4425,7 @@ const machine_t machines[] = {
.max_multi = 0
},
.bus_flags = MACHINE_AT,
.flags = MACHINE_IDE,
.flags = 0,
.ram = {
.min = 1024,
.max = 32768,

View File

@@ -307,7 +307,7 @@ mmutranslatereal_normal(uint32_t addr, int rw)
if ((temp & 0x80) && (cr4 & CR4_PSE)) {
/*4MB page*/
if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (((CPL == 3) && !cpl_override) || (is486 && (cr0 & WP_FLAG))))) {
if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) {
cr2 = addr;
temp &= 1;
if (CPL == 3)
@@ -328,7 +328,7 @@ mmutranslatereal_normal(uint32_t addr, int rw)
temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc));
temp3 = temp & temp2;
if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || (is486 && (cr0 & WP_FLAG))))) {
if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) {
cr2 = addr;
temp &= 1;
if (CPL == 3)

137
src/pci.c
View File

@@ -59,14 +59,15 @@ static uint8_t pci_irqs[16], pci_irq_level[16];
static uint64_t pci_irq_hold[16];
static pci_mirq_t pci_mirqs[8];
static int pci_type,
pci_switch,
pci_index,
pci_func,
pci_card,
pci_bus,
pci_enable,
pci_key;
static int trc_reg = 0;
pci_switch,
pci_index,
pci_func,
pci_card,
pci_bus,
pci_enable,
pci_key;
static int trc_reg = 0;
static uint32_t pci_base = 0xc000, pci_size = 0x1000;
static void pci_reset_regs(void);
@@ -388,22 +389,40 @@ static uint8_t pci_type2_read(uint16_t port, void *priv);
void
pci_set_pmc(uint8_t pmc)
{
pci_reset_regs();
pci_log("pci_set_pmc(%02X)\n", pmc);
// pci_reset_regs();
if (!pci_pmc && (pmc & 0x01)) {
io_removehandler(pci_base, pci_size,
pci_type2_read, NULL, NULL,
pci_type2_write, NULL, NULL, NULL);
io_removehandler(0x0cf8, 1,
pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL);
io_removehandler(0x0cfa, 1,
pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL);
io_sethandler(0x0cf8, 1,
NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL);
io_sethandler(0x0cfa, 1,
pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL);
io_sethandler(0x0cfc, 4,
pci_read, NULL, NULL, pci_write, NULL, NULL, NULL);
pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL);
} else if (pci_pmc && !(pmc & 0x01)) {
io_removehandler(pci_base, pci_size,
pci_type2_read, NULL, NULL,
pci_type2_write, NULL, NULL, NULL);
if (pci_key) {
io_sethandler(pci_base, pci_size,
pci_type2_read, NULL, NULL,
pci_type2_write, NULL, NULL, NULL);
}
io_removehandler(0x0cf8, 1,
NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL);
io_removehandler(0x0cfa, 1,
pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL);
io_removehandler(0x0cfc, 4,
pci_read, NULL, NULL, pci_write, NULL, NULL, NULL);
pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL);
io_sethandler(0x0cf8, 1,
pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL);
io_sethandler(0x0cfa, 1,
@@ -421,19 +440,36 @@ pci_type2_write(uint16_t port, uint8_t val, void *priv)
if (port == 0xcf8) {
pci_func = (val >> 1) & 7;
if (!pci_key && (val & 0xf0))
io_sethandler(0xc000, 0x1000,
if (!pci_key && (val & 0xf0)) {
io_removehandler(pci_base, pci_size,
pci_type2_read, NULL, NULL,
pci_type2_write, NULL, NULL, NULL);
io_sethandler(pci_base, pci_size,
pci_type2_read, NULL, NULL,
pci_type2_write, NULL, NULL, NULL);
else if (pci_key && !(val & 0xf0))
io_removehandler(0xc000, 0x1000,
} else if (pci_key && !(val & 0xf0))
io_removehandler(pci_base, pci_size,
pci_type2_read, NULL, NULL,
pci_type2_write, NULL, NULL, NULL);
pci_key = val & 0xf0;
} else if (port == 0xcfa)
} else if (port == 0xcfa) {
pci_bus = val;
else if (port == 0xcfb) {
pci_log("Allocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1);
/* Evidently, writing here, we should also enable the
configuration space. */
io_removehandler(pci_base, pci_size,
pci_type2_read, NULL, NULL,
pci_type2_write, NULL, NULL, NULL);
io_sethandler(pci_base, pci_size,
pci_type2_read, NULL, NULL,
pci_type2_write, NULL, NULL, NULL);
/* Mark as enabled. */
pci_key |= 0x100;
} else if (port == 0xcfb) {
pci_log("Write %02X to port 0CFB\n", val);
pci_set_pmc(val);
} else {
@@ -473,32 +509,36 @@ static uint8_t
pci_type2_read(uint16_t port, void *priv)
{
uint8_t slot = 0;
uint8_t ret = 0xff;
if (port == 0xcf8)
return pci_key | (pci_func << 1);
ret = pci_key | (pci_func << 1);
else if (port == 0xcfa)
return pci_bus;
ret = pci_bus;
else if (port == 0xcfb)
return pci_pmc;
ret = pci_pmc;
else {
pci_card = (port >> 8) & 0xf;
pci_index = port & 0xff;
pci_card = (port >> 8) & 0xf;
pci_index = port & 0xff;
slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card];
if (slot != 0xff) {
if (pci_cards[slot].read)
return pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv);
slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card];
if (slot != 0xff) {
if (pci_cards[slot].read)
ret = pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv);
#ifdef ENABLE_PCI_LOG
else
pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index);
#endif
}
#ifdef ENABLE_PCI_LOG
else
pci_log("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index);
#endif
}
#ifdef ENABLE_PCI_LOG
else
pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index);
pci_log("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index);
#endif
return 0xff;
pci_log("Reading %02X at PCI register %02X at bus %02X, card %02X, function %02X\n", ret, pci_index, pci_bus, pci_card, pci_func);
}
return ret;
}
void
@@ -610,7 +650,7 @@ pci_set_irq(uint8_t card, uint8_t pci_int)
if (pci_type & PCI_NO_IRQ_STEERING)
irq_line = pci_cards[slot].read(0, 0x3c, pci_cards[slot].priv);
else {
irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 3;
irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 15;
pci_log("pci_set_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing);
irq_line = pci_irqs[irq_routing];
@@ -735,7 +775,7 @@ pci_clear_irq(uint8_t card, uint8_t pci_int)
if (pci_type & PCI_NO_IRQ_STEERING)
irq_line = pci_cards[slot].read(0, 0x3c, pci_cards[slot].priv);
else {
irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 3;
irq_routing = (pci_cards[slot].irq_routing[pci_int_index] - PCI_INTA) & 15;
// pci_log("pci_clear_irq(%02X, %02X): IRQ routing for this slot and INT pin combination: %02X\n", card, pci_int, irq_routing);
irq_line = pci_irqs[irq_routing];
@@ -782,7 +822,7 @@ pci_reset_regs(void)
{
pci_index = pci_card = pci_func = pci_bus = pci_key = 0;
io_removehandler(0xc000, 0x1000,
io_removehandler(pci_base, pci_size,
pci_type2_read, NULL, NULL,
pci_type2_write, NULL, NULL, NULL);
}
@@ -816,12 +856,17 @@ void
pci_reset(void)
{
if (pci_switch) {
pci_log("pci_reset(): Switchable configuration mechanism\n");
pci_pmc = 0x00;
io_removehandler(0x0cf8, 1,
NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL);
io_removehandler(0x0cfc, 4,
pci_read, NULL, NULL, pci_write, NULL, NULL, NULL);
pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL);
io_removehandler(0x0cf8, 1,
pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL);
io_removehandler(0x0cfa, 1,
pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL);
io_sethandler(0x0cf8, 1,
pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL);
io_sethandler(0x0cfa, 1,
@@ -931,6 +976,9 @@ pci_init(int type)
{
int c;
pci_base = 0xc000;
pci_size = 0x1000;
pci_slots_clear();
pci_reset_hard();
@@ -941,6 +989,7 @@ pci_init(int type)
pci_switch = !!(type & PCI_CAN_SWITCH_TYPE);
if (pci_switch) {
pci_log("PCI: Switchable configuration mechanism\n");
pci_pmc = 0x00;
io_sethandler(0x0cfb, 1,
@@ -956,17 +1005,29 @@ pci_init(int type)
}
if ((type & PCI_CONFIG_TYPE_MASK) == PCI_CONFIG_TYPE_1) {
pci_log("PCI: Configuration mechanism #1\n");
io_sethandler(0x0cf8, 1,
NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL);
io_sethandler(0x0cfc, 4,
pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL);
pci_pmc = 1;
} else {
pci_log("PCI: Configuration mechanism #2\n");
io_sethandler(0x0cf8, 1,
pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL);
io_sethandler(0x0cfa, 1,
pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL);
pci_pmc = 0;
if (type & PCI_ALWAYS_EXPOSE_DEV0) {
pci_log("PCI: Always expose device 0\n");
pci_base = 0xc100;
pci_size = 0x0f00;
io_sethandler(0xc000, 0x0100,
pci_type2_read, NULL, NULL,
pci_type2_write, NULL, NULL, NULL);
}
}
for (c = 0; c < 4; c++) {

View File

@@ -76,6 +76,24 @@ msgstr "1.&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "Metoda &filtrování"

View File

@@ -76,6 +76,24 @@ msgstr "1,&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "Filteringmethode"

View File

@@ -76,6 +76,24 @@ msgstr "1.&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "Filter method"

View File

@@ -76,6 +76,24 @@ msgstr "1.&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "Filter method"

View File

@@ -76,6 +76,24 @@ msgstr "1.&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "&Método de filtrado"

View File

@@ -76,6 +76,24 @@ msgstr "1.&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "&Suodatusmetodi"

View File

@@ -76,6 +76,24 @@ msgstr "1.&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "Methode Filtre"

View File

@@ -76,6 +76,24 @@ msgstr "1,&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "Metoda filtriranja"

View File

@@ -76,6 +76,24 @@ msgstr "1,&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "Szűrési mód"

View File

@@ -76,6 +76,24 @@ msgstr "1.&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "Metodo filtro"

View File

@@ -76,6 +76,24 @@ msgstr "1.5x(&5)"
msgid "&2x"
msgstr "2x(&2)"
msgid "&3x"
msgstr "3x(&3)"
msgid "&4x"
msgstr "4x(&4)"
msgid "&5x"
msgstr "5x(&5)"
msgid "&6x"
msgstr "6x(&6)"
msgid "&7x"
msgstr "7x(&7)"
msgid "&8x"
msgstr "8x(&8)"
msgid "Filter method"
msgstr "フィルター方式"

View File

@@ -76,6 +76,24 @@ msgstr "1.5배(&5)"
msgid "&2x"
msgstr "2배(&2)"
msgid "&3x"
msgstr "3배(&3)"
msgid "&4x"
msgstr "4배(&4)"
msgid "&5x"
msgstr "5배(&5)"
msgid "&6x"
msgstr "6배(&6)"
msgid "&7x"
msgstr "7배(&7)"
msgid "&8x"
msgstr "8배(&8)"
msgid "Filter method"
msgstr "필터 형식"

View File

@@ -76,6 +76,24 @@ msgstr "1.&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "Metoda filtrowania"

View File

@@ -76,6 +76,24 @@ msgstr "1,&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "Método de filtragem"

View File

@@ -76,6 +76,24 @@ msgstr "1.&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "Método de filtragem"

View File

@@ -76,6 +76,24 @@ msgstr "1.&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "Метод фильтрации"

View File

@@ -76,6 +76,24 @@ msgstr "1.&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "&Metoda filtriranja"

View File

@@ -76,6 +76,24 @@ msgstr "1.&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "&Filtre metodu"

View File

@@ -76,6 +76,24 @@ msgstr "1.&5x"
msgid "&2x"
msgstr "&2x"
msgid "&3x"
msgstr "&3x"
msgid "&4x"
msgstr "&4x"
msgid "&5x"
msgstr "&5x"
msgid "&6x"
msgstr "&6x"
msgid "&7x"
msgstr "&7x"
msgid "&8x"
msgstr "&8x"
msgid "Filter method"
msgstr "Метод фільтрації"

View File

@@ -76,6 +76,24 @@ msgstr "1.5x(&5)"
msgid "&2x"
msgstr "2x(&2)"
msgid "&3x"
msgstr "3x(&3)"
msgid "&4x"
msgstr "4x(&4)"
msgid "&5x"
msgstr "5x(&5)"
msgid "&6x"
msgstr "6x(&6)"
msgid "&7x"
msgstr "7x(&7)"
msgid "&8x"
msgstr "8x(&8)"
msgid "Filter method"
msgstr "过滤方式"

View File

@@ -46,7 +46,9 @@ void HardwareRenderer::initializeGL()
{
m_context->makeCurrent(this);
initializeOpenGLFunctions();
m_texture = new QOpenGLTexture(QImage(2048,2048, QImage::Format::Format_RGB32));
auto image = QImage(2048, 2048, QImage::Format_RGB32);
image.fill(0xff000000);
m_texture = new QOpenGLTexture(image);
m_blt = new QOpenGLTextureBlitter;
m_blt->setRedBlueSwizzle(true);
m_blt->create();
@@ -138,6 +140,8 @@ void HardwareRenderer::initializeGL()
pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
glClearColor(0, 0, 0, 1);
m_texture->setWrapMode(QOpenGLTexture::ClampToEdge);
glClear(GL_COLOR_BUFFER_BIT);
m_context->swapBuffers(this);
}
void HardwareRenderer::paintGL() {

View File

@@ -75,6 +75,7 @@ public:
m_context = new QOpenGLContext();
m_context->setFormat(format());
m_context->create();
update();
}
~HardwareRenderer()
{

View File

@@ -75,6 +75,10 @@ extern "C" {
#include <QScreen>
#include <QString>
#include <QDir>
#if QT_CONFIG(vulkan)
#include <QVulkanInstance>
#include <QVulkanFunctions>
#endif
#include <array>
#include <unordered_map>
@@ -154,7 +158,7 @@ MainWindow::MainWindow(QWidget *parent) :
ui->stackedWidget->setMouseTracking(true);
statusBar()->setVisible(!hide_status_bar);
statusBar()->setStyleSheet("QStatusBar::item {border: None; } QStatusBar QLabel { margin-right: 2px; margin-bottom: 1px; }");
this->setStyleSheet("#centralWidget { background-color: black; }");
this->centralWidget()->setStyleSheet("background-color: black;");
ui->toolBar->setVisible(!hide_tool_bar);
renderers[0].reset(nullptr);
auto toolbar_spacer = new QWidget();
@@ -325,10 +329,25 @@ MainWindow::MainWindow(QWidget *parent) :
ui->actionVNC->setVisible(false);
#endif
#if !QT_CONFIG(vulkan)
if (vid_api == 4) vid_api = 0;
ui->actionVulkan->setVisible(false);
#if QT_CONFIG(vulkan)
bool vulkanAvailable = false;
{
QVulkanInstance instance;
instance.setApiVersion(QVersionNumber(1, 0));
if (instance.create()) {
uint32_t physicalDevices = 0;
instance.functions()->vkEnumeratePhysicalDevices(instance.vkInstance(), &physicalDevices, nullptr);
if (physicalDevices != 0) {
vulkanAvailable = true;
}
}
}
if (!vulkanAvailable)
#endif
{
if (vid_api == 4) vid_api = 0;
ui->actionVulkan->setVisible(false);
}
QActionGroup* actGroup = nullptr;
@@ -416,12 +435,36 @@ MainWindow::MainWindow(QWidget *parent) :
case 3:
ui->action2x->setChecked(true);
break;
case 4:
ui->action3x->setChecked(true);
break;
case 5:
ui->action4x->setChecked(true);
break;
case 6:
ui->action5x->setChecked(true);
break;
case 7:
ui->action6x->setChecked(true);
break;
case 8:
ui->action7x->setChecked(true);
break;
case 9:
ui->action8x->setChecked(true);
break;
}
actGroup = new QActionGroup(this);
actGroup->addAction(ui->action0_5x);
actGroup->addAction(ui->action1x);
actGroup->addAction(ui->action1_5x);
actGroup->addAction(ui->action2x);
actGroup->addAction(ui->action3x);
actGroup->addAction(ui->action4x);
actGroup->addAction(ui->action5x);
actGroup->addAction(ui->action6x);
actGroup->addAction(ui->action7x);
actGroup->addAction(ui->action8x);
switch (video_filter_method) {
case 0:
ui->actionNearest->setChecked(true);
@@ -507,15 +550,6 @@ MainWindow::MainWindow(QWidget *parent) :
#endif
if (!vnc_enabled) video_setblit(qt_blit);
if (start_in_fullscreen) {
connect(ui->stackedWidget, &RendererStack::blit, this, [this] () {
if (start_in_fullscreen) {
QTimer::singleShot(100, ui->actionFullscreen, &QAction::trigger);
start_in_fullscreen = 0;
}
});
}
#ifdef MTR_ENABLED
{
ui->actionBegin_trace->setVisible(true);
@@ -711,6 +745,10 @@ void MainWindow::showEvent(QShowEvent *event) {
QApplication::processEvents();
this->adjustSize();
}
if (start_in_fullscreen) {
start_in_fullscreen = 0;
QTimer::singleShot(0, ui->actionFullscreen, &QAction::trigger);
}
}
void MainWindow::on_actionKeyboard_requires_capture_triggered() {
@@ -1631,7 +1669,7 @@ void MainWindow::showMessage_(int flags, const QString &header, const QString &m
void MainWindow::keyPressEvent(QKeyEvent* event)
{
if (send_keyboard_input && !(kbd_req_capture && !mouse_capture && !video_fullscreen))
if (send_keyboard_input && !(kbd_req_capture && !mouse_capture))
{
// Windows keys in Qt have one-to-one mapping.
if (event->key() == Qt::Key_Pause && !keyboard_recv(0x38) && !keyboard_recv(0x138)) {
@@ -1770,6 +1808,12 @@ static void update_scaled_checkboxes(Ui::MainWindow* ui, QAction* selected) {
ui->action1x->setChecked(ui->action1x == selected);
ui->action1_5x->setChecked(ui->action1_5x == selected);
ui->action2x->setChecked(ui->action2x == selected);
ui->action3x->setChecked(ui->action3x == selected);
ui->action4x->setChecked(ui->action4x == selected);
ui->action5x->setChecked(ui->action5x == selected);
ui->action6x->setChecked(ui->action6x == selected);
ui->action7x->setChecked(ui->action7x == selected);
ui->action8x->setChecked(ui->action8x == selected);
reset_screen_size();
device_force_redraw();
@@ -1799,6 +1843,36 @@ void MainWindow::on_action2x_triggered() {
update_scaled_checkboxes(ui, ui->action2x);
}
void MainWindow::on_action3x_triggered() {
scale = 4;
update_scaled_checkboxes(ui, ui->action3x);
}
void MainWindow::on_action4x_triggered() {
scale = 5;
update_scaled_checkboxes(ui, ui->action4x);
}
void MainWindow::on_action5x_triggered() {
scale = 6;
update_scaled_checkboxes(ui, ui->action5x);
}
void MainWindow::on_action6x_triggered() {
scale = 7;
update_scaled_checkboxes(ui, ui->action6x);
}
void MainWindow::on_action7x_triggered() {
scale = 8;
update_scaled_checkboxes(ui, ui->action7x);
}
void MainWindow::on_action8x_triggered() {
scale = 9;
update_scaled_checkboxes(ui, ui->action8x);
}
void MainWindow::on_actionNearest_triggered() {
video_filter_method = 0;
ui->actionLinear->setChecked(false);

View File

@@ -81,6 +81,12 @@ private slots:
void on_action1x_triggered();
void on_action1_5x_triggered();
void on_action2x_triggered();
void on_action3x_triggered();
void on_action4x_triggered();
void on_action5x_triggered();
void on_action6x_triggered();
void on_action7x_triggered();
void on_action8x_triggered();
void on_actionLinear_triggered();
void on_actionNearest_triggered();
void on_actionFullScreen_int_triggered();

View File

@@ -118,6 +118,12 @@
<addaction name="action1x"/>
<addaction name="action1_5x"/>
<addaction name="action2x"/>
<addaction name="action3x"/>
<addaction name="action4x"/>
<addaction name="action5x"/>
<addaction name="action6x"/>
<addaction name="action7x"/>
<addaction name="action8x"/>
</widget>
<widget class="QMenu" name="menuFilter_method">
<property name="title">
@@ -478,6 +484,54 @@
<string>&amp;2x</string>
</property>
</action>
<action name="action3x">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;3x</string>
</property>
</action>
<action name="action4x">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;4x</string>
</property>
</action>
<action name="action5x">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;5x</string>
</property>
</action>
<action name="action6x">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;6x</string>
</property>
</action>
<action name="action7x">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;7x</string>
</property>
</action>
<action name="action8x">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;8x</string>
</property>
</action>
<action name="actionNearest">
<property name="checkable">
<bool>true</bool>

View File

@@ -18,7 +18,6 @@
* Copyright 2021-2022 Cacodemon345
* Copyright 2021-2022 Teemu Korhonen
*/
#include "qt_mediamenu.hpp"
#include "qt_progsettings.hpp"
#include "qt_machinestatus.hpp"
@@ -55,6 +54,7 @@ extern "C" {
#include "qt_util.hpp"
#include "qt_deviceconfig.hpp"
#include "qt_mediahistorymanager.hpp"
#include "qt_mediamenu.hpp"
std::shared_ptr<MediaMenu> MediaMenu::ptr;

View File

@@ -194,6 +194,9 @@ OpenGLRenderer::initialize()
emit initialized();
glClear(GL_COLOR_BUFFER_BIT);
context->swapBuffers(this);
} catch (const opengl_init_error &e) {
/* Mark all buffers as in use */
for (auto &flag : buf_usage)

View File

@@ -416,6 +416,7 @@ RendererStack::createRenderer(Renderer renderer)
current->setFocusPolicy(Qt::NoFocus);
current->setFocusProxy(this);
current->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
current->setStyleSheet("background-color: black");
addWidget(current.get());
this->setStyleSheet("background-color: black");

View File

@@ -795,18 +795,8 @@ VulkanWindowRenderer::VulkanWindowRenderer(QWidget* parent)
: QVulkanWindow(parent->windowHandle())
{
parentWidget = parent;
instance.setLayers(QByteArrayList() << "VK_LAYER_KHRONOS_validation");
instance.setExtensions(QByteArrayList() << "VK_EXT_debug_report");
instance.setApiVersion(QVersionNumber(1, 0));
if (!instance.create()) {
throw std::runtime_error("Could not create Vulkan instance");
}
uint32_t physicalDevices = 0;
instance.functions()->vkEnumeratePhysicalDevices(instance.vkInstance(), &physicalDevices, nullptr);
if (physicalDevices == 0) {
throw std::runtime_error("No physical devices available.");
}
qDebug() << instance.layers();
instance.create();
setVulkanInstance(&instance);
setPhysicalDeviceIndex(0);
setPreferredColorFormats({VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_A8B8G8R8_UNORM_PACK32});

View File

@@ -174,7 +174,7 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw)
RAWKEYBOARD rawKB = raw->data.keyboard;
scancode = rawKB.MakeCode;
if (kbd_req_capture && !mouse_capture && !video_fullscreen)
if (kbd_req_capture && !mouse_capture)
return;
/* If it's not a scan code that starts with 0xE1 */

View File

@@ -551,12 +551,24 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len)
case 0x08:
case 0x28:
case 0xa8:
/* Round it to the nearest 2048 bytes. */
dev->max_transfer_len = (dev->max_transfer_len >> 11) << 11;
/* FALLTHROUGH */
case 0xb9:
case 0xbe:
/* Round it to the nearest (block length) bytes. */
if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) {
/* READ CD MSF and READ CD: Round the request length to the sector size - the device must ensure
that a media access comand does not DRQ in the middle of a sector. One of the drivers that
relies on the correctness of this behavior is MTMCDAI.SYS (the Mitsumi CD-ROM driver) for DOS
which uses the READ CD command to read data on some CD types. */
if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) {
/* Round to sector length. */
dlen = ((double) dev->max_transfer_len) / ((double) block_len);
dev->max_transfer_len = ((uint16_t) floor(dlen)) * block_len;
}
} else {
/* Round it to the nearest 2048 bytes. */
dev->max_transfer_len = (dev->max_transfer_len >> 11) << 11;
}
/* Make sure total length is not bigger than sum of the lengths of
all the requested blocks. */
bt = (dev->requested_blocks * block_len);
@@ -574,7 +586,8 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len)
break;
}
}
/*FALLTHROUGH*/
/* FALLTHROUGH */
default:
dev->packet_len = len;
break;
@@ -591,16 +604,6 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len)
else if (len > dev->max_transfer_len)
dev->request_length = dev->max_transfer_len;
/* READ CD MSF and READ CD: Round the request length to the sector size - the device must ensure
that a media access comand does not DRQ in the middle of a sector. One of the drivers that
relies on the correctness of this behavior is MTMCDAI.SYS (the Mitsumi CD-ROM driver) for DOS
which uses the READ CD command to read data on some CD types. */
if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) {
/* Round to sector length. */
dlen = ((double) dev->request_length) / ((double) block_len);
dev->request_length = ((uint16_t) floor(dlen)) * block_len;
}
return;
}

View File

@@ -518,7 +518,9 @@ esp_dma_enable(esp_t *dev, int level)
esp_log("ESP DMA Enabled\n");
dev->dma_enabled = 1;
dev->dma_86c01.status |= 0x02;
if ((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) {
timer_stop(&dev->timer);
if (((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) &&
((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_PAD)) {
timer_on_auto(&dev->timer, 40.0);
} else {
esp_log("Period = %lf\n", dev->period);
@@ -924,6 +926,7 @@ esp_write_response(esp_t *dev)
buf[0] = dev->status;
buf[1] = 0;
esp_log("esp_write_response(): %02X %02X\n", buf[0], buf[1]);
if (dev->dma) {
if (dev->mca) {
@@ -953,10 +956,13 @@ esp_callback(void *p)
{
esp_t *dev = (esp_t *) p;
if (dev->dma_enabled || dev->do_cmd) {
if (dev->dma_enabled || dev->do_cmd || ((dev->rregs[ESP_CMD] & CMD_CMD) == CMD_PAD)) {
if ((dev->rregs[ESP_CMD] & CMD_CMD) == CMD_TI) {
esp_log("ESP SCSI Handle TI Callback\n");
handle_ti(dev);
} else if ((dev->rregs[ESP_CMD] & CMD_CMD) == CMD_PAD) {
esp_log("ESP SCSI Handle PAD Callback\n");
handle_ti(dev);
}
}
@@ -1084,6 +1090,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val)
}
break;
case CMD_TI:
esp_log("val = %02X\n", val);
break;
case CMD_SEL:
handle_s_without_atn(dev);
@@ -1107,9 +1114,9 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val)
esp_raise_irq(dev);
break;
case CMD_PAD:
dev->rregs[ESP_RSTAT] = STAT_TC;
dev->rregs[ESP_RINTR] |= INTR_FC;
dev->rregs[ESP_RSEQ] = 0;
esp_log("val = %02X\n", val);
timer_stop(&dev->timer);
timer_on_auto(&dev->timer, dev->period);
esp_log("ESP Transfer Pad\n");
break;
case CMD_SATN:
@@ -1173,6 +1180,9 @@ esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir)
} else {
dma_bm_read(dev->dma_regs[DMA_SPA], buf, len, 4);
}
esp_log("DMA: Address = %08X, Length = %08X (%02X %02X %02X %02X -> %02X %02X %02X %02X)\n", dev->dma_regs[DMA_SPA], len,
ram[dev->dma_regs[DMA_SPA]], ram[dev->dma_regs[DMA_SPA] + 1], ram[dev->dma_regs[DMA_SPA] + 2], ram[dev->dma_regs[DMA_SPA] + 3],
buf[0], buf[1], buf[2], buf[3]);
/* update status registers */
dev->dma_regs[DMA_WBC] -= len;
@@ -1215,6 +1225,7 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val)
switch (val & DMA_CMD_MASK) {
case 0: /*IDLE*/
esp_dma_enable(dev, 0);
esp_log("PCI DMA disable\n");
break;
case 1: /*BLAST*/
break;
@@ -1227,6 +1238,7 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val)
dev->dma_regs[DMA_WMAC] = dev->dma_regs[DMA_SMDLA];
dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_BCMBLT | DMA_STAT_SCSIINT | DMA_STAT_DONE | DMA_STAT_ABORT | DMA_STAT_ERROR | DMA_STAT_PWDN);
esp_dma_enable(dev, 1);
esp_log("PCI DMA enable\n");
break;
default: /* can't happen */
abort();
@@ -1251,6 +1263,7 @@ static void
esp_pci_soft_reset(esp_t *dev)
{
esp_irq(dev, 0);
dev->rregs[ESP_RSTAT] &= ~STAT_INT;
esp_pci_hard_reset(dev);
}
@@ -1632,9 +1645,11 @@ esp_pci_read(int func, int addr, void *p)
case 0x03:
return 0x20;
case 0x04:
return esp_pci_regs[0x04] & 3; /*Respond to IO*/
return esp_pci_regs[0x04] | 0x80; /*Respond to IO*/
case 0x05:
return esp_pci_regs[0x05];
case 0x07:
return 2;
return esp_pci_regs[0x07] | 0x02;
case 0x08:
return 0; /*Revision ID*/
case 0x09:
@@ -1646,7 +1661,7 @@ esp_pci_read(int func, int addr, void *p)
case 0x0E:
return 0; /*Header type */
case 0x10:
return 1; /*I/O space*/
return (esp_pci_bar[0].addr_regs[1] & 0x80) | 0x01; /*I/O space*/
case 0x11:
return esp_pci_bar[0].addr_regs[1];
case 0x12:
@@ -1707,10 +1722,25 @@ esp_pci_write(int func, int addr, uint8_t val, void *p)
valxor = (val & 3) ^ esp_pci_regs[addr];
if (valxor & PCI_COMMAND_IO) {
esp_io_remove(dev, dev->PCIBase, 0x80);
if ((dev->PCIBase != 0) && (val & PCI_COMMAND_IO))
if ((val & PCI_COMMAND_IO) && (dev->PCIBase != 0))
esp_io_set(dev, dev->PCIBase, 0x80);
}
esp_pci_regs[addr] = val & 3;
if (dev->has_bios && (valxor & PCI_COMMAND_MEM)) {
esp_bios_disable(dev);
if ((val & PCI_COMMAND_MEM) && (esp_pci_bar[1].addr & 0x00000001))
esp_bios_set_addr(dev, dev->BIOSBase);
}
if (dev->has_bios)
esp_pci_regs[addr] = val & 0x47;
else
esp_pci_regs[addr] = val & 0x45;
break;
case 0x05:
esp_pci_regs[addr] = val & 0x01;
break;
case 0x07:
esp_pci_regs[addr] &= ~(val & 0xf9);
break;
case 0x10:
@@ -1723,7 +1753,7 @@ esp_pci_write(int func, int addr, uint8_t val, void *p)
/* Then let's set the PCI regs. */
esp_pci_bar[0].addr_regs[addr & 3] = val;
/* Then let's calculate the new I/O base. */
esp_pci_bar[0].addr &= 0xff00;
esp_pci_bar[0].addr &= 0xff80;
dev->PCIBase = esp_pci_bar[0].addr;
/* Log the new base. */
// esp_log("ESP PCI: New I/O base is %04X\n" , dev->PCIBase);
@@ -1747,16 +1777,16 @@ esp_pci_write(int func, int addr, uint8_t val, void *p)
/* Then let's set the PCI regs. */
esp_pci_bar[1].addr_regs[addr & 3] = val;
/* Then let's calculate the new I/O base. */
esp_pci_bar[1].addr &= 0xfff80001;
dev->BIOSBase = esp_pci_bar[1].addr & 0xfff80000;
esp_pci_bar[1].addr &= 0xffff0001;
dev->BIOSBase = esp_pci_bar[1].addr & 0xffff0000;
/* Log the new base. */
// esp_log("ESP PCI: New BIOS base is %08X\n" , dev->BIOSBase);
/* We're done, so get out of the here. */
if (esp_pci_bar[1].addr & 0x00000001)
if ((esp_pci_regs[0x04] & PCI_COMMAND_MEM) && (esp_pci_bar[1].addr & 0x00000001))
esp_bios_set_addr(dev, dev->BIOSBase);
return;
case 0x3C:
case 0x3c:
esp_pci_regs[addr] = val;
dev->irq = val;
esp_log("ESP IRQ now: %i\n", val);

View File

@@ -540,7 +540,7 @@ cga_pravetz_init(const device_t *info)
{
cga_t *cga = cga_standalone_init(info);
loadfont("roms/video/cga/CGA - PRAVETZ.BIN", 10);
loadfont("roms/video/cga/PRAVETZ-VDC2.BIN", 10);
io_removehandler(0x03dd, 0x0001, cga_in, NULL, NULL, cga_out, NULL, NULL, cga);
io_sethandler(0x03dd, 0x0001, cga_pravetz_in, NULL, NULL, cga_pravetz_out, NULL, NULL, cga);

View File

@@ -670,7 +670,8 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
if ((svga->seqaddr == 2) && !gd54xx->unlocked) {
o = svga->seqregs[svga->seqaddr & 0x1f];
svga_out(addr, val, svga);
svga->seqregs[svga->seqaddr & 0x1f] = (o & 0xf0) | (val & 0x0f);
if (svga->gdcreg[0xb] & 0x04)
svga->seqregs[svga->seqaddr & 0x1f] = (o & 0xf0) | (val & 0x0f);
return;
} else if ((svga->seqaddr > 6) && !gd54xx->unlocked)
return;
@@ -878,10 +879,6 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
case 0x09:
case 0x0a:
case 0x0b:
if (svga->gdcreg[0xb] & 0x04)
svga->writemode = svga->gdcreg[5] & 7;
else
svga->writemode = svga->gdcreg[5] & 3;
svga->adv_flags = 0;
if (svga->gdcreg[0xb] & 0x01)
svga->adv_flags = FLAG_EXTRA_BANKS;
@@ -893,6 +890,18 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
svga->adv_flags |= FLAG_LATCH8;
if (svga->gdcreg[0xb] & 0x10)
svga->adv_flags |= FLAG_ADDR_BY16;
if (svga->gdcreg[0xb] & 0x04)
svga->writemode = svga->gdcreg[5] & 7;
else {
svga->gdcreg[5] &= ~0x04;
svga->writemode = svga->gdcreg[5] & 3;
svga->adv_flags = 0;
svga->gdcreg[0] &= 0x0f;
gd543x_mmio_write(0xb8000, svga->gdcreg[0], gd54xx);
svga->gdcreg[1] &= 0x0f;
gd543x_mmio_write(0xb8004, svga->gdcreg[1], gd54xx);
svga->seqregs[2] &= 0x0f;
}
gd54xx_recalc_banking(gd54xx);
break;

View File

@@ -98,6 +98,12 @@ typedef struct banshee_t {
uint32_t vidScreenSize;
uint32_t vidSerialParallelPort;
uint32_t agpReqSize;
uint32_t agpHostAddressHigh;
uint32_t agpHostAddressLow;
uint32_t agpGraphicsAddress;
uint32_t agpGraphicsStride;
int overlay_pix_fmt;
uint32_t hwCurPatAddr, hwCurLoc, hwCurC0, hwCurC1;
@@ -161,19 +167,25 @@ enum {
Video_vidOverlayDvdy = 0xac,
Video_vidOverlayDvdyOffset = 0xe0,
Video_vidDesktopStartAddr = 0xe4,
Video_vidDesktopOverlayStride = 0xe8
Video_vidDesktopOverlayStride = 0xe8,
};
enum {
cmdBaseAddr0 = 0x20,
cmdBaseSize0 = 0x24,
cmdBump0 = 0x28,
cmdRdPtrL0 = 0x2c,
cmdRdPtrH0 = 0x30,
cmdAMin0 = 0x34,
cmdAMax0 = 0x3c,
cmdFifoDepth0 = 0x44,
cmdHoleCnt0 = 0x48
cmdBaseAddr0 = 0x20,
cmdBaseSize0 = 0x24,
cmdBump0 = 0x28,
cmdRdPtrL0 = 0x2c,
cmdRdPtrH0 = 0x30,
cmdAMin0 = 0x34,
cmdAMax0 = 0x3c,
cmdFifoDepth0 = 0x44,
cmdHoleCnt0 = 0x48,
Agp_agpReqSize = 0x00,
Agp_agpHostAddressLow = 0x04,
Agp_agpHostAddressHigh = 0x08,
Agp_agpGraphicsAddress = 0x0C,
Agp_agpGraphicsStride = 0x10,
};
#define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12)
@@ -515,7 +527,7 @@ banshee_recalctimings(svga_t *svga)
svga->bpp = 32;
break;
default:
fatal("Unknown pixel format %08x\n", banshee->vgaInit0);
fatal("Unknown pixel format %08x (vgaInit0=%08x)\n", VIDPROCCFG_DESKTOP_PIX_FORMAT, banshee->vgaInit0);
}
if (!(banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) && (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE))
svga->rowcount = 1;
@@ -1123,6 +1135,26 @@ banshee_cmd_read(banshee_t *banshee, uint32_t addr)
uint32_t ret = 0xffffffff;
switch (addr & 0x1fc) {
case Agp_agpHostAddressLow:
ret = banshee->agpHostAddressLow;
break;
case Agp_agpHostAddressHigh:
ret = banshee->agpHostAddressHigh;
break;
case Agp_agpGraphicsAddress:
ret = banshee->agpGraphicsAddress;
break;
case Agp_agpGraphicsStride:
ret = banshee->agpGraphicsStride;
break;
case Agp_agpReqSize:
ret = banshee->agpReqSize;
break;
case cmdBaseAddr0:
ret = voodoo->cmdfifo_base >> 12;
// banshee_log("Read cmdfifo_base %08x\n", ret);
@@ -1142,7 +1174,7 @@ banshee_cmd_read(banshee_t *banshee, uint32_t addr)
break;
default:
fatal("Unknown banshee_cmd_read %08x\n", addr);
fatal("Unknown banshee_cmd_read 0x%08x (reg 0x%03x)\n", addr, addr & 0x1fc);
}
return ret;
@@ -1348,6 +1380,26 @@ banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val)
voodoo_t *voodoo = banshee->voodoo;
// banshee_log("banshee_cmd_write: addr=%03x val=%08x\n", addr & 0x1fc, val);
switch (addr & 0x1fc) {
case Agp_agpHostAddressLow:
banshee->agpHostAddressLow = val;
break;
case Agp_agpHostAddressHigh:
banshee->agpHostAddressHigh = val;
break;
case Agp_agpGraphicsAddress:
banshee->agpGraphicsAddress = val;
break;
case Agp_agpGraphicsStride:
banshee->agpGraphicsStride = val;
break;
case Agp_agpReqSize:
banshee->agpReqSize = val;
break;
case cmdBaseAddr0:
voodoo->cmdfifo_base = (val & 0xfff) << 12;
voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12);
@@ -1382,7 +1434,7 @@ banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val)
break;
default:
banshee_log("Unknown banshee_cmd_write: addr=%08x val=%08x\n", addr, val);
banshee_log("Unknown banshee_cmd_write: addr=%08x val=%08x reg=0x%03x\n", addr, val, addr & 0x1fc);
break;
}
@@ -2857,7 +2909,8 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int
}
if (!banshee->has_bios)
mem_size = info->local; /* fixed size for on-board chips */
// mem_size = info->local; /* fixed size for on-board chips */
mem_size = device_get_config_int("memory"); /* MS-6168 / Bora Pro can do both 8 and 16 MB. */
else if (has_sgram) {
if (banshee->type == TYPE_VELOCITY100)
mem_size = 8; /* Velocity 100 only supports 8 MB */
@@ -3001,7 +3054,7 @@ v3_2000_agp_init(const device_t *info)
static void *
v3_2000_agp_onboard_init(const device_t *info)
{
return banshee_init_common(info, NULL, 0, TYPE_V3_2000, VOODOO_3, 1);
return banshee_init_common(info, NULL, 1, TYPE_V3_2000, VOODOO_3, 1);
}
static void *
v3_3000_init(const device_t *info)
@@ -3144,7 +3197,7 @@ const device_t voodoo_3_2000_agp_onboard_8m_device = {
{ .available = NULL },
.speed_changed = banshee_speed_changed,
.force_redraw = banshee_force_redraw,
banshee_sdram_config
banshee_sgram_config
};
const device_t voodoo_3_3000_device = {

View File

@@ -73,6 +73,7 @@ void
voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
{
voodoo_t *voodoo = (voodoo_t *) p;
void (*voodoo_recalc_tex)(voodoo_t *voodoo, int tmu) = NULL;
union {
uint32_t i;
float f;
@@ -82,6 +83,11 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
if (!chip)
chip = 0xf;
if (voodoo->type == VOODOO_3)
voodoo_recalc_tex = voodoo_recalc_tex3;
else
voodoo_recalc_tex = voodoo_recalc_tex12;
tempif.i = val;
// voodoo_reg_log("voodoo_reg_write_l: addr=%08x val=%08x(%f) chip=%x\n", addr, val, tempif.f, chip);
addr &= 0x3fc;

View File

@@ -59,7 +59,94 @@ voodoo_texture_log(const char *fmt, ...)
#endif
void
voodoo_recalc_tex(voodoo_t *voodoo, int tmu)
voodoo_recalc_tex12(voodoo_t *voodoo, int tmu)
{
int aspect = (voodoo->params.tLOD[tmu] >> 21) & 3;
int width = 256, height = 256;
int shift = 8;
int lod;
uint32_t base = voodoo->params.texBaseAddr[tmu];
uint32_t offset = 0;
int tex_lod = 0;
if (voodoo->params.tLOD[tmu] & LOD_S_IS_WIDER)
height >>= aspect;
else {
width >>= aspect;
shift -= aspect;
}
if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD)) {
width >>= 1;
height >>= 1;
shift--;
tex_lod++;
if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)
base = voodoo->params.texBaseAddr1[tmu];
}
for (lod = 0; lod <= LOD_MAX + 1; lod++) {
if (!width)
width = 1;
if (!height)
height = 1;
if (shift < 0)
shift = 0;
voodoo->params.tex_base[tmu][lod] = base + offset;
if (voodoo->params.tformat[tmu] & 8)
voodoo->params.tex_end[tmu][lod] = base + offset + (width * height * 2);
else
voodoo->params.tex_end[tmu][lod] = base + offset + (width * height);
voodoo->params.tex_w_mask[tmu][lod] = width - 1;
voodoo->params.tex_w_nmask[tmu][lod] = ~(width - 1);
voodoo->params.tex_h_mask[tmu][lod] = height - 1;
voodoo->params.tex_shift[tmu][lod] = shift;
voodoo->params.tex_lod[tmu][lod] = tex_lod;
if (!(voodoo->params.tLOD[tmu] & LOD_SPLIT) || ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) {
if (!(voodoo->params.tLOD[tmu] & LOD_ODD) || lod != 0) {
if (voodoo->params.tformat[tmu] & 8)
offset += width * height * 2;
else
offset += width * height;
if (voodoo->params.tLOD[tmu] & LOD_SPLIT) {
width >>= 2;
height >>= 2;
shift -= 2;
tex_lod += 2;
} else {
width >>= 1;
height >>= 1;
shift--;
tex_lod++;
}
if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) {
switch (tex_lod) {
case 0:
base = voodoo->params.texBaseAddr[tmu];
break;
case 1:
base = voodoo->params.texBaseAddr1[tmu];
break;
case 2:
base = voodoo->params.texBaseAddr2[tmu];
break;
default:
base = voodoo->params.texBaseAddr38[tmu];
break;
}
}
}
}
}
voodoo->params.tex_width[tmu] = width;
}
void
voodoo_recalc_tex3(voodoo_t *voodoo, int tmu)
{
int aspect = (voodoo->params.tLOD[tmu] >> 21) & 3;
int width = 256, height = 256;

View File

@@ -633,7 +633,7 @@ MINIVHDOBJ := cwalk.o libxml2_encoding.o minivhd_convert.o \
minivhd_struct_rw.o minivhd_util.o
CDROMOBJ := cdrom.o \
cdrom_image_backend.o cdrom_image_viso.o cdrom_image.o
cdrom_image_backend.o cdrom_image_viso.o cdrom_image.o cdrom_mitsumi.o
ZIPOBJ := zip.o

View File

@@ -25,59 +25,63 @@
#include <86box/86box.h>
#include <86box/plat_dynld.h>
#ifdef ENABLE_DYNLD_LOG
int dynld_do_log = ENABLE_DYNLD_LOG;
static void
dynld_log(const char *fmt, ...)
{
va_list ap;
if (dynld_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define dynld_log(fmt, ...)
#define dynld_log(fmt, ...)
#endif
void *
dynld_module(const char *name, dllimp_t *table)
{
HMODULE h;
HMODULE h;
dllimp_t *imp;
void *func;
void *func;
/* See if we can load the desired module. */
if ((h = LoadLibrary(name)) == NULL) {
dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError());
return (NULL);
dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError());
return(NULL);
}
/* Now load the desired function pointers. */
for (imp = table; imp->name != NULL; imp++) {
func = GetProcAddress(h, imp->name);
if (func == NULL) {
dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n",
name, imp->name, GetLastError());
FreeLibrary(h);
return (NULL);
}
for (imp=table; imp->name!=NULL; imp++) {
func = GetProcAddress(h, imp->name);
if (func == NULL) {
dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n",
name, imp->name, GetLastError());
FreeLibrary(h);
return(NULL);
}
/* To overcome typing issues.. */
*(char **) imp->func = (char *) func;
/* To overcome typing issues.. */
*(char **)imp->func = (char *)func;
}
/* All good. */
dynld_log("loaded %s\n", name);
return ((void *) h);
return((void *)h);
}
void
dynld_close(void *handle)
{
if (handle != NULL)
FreeLibrary((HMODULE) handle);
FreeLibrary((HMODULE)handle);
}