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

This commit is contained in:
Jasmine Iwanek
2023-12-10 20:49:43 -05:00
27 changed files with 1294 additions and 1266 deletions

View File

@@ -381,10 +381,10 @@ jobs:
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy-x86_64-gha${{ github.run_number }}'
path: build/artifacts/**
macos11:
name: "macOS 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
macos12:
name: "macOS 12 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
runs-on: macos-11
runs-on: macos-12
env:
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed

View File

@@ -226,11 +226,11 @@ jobs:
with:
category: "/language:${{matrix.language}}"
analyze-macos11:
analyze-macos12:
name: "Analyze macOS 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
name: "Analyze macOS 12 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
runs-on: macos-11
runs-on: macos-12
permissions:
actions: read

View File

@@ -343,6 +343,11 @@ mo_load(mo_t *dev, char *fn)
uint32_t size = 0;
unsigned int found = 0;
if (!dev->drv) {
mo_eject(dev->id);
return 0;
}
is_mdi = image_is_mdi(fn);
dev->drv->fp = plat_fopen(fn, dev->drv->read_only ? "rb" : "rb+");
@@ -403,7 +408,7 @@ mo_disk_reload(mo_t *dev)
void
mo_disk_unload(mo_t *dev)
{
if (dev->drv->fp) {
if (dev->drv && dev->drv->fp) {
fclose(dev->drv->fp);
dev->drv->fp = NULL;
}
@@ -412,7 +417,7 @@ mo_disk_unload(mo_t *dev)
void
mo_disk_close(mo_t *dev)
{
if (dev->drv->fp) {
if (dev->drv && dev->drv->fp) {
mo_disk_unload(dev);
memcpy(dev->drv->prev_image_path, dev->drv->image_path, sizeof(dev->drv->prev_image_path));

View File

@@ -485,6 +485,11 @@ zip_load(zip_t *dev, char *fn)
{
int size = 0;
if (!dev->drv) {
zip_eject(dev->id);
return 0;
}
dev->drv->fp = plat_fopen(fn, dev->drv->read_only ? "rb" : "rb+");
if (!dev->drv->fp) {
if (!dev->drv->read_only) {
@@ -548,7 +553,7 @@ zip_disk_reload(zip_t *dev)
void
zip_disk_unload(zip_t *dev)
{
if (dev->drv->fp) {
if (dev->drv && dev->drv->fp) {
fclose(dev->drv->fp);
dev->drv->fp = NULL;
}
@@ -557,7 +562,7 @@ zip_disk_unload(zip_t *dev)
void
zip_disk_close(zip_t *dev)
{
if (dev->drv->fp) {
if (dev->drv && dev->drv->fp) {
zip_disk_unload(dev);
memcpy(dev->drv->prev_image_path, dev->drv->image_path, sizeof(dev->drv->prev_image_path));

View File

@@ -137,7 +137,7 @@ typedef struct ibm8514_t {
} accel;
uint16_t test;
int ibm_mode;
int vendor_mode[2];
int v_total;
int dispend;

View File

@@ -34,53 +34,54 @@ extern int cgablink;
extern int scrollcache;
extern uint8_t edatlookup[4][4];
extern uint8_t egaremap2bpp[256];
void svga_recalc_remap_func(svga_t *svga);
extern void svga_recalc_remap_func(svga_t *svga);
void svga_render_null(svga_t *svga);
void svga_render_blank(svga_t *svga);
void svga_render_overscan_left(svga_t *svga);
void svga_render_overscan_right(svga_t *svga);
void svga_render_text_40(svga_t *svga);
void svga_render_text_80(svga_t *svga);
void svga_render_text_80_ksc5601(svga_t *svga);
extern void svga_render_null(svga_t *svga);
extern void svga_render_blank(svga_t *svga);
extern void svga_render_overscan_left(svga_t *svga);
extern void svga_render_overscan_right(svga_t *svga);
extern void svga_render_text_40(svga_t *svga);
extern void svga_render_text_80(svga_t *svga);
extern void svga_render_text_80_ksc5601(svga_t *svga);
void svga_render_2bpp_lowres(svga_t *svga);
void svga_render_2bpp_highres(svga_t *svga);
void svga_render_2bpp_headland_highres(svga_t *svga);
void svga_render_4bpp_lowres(svga_t *svga);
void svga_render_4bpp_highres(svga_t *svga);
void svga_render_8bpp_lowres(svga_t *svga);
void svga_render_8bpp_highres(svga_t *svga);
void svga_render_8bpp_tseng_lowres(svga_t *svga);
void svga_render_8bpp_tseng_highres(svga_t *svga);
void svga_render_8bpp_gs_lowres(svga_t *svga);
void svga_render_8bpp_gs_highres(svga_t *svga);
void svga_render_8bpp_rgb_lowres(svga_t *svga);
void svga_render_8bpp_rgb_highres(svga_t *svga);
void svga_render_15bpp_lowres(svga_t *svga);
void svga_render_15bpp_highres(svga_t *svga);
void svga_render_15bpp_mix_lowres(svga_t *svga);
void svga_render_15bpp_mix_highres(svga_t *svga);
void svga_render_16bpp_lowres(svga_t *svga);
void svga_render_16bpp_highres(svga_t *svga);
void svga_render_24bpp_lowres(svga_t *svga);
void svga_render_24bpp_highres(svga_t *svga);
void svga_render_32bpp_lowres(svga_t *svga);
void svga_render_32bpp_highres(svga_t *svga);
void svga_render_ABGR8888_lowres(svga_t *svga);
void svga_render_ABGR8888_highres(svga_t *svga);
void svga_render_RGBA8888_lowres(svga_t *svga);
void svga_render_RGBA8888_highres(svga_t *svga);
extern void svga_render_2bpp_lowres(svga_t *svga);
extern void svga_render_2bpp_highres(svga_t *svga);
extern void svga_render_2bpp_headland_highres(svga_t *svga);
extern void svga_render_4bpp_lowres(svga_t *svga);
extern void svga_render_4bpp_highres(svga_t *svga);
extern void svga_render_8bpp_lowres(svga_t *svga);
extern void svga_render_8bpp_highres(svga_t *svga);
extern void svga_render_8bpp_tseng_lowres(svga_t *svga);
extern void svga_render_8bpp_tseng_highres(svga_t *svga);
extern void svga_render_8bpp_gs_lowres(svga_t *svga);
extern void svga_render_8bpp_gs_highres(svga_t *svga);
extern void svga_render_8bpp_rgb_lowres(svga_t *svga);
extern void svga_render_8bpp_rgb_highres(svga_t *svga);
extern void svga_render_15bpp_lowres(svga_t *svga);
extern void svga_render_15bpp_highres(svga_t *svga);
extern void svga_render_15bpp_mix_lowres(svga_t *svga);
extern void svga_render_15bpp_mix_highres(svga_t *svga);
extern void svga_render_16bpp_lowres(svga_t *svga);
extern void svga_render_16bpp_highres(svga_t *svga);
extern void svga_render_24bpp_lowres(svga_t *svga);
extern void svga_render_24bpp_highres(svga_t *svga);
extern void svga_render_32bpp_lowres(svga_t *svga);
extern void svga_render_32bpp_highres(svga_t *svga);
extern void svga_render_ABGR8888_lowres(svga_t *svga);
extern void svga_render_ABGR8888_highres(svga_t *svga);
extern void svga_render_RGBA8888_lowres(svga_t *svga);
extern void svga_render_RGBA8888_highres(svga_t *svga);
void ibm8514_render_8bpp(svga_t *svga);
void ibm8514_render_15bpp(svga_t *svga);
void ibm8514_render_16bpp(svga_t *svga);
void ibm8514_render_24bpp(svga_t *svga);
void ibm8514_render_BGR(svga_t *svga);
void ibm8514_render_32bpp(svga_t *svga);
void ibm8514_render_ABGR8888(svga_t *svga);
void ibm8514_render_RGBA8888(svga_t *svga);
extern void ibm8514_render_8bpp(svga_t *svga);
extern void ibm8514_render_15bpp(svga_t *svga);
extern void ibm8514_render_16bpp(svga_t *svga);
extern void ibm8514_render_24bpp(svga_t *svga);
extern void ibm8514_render_BGR(svga_t *svga);
extern void ibm8514_render_32bpp(svga_t *svga);
extern void ibm8514_render_ABGR8888(svga_t *svga);
extern void ibm8514_render_RGBA8888(svga_t *svga);
extern void (*svga_render)(svga_t *svga);

View File

@@ -168,7 +168,7 @@ pit_irq0_timer(int new_out, int old_out)
void
machine_common_init(UNUSED(const machine_t *model))
{
uint8_t cpu_requires_fast_pit = is486 || (is8086 && (cpu_s->rspeed >= 8000000));
uint8_t cpu_requires_fast_pit = is486 || (!is286 && is8086 && (cpu_s->rspeed >= 8000000));
/* System devices first. */
pic_init();

View File

