mirror of
https://github.com/86Box/86Box.git
synced 2026-02-24 02:18:20 -07:00
Merge remote-tracking branch 'upstream/master' into feature/mtrr
This commit is contained in:
28
.github/workflows/c-cpp.yml
vendored
28
.github/workflows/c-cpp.yml
vendored
@@ -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
|
||||
|
||||
30
src/86box.c
30
src/86box.c
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
443
src/cdrom/cdrom_mitsumi.c
Normal 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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
22
src/include/86box/cdrom_mitsumi.h
Normal file
22
src/include/86box/cdrom_mitsumi.h
Normal 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*/
|
||||
@@ -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;
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
137
src/pci.c
@@ -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++) {
|
||||
|
||||
@@ -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í"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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 "フィルター方式"
|
||||
|
||||
|
||||
@@ -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 "필터 형식"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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 "Метод фильтрации"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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 "Метод фільтрації"
|
||||
|
||||
|
||||
@@ -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 "过滤方式"
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -75,6 +75,7 @@ public:
|
||||
m_context = new QOpenGLContext();
|
||||
m_context->setFormat(format());
|
||||
m_context->create();
|
||||
update();
|
||||
}
|
||||
~HardwareRenderer()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>&2x</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action3x">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&3x</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action4x">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&4x</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action5x">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&5x</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action6x">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&6x</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action7x">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&7x</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action8x">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&8x</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionNearest">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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});
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user