diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 8dbd4a4b5..a91518084 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -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 diff --git a/src/86box.c b/src/86box.c index 6e8fa52dd..2c29b69ea 100644 --- a/src/86box.c +++ b/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); diff --git a/src/cdrom/CMakeLists.txt b/src/cdrom/CMakeLists.txt index 347a0e19d..6ed0acb0c 100644 --- a/src/cdrom/CMakeLists.txt +++ b/src/cdrom/CMakeLists.txt @@ -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) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index f4da5ce13..1209f09ad 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.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) { diff --git a/src/cdrom/cdrom_mitsumi.c b/src/cdrom/cdrom_mitsumi.c new file mode 100644 index 000000000..3ade6586c --- /dev/null +++ b/src/cdrom/cdrom_mitsumi.c @@ -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, + * + * Copyright 2022 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include +#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 +}; diff --git a/src/chipset/opti5x7.c b/src/chipset/opti5x7.c index d85ed4f54..76989481e 100644 --- a/src/chipset/opti5x7.c +++ b/src/chipset/opti5x7.c @@ -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 +}; diff --git a/src/chipset/opti822.c b/src/chipset/opti822.c index ec8ce699e..2605c27b9 100644 --- a/src/chipset/opti822.c +++ b/src/chipset/opti822.c @@ -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, + * + * Copyright 2022 Miran Grca. */ - #include #include #include @@ -22,22 +23,30 @@ #include #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); diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c index b2e9ae0e0..95aaf4cb6 100644 --- a/src/chipset/opti895.c +++ b/src/chipset/opti895.c @@ -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", diff --git a/src/config.c b/src/config.c index 11c8bdf50..e433e4071 100644 --- a/src/config.c +++ b/src/config.c @@ -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); diff --git a/src/cpu/808x.c b/src/cpu/808x.c index f74fcda52..ade656dd8 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -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; diff --git a/src/cpu/x86_ops_flag.h b/src/cpu/x86_ops_flag.h index 3da048dd5..16215b525 100644 --- a/src/cpu/x86_ops_flag.h +++ b/src/cpu/x86_ops_flag.h @@ -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(); diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index 685ef8427..2f51699cf 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -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, diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index c74e8eb76..72c74a144 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -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); diff --git a/src/include/86box/cdrom_mitsumi.h b/src/include/86box/cdrom_mitsumi.h new file mode 100644 index 000000000..747668c5d --- /dev/null +++ b/src/include/86box/cdrom_mitsumi.h @@ -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, + * + * Copyright 2022 Miran Grca. + */ +#ifndef CDROM_MITSUMI_H +#define CDROM_MITSUMI_H + +extern const device_t mitsumi_cdrom_device; + +#endif /*CDROM_MITSUMI_H*/ diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 6cd49b2f1..25f6ac924 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.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; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index c5b9d7b59..cb7ecbe3b 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -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 *); diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 230af8993..9f36fd7c9 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -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 diff --git a/src/include/86box/vid_voodoo_common.h b/src/include/86box/vid_voodoo_common.h index 0671d2913..e61a70836 100644 --- a/src/include/86box/vid_voodoo_common.h +++ b/src/include/86box/vid_voodoo_common.h @@ -32,6 +32,13 @@ #define TEX_CACHE_MAX 64 +#ifdef __cplusplus +#include +using atomic_int = std::atomic; +#else +#include +#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]; diff --git a/src/include/86box/vid_voodoo_texture.h b/src/include/86box/vid_voodoo_texture.h index d5ab603ab..2e0af97a3 100644 --- a/src/include/86box/vid_voodoo_texture.h +++ b/src/include/86box/vid_voodoo_texture.h @@ -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); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 1f616b791..4d0b27b98 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -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); diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index f47a6f6df..a5bff87d7 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -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); diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 4e51acb47..c0c18f3c7 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -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); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 0aa0468fa..a58f9c97d 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -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) { diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index 7e55766df..51d23da40 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -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(); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 4ef77535e..3542d0235 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -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, diff --git a/src/mem/mem.c b/src/mem/mem.c index 6d495b41b..55ad5f3a1 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -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) diff --git a/src/pci.c b/src/pci.c index b4078167c..6b51b0769 100644 --- a/src/pci.c +++ b/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++) { diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 4b5c8d30d..d6ce352ef 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -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í" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 45f344a9e..2897b23f5 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -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" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index 9ea707546..48e978f86 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -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" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 916619b02..a6b577322 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -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" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 0923b9948..4c803a442 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -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" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index ea250563d..2bfc8c1fc 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -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" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 98a5f60fa..beb98e567 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -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" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 7b9cd71ea..c39644c00 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -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" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 022523ff9..7d3d524c9 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -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" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index a32efc320..d7b2c5006 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -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" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 146275c74..790ea1ebc 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -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 "フィルター方式" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 13f5be067..05d8dcf59 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -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 "필터 형식" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 1a17217d6..71d109e2a 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -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" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 44c03cfec..29e6031a6 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -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" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 1cf187a0c..8349f7035 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -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" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index b483fabb3..9e0b4101d 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -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 "Метод фильтрации" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 6ea64a7c2..80f36a022 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -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" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 58f2c08bb..aa0273c79 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -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" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 5b16fa84c..f40e4d826 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -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 "Метод фільтрації" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index b83ab1d46..a863fc4b3 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -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 "过滤方式" diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp index 29b3613ea..dd0eed632 100644 --- a/src/qt/qt_hardwarerenderer.cpp +++ b/src/qt/qt_hardwarerenderer.cpp @@ -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() { diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp index 6bf0d3276..30515a2e8 100644 --- a/src/qt/qt_hardwarerenderer.hpp +++ b/src/qt/qt_hardwarerenderer.hpp @@ -75,6 +75,7 @@ public: m_context = new QOpenGLContext(); m_context->setFormat(format()); m_context->create(); + update(); } ~HardwareRenderer() { diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index e43db23e7..9e81531ab 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -75,6 +75,10 @@ extern "C" { #include #include #include +#if QT_CONFIG(vulkan) +#include +#include +#endif #include #include @@ -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); diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index ef70a0826..692b9c3f0 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -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(); diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 3551eddb1..fcc337cb3 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -118,6 +118,12 @@ + + + + + + @@ -478,6 +484,54 @@ &2x + + + true + + + &3x + + + + + true + + + &4x + + + + + true + + + &5x + + + + + true + + + &6x + + + + + true + + + &7x + + + + + true + + + &8x + + true diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index bea1af22f..560249660 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -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::ptr; diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index b3e771fea..6d5b36d80 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -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) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 670a0d0da..2d32f24a8 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -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"); diff --git a/src/qt/qt_vulkanwindowrenderer.cpp b/src/qt/qt_vulkanwindowrenderer.cpp index 629665d62..ba32d6e9b 100644 --- a/src/qt/qt_vulkanwindowrenderer.cpp +++ b/src/qt/qt_vulkanwindowrenderer.cpp @@ -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}); diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index 1e5ec5a71..e798093c0 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -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 */ diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index c004a8044..bee60bb5f 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -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; } diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 109a699d9..9fe6ee04c 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -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); diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 3cd581488..a49c89c18 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -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); diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 16839d93a..04791cb19 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -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; diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index d1521ce05..6775864fa 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -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 = { diff --git a/src/video/vid_voodoo_reg.c b/src/video/vid_voodoo_reg.c index 9eb2dc3f8..1b8e13022 100644 --- a/src/video/vid_voodoo_reg.c +++ b/src/video/vid_voodoo_reg.c @@ -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; diff --git a/src/video/vid_voodoo_texture.c b/src/video/vid_voodoo_texture.c index 12ec56d0b..9d1149c65 100644 --- a/src/video/vid_voodoo_texture.c +++ b/src/video/vid_voodoo_texture.c @@ -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; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 8e0156943..3718cd952 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -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 diff --git a/src/win/win_dynld.c b/src/win/win_dynld.c index 66fd0503d..98eb4739f 100644 --- a/src/win/win_dynld.c +++ b/src/win/win_dynld.c @@ -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); }