@@ -16,34 +16,27 @@
/* Ported over from QEMU */
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <wchar.h>
#include <time.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/timer.h>
#include <86box/nvr.h>
#include <86box/vid_ati_eeprom.h>
#include <86box/net_eeprom_nmc93cxx.h>
#include <86box/plat_unused.h>
struct nmc93cxx_eeprom_t {
uint8_t tick;
uint8_t address;
uint8_t command;
uint8_t writable;
uint8_t eecs;
uint8_t eesk;
uint8_t eedo;
ati_eeprom_t dev;
uint8_t addrbits;
uint16_t size;
uint16_t data;
char filename[1024];
uint16_t contents[];
};
typedef struct nmc93cxx_eeprom_t nmc93cxx_eeprom_t;
@@ -99,19 +92,19 @@ nmc93cxx_eeprom_init_params(UNUSED(const device_t *info), void *params)
eeprom->size = nwords;
eeprom->addrbits = addrbits;
/* Output DO is tristate, read results in 1. */
eeprom->eedo = 1;
eeprom->dev.out = 1;
if (params_details->filename) {
FILE *fp = nvr_fopen(params_details->filename, "rb");
strncpy(eeprom->filename, params_details->filename, sizeof(eeprom->filename) - 1);
if (fp) {
filldefault = !fread(eeprom->contents, sizeof(uint16_t), nwords, fp);
filldefault = !fread(eeprom->dev.data, sizeof(uint16_t), nwords, fp);
fclose(fp);
}
}
if (filldefault) {
memcpy(eeprom->contents, params_details->default_content, nwords * sizeof(uint16_t));
memcpy(eeprom->dev.data, params_details->default_content, nwords * sizeof(uint16_t));
}
return eeprom;
@@ -120,47 +113,47 @@ nmc93cxx_eeprom_init_params(UNUSED(const device_t *info), void *params)
void
nmc93cxx_eeprom_write(nmc93cxx_eeprom_t *eeprom, int eecs, int eesk, int eedi)
{
uint8_t tick = eeprom->tick;
uint8_t eedo = eeprom->eedo;
uint16_t address = eeprom->address;
uint8_t command = eeprom->command;
uint8_t tick = eeprom->dev.count;
uint8_t eedo = eeprom->dev.out;
uint16_t address = eeprom->dev.address;
uint8_t command = eeprom->dev.opcode;
nmc93cxx_eeprom_log(1, "CS=%u SK=%u DI=%u DO=%u, tick = %u\n",
eecs, eesk, eedi, eedo, tick);
if (!eeprom->eecs && eecs) {
if (!eeprom->dev.oldena && eecs) {
/* Start chip select cycle. */
nmc93cxx_eeprom_log(1, "Cycle start, waiting for 1st start bit (0)\n");
tick = 0;
command = 0x0;
address = 0x0;
} else if (eeprom->eecs && !eecs) {
} else if (eeprom->dev.oldena && !eecs) {
/* End chip select cycle. This triggers write / erase. */
if (eeprom->writable) {
if (!eeprom->dev.wp) {
uint8_t subcommand = address >> (eeprom->addrbits - 2);
if (command == 0 && subcommand == 2) {
/* Erase all. */
for (address = 0; address < eeprom->size; address++) {
eeprom->contents[address] = 0xffff;
eeprom->dev.data[address] = 0xffff;
}
} else if (command == 3) {
/* Erase word. */
eeprom->contents[address] = 0xffff;
eeprom->dev.data[address] = 0xffff;
} else if (tick >= 2 + 2 + eeprom->addrbits + 16) {
if (command == 1) {
/* Write word. */
eeprom->contents[address] &= eeprom->data;
eeprom->dev.data[address] &= eeprom->dev.dat;
} else if (command == 0 && subcommand == 1) {
/* Write all. */
for (address = 0; address < eeprom->size; address++) {
eeprom->contents[address] &= eeprom->data;
eeprom->dev.data[address] &= eeprom->dev.dat;
}
}
}
}
/* Output DO is tristate, read results in 1. */
eedo = 1;
} else if (eecs && !eeprom->eesk && eesk) {
} else if (eecs && !eeprom->dev.oldclk && eesk) {
/* Raising edge of clock shifts data in. */
if (tick == 0) {
/* Wait for 1st start bit. */
@@ -194,8 +187,8 @@ nmc93cxx_eeprom_write(nmc93cxx_eeprom_t *eeprom, int eecs, int eesk, int eedi)
tick++;
address = ((address << 1) | eedi);
if (tick == 2 + 2 + eeprom->addrbits) {
nmc93cxx_eeprom_log(1, "%s command, address = 0x%02x (value 0x%04x)\n",
opstring[command], address, eeprom->contents[address]);
nmc93cxx_eeprom_log(1, "Address = 0x%02x (value 0x%04x)\n",
address, eeprom->dev.data[address]);
if (command == 2) {
eedo = 0;
}
@@ -205,7 +198,7 @@ nmc93cxx_eeprom_write(nmc93cxx_eeprom_t *eeprom, int eecs, int eesk, int eedi)
switch (address >> (eeprom->addrbits - 2)) {
case 0:
nmc93cxx_eeprom_log(1, "write disable command\n");
eeprom->writable = 0;
eeprom->dev.wp = 1;
break;
case 1:
nmc93cxx_eeprom_log(1, "write all command\n");
@@ -215,7 +208,7 @@ nmc93cxx_eeprom_write(nmc93cxx_eeprom_t *eeprom, int eecs, int eesk, int eedi)
break;
case 3:
nmc93cxx_eeprom_log(1, "write enable command\n");
eeprom->writable = 1;
eeprom->dev.wp = 0;
break;
default:
@@ -223,7 +216,7 @@ nmc93cxx_eeprom_write(nmc93cxx_eeprom_t *eeprom, int eecs, int eesk, int eedi)
}
} else {
/* Read, write or erase word. */
eeprom->data = eeprom->contents[address];
eeprom->dev.dat = eeprom->dev.data[address];
}
}
} else if (tick < 2 + 2 + eeprom->addrbits + 16) {
@@ -231,28 +224,28 @@ nmc93cxx_eeprom_write(nmc93cxx_eeprom_t *eeprom, int eecs, int eesk, int eedi)
tick++;
if (command == 2) {
/* Read word. */
eedo = ((eeprom->data & 0x8000) != 0);
eedo = ((eeprom->dev.dat & 0x8000) != 0);
}
eeprom->data <<= 1;
eeprom->data += eedi;
eeprom->dev.dat <<= 1;
eeprom->dev.dat += eedi;
} else {
nmc93cxx_eeprom_log(1, "additional unneeded tick, not processed\n");
}
}
/* Save status of EEPROM. */
eeprom->tick = tick;
eeprom->eecs = eecs;
eeprom->eesk = eesk;
eeprom->eedo = eedo;
eeprom->address = address;
eeprom->command = command;
eeprom->dev.count = tick;
eeprom->dev.oldena = eecs;
eeprom->dev.oldclk = eesk;
eeprom->dev.out = eedo;
eeprom->dev.address = address;
eeprom->dev.opcode = command;
}
uint16_t
nmc93cxx_eeprom_read(nmc93cxx_eeprom_t *eeprom)
{
/* Return status of pin DO (0 or 1). */
return eeprom->eedo;
return eeprom->dev.out;
}
static void
@@ -261,7 +254,7 @@ nmc93cxx_eeprom_close(void *priv)
nmc93cxx_eeprom_t *eeprom = (nmc93cxx_eeprom_t *) priv;
FILE *fp = nvr_fopen(eeprom->filename, "wb");
if (fp) {
fwrite(eeprom->contents, 2, eeprom->size, fp);
fwrite(eeprom->dev.data, 2, eeprom->size, fp);
fclose(fp);
}
free(priv);
@@ -271,7 +264,7 @@ uint16_t *
nmc93cxx_eeprom_data(nmc93cxx_eeprom_t *eeprom)
{
/* Get EEPROM data array. */
return &eeprom->contents[0];
return &eeprom->dev.data[0];
}
const device_t nmc93cxx_device = {

File diff suppressed because it is too large Load Diff

View File

@@ -371,6 +371,8 @@ if (APPLE AND CMAKE_MACOSX_BUNDLE)
endif()
if (UNIX AND NOT APPLE AND NOT HAIKU)
target_sources(ui PRIVATE x11_util.c)
find_package(X11 REQUIRED)
target_link_libraries(ui PRIVATE X11::X11 X11::Xi)
target_sources(ui PRIVATE evdev_keyboard.cpp xinput2_mouse.cpp)

View File

@@ -117,6 +117,11 @@ extern int qt_nvr_save(void);
# undef KeyRelease
#endif
#if defined Q_OS_UNIX && !defined Q_OS_HAIKU && !defined Q_OS_MACOS
#include <qpa/qplatformwindow.h>
#include "x11_util.h"
#endif
#ifdef Q_OS_MACOS
# include "cocoa_keyboard.hpp"
// The namespace is required to avoid clashing typedefs; we only use this
@@ -712,6 +717,20 @@ MainWindow::MainWindow(QWidget *parent)
# endif
{}
#endif
#if defined Q_OS_UNIX && !defined Q_OS_MACOS && !defined Q_OS_HAIKU
if (QApplication::platformName().contains("xcb")) {
QTimer::singleShot(0, this, [this] {
auto whandle = windowHandle();
if (! whandle) {
qWarning() << "No window handle";
} else {
QPlatformWindow *window = whandle->handle();
set_wm_class(window->winId(), vm_name);
}
});
}
#endif
}
void

22
src/qt/x11_util.c Normal file
View File

@@ -0,0 +1,22 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include "x11_util.h"
void set_wm_class(unsigned long window, char *res_name) {
Display* display = XOpenDisplay(NULL);
if (display == NULL) {
return;
}
XClassHint hint;
XGetClassHint(display, window, &hint);
hint.res_name = res_name;
XSetClassHint(display, window, &hint);
// During testing, I've had to issue XGetClassHint after XSetClassHint
// to get the window manager to recognize the change.
XGetClassHint(display, window, &hint);
}

9
src/qt/x11_util.h Normal file
View File

@@ -0,0 +1,9 @@
#ifdef __cplusplus
extern "C" {
#endif
void set_wm_class(unsigned long window, char *res_name);
#ifdef __cplusplus
}
#endif

View File

@@ -709,7 +709,7 @@ static int
scsi_disk_blocks(scsi_disk_t *dev, int32_t *len, UNUSED(int first_batch), int out)
{
*len = 0;
uint32_t medium_size = hdd_image_get_last_sector(dev->id);
uint32_t medium_size = hdd_image_get_last_sector(dev->id) + 1;
if (!dev->sector_len) {
scsi_disk_command_complete(dev);

View File

@@ -945,7 +945,7 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv)
break;
case 0xff:
if (sb->dsp.sb_type > SBAWE32) {
if ((sb->dsp.sb_type > SBAWE32) && !sb->dsp.sb_16_dma_supported) {
/*
Bit 5: High DMA channel enabled (0 = yes, 1 = no);
Bit 2: ????;

View File

@@ -270,6 +270,11 @@ sdl_close(void)
sdl_destroy_texture();
sdl_destroy_window();
if (pixeldata != NULL) {
free(pixeldata);
pixeldata = NULL;
}
/* Quit. */
SDL_Quit();
sdl_flags = -1;
@@ -430,6 +435,8 @@ sdl_init_common(int flags)
/* Make sure we get a clean exit. */
atexit(sdl_close);
pixeldata = malloc(2048 * 2048 * 4);
/* Register our renderer! */
video_setblit(sdl_blit_shim);

View File

@@ -2009,7 +2009,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
if (dev->accel.cur_y >= 0x600)
dev->accel.cy |= ~0x5ff;
if ((dev->local >= 2) && dev->accel.ge_offset && (dev->accel_bpp == 24))
if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24))
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
else
dev->accel.dest = dev->accel.cy * dev->pitch;
@@ -2061,7 +2061,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
if (!(dev->accel.cmd & 0x40) && (frgd_mix == 2) && (bkgd_mix == 2) && (pixcntl == 0) && (cmd == 2)) {
if (!(dev->accel.sx & 1)) {
dev->accel.output = 1;
if ((dev->local >= 2) && dev->accel.ge_offset && (dev->accel_bpp == 24))
if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24))
dev->accel.newdest_out = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch);
else
dev->accel.newdest_out = (dev->accel.cy + 1) * dev->pitch;
@@ -2075,7 +2075,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
if (!(dev->accel.cmd & 2) && (frgd_mix == 2) && (pixcntl == 0) && (cmd == 2)) {
if (!(dev->accel.sx & 1)) {
dev->accel.input = 1;
if ((dev->local >= 2) && dev->accel.ge_offset && (dev->accel_bpp == 24))
if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24))
dev->accel.newdest_in = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch);
else
dev->accel.newdest_in = (dev->accel.cy + 1) * dev->pitch;
@@ -2258,7 +2258,7 @@ rect_fill_pix:
break;
}
if ((dev->local >= 2) && dev->accel.ge_offset && (dev->accel_bpp == 24))
if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24))
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
else
dev->accel.dest = dev->accel.cy * dev->pitch;
@@ -2343,7 +2343,7 @@ rect_fill_pix:
else
dev->accel.cy--;
if ((dev->local >= 2) && dev->accel.ge_offset && (dev->accel_bpp == 24))
if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24))
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
else
dev->accel.dest = dev->accel.cy * dev->pitch;
@@ -2435,7 +2435,7 @@ rect_fill_pix:
else
dev->accel.cy--;
if ((dev->local >= 2) && dev->accel.ge_offset && (dev->accel_bpp == 24))
if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24))
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
else
dev->accel.dest = dev->accel.cy * dev->pitch;
@@ -2494,7 +2494,7 @@ rect_fill_pix:
else
dev->accel.cy--;
if ((dev->local >= 2) && dev->accel.ge_offset && (dev->accel_bpp == 24)) {
if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) {
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
dev->accel.newdest_in = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch);
} else {
@@ -2519,7 +2519,7 @@ rect_fill_pix:
else
dev->accel.cy--;
if ((dev->local >= 2) && dev->accel.ge_offset && (dev->accel_bpp == 24)) {
if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) {
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
dev->accel.newdest_in = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch);
} else {
@@ -2575,7 +2575,7 @@ rect_fill_pix:
else
dev->accel.cy--;
if ((dev->local >= 2) && dev->accel.ge_offset && (dev->accel_bpp == 24)) {
if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) {
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
dev->accel.newdest_out = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch);
} else {
@@ -2600,7 +2600,7 @@ rect_fill_pix:
else
dev->accel.cy--;
if ((dev->local >= 2) && dev->accel.ge_offset && (dev->accel_bpp == 24)) {
if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24)) {
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
dev->accel.newdest_out = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch);
} else {
@@ -2690,7 +2690,7 @@ rect_fill_pix:
else
dev->accel.cy--;
if ((dev->local >= 2) && dev->accel.ge_offset && (dev->accel_bpp == 24))
if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24))
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
else
dev->accel.dest = dev->accel.cy * dev->pitch;
@@ -2767,7 +2767,7 @@ rect_fill:
else
dev->accel.cy--;
if ((dev->local >= 2) && dev->accel.ge_offset && (dev->accel_bpp == 24))
if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24))
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
else
dev->accel.dest = dev->accel.cy * dev->pitch;
@@ -2838,7 +2838,7 @@ rect_fill:
else
dev->accel.cy--;
if ((dev->local >= 2) && dev->accel.ge_offset && (dev->accel_bpp == 24))
if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24))
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
else
dev->accel.dest = dev->accel.cy * dev->pitch;
@@ -2923,7 +2923,7 @@ rect_fill:
else
dev->accel.cy--;
if ((dev->local >= 2) && dev->accel.ge_offset && (dev->accel_bpp == 24))
if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24))
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
else
dev->accel.dest = dev->accel.cy * dev->pitch;
@@ -2990,7 +2990,7 @@ rect_fill:
else
dev->accel.cy--;
if ((dev->local >= 2) && dev->accel.ge_offset && (dev->accel_bpp == 24))
if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && (dev->accel_bpp == 24))
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
else
dev->accel.dest = dev->accel.cy * dev->pitch;
@@ -3685,7 +3685,7 @@ bitblt:
}
}
} else {
if ((dev->accel_bpp == 24) && (dev->local >= 2) && (dev->accel.cmd == 0xc2b5)) {
if ((dev->accel_bpp == 24) && ((dev->local & 0xff) >= 0x02) && (dev->accel.cmd == 0xc2b5)) {
int64_t cx;
int64_t dx;

View File

@@ -101,7 +101,6 @@ typedef struct mach_t {
uint8_t bank_r;
uint16_t shadow_set;
int ext_on[2];
int ati_mode[2];
struct {
uint8_t line_idx;
@@ -1173,7 +1172,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
}
break;
case 3:
READ(dev->accel.src + ((dev->accel.cx)), mix);
READ(dev->accel.src + dev->accel.cx, mix);
mix = (mix & rd_mask) == rd_mask;
break;
@@ -1296,6 +1295,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
dev->accel.cx += mach->accel.src_width;
else
dev->accel.cx -= mach->accel.src_width;
dev->accel.cy += (mach->accel.src_y_dir ? 1 : -1);
if (dev->bpp)
dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch));
@@ -2267,7 +2267,7 @@ mach_accel_out_pixtrans(mach_t *mach, ibm8514_t *dev, uint16_t val)
case 0x000: /*8-bit size*/
if (mono_src == 2) {
if ((frgd_sel != 2) && (bkgd_sel != 2)) {
if ((mach->accel.dp_config & 0x1000) && (dev->local >= 2))
if ((mach->accel.dp_config & 0x1000) && ((dev->local & 0xff) >= 0x02))
val = (val >> 8) | (val << 8);
mach_accel_start(mach->accel.cmd_type, 1, 8, val | (val << 16), 0, mach, dev);
} else
@@ -2325,7 +2325,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
svga_recalctimings(svga);
break;
case 0xad:
if (dev->local >= 2) {
if ((dev->local & 0xff) >= 0x02) {
if ((old ^ val) & 0x0c)
svga_recalctimings(svga);
}
@@ -2341,7 +2341,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
if (mach->regs[0xbe] & 0x08) { /* Read/write bank mode */
mach->bank_r = (((mach->regs[0xb2] & 1) << 3) | ((mach->regs[0xb2] & 0xe0) >> 5));
mach->bank_w = ((mach->regs[0xb2] & 0x1e) >> 1);
if (dev->local >= 2) {
if ((dev->local & 0xff) >= 0x02) {
mach->bank_r |= ((mach->regs[0xae] & 0x0c) << 2);
mach->bank_w |= ((mach->regs[0xae] & 3) << 4);
}
@@ -2349,7 +2349,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
mach_log("Separate B2Bank = %02x, AEbank = %02x.\n", mach->regs[0xb2], mach->regs[0xae]);
} else { /* Single bank mode */
mach->bank_w = ((mach->regs[0xb2] & 0x1e) >> 1);
if (dev->local >= 2) {
if ((dev->local & 0xff) >= 0x02) {
mach->bank_w |= ((mach->regs[0xae] & 3) << 4);
}
mach->bank_r = mach->bank_w;
@@ -2377,7 +2377,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
svga_recalctimings(svga);
break;
case 0xb8:
if (dev->local >= 2) {
if ((dev->local & 0xff) >= 0x02) {
if ((old ^ val) & 0x40)
svga_recalctimings(svga);
} else {
@@ -2401,7 +2401,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
case 0x2ed:
rs2 = !!(mach->accel.ext_ge_config & 0x1000);
rs3 = !!(mach->accel.ext_ge_config & 0x2000);
if (dev->local >= 2) {
if ((dev->local & 0xff) >= 0x02) {
if (mach->pci_bus && !mach->ramdac_type)
ati68860_ramdac_out((addr & 3) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga);
else
@@ -2416,7 +2416,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
case 0x3C9:
rs2 = !!(mach->regs[0xa0] & 0x20);
rs3 = !!(mach->regs[0xa0] & 0x40);
if (dev->local >= 2) {
if ((dev->local & 0xff) >= 0x02) {
if (mach->pci_bus && !mach->ramdac_type)
ati68860_ramdac_out((addr & 3) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga);
else
@@ -2484,7 +2484,7 @@ mach_in(uint16_t addr, void *priv)
break;
case 0xb0:
temp = mach->regs[0xb0] | 0x80;
if (dev->local >= 2) { /*Mach32 VGA 1MB memory*/
if ((dev->local & 0xff) >= 0x02) { /*Mach32 VGA 1MB memory*/
temp |= 0x08;
temp &= ~0x10;
} else { /*ATI 28800 VGA 512kB memory*/
@@ -2514,7 +2514,7 @@ mach_in(uint16_t addr, void *priv)
case 0x2ed:
rs2 = !!(mach->accel.ext_ge_config & 0x1000);
rs3 = !!(mach->accel.ext_ge_config & 0x2000);
if (dev->local >= 2) {
if ((dev->local & 0xff) >= 0x02) {
if (mach->pci_bus && !mach->ramdac_type)
temp = ati68860_ramdac_in((addr & 3) | (rs2 << 2) | (rs3 << 3), svga->ramdac, svga);
else
@@ -2529,7 +2529,7 @@ mach_in(uint16_t addr, void *priv)
case 0x3C9:
rs2 = !!(mach->regs[0xa0] & 0x20);
rs3 = !!(mach->regs[0xa0] & 0x40);
if (dev->local >= 2) {
if ((dev->local & 0xff) >= 0x02) {
if (mach->pci_bus && !mach->ramdac_type)
temp = ati68860_ramdac_in((addr & 3) | (rs2 << 2) | (rs3 << 3), svga->ramdac, svga);
else
@@ -2564,7 +2564,7 @@ mach_recalctimings(svga_t *svga)
clock_sel = ((svga->miscout >> 2) & 3) | ((mach->regs[0xbe] & 0x10) >> 1) | ((mach->regs[0xb9] & 2) << 1);
if (dev->local >= 2) {
if ((dev->local & 0xff) >= 0x02) {
if (mach->regs[0xad] & 0x04)
svga->ma_latch |= 0x40000;
@@ -2583,14 +2583,18 @@ mach_recalctimings(svga_t *svga)
svga->htotal <<= 1;
svga->rowoffset <<= 1;
svga->gdcreg[5] &= ~0x40;
svga->attrregs[0x10] &= ~0x40;
}
if (mach->regs[0xb0] & 0x20)
if (mach->regs[0xb0] & 0x20) {
svga->gdcreg[5] |= 0x40;
svga->attrregs[0x10] |= 0x40;
}
mach_log("ON[0]=%d, ON[1]=%d, exton[0]=%d, exton[1]=%d, vendormode0=%d, vendormode1=%d.\n", dev->on[0], dev->on[1], mach->ext_on[0], mach->ext_on[1], dev->vendor_mode[0], dev->vendor_mode[1]);
if (dev->on[0] || dev->on[1]) {
mach_log("8514/A ON.\n");
if (dev->local >= 2) {
if ((dev->local & 0xff) >= 0x02) {
dev->h_disp = (dev->hdisp + 1) << 3;
dev->h_total = (dev->htotal + 1);
dev->v_total = (dev->vtotal + 1);
@@ -2639,7 +2643,6 @@ mach_recalctimings(svga_t *svga)
dev->v_syncstart >>= 1;
dev->v_total >>= 1;
}
dev->pitch = dev->ext_pitch;
dev->rowoffset = dev->ext_crt_pitch;
if ((mach->accel.ext_ge_config & 0x800) || (!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800))) {
@@ -2757,39 +2760,58 @@ mach_recalctimings(svga_t *svga)
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen);
if (mach->regs[0xa7] & 0x80)
svga->clock *= 3;
switch (svga->gdcreg[5] & 0x60) {
case 0x00:
if (svga->bpp <= 8) {
if (svga->attrregs[0x10] & 0x40) { /*8bpp mode*/
svga->map8 = svga->pallook;
if (svga->lowres) /*Low res (320)*/
svga->render = svga_render_8bpp_lowres;
else {
svga->render = svga_render_8bpp_highres;
svga->ma_latch <<= 1;
svga->rowoffset <<= 1;
}
} else {
mach_log("4bpp.\n");
if (svga->seqregs[1] & 8) /*Low res (320)*/
svga->render = svga_render_4bpp_lowres;
else
svga->render = svga_render_4bpp_highres;
break;
case 0x20: /*4 colours*/
if (svga->seqregs[1] & 8) /*Low res (320)*/
svga->render = svga_render_2bpp_lowres;
else
svga->render = svga_render_2bpp_highres;
break;
case 0x40:
case 0x60: /*256+ colours*/
switch (svga->bpp) {
default:
case 8:
svga->map8 = svga->pallook;
if (svga->lowres)
svga->render = svga_render_8bpp_lowres;
else {
svga->render = svga_render_8bpp_highres;
svga->ma_latch <<= 1;
svga->rowoffset <<= 1;
}
break;
}
} else {
switch (svga->gdcreg[5] & 0x60) {
case 0x00:
if (svga->seqregs[1] & 8) /*Low res (320)*/
svga->render = svga_render_4bpp_lowres;
else
svga->render = svga_render_4bpp_highres;
break;
case 0x20: /*4 colours*/
if (svga->seqregs[1] & 8) /*Low res (320)*/
svga->render = svga_render_2bpp_lowres;
else
svga->render = svga_render_2bpp_highres;
break;
case 0x40:
case 0x60: /*256+ colours*/
switch (svga->bpp) {
default:
case 8:
svga->map8 = svga->pallook;
if (svga->lowres)
svga->render = svga_render_8bpp_lowres;
else {
svga->render = svga_render_8bpp_highres;
svga->ma_latch <<= 1;
svga->rowoffset <<= 1;
}
break;
}
break;
}
break;
default:
break;
default:
break;
}
}
}
}
@@ -3689,11 +3711,11 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach)
WRITE8(port, dev->accel.advfunc_cntl, val);
dev->on[port & 1] = (dev->accel.advfunc_cntl & 0x01);
mach_log("%04x: ON=%d.\n", port, dev->on[port & 1]);
mach_log("ATI 8514/A: (0x%04x): ON=%d.\n", port, dev->on[port & 1]);
vga_on = !dev->on[port & 1];
mach->ext_on[port & 1] = dev->on[port & 1];
mach32_updatemapping(mach);
mach->ati_mode[port & 1] = 0;
dev->vendor_mode[port & 1] = 0;
svga_recalctimings(svga);
break;
@@ -3770,6 +3792,7 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach)
else
dev->ext_crt_pitch <<= 1;
}
mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val);
svga_recalctimings(svga);
break;
@@ -3814,9 +3837,10 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach)
case 0x4aef:
WRITE8(port, mach->accel.clock_sel, val);
dev->on[port & 1] = mach->accel.clock_sel & 0x01;
mach_log("ATI 8514/A: (0x%04x): ON=%d.\n", port, dev->on[port & 1]);
mach->ext_on[port & 1] = dev->on[port & 1];
vga_on = !dev->on[port & 1];
mach->ati_mode[port & 1] = 1;
dev->vendor_mode[port & 1] = 1;
svga_recalctimings(svga);
break;
@@ -3837,9 +3861,7 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach)
case 0x5aee:
case 0x5aef:
WRITE8(port, mach->shadow_set, val);
if (port & 1)
mach_log("Shadow set = %02x.\n", mach->shadow_set & 0x03);
mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val);
svga_recalctimings(svga);
break;
@@ -3882,13 +3904,14 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach)
case 0x76ef:
WRITE8(port, mach->accel.ge_pitch, val);
dev->ext_pitch = ((mach->accel.ge_pitch & 0xff) << 3);
mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val);
svga_recalctimings(svga);
break;
case 0x7aee:
case 0x7aef:
WRITE8(port, mach->accel.ext_ge_config, val);
if (dev->local >= 2) {
if ((dev->local & 0xff) >= 0x02) {
if (mach->accel.crt_pitch & 0xff)
dev->ext_crt_pitch = mach->accel.crt_pitch & 0xff;
switch (mach->accel.ext_ge_config & 0x30) {
@@ -3912,9 +3935,10 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach)
break;
}
svga_set_ramdac_type(svga, !!(mach->accel.ext_ge_config & 0x4000));
mach->ati_mode[port & 1] = 1;
dev->vendor_mode[port & 1] = 1;
mach32_updatemapping(mach);
}
mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val);
svga_recalctimings(svga);
break;
@@ -3922,7 +3946,7 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach)
case 0x7eef:
WRITE8(port, mach->accel.eeprom_control, val);
ati_eeprom_write(&mach->eeprom, mach->accel.eeprom_control & 4, mach->accel.eeprom_control & 2, mach->accel.eeprom_control & 1);
mach_log("[%04X]: 7EEE+%d VGA ON = %d, Ext = %i, val = %04x, pagesel = %04x.\n", CS, port & 1, vga_on, ibm8514_on, mach->accel.eeprom_control & 0x10ff, (mach->accel.eeprom_control & 0xf0) << 7);
mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val);
svga_recalctimings(svga);
break;
@@ -4274,7 +4298,7 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in
case 0xdaee:
if (len != 1) {
temp = mach->accel.src_x;
if (dev->local >= 2)
if ((dev->local & 0xff) >= 0x02)
temp &= 0x7ff;
} else
temp = mach->accel.src_x & 0xff;
@@ -4287,7 +4311,7 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in
case 0xdeee:
if (len != 1) {
temp = mach->accel.src_y;
if (dev->local >= 2)
if ((dev->local & 0xff) >= 0x02)
temp &= 0x7ff;
} else
temp = mach->accel.src_y & 0xff;
@@ -4617,10 +4641,47 @@ mach_accel_inl(uint16_t port, void *priv)
return temp;
}
static void
mach32_write_linear(uint32_t addr, uint8_t val, void *priv)
static uint32_t
mach32_decode_addr(svga_t *svga, uint32_t addr, int write)
{
svga_t *svga = (svga_t *) priv;
int memory_map_mode = (svga->gdcreg[6] >> 2) & 3;
addr &= 0x1ffff;
switch (memory_map_mode) {
case 0:
break;
case 1:
if (addr >= 0x10000)
return 0xffffffff;
break;
case 2:
addr -= 0x10000;
if (addr >= 0x8000)
return 0xffffffff;
break;
default:
case 3:
addr -= 0x18000;
if (addr >= 0x8000)
return 0xffffffff;
break;
}
if (memory_map_mode <= 1) {
if (write)
addr = (addr & svga->banked_mask) + svga->write_bank;
else
addr = (addr & svga->banked_mask) + svga->read_bank;
}
return addr;
}
static __inline void
mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach)
{
svga_t *svga = &mach->svga;
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
int writemask2 = svga->writemask;
int reset_wm = 0;
@@ -4631,6 +4692,12 @@ mach32_write_linear(uint32_t addr, uint8_t val, void *priv)
cycles -= svga->monitor->mon_video_timing_write_b;
if (!linear) {
addr = mach32_decode_addr(svga, addr, 1);
if (addr == 0xffffffff)
return;
}
if (!(svga->gdcreg[6] & 1))
svga->fullchange = 2;
@@ -4639,6 +4706,9 @@ mach32_write_linear(uint32_t addr, uint8_t val, void *priv)
addr &= ~3;
} else if (svga->chain4 && (svga->writemode < 4)) {
writemask2 = 1 << (addr & 3);
if (!linear)
addr &= ~3;
addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
} else if (svga->chain2_write) {
writemask2 &= ~0xa;
@@ -4750,40 +4820,31 @@ static void
mach32_write(uint32_t addr, uint8_t val, void *priv)
{
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
addr = (addr & svga->banked_mask) + svga->write_bank;
mach32_write_linear(addr, val, svga);
mach32_write_common(addr, val, 0, mach);
}
static void
mach32_writew(uint32_t addr, uint16_t val, void *priv)
{
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
addr = (addr & svga->banked_mask) + svga->write_bank;
mach32_write_linear(addr, val & 0xff, svga);
mach32_write_linear(addr + 1, val >> 8, svga);
mach32_write_common(addr, val & 0xff, 0, mach);
mach32_write_common(addr + 1, val >> 8, 0, mach);
}
static void
mach32_writel(uint32_t addr, uint32_t val, void *priv)
{
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
addr = (addr & svga->banked_mask) + svga->write_bank;
mach32_write_linear(addr, val & 0xff, svga);
mach32_write_linear(addr + 1, val >> 8, svga);
mach32_write_linear(addr + 2, val >> 16, svga);
mach32_write_linear(addr + 3, val >> 24, svga);
mach32_write_common(addr, val & 0xff, 0, mach);
mach32_write_common(addr + 1, val >> 8, 0, mach);
mach32_write_common(addr + 2, val >> 16, 0, mach);
mach32_write_common(addr + 3, val >> 24, 0, mach);
}
static uint8_t
mach32_read_linear(uint32_t addr, void *priv)
static __inline uint8_t
mach32_read_common(uint32_t addr, int linear, mach_t *mach)
{
svga_t *svga = (svga_t *) priv;
svga_t *svga = &mach->svga;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint32_t latch_addr = 0;
int readplane = svga->readplane;
@@ -4793,6 +4854,12 @@ mach32_read_linear(uint32_t addr, void *priv)
cycles -= svga->monitor->mon_video_timing_read_b;
if (!linear) {
addr = mach32_decode_addr(svga, addr, 0);
if (addr == 0xffffffff)
return 0xff;
}
count = 2;
latch_addr = (addr << count) & svga->decode_mask;
@@ -4865,11 +4932,9 @@ static uint8_t
mach32_read(uint32_t addr, void *priv)
{
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
uint8_t ret;
addr = (addr & svga->banked_mask) + svga->read_bank;
ret = mach32_read_linear(addr, svga);
ret = mach32_read_common(addr, 0, mach);
return ret;
}
@@ -4877,12 +4942,10 @@ static uint16_t
mach32_readw(uint32_t addr, void *priv)
{
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
uint16_t ret;
addr = (addr & svga->banked_mask) + svga->read_bank;
ret = mach32_read_linear(addr, svga);
ret |= (mach32_read_linear(addr + 1, svga) << 8);
ret = mach32_read_common(addr, 0, mach);
ret |= (mach32_read_common(addr + 1, 0, mach) << 8);
return ret;
}
@@ -4890,23 +4953,22 @@ static uint32_t
mach32_readl(uint32_t addr, void *priv)
{
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
uint32_t ret;
addr = (addr & svga->banked_mask) + svga->read_bank;
ret = mach32_read_linear(addr, svga);
ret |= (mach32_read_linear(addr + 1, svga) << 8);
ret |= (mach32_read_linear(addr + 2, svga) << 16);
ret |= (mach32_read_linear(addr + 3, svga) << 24);
ret = mach32_read_common(addr, 0, mach);
ret |= (mach32_read_common(addr + 1, 0, mach) << 8);
ret |= (mach32_read_common(addr + 2, 0, mach) << 16);
ret |= (mach32_read_common(addr + 3, 0, mach) << 24);
return ret;
}
static void
mach32_ap_writeb(uint32_t addr, uint8_t val, void *priv)
{
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
uint8_t port_dword = addr & 0xfc;
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint8_t port_dword = addr & 0xfc;
if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) &&
((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) {
@@ -4918,17 +4980,21 @@ mach32_ap_writeb(uint32_t addr, uint8_t val, void *priv)
mach_accel_outb(0x02e8 + (addr & 1) + (port_dword << 8), val, mach);
}
} else {
mach_log("Linear WORDB Write=%08x.\n", addr);
mach32_write_linear(addr, val, svga);
mach_log("Linear WORDB Write=%08x, val=%02x.\n", addr, val);
if (dev->on[0] || dev->on[1])
mach32_write_common(addr, val, 1, mach);
else
svga_write_linear(addr, val, svga);
}
}
static void
mach32_ap_writew(uint32_t addr, uint16_t val, void *priv)
{
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
uint8_t port_dword = addr & 0xfc;
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint8_t port_dword = addr & 0xfc;
if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) &&
((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) {
@@ -4940,18 +5006,22 @@ mach32_ap_writew(uint32_t addr, uint16_t val, void *priv)
mach_accel_outw(0x02e8 + (port_dword << 8), val, mach);
}
} else {
mach_log("Linear WORDW Write=%08x.\n", addr);
mach32_write_linear(addr, val & 0xff, svga);
mach32_write_linear(addr + 1, val >> 8, svga);
mach_log("Linear WORDW Write=%08x, val=%04x.\n", addr, val);
if (dev->on[0] || dev->on[1]) {
mach32_write_common(addr, val & 0xff, 1, mach);
mach32_write_common(addr + 1, val >> 8, 1, mach);
} else
svga_writew_linear(addr, val, svga);
}
}
static void
mach32_ap_writel(uint32_t addr, uint32_t val, void *priv)
{
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
uint8_t port_dword = addr & 0xfc;
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint8_t port_dword = addr & 0xfc;
if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) &&
((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) {
@@ -4965,31 +5035,40 @@ mach32_ap_writel(uint32_t addr, uint32_t val, void *priv)
mach_accel_outw(0x02e8 + (port_dword << 8) + 4, val >> 16, mach);
}
} else {
mach_log("Linear WORDL Write=%08x.\n", addr);
mach32_write_linear(addr, val & 0xff, svga);
mach32_write_linear(addr + 1, val >> 8, svga);
mach32_write_linear(addr + 2, val >> 16, svga);
mach32_write_linear(addr + 3, val >> 24, svga);
mach_log("Linear WORDL Write=%08x, val=%08x.\n", addr, val);
if (dev->on[0] || dev->on[1]) {
mach32_write_common(addr, val & 0xff, 1, mach);
mach32_write_common(addr + 1, val >> 8, 1, mach);
mach32_write_common(addr + 2, val >> 16, 1, mach);
mach32_write_common(addr + 3, val >> 24, 1, mach);
} else
svga_writel_linear(addr, val, svga);
}
}
static uint8_t
mach32_ap_readb(uint32_t addr, void *priv)
{
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint8_t temp;
uint8_t port_dword = addr & 0xfc;
uint8_t port_dword = addr & 0xfc;
if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) &&
((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) {
if (addr & 0x100) {
if (addr & 0x100)
temp = mach_accel_inb(0x02ee + (addr & 1) + (port_dword << 8), mach);
} else {
else
temp = mach_accel_inb(0x02e8 + (addr & 1) + (port_dword << 8), mach);
}
} else
temp = mach32_read_linear(addr, svga);
} else {
if (dev->on[0] || dev->on[1])
temp = mach32_read_common(addr, 1, mach);
else
temp = svga_read_linear(addr, svga);
mach_log("Linear WORDB Read=%08x, ret=%02x, fast=%d.\n", addr, temp, svga->fast);
}
return temp;
}
@@ -4997,21 +5076,26 @@ mach32_ap_readb(uint32_t addr, void *priv)
static uint16_t
mach32_ap_readw(uint32_t addr, void *priv)
{
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint16_t temp;
uint8_t port_dword = addr & 0xfc;
uint8_t port_dword = addr & 0xfc;
if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) &&
((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) {
if (addr & 0x100) {
if (addr & 0x100)
temp = mach_accel_inw(0x02ee + (port_dword << 8), mach);
} else {
else
temp = mach_accel_inw(0x02e8 + (port_dword << 8), mach);
}
} else {
temp = mach32_read_linear(addr, svga);
temp |= (mach32_read_linear(addr + 1, svga) << 8);
if (dev->on[0] || dev->on[1]) {
temp = mach32_read_common(addr, 1, mach);
temp |= (mach32_read_common(addr + 1, 1, mach) << 8);
} else
temp = svga_readw_linear(addr, svga);
mach_log("Linear WORDW Read=%08x, ret=%04x.\n", addr, temp);
}
return temp;
@@ -5020,10 +5104,11 @@ mach32_ap_readw(uint32_t addr, void *priv)
static uint32_t
mach32_ap_readl(uint32_t addr, void *priv)
{
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
mach_t *mach = (mach_t *) priv;
svga_t *svga = &mach->svga;
const ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
uint32_t temp;
uint8_t port_dword = addr & 0xfc;
uint8_t port_dword = addr & 0xfc;
if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) &&
((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) {
@@ -5035,10 +5120,15 @@ mach32_ap_readl(uint32_t addr, void *priv)
temp |= (mach_accel_inw(0x02e8 + (port_dword << 8) + 4, mach) << 8);
}
} else {
temp = mach32_read_linear(addr, svga);
temp |= (mach32_read_linear(addr + 1, svga) << 8);
temp |= (mach32_read_linear(addr + 2, svga) << 16);
temp |= (mach32_read_linear(addr + 3, svga) << 24);
if (dev->on[0] || dev->on[1]) {
temp = mach32_read_common(addr, 1, mach);
temp |= (mach32_read_common(addr + 1, 1, mach) << 8);
temp |= (mach32_read_common(addr + 2, 1, mach) << 16);
temp |= (mach32_read_common(addr + 3, 1, mach) << 24);
} else
temp = svga_readl_linear(addr, svga);
mach_log("Linear WORDL Read=%08x, ret=%08x, ON0=%d, ON1=%d.\n", addr, temp, dev->on[0], dev->on[1]);
}
return temp;
@@ -5098,7 +5188,7 @@ mach32_updatemapping(mach_t *mach)
mach->ap_size = 4;
mem_mapping_disable(&mach->mmio_linear_mapping);
}
if ((mach->ext_on[0] || mach->ext_on[1]) && (dev->local >= 2) && (mach->ati_mode[0] || mach->ati_mode[1])) {
if (((dev->local & 0xff) >= 0x02) && (dev->on[0] || dev->on[1]) && (mach->ext_on[0] || mach->ext_on[1]) && (dev->vendor_mode[0] || dev->vendor_mode[1])) {
mach_log("ExtON.\n");
mem_mapping_set_handler(&svga->mapping, mach32_read, mach32_readw, mach32_readl, mach32_write, mach32_writew, mach32_writel);
mem_mapping_set_p(&svga->mapping, mach);
@@ -5120,18 +5210,25 @@ mach32_hwcursor_draw(svga_t *svga, int displine)
uint32_t color0;
uint32_t color1;
if (dev->accel_bpp == 8) {
color0 = dev->pallook[mach->cursor_col_0];
color1 = dev->pallook[mach->cursor_col_1];
} else if (dev->accel_bpp == 15) {
color0 = video_15to32[((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0) & 0xffff];
color1 = video_15to32[((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1) & 0xffff];
} else if (dev->accel_bpp == 16) {
color0 = video_16to32[((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0) & 0xffff];
color1 = video_16to32[((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1) & 0xffff];
} else {
color0 = ((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0);
color1 = ((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1);
switch (dev->accel_bpp) {
case 8:
color0 = dev->pallook[mach->cursor_col_0];
color1 = dev->pallook[mach->cursor_col_1];
break;
case 15:
color0 = video_15to32[((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0) & 0xffff];
color1 = video_15to32[((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1) & 0xffff];
break;
case 16:
color0 = video_16to32[((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0) & 0xffff];
color1 = video_16to32[((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1) & 0xffff];
break;
case 24:
case 32:
default:
color0 = ((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0);
color1 = ((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1);
break;
}
if (dev->interlace && dev->hwcursor_oddeven)
@@ -5603,7 +5700,7 @@ mach8_init(const device_t *info)
mach->memory = device_get_config_int("memory");
mach->ramdac_type = mach->pci_bus ? device_get_config_int("ramdac") : 1;
if (dev->local >= 2) {
if ((dev->local & 0xff) >= 0x02) {
if (mach->pci_bus) {
if (mach->has_bios) {
rom_init(&mach->bios_rom,
@@ -5639,7 +5736,7 @@ mach8_init(const device_t *info)
0, MEM_MAPPING_EXTERNAL);
}
if (dev->local >= 2) {
if ((dev->local & 0xff) >= 0x02) {
svga_init(info, svga, mach, mach->memory << 10, /*default: 2MB for Mach32*/
mach_recalctimings,
mach_in, mach_out,
@@ -5721,7 +5818,7 @@ mach8_init(const device_t *info)
io_sethandler(0x02ea, 4, mach_in, NULL, NULL, mach_out, NULL, NULL, mach);
mach_io_set(mach);
if (dev->local >= 2) {
if ((dev->local & 0xff) >= 0x02) {
svga->decode_mask = (4 << 20) - 1;
mach->cursor_col_1 = 0xff;
mach->ext_cur_col_1_r = 0xff;

View File

@@ -650,6 +650,23 @@ gd54xx_is_5434(svga_t *svga)
return 0;
}
static void
gd54xx_set_svga_fast(gd54xx_t *gd54xx)
{
svga_t *svga = &gd54xx->svga;
if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5422) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5424))
svga->fast = ((svga->gdcreg[8] == 0xff) && !(svga->gdcreg[3] & 0x18) &&
!svga->gdcreg[1]) &&
((svga->chain4 && svga->packed_chain4) || svga->fb_only) &&
!(svga->adv_flags & FLAG_ADDR_BY8);
/* TODO: needs verification on other Cirrus chips */
else
svga->fast = ((svga->gdcreg[8] == 0xff) && !(svga->gdcreg[3] & 0x18) &&
!svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) ||
svga->fb_only);
}
static void
gd54xx_out(uint16_t addr, uint8_t val, void *priv)
{
@@ -793,13 +810,14 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv)
break;
case 0x07:
svga->packed_chain4 = svga->seqregs[7] & 1;
svga_recalctimings(svga);
if (gd54xx_is_5422(svga))
gd543x_recalc_mapping(gd54xx);
else
svga->seqregs[svga->seqaddr] &= 0x0f;
if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)
svga->set_reset_disabled = svga->seqregs[7] & 1;
gd54xx_set_svga_fast(gd54xx);
svga_recalctimings(svga);
break;
case 0x17:
if (gd54xx_is_5422(svga))
@@ -919,10 +937,8 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv)
break;
}
if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5422) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5424))
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); /*TODO: needs verification on other Cirrus chips*/
else
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || svga->fb_only);
gd54xx_set_svga_fast(gd54xx);
if (((svga->gdcaddr == 5) && ((val ^ o) & 0x70)) || ((svga->gdcaddr == 6) && ((val ^ o) & 1)))
svga_recalctimings(svga);
} else {

View File

@@ -61,8 +61,6 @@ static uint32_t pallook64[256];
static int ega_type = 0;
static int old_overscan_color = 0;
uint8_t egaremap2bpp[256];
/* 3C2 controls default mode on EGA. On VGA, it determines monitor type (mono or colour):
7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines). */
int egaswitchread;
@@ -1282,32 +1280,6 @@ ega_init(ega_t *ega, int monitor_type, int is_mono)
}
}
for (c = 0; c < 4; c++) {
for (d = 0; d < 4; d++) {
edatlookup[c][d] = 0;
if (c & 1)
edatlookup[c][d] |= 1;
if (d & 1)
edatlookup[c][d] |= 2;
if (c & 2)
edatlookup[c][d] |= 0x10;
if (d & 2)
edatlookup[c][d] |= 0x20;
}
}
for (c = 0; c < 256; c++) {
egaremap2bpp[c] = 0;
if (c & 0x01)
egaremap2bpp[c] |= 0x01;
if (c & 0x04)
egaremap2bpp[c] |= 0x02;
if (c & 0x10)
egaremap2bpp[c] |= 0x04;
if (c & 0x40)
egaremap2bpp[c] |= 0x08;
}
if (is_mono) {
for (c = 0; c < 256; c++) {
if (((c >> 3) & 3) == 0)

View File

@@ -605,6 +605,14 @@ et4000_recalctimings(svga_t *svga)
}
}
}
if ((svga->bpp == 8) && ((svga->gdcreg[5] & 0x60) >= 0x40)) {
svga->map8 = svga->pallook;
if (svga->lowres)
svga->render = svga_render_8bpp_lowres;
else
svga->render = svga_render_8bpp_highres;
}
}
static void

View File

@@ -219,7 +219,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
dev->on[1] = dev->on[0];
}
svga_log("3C3: XGA ON = %d.\n", xga->on);
svga_log("3C3: VGA ON = %d.\n", val & 0x01);
vga_on = val & 0x01;
break;
case 0x3c4:
@@ -611,7 +611,7 @@ svga_recalctimings(svga_t *svga)
svga->clock = (svga->vidclock) ? VGACONST2 : VGACONST1;
svga->lowres = svga->attrregs[0x10] & 0x40;
svga->lowres = !!(svga->attrregs[0x10] & 0x40);
svga->interlace = 0;
@@ -639,67 +639,82 @@ svga_recalctimings(svga_t *svga)
svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8;
svga->hdisp_old = svga->hdisp;
switch (svga->gdcreg[5] & 0x60) {
case 0x00:
if (svga->bpp <= 8) {
if (svga->attrregs[0x10] & 0x40) { /*8bpp mode*/
svga->map8 = svga->pallook;
if (svga->lowres) /*Low res (320)*/
svga->render = svga_render_8bpp_lowres;
else
svga->render = svga_render_8bpp_highres;
} else {
if (svga->seqregs[1] & 8) /*Low res (320)*/
svga->render = svga_render_4bpp_lowres;
else
svga->render = svga_render_4bpp_highres;
break;
case 0x20: /*4 colours*/
if (svga->seqregs[1] & 8) /*Low res (320)*/
svga->render = svga_render_2bpp_lowres;
else
svga->render = svga_render_2bpp_highres;
break;
case 0x40:
case 0x60: /*256+ colours*/
switch (svga->bpp) {
case 8:
svga->map8 = svga->pallook;
if (svga->lowres)
svga->render = svga_render_8bpp_lowres;
else
svga->render = svga_render_8bpp_highres;
break;
case 15:
if (svga->lowres)
svga->render = svga_render_15bpp_lowres;
else
svga->render = svga_render_15bpp_highres;
break;
case 16:
if (svga->lowres)
svga->render = svga_render_16bpp_lowres;
else
svga->render = svga_render_16bpp_highres;
break;
case 17:
if (svga->lowres)
svga->render = svga_render_15bpp_mix_lowres;
else
svga->render = svga_render_15bpp_mix_highres;
break;
case 24:
if (svga->lowres)
svga->render = svga_render_24bpp_lowres;
else
svga->render = svga_render_24bpp_highres;
break;
case 32:
if (svga->lowres)
svga->render = svga_render_32bpp_lowres;
else
svga->render = svga_render_32bpp_highres;
break;
}
} else {
switch (svga->gdcreg[5] & 0x60) {
case 0x00:
if (svga->seqregs[1] & 8) /*Low res (320)*/
svga->render = svga_render_4bpp_lowres;
else
svga->render = svga_render_4bpp_highres;
break;
case 0x20: /*4 colours*/
if (svga->seqregs[1] & 8) /*Low res (320)*/
svga->render = svga_render_2bpp_lowres;
else
svga->render = svga_render_2bpp_highres;
break;
case 0x40:
case 0x60: /*256+ colours*/
switch (svga->bpp) {
case 8:
svga->map8 = svga->pallook;
if (svga->lowres)
svga->render = svga_render_8bpp_lowres;
else
svga->render = svga_render_8bpp_highres;
break;
case 15:
if (svga->lowres)
svga->render = svga_render_15bpp_lowres;
else
svga->render = svga_render_15bpp_highres;
break;
case 16:
if (svga->lowres)
svga->render = svga_render_16bpp_lowres;
else
svga->render = svga_render_16bpp_highres;
break;
case 17:
if (svga->lowres)
svga->render = svga_render_15bpp_mix_lowres;
else
svga->render = svga_render_15bpp_mix_highres;
break;
case 24:
if (svga->lowres)
svga->render = svga_render_24bpp_lowres;
else
svga->render = svga_render_24bpp_highres;
break;
case 32:
if (svga->lowres)
svga->render = svga_render_32bpp_lowres;
else
svga->render = svga_render_32bpp_highres;
break;
default:
break;
}
break;
default:
break;
}
break;
default:
break;
default:
break;
}
}
}
}
@@ -727,7 +742,7 @@ svga_recalctimings(svga_t *svga)
}
if (ibm8514_active && (svga->dev8514 != NULL)) {
if (!dev->local)
if ((dev->local & 0xff) == 0x00)
ibm8514_recalctimings(svga);
}
@@ -1001,7 +1016,7 @@ svga_poll(void *priv)
else
svga->cursoron = svga->blink & (16 + (16 * blink_delay));
if (!(svga->gdcreg[6] & 1) && !(svga->blink & 15))
if (!(svga->blink & 15))
svga->fullchange = 2;
svga->blink = (svga->blink + 1) & 0x7f;

View File

@@ -16,6 +16,7 @@
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
@@ -392,202 +393,6 @@ svga_render_text_80_ksc5601(svga_t *svga)
}
}
void
svga_render_2bpp_lowres(svga_t *svga)
{
int changed_offset;
int x;
uint8_t dat[2];
uint32_t addr;
uint32_t *p;
uint32_t changed_addr;
if ((svga->displine + svga->y_add) < 0)
return;
if (svga->force_old_addr) {
changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12;
if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) {
p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) {
addr = svga->ma;
if (!(svga->crtc[0x17] & 0x40)) {
addr = (addr << 1) & svga->vram_mask;
addr &= ~7;
if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000))
addr |= 4;
if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000))
addr |= 4;
}
if (!(svga->crtc[0x17] & 0x01))
addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0);
if (!(svga->crtc[0x17] & 0x02))
addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0);
dat[0] = svga->vram[addr];
dat[1] = svga->vram[addr | 0x1];
if (svga->seqregs[1] & 4)
svga->ma += 2;
else
svga->ma += 4;
svga->ma &= svga->vram_mask;
p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]];
p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]];
p += 16;
}
}
} else {
changed_addr = svga->remap_func(svga, svga->ma);
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) {
addr = svga->remap_func(svga, svga->ma);
dat[0] = svga->vram[addr];
dat[1] = svga->vram[addr | 0x1];
if (svga->seqregs[1] & 4)
svga->ma += 2;
else
svga->ma += 4;
svga->ma &= svga->vram_mask;
p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]];
p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]];
p += 16;
}
}
}
}
void
svga_render_2bpp_highres(svga_t *svga)
{
int changed_offset;
int x;
uint8_t dat[2];
uint32_t addr;
uint32_t *p;
uint32_t changed_addr;
if ((svga->displine + svga->y_add) < 0)
return;
if (svga->force_old_addr) {
changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12;
if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) {
p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
addr = svga->ma;
if (!(svga->crtc[0x17] & 0x40)) {
addr = (addr << 1) & svga->vram_mask;
addr &= ~7;
if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000))
addr |= 4;
if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000))
addr |= 4;
}
if (!(svga->crtc[0x17] & 0x01))
addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0);
if (!(svga->crtc[0x17] & 0x02))
addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0);
dat[0] = svga->vram[addr];
dat[1] = svga->vram[addr | 0x1];
if (svga->seqregs[1] & 4)
svga->ma += 2;
else
svga->ma += 4;
svga->ma &= svga->vram_mask;
p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
p[3] = svga->pallook[svga->egapal[dat[0] & 3]];
p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
p[7] = svga->pallook[svga->egapal[dat[1] & 3]];
p += 8;
}
}
} else {
changed_addr = svga->remap_func(svga, svga->ma);
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
addr = svga->remap_func(svga, svga->ma);
dat[0] = svga->vram[addr];
dat[1] = svga->vram[addr | 0x1];
if (svga->seqregs[1] & 4)
svga->ma += 2;
else
svga->ma += 4;
svga->ma &= svga->vram_mask;
p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
p[3] = svga->pallook[svga->egapal[dat[0] & 3]];
p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
p[7] = svga->pallook[svga->egapal[dat[1] & 3]];
p += 8;
}
}
}
}
void
svga_render_2bpp_headland_highres(svga_t *svga)
{
@@ -643,243 +448,225 @@ svga_render_2bpp_headland_highres(svga_t *svga)
}
}
void
svga_render_4bpp_lowres(svga_t *svga)
static void
svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits)
{
int x;
int oddeven;
uint32_t addr;
uint32_t *p;
uint8_t edat[4];
uint8_t dat;
uint32_t changed_addr;
uint32_t changed_offset;
const bool blinked = svga->blink & 0x10;
const bool attrblink = ((svga->attrregs[0x10] & 0x08) != 0);
/*
The following is likely how it works on an IBM VGA - that is, it works with its BIOS.
But on some cards, certain modes are broken.
- S3 Trio: mode 13h (320x200x8), incbypow2 given as 2 treated as 0
- ET4000/W32i: mode 2Eh (640x480x8), incevery given as 2 treated as 1
*/
const bool forcepacked = combine8bits && (svga->force_old_addr || svga->packed_chain4);
/*
SVGA cards with a high-resolution 8bpp mode may actually bypass the VGA shifter logic.
- HT-216 (+ other Video7 chipsets?) has 0x3C4.0xC8 bit 4 which, when set to 1, loads
bytes directly, bypassing the shifters.
*/
const bool highres8bpp = combine8bits && highres;
const bool dwordload = ((svga->seqregs[0x01] & 0x10) != 0);
const bool wordload = ((svga->seqregs[0x01] & 0x04) != 0) && !dwordload;
const bool wordincr = ((svga->crtc[0x17] & 0x08) != 0);
const bool dwordincr = ((svga->crtc[0x14] & 0x20) != 0) && !wordincr;
const bool dwordshift = ((svga->crtc[0x14] & 0x40) != 0);
const bool wordshift = ((svga->crtc[0x17] & 0x40) == 0) && !dwordshift;
const uint32_t incbypow2 = forcepacked ? 0 : (dwordshift ? 2 : wordshift ? 1 : 0);
const uint32_t incevery = forcepacked ? 1 : (dwordincr ? 4 : wordincr ? 2 : 1);
const uint32_t loadevery = forcepacked ? 1 : (dwordload ? 4 : wordload ? 2 : 1);
const bool shift4bit = ((svga->gdcreg[0x05] & 0x40) == 0x40) || highres8bpp;
const bool shift2bit = ((svga->gdcreg[0x05] & 0x60) == 0x20) && !shift4bit;
const int dwshift = highres ? 0 : 1;
const int dotwidth = 1 << dwshift;
const int charwidth = dotwidth * (combine8bits ? 4 : 8);
const uint32_t planemask = 0x11111111 * (uint32_t) (svga->plane_mask);
const uint32_t blinkmask = (attrblink ? 0x88888888 : 0x0);
const uint32_t blinkval = (attrblink && blinked ? 0x88888888 : 0x0);
/*
This is actually a 8x 3-bit lookup table,
preshifted by 2 bits to allow shifting by multiples of 4 bits.
Anyway, when we perform a planar-to-chunky conversion,
we keep the pixel values in a scrambled order.
This lookup table unscrambles them.
WARNING: Octal values are used here!
*/
const uint32_t shift_values = (shift4bit
? ((067452301) << 2)
: shift2bit
? ((026370415) << 2)
: ((002461357) << 2));
if ((svga->displine + svga->y_add) < 0)
return;
if (svga->force_old_addr) {
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) {
p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) {
addr = svga->ma;
oddeven = 0;
if (!(svga->crtc[0x17] & 0x40)) {
addr = (addr << 1) & svga->vram_mask;
if (svga->seqregs[1] & 4)
oddeven = (addr & 4) ? 1 : 0;
addr &= ~7;
if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000))
addr |= 4;
if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000))
addr |= 4;
}
if (!(svga->crtc[0x17] & 0x01))
addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0);
if (!(svga->crtc[0x17] & 0x02))
addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0);
if (svga->seqregs[1] & 4) {
edat[0] = svga->vram[addr | oddeven];
edat[2] = svga->vram[addr | oddeven | 0x2];
edat[1] = edat[3] = 0;
svga->ma += 2;
} else {
*(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]);
svga->ma += 4;
}
svga->ma &= svga->vram_mask;
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
p += 16;
}
}
} else {
changed_addr = svga->remap_func(svga, svga->ma);
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) {
addr = svga->remap_func(svga, svga->ma);
oddeven = 0;
if (svga->seqregs[1] & 4) {
oddeven = (addr & 4) ? 1 : 0;
edat[0] = svga->vram[addr | oddeven];
edat[2] = svga->vram[addr | oddeven | 0x2];
edat[1] = edat[3] = 0;
svga->ma += 2;
} else {
*(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]);
svga->ma += 4;
}
svga->ma &= svga->vram_mask;
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
p += 16;
}
}
}
}
void
svga_render_4bpp_highres(svga_t *svga)
{
int changed_offset;
int x;
int oddeven;
uint32_t addr;
uint32_t *p;
uint8_t edat[4];
uint8_t dat;
uint32_t changed_addr;
if ((svga->displine + svga->y_add) < 0)
return;
if (svga->force_old_addr) {
if (svga->force_old_addr)
changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12;
else
changed_offset = svga->remap_func(svga, svga->ma) >> 12;
if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) {
p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add];
if (!(svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange))
return;
p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
addr = svga->ma;
oddeven = 0;
uint32_t incr_counter = 0;
uint32_t load_counter = 0;
uint32_t edat = 0;
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += charwidth) {
if (load_counter == 0) {
/* Find our address */
if (svga->force_old_addr) {
addr = ((svga->ma & ~0x3) << incbypow2);
if (!(svga->crtc[0x17] & 0x40)) {
addr = (addr << 1) & svga->vram_mask;
if (svga->seqregs[1] & 4)
oddeven = (addr & 4) ? 1 : 0;
addr &= ~7;
if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000))
addr |= 4;
if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000))
addr |= 4;
if (incbypow2 == 2) {
if (svga->ma & (4 << 15))
addr |= 0x8;
if (svga->ma & (4 << 14))
addr |= 0x4;
} else if (incbypow2 == 1) {
if ((svga->crtc[0x17] & 0x20)) {
if (svga->ma & (4 << 15))
addr |= 0x4;
} else {
if (svga->ma & (4 << 13))
addr |= 0x4;
}
} else {
/* Nothing */
}
if (!(svga->crtc[0x17] & 0x01))
addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0);
if (!(svga->crtc[0x17] & 0x02))
addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0);
} else if (svga->remap_required)
addr = svga->remap_func(svga, svga->ma);
else
addr = svga->ma;
if (svga->seqregs[1] & 4) {
edat[0] = svga->vram[addr | oddeven];
edat[2] = svga->vram[addr | oddeven | 0x2];
edat[1] = edat[3] = 0;
svga->ma += 2;
addr &= svga->vram_display_mask;
/* Load VRAM */
edat = *(uint32_t *) &svga->vram[addr];
/*
EGA and VGA actually use 4bpp planar as its native format.
But 4bpp chunky is generally easier to deal with on a modern CPU.
shift4bit is the native format for this renderer (4bpp chunky).
*/
if (!shift4bit) {
if (shift2bit) {
/* Group 2x 2bpp values into 4bpp values */
edat = (edat & 0xCCCC3333) | ((edat << 14) & 0x33330000) | ((edat >> 14) & 0x0000CCCC);
} else {
*(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]);
svga->ma += 4;
/* Group 4x 1bpp values into 4bpp values */
edat = (edat & 0xAA55AA55) | ((edat << 7) & 0x55005500) | ((edat >> 7) & 0x00AA00AA);
edat = (edat & 0xCCCC3333) | ((edat << 14) & 0x33330000) | ((edat >> 14) & 0x0000CCCC);
}
svga->ma &= svga->vram_mask;
}
} else {
/*
According to the 82C451 VGA clone chipset datasheet, all 4 planes chain in a ring.
So, rotate them all around.
Planar version: edat = (edat >> 8) | (edat << 24);
Here's the chunky version...
*/
edat = ((edat >> 1) & 0x77777777) | ((edat << 3) & 0x88888888);
}
load_counter += 1;
if (load_counter >= loadevery)
load_counter = 0;
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
incr_counter += 1;
if (incr_counter >= incevery) {
incr_counter = 0;
svga->ma += 4;
/* DISCREPANCY TODO FIXME 2/4bpp used vram_mask, 8bpp used vram_display_mask --GM */
svga->ma &= svga->vram_display_mask;
}
p += 8;
uint32_t current_shift = shift_values;
uint32_t out_edat = edat;
/*
Apply blink
FIXME: Confirm blink behaviour on real hardware
The VGA 4bpp graphics blink logic was a pain to work out.
If plane 3 is enabled in the attribute controller, then:
- if bit 3 is 0, then we force the output of it to be 1.
- if bit 3 is 1, then the output blinks.
This can be tested with Lotus 1-2-3 release 2.3 with the WYSIWYG addon.
If plane 3 is disabled in the attribute controller, then the output blinks.
This can be tested with QBASIC SCREEN 10 - anything using color #2 should
blink and nothing else.
If you can simplify the following and have it still work, give yourself a medal.
*/
out_edat = ((out_edat & planemask & ~blinkmask) | ((out_edat | ~planemask) & blinkmask & blinkval)) ^ blinkmask;
for (int i = 0; i < 8; i += 2) {
/*
c0 denotes the first 4bpp pixel shifted, while c1 denotes the second.
For 8bpp modes, the first 4bpp pixel is the upper 4 bits.
*/
uint32_t c0 = (out_edat >> (current_shift & 0x1C)) & 0xF;
current_shift >>= 3;
uint32_t c1 = (out_edat >> (current_shift & 0x1C)) & 0xF;
current_shift >>= 3;
if (combine8bits) {
uint32_t ccombined = (c0 << 4) | c1;
uint32_t p0 = svga->map8[ccombined];
const int outoffs = (i >> 1) << dwshift;
for (int subx = 0; subx < dotwidth; subx++)
p[outoffs + subx] = p0;
} else {
uint32_t p0 = svga->pallook[svga->egapal[c0]];
uint32_t p1 = svga->pallook[svga->egapal[c1]];
const int outoffs = i << dwshift;
for (int subx = 0; subx < dotwidth; subx++)
p[outoffs + subx] = p0;
for (int subx = 0; subx < dotwidth; subx++)
p[outoffs + subx + dotwidth] = p1;
}
}
} else {
changed_addr = svga->remap_func(svga, svga->ma);
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
addr = svga->remap_func(svga, svga->ma);
oddeven = 0;
if (svga->seqregs[1] & 4) {
oddeven = (addr & 4) ? 1 : 0;
edat[0] = svga->vram[addr | oddeven];
edat[2] = svga->vram[addr | oddeven | 0x2];
edat[1] = edat[3] = 0;
svga->ma += 2;
} else {
*(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]);
svga->ma += 4;
}
svga->ma &= svga->vram_mask;
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
p += 8;
}
}
p += charwidth;
}
}
/*
Remap these to the paletted renderer
(*, highres, combine8bits)
*/
void svga_render_2bpp_lowres(svga_t *svga) { svga_render_indexed_gfx(svga, false, false); }
void svga_render_2bpp_highres(svga_t *svga) { svga_render_indexed_gfx(svga, true, false); }
void svga_render_4bpp_lowres(svga_t *svga) { svga_render_indexed_gfx(svga, false, false); }
void svga_render_4bpp_highres(svga_t *svga) { svga_render_indexed_gfx(svga, true, false); }
void svga_render_8bpp_lowres(svga_t *svga) { svga_render_indexed_gfx(svga, false, true); }
void svga_render_8bpp_highres(svga_t *svga) { svga_render_indexed_gfx(svga, true, true); }
// TODO: Integrate more of this into the generic paletted renderer --GM
#if 0
void
svga_render_8bpp_lowres(svga_t *svga)
{
@@ -1034,6 +821,7 @@ svga_render_8bpp_highres(svga_t *svga)
}
}
}
#endif
void
svga_render_8bpp_tseng_lowres(svga_t *svga)

View File

@@ -211,6 +211,7 @@ enum {
Agp_agpGraphicsStride = 0x10,
};
#define VGAINIT0_RAMDAC_8BIT (1 << 2)
#define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12)
#define VIDPROCCFG_VIDPROC_ENABLE (1 << 0)
@@ -765,6 +766,7 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *priv)
break;
case Init_vgaInit0:
banshee->vgaInit0 = val;
svga_set_ramdac_type(svga, (val & VGAINIT0_RAMDAC_8BIT ? RAMDAC_8BIT : RAMDAC_6BIT));
break;
case Init_vgaInit1:
banshee->vgaInit1 = val;

View File

@@ -160,7 +160,7 @@ cmdfifo_get(voodoo_t *voodoo)
uint32_t val;
if (!voodoo->cmdfifo_in_sub) {
while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr) {
while (voodoo->fifo_thread_run && (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr)) {
thread_wait_event(voodoo->wake_fifo_thread, -1);
thread_reset_event(voodoo->wake_fifo_thread);
}

View File

@@ -519,7 +519,6 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv)
xga_updatemapping(svga);
break;
case 4:
xga->access_mode &= ~8;
if ((xga->disp_cntl_2 & 7) == 4)
xga->aperture_cntl = 0;
break;
@@ -926,16 +925,22 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b
addr += (x >> 3);
if (!skip) {
READ(addr, byte);
} else {
} else
byte = mem_readb_phys(addr);
}
if (xga->linear_endian_reverse) {
if (xga->linear_endian_reverse)
bits = 7 - (x & 7);
} else {
if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8))
bits = (x & 7);
else {
bits = 7 - (x & 7);
else {
if (xga->accel.px_map_format[xga->accel.dst_map] & 8) {
if ((xga->accel.px_map_format[xga->accel.src_map] & 8) && (xga->accel.px_map_format[map] & 8))
bits = (x & 7);
else
bits = 7 - (x & 7);
} else {
if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8))
bits = (x & 7);
else
bits = 7 - (x & 7);
}
}
px = (byte >> bits) & 1;
@@ -966,17 +971,16 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
addr += (x >> 3);
if (!skip) {
READ(addr, byte);
} else {
} else
byte = mem_readb_phys(addr);
}
if (xga->linear_endian_reverse) {
if (xga->linear_endian_reverse)
bits = 7 - (x & 7);
} else {
else {
if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8))
bits = (x & 7);
else {
else
bits = 7 - (x & 7);
}
}
px = (byte >> bits) & 1;
return px;
@@ -985,9 +989,9 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
addr += (x >> 1);
if (!skip) {
READ(addr, byte);
} else {
} else
byte = mem_readb_phys(addr);
}
return byte;
case 3: /*8-bit*/
addr += (y * width);
@@ -1010,9 +1014,8 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
} else {
if (!skip) {
READW(addr, byte);
} else {
} else
byte = mem_readb_phys(addr) | (mem_readb_phys(addr + 1) << 8);
}
}
return byte;
@@ -1045,9 +1048,9 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
addr += (x >> 3);
if (!skip) {
READ(addr, byte);
} else {
} else
byte = mem_readb_phys(addr);
}
if (xga->linear_endian_reverse) {
mask = 1 << (7 - (x & 7));
} else {
@@ -1079,14 +1082,13 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
} else {
byte = mem_readb_phys(addr);
}
if (xga->linear_endian_reverse) {
if (xga->linear_endian_reverse)
mask = 0x0f << ((1 - (x & 1)) << 2);
} else {
if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) {
else {
if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8))
mask = 0x0f << ((x & 1) << 2);
} else {
else
mask = 0x0f << ((1 - (x & 1)) << 2);
}
}
byte = (byte & ~mask) | (pixel & mask);
if (!skip) {
@@ -1136,8 +1138,8 @@ xga_short_stroke(svga_t *svga, uint8_t ssv)
uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map];
int y = ssv & 0x0f;
int x = 0;
int dx;
int dy;
int16_t dx;
int16_t dy;
int dirx = 0;
int diry = 0;
@@ -1269,41 +1271,29 @@ xga_line_draw_write(svga_t *svga)
int err;
int tmpswap;
int steep = 1;
int xdir;
int ydir;
int xdir = (xga->accel.octant & 0x04) ? -1 : 1;
int ydir = (xga->accel.octant & 0x02) ? -1 : 1;
int y = xga->accel.blt_width;
int x = 0;
int dx;
int dy;
int16_t dx;
int16_t dy;
int draw_pixel;
dminor = (xga->accel.bres_k1);
dminor = xga->accel.bres_k1;
if (xga->accel.bres_k1 & 0x2000)
dminor |= ~0x1fff;
dminor >>= 1;
destxtmp = (xga->accel.bres_k2);
destxtmp = xga->accel.bres_k2;
if (xga->accel.bres_k2 & 0x2000)
destxtmp |= ~0x1fff;
dmajor = -(destxtmp - (dminor << 1)) >> 1;
err = (xga->accel.bres_err_term);
err = xga->accel.bres_err_term;
if (xga->accel.bres_err_term & 0x2000)
err |= ~0x1fff;
if (xga->accel.octant & 0x02) {
ydir = -1;
} else {
ydir = 1;
}
if (xga->accel.octant & 0x04) {
xdir = -1;
} else {
xdir = 1;
}
dx = xga->accel.dst_map_x & 0x1fff;
if (xga->accel.dst_map_x >= 0x1800)
dx |= ~0x17ff;
@@ -1492,26 +1482,14 @@ xga_bitblt(svga_t *svga)
uint32_t srcwidth = xga->accel.px_map_width[xga->accel.src_map];
uint32_t patheight = xga->accel.px_map_height[xga->accel.pat_src];
uint32_t srcheight = xga->accel.px_map_height[xga->accel.src_map];
#if 0
uint32_t dstheight = xga->accel.px_map_height[xga->accel.dst_map];
#endif
uint32_t frgdcol = xga->accel.frgd_color;
uint32_t bkgdcol = xga->accel.bkgd_color;
int16_t dx;
int16_t dy;
int mix = 0;
int xdir;
int ydir;
if (xga->accel.octant & 0x02) {
ydir = -1;
} else {
ydir = 1;
}
if (xga->accel.octant & 0x04) {
xdir = -1;
} else {
xdir = 1;
}
int xdir = (xga->accel.octant & 0x04) ? -1 : 1;
int ydir = (xga->accel.octant & 0x02) ? -1 : 1;
xga->accel.x = xga->accel.blt_width & 0xfff;
xga->accel.y = xga->accel.blt_height & 0xfff;
@@ -1520,12 +1498,13 @@ xga_bitblt(svga_t *svga)
xga->accel.sy = xga->accel.src_map_y & 0xfff;
xga->accel.px = xga->accel.pat_map_x & 0xfff;
xga->accel.py = xga->accel.pat_map_y & 0xfff;
xga->accel.dx = xga->accel.dst_map_x & 0x1fff;
dx = xga->accel.dst_map_x & 0x1fff;
dy = xga->accel.dst_map_y & 0x1fff;
if (xga->accel.dst_map_x >= 0x1800)
xga->accel.dx |= ~0x17ff;
xga->accel.dy = xga->accel.dst_map_y & 0x1fff;
dx |= ~0x17ff;
if (xga->accel.dst_map_y >= 0x1800)
xga->accel.dy |= ~0x17ff;
dy |= ~0x17ff;
xga_log("D(%d,%d), SWH(%d,%d), BLT(%d,%d), dstwidth=%d.\n", dx, dy, xga->accel.x, xga->accel.y, srcwidth, srcheight, dstwidth);
xga->accel.pattern = 0;
@@ -1544,44 +1523,46 @@ xga_bitblt(svga_t *svga)
xga->accel.pattern = 1;
else {
if ((dstwidth == (xga->h_disp - 1)) && (srcwidth == 1)) {
if ((xga->accel.dst_map == 1) && (xga->accel.src_map == 2) && xga->linear_endian_reverse) {
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px_map_format[xga->accel.src_map] >= 0x0b)) {
if ((xga->accel.dst_map == 1) && (xga->accel.src_map == 2)) {
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px_map_format[xga->accel.src_map] >= 0x0b))
xga->accel.pattern = 1;
}
}
}
}
xga_log("PAT8: PatFormat=%x, SrcFormat=%x, DstFormat=%x.\n", xga->accel.px_map_format[xga->accel.pat_src] & 8, (xga->accel.px_map_format[xga->accel.src_map]), (xga->accel.px_map_format[xga->accel.dst_map]));
xga_log("Pattern Map = 8: CMD = %08x: SRCBase = %08x, DSTBase = %08x, from/to vram dir = %d, "
"cmd dir = %06x\n", xga->accel.command, srcbase, dstbase, xga->from_to_vram,
xga->accel.dir_cmd);
xga_log("CMD = %08x: Y = %d, X = %d, patsrc = %02x, srcmap = %d, dstmap = %d, py = %d, "
"sy = %d, dy = %d, width0 = %d, width1 = %d, width2 = %d, width3 = %d\n",
xga->accel.command, xga->accel.y, xga->accel.x, xga->accel.pat_src, xga->accel.src_map,
xga->accel.dst_map, xga->accel.py, xga->accel.sy, xga->accel.dy,
xga->accel.dst_map, xga->accel.py, xga->accel.sy, dy,
xga->accel.px_map_width[0], xga->accel.px_map_width[1],
xga->accel.px_map_width[2], xga->accel.px_map_width[3]);
while (xga->accel.y >= 0) {
if (xga->accel.command & 0xc0) {
if ((xga->accel.dx >= xga->accel.mask_map_origin_x_off) && (xga->accel.dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (xga->accel.dy >= xga->accel.mask_map_origin_y_off) && (xga->accel.dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(1, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
}
}
} else {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(1, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(1, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
}
}
}
@@ -1589,17 +1570,19 @@ xga_bitblt(svga_t *svga)
xga->accel.sx = ((xga->accel.sx + xdir) & srcwidth) | (xga->accel.sx & ~srcwidth);
else
xga->accel.sx += xdir;
xga->accel.dx += xdir;
dx += xdir;
xga->accel.x--;
if (xga->accel.x < 0) {
xga->accel.x = (xga->accel.blt_width & 0xfff);
xga->accel.x = xga->accel.blt_width & 0xfff;
xga->accel.dx = xga->accel.dst_map_x & 0x1fff;
dx = xga->accel.dst_map_x & 0x1fff;
if (xga->accel.dst_map_x >= 0x1800)
xga->accel.dx |= ~0x17ff;
dx |= ~0x17ff;
xga->accel.sx = xga->accel.src_map_x & 0xfff;
xga->accel.dy += ydir;
dy += ydir;
if (xga->accel.pattern)
xga->accel.sy = ((xga->accel.sy + ydir) & srcheight) | (xga->accel.sy & ~srcheight);
else
@@ -1608,8 +1591,8 @@ xga_bitblt(svga_t *svga)
xga->accel.y--;
if (xga->accel.y < 0) {
xga->accel.dst_map_x = xga->accel.dx;
xga->accel.dst_map_y = xga->accel.dy;
xga->accel.dst_map_x = dx;
xga->accel.dst_map_y = dy;
return;
}
}
@@ -1620,13 +1603,12 @@ xga_bitblt(svga_t *svga)
else {
if (dstwidth == (xga->h_disp - 1)) {
if (srcwidth == (xga->h_disp - 1)) {
if ((xga->accel.src_map == 1) && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2) && xga->linear_endian_reverse) {
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) {
if ((xga->accel.src_map == 1) && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2)) {
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px <= 7) && (xga->accel.py <= 3))
xga->accel.pattern = 1;
}
}
} else {
if (!xga->accel.src_map && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2) && xga->linear_endian_reverse) {
if (!xga->accel.src_map && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2)) {
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) {
if ((patwidth >= 7) && ((xga->accel.command & 0xc0) == 0x40))
xga->accel.pattern = 0;
@@ -1638,6 +1620,7 @@ xga_bitblt(svga_t *svga)
}
}
xga_log("PAT%d: PatFormat=%x, SrcFormat=%x, DstFormat=%x.\n", xga->accel.pat_src, xga->accel.px_map_format[xga->accel.pat_src] & 8, (xga->accel.px_map_format[xga->accel.src_map]), (xga->accel.px_map_format[xga->accel.dst_map]));
xga_log("XGA bitblt linear endian reverse=%d, octanty=%d, src command = %08x, pxsrcmap=%x, "
"pxdstmap=%x, srcmap=%d, patmap=%d, dstmap=%d, dstwidth=%d, dstheight=%d, srcwidth=%d, "
"srcheight=%d, dstbase=%08x, srcbase=%08x.\n", xga->linear_endian_reverse, ydir,
@@ -1661,7 +1644,7 @@ xga_bitblt(svga_t *svga)
area_state ^= 1;
if (xga->accel.command & 0xc0) {
if ((xga->accel.dx >= xga->accel.mask_map_origin_x_off) && (xga->accel.dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (xga->accel.dy >= xga->accel.mask_map_origin_y_off) && (xga->accel.dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
if (area_state)
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
else
@@ -1670,56 +1653,58 @@ xga_bitblt(svga_t *svga)
if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) <= 3)
src_dat &= 0xff;
dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(area_state, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_log("1SRCDat=%02x, DSTDat=%02x, Old=%02x, MIX=%d.\n", src_dat, dest_dat, old_dest_dat, area_state);
xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
}
}
} else {
if (area_state)
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
else
src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol;
if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) {
if (area_state)
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
else
src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol;
if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) <= 3)
src_dat &= 0xff;
if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) <= 3)
src_dat &= 0xff;
dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(area_state, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_log("2Fill: NumXY(%d,%d): DXY(%d,%d): SRCDat=%02x, DSTDat=%02x, Old=%02x, frgdcol=%02x, bkgdcol=%02x, MIX=%d, frgdmix=%02x, bkgdmix=%02x, dstmapfmt=%02x, srcmapfmt=%02x, srcmapnum=%d.\n", x, y, xga->accel.dx, xga->accel.dy, src_dat, dest_dat, old_dest_dat, frgdcol, bkgdcol, area_state, xga->accel.frgd_mix & 0x1f, xga->accel.bkgd_mix & 0x1f, xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.src_map);
xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(area_state, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_log("2Fill: NumXY(%d,%d): DXY(%d,%d): SRCDat=%02x, DSTDat=%02x, Old=%02x, frgdcol=%02x, bkgdcol=%02x, MIX=%d, frgdmix=%02x, bkgdmix=%02x, dstmapfmt=%02x, srcmapfmt=%02x, srcmapnum=%d.\n", x, y, dx, dy, src_dat, dest_dat, old_dest_dat, frgdcol, bkgdcol, area_state, xga->accel.frgd_mix & 0x1f, xga->accel.bkgd_mix & 0x1f, xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.src_map);
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
}
}
}
xga->accel.sx = ((xga->accel.sx + 1) & srcwidth) | (xga->accel.sx & ~srcwidth);
xga->accel.px = ((xga->accel.px + 1) & patwidth) | (xga->accel.px & ~patwidth);
xga->accel.dx++;
dx++;
xga->accel.x--;
if (xga->accel.x < 0) {
area_state = 0;
xga->accel.y--;
xga->accel.x = xga->accel.blt_width & 0xfff;
xga->accel.dx = xga->accel.dst_map_x & 0x1fff;
dx = xga->accel.dst_map_x & 0x1fff;
if (xga->accel.dst_map_x >= 0x1800)
xga->accel.dx |= ~0x17ff;
dx |= ~0x17ff;
xga->accel.sx = xga->accel.src_map_x & 0xfff;
xga->accel.px = xga->accel.pat_map_x & 0xfff;
xga->accel.sy = ((xga->accel.sy + ydir) & srcheight) | (xga->accel.sy & ~srcheight);
xga->accel.py += ydir;
xga->accel.dy += ydir;
dy += ydir;
if (xga->accel.y < 0) {
xga->accel.dst_map_x = xga->accel.dx;
xga->accel.dst_map_y = xga->accel.dy;
xga->accel.dst_map_x = dx;
xga->accel.dst_map_y = dy;
return;
}
}
@@ -1729,32 +1714,34 @@ xga_bitblt(svga_t *svga)
mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1);
if (xga->accel.command & 0xc0) {
if ((xga->accel.dx >= xga->accel.mask_map_origin_x_off) && (xga->accel.dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (xga->accel.dy >= xga->accel.mask_map_origin_y_off) && (xga->accel.dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
if (mix) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
} else {
src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol;
}
dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(mix, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
}
}
} else {
if (mix) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
} else {
src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol;
}
dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(mix, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) {
if (mix) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol;
} else {
src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol;
}
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(mix, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
}
}
}
@@ -1763,15 +1750,16 @@ xga_bitblt(svga_t *svga)
xga->accel.px = ((xga->accel.px + xdir) & patwidth) | (xga->accel.px & ~patwidth);
else
xga->accel.px += xdir;
xga->accel.dx += xdir;
dx += xdir;
xga->accel.x--;
if (xga->accel.x < 0) {
xga->accel.y--;
xga->accel.x = (xga->accel.blt_width & 0xfff);
xga->accel.x = xga->accel.blt_width & 0xfff;
xga->accel.dx = xga->accel.dst_map_x & 0x1fff;
dx = xga->accel.dst_map_x & 0x1fff;
if (xga->accel.dst_map_x >= 0x1800)
xga->accel.dx |= ~0x17ff;
dx |= ~0x17ff;
xga->accel.sx = xga->accel.src_map_x & 0xfff;
xga->accel.px = xga->accel.pat_map_x & 0xfff;
@@ -1780,11 +1768,12 @@ xga_bitblt(svga_t *svga)
xga->accel.py = ((xga->accel.py + ydir) & patheight) | (xga->accel.py & ~patheight);
else
xga->accel.py += ydir;
xga->accel.dy += ydir;
dy += ydir;
if (xga->accel.y < 0) {
xga->accel.dst_map_x = xga->accel.dx;
xga->accel.dst_map_y = xga->accel.dy;
xga->accel.dst_map_x = dx;
xga->accel.dst_map_y = dy;
return;
}
}

View File

@@ -78,6 +78,7 @@
volatile int screenshots = 0;
uint8_t edatlookup[4][4];
uint8_t egaremap2bpp[256];
uint8_t fontdat[2048][8]; /* IBM CGA font */
uint8_t fontdatm[2048][16]; /* IBM MDA font */
uint8_t fontdat2[2048][8]; /* IBM CGA 2nd instance font */
@@ -915,6 +916,18 @@ video_init(void)
}
}
for (uint16_t c = 0; c < 256; c++) {
egaremap2bpp[c] = 0;
if (c & 0x01)
egaremap2bpp[c] |= 0x01;
if (c & 0x04)
egaremap2bpp[c] |= 0x02;
if (c & 0x10)
egaremap2bpp[c] |= 0x04;
if (c & 0x40)
egaremap2bpp[c] |= 0x08;
}
video_6to8 = malloc(4 * 256);
for (uint16_t c = 0; c < 256; c++)
video_6to8[c] = calc_6to8(c);