Merge branch '86Box:master' into master

This commit is contained in:
starfrost
2025-03-30 23:56:55 +01:00
committed by GitHub
24 changed files with 691 additions and 430 deletions

View File

@@ -999,8 +999,7 @@ void
serial_standalone_init(void)
{
while (next_inst < SERIAL_MAX)
device_add_inst(!strcmp(machine_get_internal_name(), "if386sx") ? &ns16450_device :
&ns8250_device, next_inst + 1);
device_add_inst(&ns8250_device, next_inst + 1);
};
const device_t ns8250_device = {

View File

@@ -92,8 +92,8 @@ typedef struct ibm8514_t {
uint16_t advfunc_cntl;
uint16_t cur_y;
uint16_t cur_x;
uint16_t destx;
uint16_t desty;
int16_t destx;
int16_t desty;
int16_t desty_axstp;
int16_t destx_distp;
int16_t err_term;
@@ -250,4 +250,9 @@ typedef struct ibm8514_t {
} ibm8514_t;
#define IBM_8514A (((dev->local & 0xff) == 0x00) && (dev->extensions == 0x00))
#define ATI_8514A_ULTRA (((dev->local & 0xff) == 0x00) && (dev->extensions == 0x01))
#define ATI_GRAPHICS_ULTRA ((dev->local & 0xff) == 0x01)
#define ATI_MACH32 ((dev->local & 0xff) == 0x02)
#endif /*VIDEO_8514A_H*/

View File

@@ -77,7 +77,8 @@ typedef struct mach_t {
uint8_t overscan_g_col_24;
uint8_t overscan_r_col_24;
uint16_t fifo_test_data[17];
int resolution_crt;
int port_len;
int crt_resolution;
struct {
uint8_t line_idx;

View File

@@ -653,7 +653,9 @@ machine_at_if386sx_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
machine_at_common_init_ex(model, 2);
device_add(&amstrad_megapc_nvr_device); /* NVR that is initialized to all 0x00's. */
device_add(&keyboard_at_phoenix_device);
device_add(&neat_sx_device);
@@ -663,6 +665,12 @@ machine_at_if386sx_init(const machine_t *model)
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
/*
One serial port - on the real hardware IF386AX, it is on the VL 16C451,
alognside the bidirectional parallel port.
*/
device_add_inst(&ns16450_device, 1);
return ret;
}

View File

@@ -1071,7 +1071,7 @@ nic_init(const device_t *info)
mac_oui = (((int) dev->maclocal[0]) << 16);
mac_oui |= (((int) dev->maclocal[1]) << 8);
mac_oui |= ((int) dev->maclocal[2]);
device_set_config_mac("mac", mac);
device_set_config_mac("mac_oui", mac_oui);
} else {
dev->maclocal[0] = (mac_oui >> 16) & 0xff;
dev->maclocal[1] = (mac_oui >> 8) & 0xff;

View File

@@ -37,7 +37,7 @@ void
HardwareRenderer::resizeGL(int w, int h)
{
m_context->makeCurrent(this);
glViewport(0, 0, qRound(w * devicePixelRatio()), qRound(h * devicePixelRatio()));
glViewport(0, 0, qRound(w * devicePixelRatioF()), qRound(h * devicePixelRatioF()));
}
#define PROGRAM_VERTEX_ATTRIBUTE 0
@@ -220,14 +220,17 @@ HardwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h)
#endif
buf_usage[buf_idx].clear();
source.setRect(x, y, w, h);
if (origSource != source)
if (origSource != source) {
this->pixelRatio = devicePixelRatioF();
onResize(this->width(), this->height());
}
update();
}
void
HardwareRenderer::resizeEvent(QResizeEvent *event)
{
this->pixelRatio = devicePixelRatioF();
onResize(width(), height());
QOpenGLWindow::resizeEvent(event);

View File

@@ -1154,14 +1154,15 @@ OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h)
buf_usage[buf_idx].clear();
source.setRect(x, y, w, h);
this->pixelRatio = devicePixelRatio();
onResize(this->width(), this->height());
#ifdef Q_OS_MACOS
glw.glViewport(
destination.x() * devicePixelRatio(),
destination.y() * devicePixelRatio(),
destination.width() * devicePixelRatio(),
destination.height() * devicePixelRatio());
destination.x(),
destination.y(),
destination.width(),
destination.height());
#endif
if (video_framerate == -1)
@@ -1187,6 +1188,7 @@ OpenGLRenderer::exposeEvent(QExposeEvent *event)
if (!isInitialized)
initialize();
this->pixelRatio = devicePixelRatio();
onResize(size().width(), size().height());
}
@@ -1195,6 +1197,7 @@ OpenGLRenderer::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event);
this->pixelRatio = devicePixelRatio();
onResize(event->size().width(), event->size().height());
if (notReady())
@@ -1203,10 +1206,10 @@ OpenGLRenderer::resizeEvent(QResizeEvent *event)
context->makeCurrent(this);
glw.glViewport(
destination.x() * devicePixelRatio(),
destination.y() * devicePixelRatio(),
destination.width() * devicePixelRatio(),
destination.height() * devicePixelRatio());
destination.x(),
destination.y(),
destination.width(),
destination.height());
}
void
@@ -1386,10 +1389,10 @@ OpenGLRenderer::render()
uint32_t x, y, w, h;
} window_rect;
window_rect.x = destination.x() * devicePixelRatio();
window_rect.y = destination.y() * devicePixelRatio();
window_rect.w = destination.width() * devicePixelRatio();
window_rect.h = destination.height() * devicePixelRatio();
window_rect.x = destination.x();
window_rect.y = destination.y();
window_rect.w = destination.width();
window_rect.h = destination.height();
glw.glBindTexture(GL_TEXTURE_2D, scene_texture.id);
scene_texture.min_filter = scene_texture.mag_filter = video_filter_method ? GL_LINEAR : GL_NEAREST;
@@ -1652,7 +1655,7 @@ OpenGLRenderer::render()
}
if (monitors[r_monitor_index].mon_screenshots) {
int width = destination.width() * devicePixelRatio(), height = destination.height() * devicePixelRatio();
int width = destination.width(), height = destination.height();
char path[1024];
char fn[256];

View File

@@ -59,6 +59,9 @@ RendererCommon::onResize(int width, int height)
bool main_max = main_window->isMaximized();
bool main_is_max = (main_is_ancestor && main_max == false);
width = round(pixelRatio * width);
height = round(pixelRatio * height);
if (is_fs && (video_fullscreen_scale_maximized ? (parent_max && main_is_max) : 1))
destination.setRect(0, 0, width, height);
else {

View File

@@ -49,5 +49,7 @@ protected:
QRect destination;
QWidget *parentWidget { nullptr };
double pixelRatio = 1.0;
std::vector<std::atomic_flag> buf_usage;
};

View File

@@ -137,54 +137,63 @@ SettingsNetwork::onCurrentMachineChanged(int machineId)
{
this->machineId = machineId;
int c = 0;
int selectedRow = 0;
int c = 0;
int selectedRow = 0;
for (int i = 0; i < NET_CARD_MAX; ++i) {
auto *cbox = findChild<QComboBox *>(QString("comboBoxNIC%1").arg(i + 1));
auto *model = cbox->model();
auto removeRows = model->rowCount();
c = 0;
selectedRow = 0;
// Network Card
QComboBox * cbox_[NET_CARD_MAX] = { 0 };
QAbstractItemModel *models[NET_CARD_MAX] = { 0 };
int removeRows_[NET_CARD_MAX] = { 0 };
int selectedRows[NET_CARD_MAX] = { 0 };
int m_has_net = machine_has_flags(machineId, MACHINE_NIC);
while (true) {
/* Skip "internal" if machine doesn't have it or this is not the primary card. */
if ((c == 1) && ((i > 0) || (machine_has_flags(machineId, MACHINE_NIC) == 0))) {
c++;
continue;
}
for (uint8_t i = 0; i < NET_CARD_MAX; ++i) {
cbox_[i] = findChild<QComboBox *>(QString("comboBoxNIC%1").arg(i + 1));
models[i] = cbox_[i]->model();
removeRows_[i] = models[i]->rowCount();
}
auto name = DeviceConfig::DeviceName(network_card_getdevice(c), network_card_get_internal_name(c), 1);
if (name.isEmpty()) {
break;
}
c = 0;
while (true) {
const QString name = DeviceConfig::DeviceName(network_card_getdevice(c),
network_card_get_internal_name(c), 1);
if (network_card_available(c) && device_is_valid(network_card_getdevice(c), machineId)) {
int row = Models::AddEntry(model, name, c);
if (c == net_cards_conf[i].device_num) {
selectedRow = row - removeRows;
if (name.isEmpty())
break;
if (network_card_available(c)) {
if (device_is_valid(network_card_getdevice(c), machineId)) {
for (uint8_t i = 0; i < NET_CARD_MAX; ++i) {
if ((c != 1) || ((i == 0) && m_has_net)) {
int row = Models::AddEntry(models[i], name, c);
if (c == net_cards_conf[i].device_num)
selectedRows[i] = row - removeRows_[i];
}
}
}
c++;
}
model->removeRows(0, removeRows);
cbox->setEnabled(model->rowCount() > 0);
cbox->setCurrentIndex(-1);
cbox->setCurrentIndex(selectedRow);
c++;
}
cbox = findChild<QComboBox *>(QString("comboBoxNet%1").arg(i + 1));
model = cbox->model();
removeRows = model->rowCount();
for (uint8_t i = 0; i < NET_CARD_MAX; ++i) {
models[i]->removeRows(0, removeRows_[i]);
cbox_[i]->setEnabled(models[i]->rowCount() > 1);
cbox_[i]->setCurrentIndex(-1);
cbox_[i]->setCurrentIndex(selectedRows[i]);
auto cbox = findChild<QComboBox *>(QString("comboBoxNet%1").arg(i + 1));
auto model = cbox->model();
auto removeRows = model->rowCount();
Models::AddEntry(model, tr("Null Driver"), NET_TYPE_NONE);
Models::AddEntry(model, "SLiRP", NET_TYPE_SLIRP);
if (network_ndev > 1) {
if (network_ndev > 1)
Models::AddEntry(model, "PCap", NET_TYPE_PCAP);
}
if (network_devmap.has_vde) {
if (network_devmap.has_vde)
Models::AddEntry(model, "VDE", NET_TYPE_VDE);
}
model->removeRows(0, removeRows);
cbox->setCurrentIndex(cbox->findData(net_cards_conf[i].net_type));
@@ -205,6 +214,7 @@ SettingsNetwork::onCurrentMachineChanged(int machineId)
model->removeRows(0, removeRows);
cbox->setCurrentIndex(selectedRow);
}
if (net_cards_conf[i].net_type == NET_TYPE_VDE) {
QString currentVdeSocket = net_cards_conf[i].host_dev_name;
auto editline = findChild<QLineEdit *>(QString("socketVDENIC%1").arg(i+1));

View File

@@ -83,31 +83,45 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId)
ui->comboBoxRTC->setCurrentIndex(selectedRow);
ui->pushButtonConfigureRTC->setEnabled((isartc_type != 0) && isartc_has_config(isartc_type) && machineHasIsa);
for (int c = 0; c < ISAMEM_MAX; c++) {
auto *cbox = findChild<QComboBox *>(QString("comboBoxCard%1").arg(c + 1));
model = cbox->model();
d = 0;
selectedRow = 0;
while (true) {
QString name = DeviceConfig::DeviceName(isamem_get_device(d), isamem_get_internal_name(d), 0);
if (name.isEmpty()) {
break;
}
// ISA Memory Expansion Card
QComboBox * cbox[ISAMEM_MAX] = { 0 };
QAbstractItemModel *models[ISAMEM_MAX] = { 0 };
int removeRows_[ISAMEM_MAX] = { 0 };
int selectedRows[ISAMEM_MAX] = { 0 };
if (!device_is_valid(isamem_get_device(d), machineId)) {
break;
}
for (uint8_t c = 0; c < ISAMEM_MAX; ++c) {
cbox[c] = findChild<QComboBox *>(QString("comboBoxCard%1").arg(c + 1));
models[c] = cbox[c]->model();
removeRows_[c] = models[c]->rowCount();
}
int row = Models::AddEntry(model, name, d);
if (d == isamem_type[c]) {
selectedRow = row;
d = 0;
while (true) {
const QString name = DeviceConfig::DeviceName(isamem_get_device(d),
isamem_get_internal_name(d), 0);
if (name.isEmpty())
break;
if (device_is_valid(isamem_get_device(d), machineId)) {
for (uint8_t c = 0; c < ISAMEM_MAX; ++c) {
int row = Models::AddEntry(models[c], name, d);
if (d == isamem_type[c])
selectedRows[c] = row - removeRows_[c];
}
++d;
}
cbox->setCurrentIndex(-1);
cbox->setCurrentIndex(selectedRow);
cbox->setEnabled(machineHasIsa);
findChild<QPushButton *>(QString("pushButtonConfigureCard%1").arg(c + 1))->setEnabled((isamem_type[c] != 0) && isamem_has_config(isamem_type[c]) && machineHasIsa);
d++;
}
for (uint8_t c = 0; c < ISAMEM_MAX; ++c) {
models[c]->removeRows(0, removeRows_[c]);
cbox[c]->setEnabled(models[c]->rowCount() > 1);
cbox[c]->setCurrentIndex(-1);
cbox[c]->setCurrentIndex(selectedRows[c]);
findChild<QPushButton *>(QString("pushButtonConfigureCard%1").arg(c + 1))->setEnabled((isamem_type[c] != 0) &&
isamem_has_config(isamem_type[c]) && machineHasIsa);
}
}

View File

@@ -73,34 +73,49 @@ SettingsPorts::onCurrentMachineChanged(int machineId)
{
this->machineId = machineId;
for (int i = 0; i < PARALLEL_MAX; i++) {
auto *cbox = findChild<QComboBox *>(QString("comboBoxLpt%1").arg(i + 1));
auto *model = cbox->model();
const auto removeRows = model->rowCount();
int c = 0;
int selectedRow = 0;
while (true) {
const char *lptName = lpt_device_get_name(c);
if (lptName == nullptr) {
break;
}
int c = 0;
int row = Models::AddEntry(model, tr(lptName), c);
if (c == lpt_ports[i].device) {
selectedRow = row - removeRows;
}
c++;
// LPT Device
QComboBox * cbox[PARALLEL_MAX] = { 0 };
QAbstractItemModel *models[PARALLEL_MAX] = { 0 };
int removeRows_[PARALLEL_MAX] = { 0 };
int selectedRows[PARALLEL_MAX] = { 0 };
for (uint8_t i = 0; i < PARALLEL_MAX; ++i) {
cbox[i] = findChild<QComboBox *>(QString("comboBoxLpt%1").arg(i + 1));
models[i] = cbox[i]->model();
removeRows_[i] = models[i]->rowCount();
}
while (true) {
const char *lptName = lpt_device_get_name(c);
if (lptName == nullptr)
break;
const QString name = tr(lptName);
for (uint8_t i = 0; i < PARALLEL_MAX; ++i) {
int row = Models::AddEntry(models[i], name, c);
if (c == lpt_ports[i].device)
selectedRows[i] = row - removeRows_[i];
}
model->removeRows(0, removeRows);
cbox->setEnabled(model->rowCount() > 0);
cbox->setCurrentIndex(-1);
cbox->setCurrentIndex(selectedRow);
c++;
}
for (uint8_t i = 0; i < PARALLEL_MAX; ++i) {
models[i]->removeRows(0, removeRows_[i]);
cbox[i]->setEnabled(models[i]->rowCount() > 1);
cbox[i]->setCurrentIndex(-1);
cbox[i]->setCurrentIndex(selectedRows[i]);
auto *checkBox = findChild<QCheckBox *>(QString("checkBoxParallel%1").arg(i + 1));
if (checkBox != NULL)
checkBox->setChecked(lpt_ports[i].enabled > 0);
if (cbox != NULL)
cbox->setEnabled(lpt_ports[i].enabled > 0);
if (cbox[i] != NULL)
cbox[i]->setEnabled(lpt_ports[i].enabled > 0);
}
for (int i = 0; i < SERIAL_MAX; i++) {

View File

@@ -73,46 +73,51 @@ SettingsSound::onCurrentMachineChanged(const int machineId)
{
this->machineId = machineId;
int c;
int selectedRow;
int c;
int selectedRow;
// Sound Card
QComboBox * cbox[SOUND_CARD_MAX] = { 0 };
QAbstractItemModel *models[SOUND_CARD_MAX] = { 0 };
int removeRows_[SOUND_CARD_MAX] = { 0 };
int selectedRows[SOUND_CARD_MAX] = { 0 };
int m_has_snd = machine_has_flags(machineId, MACHINE_SOUND);
for (uint8_t i = 0; i < SOUND_CARD_MAX; ++i) {
QComboBox *cbox = findChild<QComboBox *>(QString("comboBoxSoundCard%1").arg(i + 1));
c = 0;
auto model = cbox->model();
auto removeRows = model->rowCount();
selectedRow = 0;
cbox[i] = findChild<QComboBox *>(QString("comboBoxSoundCard%1").arg(i + 1));
models[i] = cbox[i]->model();
removeRows_[i] = models[i]->rowCount();
}
while (true) {
/* Skip "internal" if machine doesn't have it or this is not the primary card. */
if ((c == 1) && ((i > 0) || (machine_has_flags(machineId, MACHINE_SOUND) == 0))) {
c++;
continue;
}
c = 0;
while (true) {
const QString name = DeviceConfig::DeviceName(sound_card_getdevice(c),
sound_card_get_internal_name(c), 1);
const QString name = DeviceConfig::DeviceName(sound_card_getdevice(c), sound_card_get_internal_name(c), 1);
if (name.isEmpty()) {
break;
}
if (name.isEmpty())
break;
if (sound_card_available(c)) {
const device_t *sound_dev = sound_card_getdevice(c);
if (device_is_valid(sound_dev, machineId)) {
int row = Models::AddEntry(model, name, c);
if (c == sound_card_current[i]) {
selectedRow = row - removeRows;
if (sound_card_available(c)) {
if (device_is_valid(sound_card_getdevice(c), machineId)) {
for (uint8_t i = 0; i < SOUND_CARD_MAX; ++i) {
if ((c != 1) || ((i == 0) && m_has_snd)) {
int row = Models::AddEntry(models[i], name, c);
if (c == sound_card_current[i])
selectedRows[i] = row - removeRows_[i];
}
}
}
c++;
}
model->removeRows(0, removeRows);
cbox->setEnabled(model->rowCount() > 0);
cbox->setCurrentIndex(-1);
cbox->setCurrentIndex(selectedRow);
c++;
}
for (uint8_t i = 0; i < SOUND_CARD_MAX; ++i) {
models[i]->removeRows(0, removeRows_[i]);
cbox[i]->setEnabled(models[i]->rowCount() > 1);
cbox[i]->setCurrentIndex(-1);
cbox[i]->setCurrentIndex(selectedRows[i]);
}
// Midi Out

View File

@@ -171,35 +171,48 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId)
ui->comboBoxCDInterface->setCurrentIndex(-1);
ui->comboBoxCDInterface->setCurrentIndex(selectedRow);
// SCSI Card
QComboBox * cbox[SCSI_CARD_MAX] = { 0 };
QAbstractItemModel *models[SCSI_CARD_MAX] = { 0 };
int removeRows_[SCSI_CARD_MAX] = { 0 };
int selectedRows[SCSI_CARD_MAX] = { 0 };
int m_has_scsi = machine_has_flags(machineId, MACHINE_SCSI);
for (uint8_t i = 0; i < SCSI_CARD_MAX; ++i) {
QComboBox *cbox = findChild<QComboBox *>(QString("comboBoxSCSI%1").arg(i + 1));
c = 0;
model = cbox->model();
removeRows = model->rowCount();
selectedRow = 0;
cbox[i] = findChild<QComboBox *>(QString("comboBoxSCSI%1").arg(i + 1));
models[i] = cbox[i]->model();
removeRows_[i] = models[i]->rowCount();
}
while (true) {
QString name = DeviceConfig::DeviceName(scsi_card_getdevice(c), scsi_card_get_internal_name(c), 1);
if (name.isEmpty()) {
break;
}
c = 0;
while (true) {
const QString name = DeviceConfig::DeviceName(scsi_card_getdevice(c),
scsi_card_get_internal_name(c), 1);
if (scsi_card_available(c)) {
const device_t *scsi_dev = scsi_card_getdevice(c);
if (device_is_valid(scsi_dev, machineId)) {
int row = Models::AddEntry(model, name, c);
if (c == scsi_card_current[i]) {
selectedRow = row - removeRows;
if (name.isEmpty())
break;
if (scsi_card_available(c)) {
if (device_is_valid(scsi_card_getdevice(c), machineId)) {
for (uint8_t i = 0; i < SCSI_CARD_MAX; ++i) {
if ((c != 1) || ((i == 0) && m_has_scsi)) {
int row = Models::AddEntry(models[i], name, c);
if (c == scsi_card_current[i])
selectedRows[i] = row - removeRows_[i];
}
}
}
c++;
}
model->removeRows(0, removeRows);
cbox->setEnabled(model->rowCount() > 0);
cbox->setCurrentIndex(-1);
cbox->setCurrentIndex(selectedRow);
c++;
}
for (uint8_t i = 0; i < SCSI_CARD_MAX; ++i) {
models[i]->removeRows(0, removeRows_[i]);
cbox[i]->setEnabled(models[i]->rowCount() > 1);
cbox[i]->setCurrentIndex(-1);
cbox[i]->setCurrentIndex(selectedRows[i]);
}
int is_at = IS_AT(machineId);

View File

@@ -970,17 +970,11 @@ VulkanRenderer2::startNextFrame()
m_devFuncs->vkCmdBindVertexBuffers(cb, 0, 1, &m_buf, &vbOffset);
VkViewport viewport;
if (dpi_scale) {
viewport.x = destination.x() * m_window->devicePixelRatio();
viewport.y = destination.y() * m_window->devicePixelRatio();
viewport.width = destination.width() * m_window->devicePixelRatio();
viewport.height = destination.height() * m_window->devicePixelRatio();
} else {
viewport.x = destination.x();
viewport.y = destination.y();
viewport.width = destination.width();
viewport.height = destination.height();
}
viewport.x = destination.x();
viewport.y = destination.y();
viewport.width = destination.width();
viewport.height = destination.height();
viewport.minDepth = 0;
viewport.maxDepth = 1;
m_devFuncs->vkCmdSetViewport(cb, 0, 1, &viewport);

View File

@@ -846,6 +846,7 @@ VulkanWindowRenderer::createRenderer()
void
VulkanWindowRenderer::resizeEvent(QResizeEvent *event)
{
this->pixelRatio = devicePixelRatio();
onResize(width(), height());
QVulkanWindow::resizeEvent(event);
@@ -868,8 +869,10 @@ VulkanWindowRenderer::onBlit(int buf_idx, int x, int y, int w, int h)
if (isExposed())
requestUpdate();
buf_usage[0].clear();
if (origSource != source)
if (origSource != source) {
this->pixelRatio = devicePixelRatio();
onResize(this->width(), this->height());
}
}
uint32_t

View File

@@ -357,13 +357,13 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len)
case 0xae8:
WRITE8(port, dev->hsync_start, val);
pclog("IBM 8514/A compatible: (0x%04x): val=0x%02x, hsync_start=%d.\n", port, val, (val + 1) << 3);
ibm8514_log("IBM 8514/A compatible: (0x%04x): val=0x%02x, hsync_start=%d.\n", port, val, (val + 1) << 3);
svga_recalctimings(svga);
break;
case 0xee8:
WRITE8(port, dev->hsync_width, val);
pclog("IBM 8514/A compatible: (0x%04x): val=0x%02x, hsync_width=%d, hsyncpol=%02x.\n", port, val & 0x1f, ((val & 0x1f) + 1) << 3, val & 0x20);
ibm8514_log("IBM 8514/A compatible: (0x%04x): val=0x%02x, hsync_width=%d, hsyncpol=%02x.\n", port, val & 0x1f, ((val & 0x1f) + 1) << 3, val & 0x20);
svga_recalctimings(svga);
break;
@@ -834,10 +834,25 @@ ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len)
if (dev->force_busy)
temp |= 0x0200; /*Hardware busy*/
dev->force_busy = 0;
if (dev->accel.cmd_back)
dev->force_busy = 0;
if (dev->data_available) {
temp |= 0x0100; /*Read Data available*/
dev->data_available = 0;
switch (dev->accel.cmd >> 13) {
case 2:
case 3:
case 4:
case 6:
if (dev->accel.sy < 0)
dev->data_available = 0;
break;
default:
if (!dev->accel.sy)
dev->data_available = 0;
break;
}
}
}
break;
@@ -850,9 +865,22 @@ ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len)
temp |= 0x02; /*Hardware busy*/
dev->force_busy2 = 0;
if (dev->data_available2) {
temp |= 0x01; /*Read Data available*/
dev->data_available2 = 0;
switch (dev->accel.cmd >> 13) {
case 2:
case 3:
case 4:
case 6:
if (dev->accel.sy < 0)
dev->data_available2 = 0;
break;
default:
if (!dev->accel.sy)
dev->data_available2 = 0;
break;
}
}
}
break;
@@ -931,10 +959,10 @@ ibm8514_accel_in(uint16_t port, svga_t *svga)
if (cmd == 6) {
if ((dev->subsys_cntl & INT_GE_BSY) &&
!(dev->subsys_stat & INT_GE_BSY) &&
(dev->accel.dx_ibm >= clip_l) &&
(dev->accel.dx_ibm <= clip_r_ibm) &&
(dev->accel.dy_ibm >= clip_t) &&
(dev->accel.dy_ibm <= clip_b_ibm))
(dev->accel.dx >= clip_l) &&
(dev->accel.dx <= clip_r_ibm) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b_ibm))
temp |= INT_GE_BSY;
} else {
if ((dev->subsys_cntl & INT_GE_BSY) &&
@@ -2796,8 +2824,13 @@ skip_nibble_rect_write:
{
dev->accel.x_count = 0;
dev->accel.dx_ibm = dev->accel.destx;
dev->accel.dy_ibm = dev->accel.desty;
dev->accel.dx = dev->accel.destx;
if (dev->accel.destx >= 0x600)
dev->accel.dx |= ~0x5ff;
dev->accel.dy = dev->accel.desty;
if (dev->accel.desty >= 0x600)
dev->accel.dy |= ~0x5ff;
dev->accel.cx = dev->accel.cur_x;
if (dev->accel.cur_x >= 0x600)
@@ -2812,13 +2845,13 @@ skip_nibble_rect_write:
if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) {
dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy_ibm * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch);
} else if (dev->bpp) {
dev->accel.src = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.dy_ibm * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.dy * dev->pitch);
} else {
dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy_ibm * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch);
}
dev->accel.fill_state = 0;
@@ -2844,15 +2877,15 @@ skip_nibble_rect_write:
dev->data_available2 = 1;
return; /*Wait for data from CPU*/
} else
ibm8514_log("BitBLT normal: Parameters: DX=%d, DY=%d, CX=%d, CY=%d, dstwidth=%d, dstheight=%d, clipl=%d, clipr=%d, clipt=%d, clipb=%d.\n", dev->accel.dx_ibm, dev->accel.dy_ibm, dev->accel.cx, dev->accel.cy, dev->accel.sx, dev->accel.sy, clip_l, clip_r, clip_t, clip_b);
ibm8514_log("BitBLT normal: Parameters: DX=%d, DY=%d, CX=%d, CY=%d, dstwidth=%d, dstheight=%d, clipl=%d, clipr=%d, clipt=%d, clipb=%d.\n", dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy, dev->accel.sx, dev->accel.sy, clip_l, clip_r, clip_t, clip_b);
}
if (cpu_input) {
while (count-- && (dev->accel.sy >= 0)) {
if ((dev->accel.dx_ibm >= clip_l) &&
(dev->accel.dx_ibm <= clip_r) &&
(dev->accel.dy_ibm >= clip_t) &&
(dev->accel.dy_ibm <= clip_b)) {
if ((dev->accel.dx >= clip_l) &&
(dev->accel.dx <= clip_r) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b)) {
if (pixcntl == 3) {
if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) {
READ(dev->accel.src + dev->accel.cx, mix_dat);
@@ -2916,7 +2949,7 @@ skip_nibble_rect_write:
}
}
READ(dev->accel.dest + dev->accel.dx_ibm, dest_dat);
READ(dev->accel.dest + dev->accel.dx, dest_dat);
if ((compare_mode == 0) ||
((compare_mode == 0x10) && (dest_dat >= compare)) ||
@@ -2932,20 +2965,20 @@ skip_nibble_rect_write:
goto skip_nibble_bitblt_write;
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
WRITE(dev->accel.dest + dev->accel.dx_ibm, dest_dat);
WRITE(dev->accel.dest + dev->accel.dx, dest_dat);
} else {
MIX(mix_dat & mix_mask, dest_dat, src_dat);
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
WRITE(dev->accel.dest + dev->accel.dx_ibm, dest_dat);
WRITE(dev->accel.dest + dev->accel.dx, dest_dat);
}
}
}
if (dev->accel.cmd & 0x20) {
dev->accel.dx_ibm++;
dev->accel.dx++;
dev->accel.cx++;
} else {
dev->accel.dx_ibm--;
dev->accel.dx--;
dev->accel.cx--;
}
@@ -2972,30 +3005,30 @@ skip_nibble_bitblt_write:
dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff;
if (dev->accel.cmd & 0x20) {
dev->accel.dx_ibm -= (dev->accel.sx + 1);
dev->accel.dx -= (dev->accel.sx + 1);
dev->accel.cx -= (dev->accel.sx + 1);
} else {
dev->accel.dx_ibm += (dev->accel.sx + 1);
dev->accel.dx += (dev->accel.sx + 1);
dev->accel.cx += (dev->accel.sx + 1);
}
if (dev->accel.cmd & 0x80) {
dev->accel.dy_ibm++;
dev->accel.dy++;
dev->accel.cy++;
} else {
dev->accel.dy_ibm--;
dev->accel.dy--;
dev->accel.cy--;
}
if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) {
dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy_ibm * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch);
} else if (dev->bpp) {
dev->accel.src = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.dy_ibm * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.dy * dev->pitch);
} else {
dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy_ibm * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch);
}
dev->accel.sy--;
@@ -3018,10 +3051,10 @@ skip_nibble_bitblt_write:
mix_dat >>= 8;
dev->accel.temp_cnt = 8;
}
if ((dev->accel.dx_ibm >= clip_l) &&
(dev->accel.dx_ibm <= clip_r) &&
(dev->accel.dy_ibm >= clip_t) &&
(dev->accel.dy_ibm <= clip_b)) {
if ((dev->accel.dx >= clip_l) &&
(dev->accel.dx <= clip_r) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b)) {
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = bkgd_color;
@@ -3040,7 +3073,7 @@ skip_nibble_bitblt_write:
break;
}
READ(dev->accel.dest + dev->accel.dx_ibm, dest_dat);
READ(dev->accel.dest + dev->accel.dx, dest_dat);
if ((compare_mode == 0) ||
((compare_mode == 0x10) && (dest_dat >= compare)) ||
@@ -3052,7 +3085,7 @@ skip_nibble_bitblt_write:
old_dest_dat = dest_dat;
MIX(mix_dat & mix_mask, dest_dat, src_dat);
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
WRITE(dev->accel.dest + dev->accel.dx_ibm, dest_dat);
WRITE(dev->accel.dest + dev->accel.dx, dest_dat);
}
}
@@ -3063,10 +3096,10 @@ skip_nibble_bitblt_write:
}
if (dev->accel.cmd & 0x20) {
dev->accel.dx_ibm++;
dev->accel.dx++;
dev->accel.cx++;
} else {
dev->accel.dx_ibm--;
dev->accel.dx--;
dev->accel.cx--;
}
@@ -3075,30 +3108,30 @@ skip_nibble_bitblt_write:
dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff;
if (dev->accel.cmd & 0x20) {
dev->accel.dx_ibm -= (dev->accel.sx + 1);
dev->accel.dx -= (dev->accel.sx + 1);
dev->accel.cx -= (dev->accel.sx + 1);
} else {
dev->accel.dx_ibm += (dev->accel.sx + 1);
dev->accel.dx += (dev->accel.sx + 1);
dev->accel.cx += (dev->accel.sx + 1);
}
if (dev->accel.cmd & 0x80) {
dev->accel.dy_ibm++;
dev->accel.dy++;
dev->accel.cy++;
} else {
dev->accel.dy_ibm--;
dev->accel.dy--;
dev->accel.cy--;
}
if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) {
dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy_ibm * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch);
} else if (dev->bpp) {
dev->accel.src = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.dy_ibm * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.dy * dev->pitch);
} else {
dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy_ibm * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch);
}
dev->accel.sy--;
@@ -3117,10 +3150,10 @@ skip_nibble_bitblt_write:
dev->accel.temp_cnt = 8;
mix_dat = old_mix_dat;
}
if ((dev->accel.dx_ibm >= clip_l) &&
(dev->accel.dx_ibm <= clip_r) &&
(dev->accel.dy_ibm >= clip_t) &&
(dev->accel.dy_ibm <= clip_b)) {
if ((dev->accel.dx >= clip_l) &&
(dev->accel.dx <= clip_r) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b)) {
switch ((mix_dat & 0x01) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = bkgd_color;
@@ -3139,7 +3172,7 @@ skip_nibble_bitblt_write:
break;
}
READ(dev->accel.dest + dev->accel.dx_ibm, dest_dat);
READ(dev->accel.dest + dev->accel.dx, dest_dat);
if ((compare_mode == 0) ||
((compare_mode == 0x10) && (dest_dat >= compare)) ||
@@ -3151,7 +3184,7 @@ skip_nibble_bitblt_write:
old_dest_dat = dest_dat;
MIX(mix_dat & 0x01, dest_dat, src_dat);
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
WRITE(dev->accel.dest + dev->accel.dx_ibm, dest_dat);
WRITE(dev->accel.dest + dev->accel.dx, dest_dat);
}
}
@@ -3159,10 +3192,10 @@ skip_nibble_bitblt_write:
mix_dat >>= 1;
if (dev->accel.cmd & 0x20) {
dev->accel.dx_ibm++;
dev->accel.dx++;
dev->accel.cx++;
} else {
dev->accel.dx_ibm--;
dev->accel.dx--;
dev->accel.cx--;
}
@@ -3171,36 +3204,36 @@ skip_nibble_bitblt_write:
dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff;
if (dev->accel.cmd & 0x20) {
dev->accel.dx_ibm -= (dev->accel.sx + 1);
dev->accel.dx -= (dev->accel.sx + 1);
dev->accel.cx -= (dev->accel.sx + 1);
} else {
dev->accel.dx_ibm += (dev->accel.sx + 1);
dev->accel.dx += (dev->accel.sx + 1);
dev->accel.cx += (dev->accel.sx + 1);
}
if (dev->accel.cmd & 0x80) {
dev->accel.dy_ibm++;
dev->accel.dy++;
dev->accel.cy++;
} else {
dev->accel.dy_ibm--;
dev->accel.dy--;
dev->accel.cy--;
}
if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) {
dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy_ibm * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch);
} else if (dev->bpp) {
dev->accel.src = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.dy_ibm * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.dy * dev->pitch);
} else {
dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy_ibm * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch);
}
dev->accel.sy--;
if (dev->accel.sy < 0) {
dev->accel.destx = dev->accel.dx_ibm;
dev->accel.desty = dev->accel.dy_ibm;
dev->accel.destx = dev->accel.dx;
dev->accel.desty = dev->accel.dy;
dev->accel.cmd_back = 1;
dev->fifo_idx = 0;
return;
@@ -3214,13 +3247,13 @@ skip_nibble_bitblt_write:
int64_t dx;
cx = (int64_t) dev->accel.cx;
dx = (int64_t) dev->accel.dx_ibm;
dx = (int64_t) dev->accel.dx;
while (1) {
if ((dx >= (((int64_t)clip_l) * 3)) &&
(dx <= (((uint64_t)clip_r) * 3)) &&
(dev->accel.dy_ibm >= (clip_t << 1)) &&
(dev->accel.dy_ibm <= (clip_b << 1))) {
(dev->accel.dy >= (clip_t << 1)) &&
(dev->accel.dy <= (clip_b << 1))) {
READ(dev->accel.src + cx, src_dat);
READ(dev->accel.dest + dx, dest_dat);
dest_dat = (src_dat & wrt_mask) | (dest_dat & ~wrt_mask);
@@ -3239,10 +3272,10 @@ skip_nibble_bitblt_write:
}
} else {
while (count-- && dev->accel.sy >= 0) {
if ((dev->accel.dx_ibm >= clip_l) &&
(dev->accel.dx_ibm <= clip_r) &&
(dev->accel.dy_ibm >= clip_t) &&
(dev->accel.dy_ibm <= clip_b)) {
if ((dev->accel.dx >= clip_l) &&
(dev->accel.dx <= clip_r) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b)) {
if (pixcntl == 3) {
if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) {
READ(dev->accel.src + dev->accel.cx, mix_dat);
@@ -3276,7 +3309,7 @@ skip_nibble_bitblt_write:
break;
}
READ(dev->accel.dest + dev->accel.dx_ibm, dest_dat);
READ(dev->accel.dest + dev->accel.dx, dest_dat);
if ((compare_mode == 0) ||
((compare_mode == 0x10) && (dest_dat >= compare)) ||
@@ -3291,11 +3324,11 @@ skip_nibble_bitblt_write:
if (dev->accel.cmd & 0x04) {
if (dev->accel.sx) {
WRITE(dev->accel.dest + dev->accel.dx_ibm, dest_dat);
WRITE(dev->accel.dest + dev->accel.dx, dest_dat);
}
} else {
WRITE(dev->accel.dest + dev->accel.dx_ibm, dest_dat);
ibm8514_log("BitBLT DX=%d, DY=%d, data=%02x, old=%02x, src=%02x, frmix=%02x, bkmix=%02x, pixcntl=%d.\n", dev->accel.dx_ibm, dev->accel.dy_ibm, dest_dat, old_dest_dat, src_dat, dev->accel.frgd_mix & 0x1f, dev->accel.bkgd_mix & 0x1f, pixcntl);
WRITE(dev->accel.dest + dev->accel.dx, dest_dat);
ibm8514_log("BitBLT DX=%d, DY=%d, data=%02x, old=%02x, src=%02x, frmix=%02x, bkmix=%02x, pixcntl=%d.\n", dev->accel.dx, dev->accel.dy, dest_dat, old_dest_dat, src_dat, dev->accel.frgd_mix & 0x1f, dev->accel.bkgd_mix & 0x1f, pixcntl);
}
}
}
@@ -3304,10 +3337,10 @@ skip_nibble_bitblt_write:
mix_dat |= 1;
if (dev->accel.cmd & 0x20) {
dev->accel.dx_ibm++;
dev->accel.dx++;
dev->accel.cx++;
} else {
dev->accel.dx_ibm--;
dev->accel.dx--;
dev->accel.cx--;
}
@@ -3317,36 +3350,36 @@ skip_nibble_bitblt_write:
dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff;
if (dev->accel.cmd & 0x20) {
dev->accel.dx_ibm -= (dev->accel.sx + 1);
dev->accel.dx -= (dev->accel.sx + 1);
dev->accel.cx -= (dev->accel.sx + 1);
} else {
dev->accel.dx_ibm += (dev->accel.sx + 1);
dev->accel.dx += (dev->accel.sx + 1);
dev->accel.cx += (dev->accel.sx + 1);
}
if (dev->accel.cmd & 0x80) {
dev->accel.dy_ibm++;
dev->accel.dy++;
dev->accel.cy++;
} else {
dev->accel.dy_ibm--;
dev->accel.dy--;
dev->accel.cy--;
}
if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) {
dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy_ibm * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch);
} else if (dev->bpp) {
dev->accel.src = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.dy_ibm * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.dy * dev->pitch);
} else {
dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy_ibm * dev->pitch);
dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch);
}
dev->accel.sy--;
if (dev->accel.sy < 0) {
dev->accel.destx = dev->accel.dx_ibm;
dev->accel.desty = dev->accel.dy_ibm;
dev->accel.destx = dev->accel.dx;
dev->accel.desty = dev->accel.dy;
dev->accel.cmd_back = 1;
dev->fifo_idx = 0;
return;
@@ -3846,10 +3879,7 @@ ibm8514_recalctimings(svga_t *svga)
else
svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0;
if (dev->dispend == 766)
dev->dispend += 2;
if (dev->dispend == 478)
if ((dev->dispend == 478) || (dev->dispend == 766))
dev->dispend += 2;
if (dev->interlace)

View File

@@ -3768,6 +3768,9 @@ mach64_ext_outb(uint16_t port, uint8_t val, void *priv)
case 0x6aee:
case 0x6aef:
WRITE8(port, mach64->config_cntl, val);
if (!mach64->pci)
mach64->linear_base = (mach64->config_cntl & 0x3ff0) << 18;
mach64_updatemapping(mach64);
break;

View File

@@ -344,7 +344,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
dev->accel.rd_mask, mach->accel.dp_config, clip_l, clip_r, clip_t, clip_b, mach->accel.linedraw_opt, dev->accel_bpp, cmd_type, mach->accel.ge_offset, count, cpu_input, mono_src, frgd_sel, dev->accel.cur_x, dev->accel.cur_y,
mach->accel.dest_x_end, dev->ext_pitch, dev->ext_crt_pitch, mach->accel.dp_config & 1, mach->accel.mono_pattern_enable);
mach_log("cmd_type = %i, frgd_sel = %i, bkgd_sel = %i, mono_src = %i.\n", cmd_type, frgd_sel, bkgd_sel, mono_src);
mach_log("cmd_type = %i, frgd_sel = %i, bkgd_sel = %i, mono_src = %i, dpconfig = %04x.\n", cmd_type, frgd_sel, bkgd_sel, mono_src, mach->accel.dp_config);
switch (cmd_type) {
case 1: /*Extended Raw Linedraw from bres_count register (0x96ee)*/
@@ -900,14 +900,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3
}
dev->accel.sy = 0;
if (mach->accel.dp_config & 0x02)
dev->accel.dest = (dev->accel.dy * dev->pitch);
else {
if (dev->bpp)
dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * dev->pitch);
else
dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch);
}
if (dev->bpp)
dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * dev->pitch);
else
dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch);
mach->accel.src_stepx = 0;
/*Source Width*/
@@ -2221,7 +2217,7 @@ mach_accel_out_pixtrans(svga_t *svga, mach_t *mach, ibm8514_t *dev, uint16_t val
case 0x200: /*16-bit size*/
if (mono_src == 2) {
if ((frgd_sel != 2) && (bkgd_sel != 2)) {
if (((mach->accel.dp_config & 0x1000) && !swap) || swap) {
if (((mach->accel.dp_config & 0x1000) && !swap) || (!(mach->accel.dp_config & 0x1000) && swap)) {
mach_log("16-bit bus size swap.\n");
val = (val >> 8) | (val << 8);
}
@@ -2250,7 +2246,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1))
addr ^= 0x60;
if (((dev->disp_cntl & 0x60) == 0x20) && ((dev->local & 0xff) >= 0x02)) {
if (((dev->disp_cntl & 0x60) == 0x20) && ATI_MACH32) {
if ((addr >= 0x3c6) && (addr <= 0x3c9)) {
mach_log("VGA DAC write regs=%03x, on=%d, display control=%02x, on1=%x, clocksel=%02x.\n",
addr, dev->on, dev->disp_cntl & 0x60, dev->accel.advfunc_cntl & 0x01, mach->accel.clock_sel & 0x01);
@@ -2281,7 +2277,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
}
break;
case 0xad:
if ((dev->local & 0xff) >= 0x02) {
if (ATI_MACH32) {
if ((old ^ val) & 0x0c) {
mach_log("ATI AD bits 2-3.\n");
svga_recalctimings(svga);
@@ -2301,14 +2297,14 @@ 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 & 0xff) >= 0x02) {
if (ATI_MACH32) {
mach->bank_r |= ((mach->regs[0xae] & 0x0c) << 2);
mach->bank_w |= ((mach->regs[0xae] & 3) << 4);
}
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 & 0xff) >= 0x02)
if (ATI_MACH32)
mach->bank_w |= ((mach->regs[0xae] & 3) << 4);
mach->bank_r = mach->bank_w;
@@ -2338,7 +2334,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
}
break;
case 0xb8:
if ((dev->local & 0xff) >= 0x02) {
if (ATI_MACH32) {
if ((old ^ val) & 0x40) {
mach_log("ATI B8 bit 6.\n");
svga_recalctimings(svga);
@@ -2367,7 +2363,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
rs2 = !!(mach->accel.ext_ge_config & 0x1000);
rs3 = !!(mach->accel.ext_ge_config & 0x2000);
mach_log("8514/A RS2=%d, RS3=%d, addr=%03x.\n", rs2, rs3, addr);
if ((dev->local & 0xff) >= 0x02) {
if (ATI_MACH32) {
if (mach->regs[0xb0] & 0x20) { /*ATI extended 8514/A mode.*/
mach_log("Extended 8514/A mode.\n");
dev->vendor_mode = 1;
@@ -2394,7 +2390,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv)
rs2 = !!(mach->regs[0xa0] & 0x20);
rs3 = !!(mach->regs[0xa0] & 0x40);
mach_log("VGA RS2=%d, RS3=%d, addr=%03x.\n", rs2, rs3, addr);
if ((dev->local & 0xff) >= 0x02) {
if (ATI_MACH32) {
if (svga->attrregs[0x10] & 0x40) {
mach_log("VGA mode.\n");
dev->vendor_mode = 0;
@@ -2495,7 +2491,7 @@ mach_in(uint16_t addr, void *priv)
case 0xb0:
temp = mach->regs[0xb0] | 0x80;
temp &= ~0x18;
if ((dev->local & 0xff) >= 0x02) { /*Mach32 VGA 1MB memory*/
if (ATI_MACH32) { /*Mach32 VGA 1MB memory*/
temp |= 0x08;
} else { /*ATI 28800 VGA 512kB memory*/
temp |= 0x10;
@@ -2524,7 +2520,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 & 0xff) >= 0x02) {
if (ATI_MACH32) {
if (dev->on)
temp = svga_in(addr, svga);
else {
@@ -2663,6 +2659,11 @@ ati_render_32bpp(svga_t *svga)
}
}
/*The situation is the following:
When ATI mode is selected, allow complete auto-detection.
But when 8514/A mode is selected, allow detection based on the shadow register sets.
*/
static void
mach_set_resolution(mach_t *mach, svga_t *svga)
{
@@ -2671,6 +2672,9 @@ mach_set_resolution(mach_t *mach, svga_t *svga)
dev->hdisp = (dev->hdisped + 1) << 3;
dev->h_total = dev->htotal + 1;
if (dev->h_total == 1) /*Default to 1024x768 87hz 8514/A htotal timings if it goes to 0.*/
dev->h_total = 0x9e;
dev->vdisp = (dev->v_disp + 1) >> 1;
if ((dev->vdisp == 478) || (dev->vdisp == 598) || (dev->vdisp == 766) || (dev->vdisp == 1022))
dev->vdisp += 2;
@@ -2683,16 +2687,72 @@ mach_set_resolution(mach_t *mach, svga_t *svga)
if (dev->interlace)
dev->v_syncstart >>= 1;
mach_log("Shadow set ATI=%x, shadow set 8514/A=%x, resolution h=%d, v=%d.\n", mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp);
mach_log("Shadow set ATI=%x, shadow set 8514/A=%x, resolution h=%d, v=%d, vtotal=%d, vsyncstart=%d.\n", mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp, dev->v_total, dev->v_syncstart);
if ((mach->accel.clock_sel & 0x01) || dev->bpp || ((mach->accel.ext_ge_config & 0x30) == 0x30)) /*ATI and 15bpp+ mode*/
svga_recalctimings(svga);
else { /*8514/A mode*/
if (mach->resolution_crt == 0x02) {
if (!(dev->accel.advfunc_cntl & 0x04)) {
dev->hdisp = 640;
dev->vdisp = 480;
svga_recalctimings(svga);
}
switch (mach->shadow_set & 0x03) {
case 0x00: /*Primary CRT Register set*/
if (dev->on) {
if (mach->crt_resolution == 0x01) {
if (ATI_8514A_ULTRA) {
if (dev->accel.advfunc_cntl & 0x04) {
if (dev->hdisp == 640) {
dev->hdisp = 1024;
dev->vdisp = 768;
svga_recalctimings(svga);
}
} else {
if (dev->hdisp == 1024) {
dev->hdisp = 640;
dev->vdisp = 480;
svga_recalctimings(svga);
}
}
} else
svga_recalctimings(svga);
} else if (mach->crt_resolution == 0x02) {
if (dev->accel.advfunc_cntl & 0x04) {
if (dev->hdisp == 640) {
dev->hdisp = 1024;
dev->vdisp = 768;
svga_recalctimings(svga);
}
} else {
if (dev->hdisp == 1024) {
dev->hdisp = 640;
dev->vdisp = 480;
svga_recalctimings(svga);
}
}
} else
svga_recalctimings(svga);
}
break;
case 0x01: /*Shadow 640x480 CRT register set*/
if (dev->on) {
if (!(dev->accel.advfunc_cntl & 0x04)) {
if (dev->hdisp == 1024) {
dev->hdisp = 640;
dev->vdisp = 480;
}
}
svga_recalctimings(svga);
}
break;
case 0x02: /*Shadow 1024x768 CRT register set*/
if (dev->on) {
if (dev->accel.advfunc_cntl & 0x04) {
if (dev->hdisp == 640) {
dev->hdisp = 1024;
dev->vdisp = 768;
}
}
svga_recalctimings(svga);
}
break;
default:
break;
}
}
}
@@ -2726,6 +2786,7 @@ ati8514_recalctimings(svga_t *svga)
if (dev->interlace)
dev->dispend >>= 1;
mach->crt_resolution = 0x00;
mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n",
dev->accel.advfunc_cntl & 0x04, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset,
mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace);
@@ -2739,7 +2800,6 @@ ati8514_recalctimings(svga_t *svga)
}
}
dev->accel_bpp = 8;
mach->resolution_crt = 0;
svga->render8514 = ibm8514_render_8bpp;
}
}
@@ -2756,7 +2816,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 & 0xff) >= 0x02) {
if (ATI_MACH32) {
if (mach->regs[0xad] & 0x04)
svga->ma_latch |= 0x40000;
@@ -2785,7 +2845,7 @@ mach_recalctimings(svga_t *svga)
} else
svga->packed_4bpp = 0;
if ((dev->local & 0xff) < 0x02) {
if (!ATI_MACH32) {
if ((mach->regs[0xb6] & 0x18) == 0x08) {
svga->hdisp <<= 1;
svga->htotal <<= 1;
@@ -2795,15 +2855,15 @@ mach_recalctimings(svga_t *svga)
svga->ati_4color = 0;
}
mach_log("ON?=%d, override=%d.\n", dev->on, svga->override);
mach_log("ON?=%d, override=%d, gelo=%04x, gehi=%04x, vgahdisp=%d.\n", dev->on, svga->override, mach->accel.ge_offset_lo, mach->accel.ge_offset_hi, svga->hdisp);
if (dev->on) {
mach_log("8514/A ON, extpitch=%d, devma=%x, vgamalatch=%x.\n", dev->ext_pitch, dev->ma, svga->ma_latch);
dev->ma_latch = (mach->accel.crt_offset_lo | (mach->accel.crt_offset_hi << 16)) << 2;
dev->ma_latch = 0; /*(mach->accel.crt_offset_lo | (mach->accel.crt_offset_hi << 16)) << 2;*/
dev->pitch = dev->ext_pitch;
dev->rowoffset = dev->ext_crt_pitch;
dev->rowcount = !!(dev->disp_cntl & 0x08);
dev->accel.ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16));
mach->accel.ge_offset = dev->accel.ge_offset;
mach_log("8514/A ON, extpitch=%d, geoffset=%x, 8514malatch=%x, vgamalatch=%x.\n", dev->ext_pitch, mach->accel.ge_offset, dev->ma_latch, svga->ma_latch);
mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x, clocksel=%02x, interlace=%x.\n",
dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04,
@@ -2823,7 +2883,8 @@ mach_recalctimings(svga_t *svga)
if (dev->interlace)
dev->dispend >>= 1;
if ((dev->local & 0xff) >= 0x02) {
mach->crt_resolution = 0x00;
if (ATI_MACH32) {
mach_log("cntl=%d, clksel=%x, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d, vgahdisp=%d.\n",
dev->accel.advfunc_cntl & 0x04, mach->accel.clock_sel & 0x01, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset,
mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace, svga->hdisp);
@@ -2864,7 +2925,6 @@ mach_recalctimings(svga_t *svga)
dev->h_disp, dev->dispend, dev->pitch, dev->ext_crt_pitch, mach->accel.ext_ge_config & 0xcec0,
dev->accel_bpp, mach->shadow_set & 3, svga->hdisp);
mach->resolution_crt = 0;
switch (dev->accel_bpp) {
case 8:
svga->render8514 = ibm8514_render_8bpp;
@@ -2902,7 +2962,6 @@ mach_recalctimings(svga_t *svga)
}
}
dev->accel_bpp = 8;
mach->resolution_crt = 0;
svga->render8514 = ibm8514_render_8bpp;
}
} else {
@@ -2913,7 +2972,7 @@ mach_recalctimings(svga_t *svga)
if ((svga->gdcreg[5] & 0x40) || (svga->attrregs[0x10] & 0x40) || (mach->regs[0xb0] & 0x20)) {
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen);
mach_log("VGA clock=%02x.\n", mach->regs[0xa7] & 0x80);
if ((dev->local & 0xff) >= 0x02) {
if (ATI_MACH32) {
if (mach->regs[0xb8] & 0x40)
svga->clock *= 2;
} else {
@@ -2973,7 +3032,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
if (!(mach->shadow_cntl & 0x04)) {
WRITE8(port, dev->hsync_start, val);
}
svga_recalctimings(svga);
mach_set_resolution(mach, svga);
}
break;
@@ -2982,28 +3041,31 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
if (!(mach->shadow_cntl & 0x04)) {
WRITE8(port, dev->hsync_width, val);
}
svga_recalctimings(svga);
mach_set_resolution(mach, svga);
}
break;
case 0x1ee8:
case 0x1ee9:
if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) /*For 8514/A mode, take the shadow sets into account.*/
svga_recalctimings(svga);
mach_set_resolution(mach, svga);
break;
case 0x6e8:
if (len == 2) {
mach_log("HDISP and HTOTAL=%04x, len=%d, set=%x, ATI mode bit=%x.\n", val, len, mach->shadow_set & 0x03, mach->accel.clock_sel & 0x01);
if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/
if (!(mach->shadow_cntl & 0x08)) {
WRITE8(port, dev->hdisped, val);
}
if (!(mach->shadow_cntl & 0x04))
dev->htotal = (val >> 8) & 0xff;
mach_set_resolution(mach, svga);
if (!(mach->shadow_cntl & 0x08)) {
if (dev->htotal || (mach->accel.clock_sel & 0x01)) {
WRITE8(port, dev->hdisped, val);
}
}
if (dev->htotal || (mach->accel.clock_sel & 0x01))
mach_set_resolution(mach, svga);
}
} else {
mach_log("HDISP and HTOTAL=%02x, len=%d, set=%x, ATI mode bit=%x.\n", val, len, mach->shadow_set & 0x03, mach->accel.clock_sel & 0x01);
@@ -3016,9 +3078,6 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
if (!(mach->shadow_cntl & 0x08)) {
WRITE8(port, dev->hdisped, val);
}
if (mach->resolution_crt == 0x00)
mach->resolution_crt = 0x02;
mach_set_resolution(mach, svga);
}
}
@@ -3030,9 +3089,9 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
if (len == 1) {
mach_log("HDISP and HTOTAL+1=%02x, len=%d, set=%x, ATI mode bit=%x.\n", val, len, mach->shadow_set & 0x03, mach->accel.clock_sel & 0x01);
if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/
if (!(mach->shadow_cntl & 0x04)) {
if (!(mach->shadow_cntl & 0x04))
dev->htotal = val;
}
mach_set_resolution(mach, svga);
}
}
@@ -3074,8 +3133,14 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
case 0x16e8:
if (len == 2) {
if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) {
if (!(mach->shadow_cntl & 0x20)) { /*For 8514/A mode, take the shadow sets into account.*/
if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/
if (!(mach->shadow_cntl & 0x20)) {
dev->v_disp = val;
dev->v_disp &= 0x1fff;
}
mach_set_resolution(mach, svga);
} else if (!(mach->accel.clock_sel & 0x01) && ((mach->shadow_set & 0x03) == 0x00) && dev->on) { /*Still write the parameter even after going to 8514/A mode if needed*/
if (!(mach->shadow_cntl & 0x20)) {
dev->v_disp = val;
dev->v_disp &= 0x1fff;
}
@@ -3084,8 +3149,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
mach_log("ATI 8514/A: V_DISP write 16E8=%d, vdisp2=%d.\n", dev->v_disp, dev->v_disp2);
mach_log("ATI 8514/A: (0x%04x): vdisp=0x%02x.\n", port, val);
} else {
if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) {
if (!(mach->shadow_cntl & 0x20)) { /*For 8514/A mode, take the shadow sets into account.*/
if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/
if (!(mach->shadow_cntl & 0x20)) {
WRITE8(port, dev->v_disp, val);
dev->v_disp &= 0x1fff;
}
@@ -3095,8 +3160,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
break;
case 0x16e9:
if (len == 1) {
if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) {
if (!(mach->shadow_cntl & 0x20)) { /*For 8514/A mode, take the shadow sets into account.*/
if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/
if (!(mach->shadow_cntl & 0x20)) {
WRITE8(port, dev->v_disp, val);
dev->v_disp &= 0x1fff;
}
@@ -3109,8 +3174,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
case 0x1ae8:
if (len == 2) {
if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) {
if (!(mach->shadow_cntl & 0x10)) { /*For 8514/A mode, take the shadow sets into account.*/
if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/
if (!(mach->shadow_cntl & 0x10)) {
dev->v_sync_start = val;
dev->v_sync_start &= 0x1fff;
}
@@ -3119,8 +3184,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
mach_log("ATI 8514/A: V_SYNCSTART write 1AE8 = %d\n", dev->v_syncstart);
mach_log("ATI 8514/A: (0x%04x): vsyncstart=0x%02x.\n", port, val);
} else {
if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) {
if (!(mach->shadow_cntl & 0x10)) { /*For 8514/A mode, take the shadow sets into account.*/
if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/
if (!(mach->shadow_cntl & 0x10)) {
WRITE8(port, dev->v_sync_start, val);
dev->v_sync_start &= 0x1fff;
}
@@ -3130,8 +3195,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
break;
case 0x1ae9:
if (len == 1) {
if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) {
if (!(mach->shadow_cntl & 0x10)) { /*For 8514/A mode, take the shadow sets into account.*/
if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/
if (!(mach->shadow_cntl & 0x10)) {
WRITE8(port, dev->v_sync_start, val);
dev->v_sync_start &= 0x1fff;
}
@@ -3152,7 +3217,6 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
svga_recalctimings(svga);
break;
case 0x42e8:
case 0x42e9:
mach_log("VBLANK stat=%02x, val=%02x.\n", dev->subsys_stat, val);
@@ -3181,12 +3245,12 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
mach_log("[%04X:%08X]: ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n",
CS, cpu_state.pc, port, val & 0x01, dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp);
if ((dev->local & 0xff) < 0x02) {
dev->ext_crt_pitch = 128;
mach_set_resolution(mach, svga);
} else {
if (ATI_MACH32) {
mach_set_resolution(mach, svga);
mach32_updatemapping(mach, svga);
} else {
dev->ext_crt_pitch = 128;
mach_set_resolution(mach, svga);
}
mach_log("Vendor IBM mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480");
break;
@@ -3390,7 +3454,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
ibm8514_accel_out_fifo(svga, port, val, len);
if (len == 2) {
if ((dev->accel.multifunc_cntl >> 12) == 5) {
if ((dev->local & 0xff) < 0x02)
if (!ATI_MACH32)
dev->ext_crt_pitch = 128;
}
}
@@ -3514,12 +3578,12 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
else
dev->ext_crt_pitch <<= 1;
}
if ((dev->local & 0xff) >= 0x02) {
if (ATI_MACH32) {
dev->on |= 0x01;
dev->vendor_mode = 1;
}
svga_recalctimings(svga);
if ((dev->local & 0xff) >= 0x01)
if (ATI_GRAPHICS_ULTRA || ATI_MACH32)
mach32_updatemapping(mach, svga);
mach_log("ATI 8514/A: (0x%04x) CRT Pitch, val=0x%02x, crtpitch=%x, len=%d, extended 8514/A mode=%02x.\n", port, val, dev->ext_crt_pitch, len, mach->regs[0xb0] & 0x20);
@@ -3548,17 +3612,17 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
else {
WRITE8(port, mach->local_cntl, val);
}
if ((dev->local & 0xff) >= 0x01)
if (ATI_GRAPHICS_ULTRA || ATI_MACH32)
mach32_updatemapping(mach, svga);
break;
case 0x36ee:
case 0x36ef:
if (len == 2) {
if ((dev->local & 0xff) >= 0x02)
if (ATI_MACH32)
mach->misc = val;
} else {
if ((dev->local & 0xff) >= 0x02)
if (ATI_MACH32)
WRITE8(port, mach->misc, val);
}
mach->misc &= 0xfff0;
@@ -3621,7 +3685,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
mach_log("Vendor ATI mode set %s resolution.\n",
(dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480");
svga_recalctimings(svga);
if ((dev->local & 0xff) >= 0x01)
if (ATI_GRAPHICS_ULTRA || ATI_MACH32)
mach32_updatemapping(mach, svga);
break;
@@ -3656,11 +3720,19 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
if ((mach->shadow_set & 0x03) == 0x00)
mach_log("Primary CRT register set.\n");
else if ((mach->shadow_set & 0x03) == 0x01) {
mach->crt_resolution = 0x01;
mach_log("CRT Shadow Set 1: 640x480.\n");
mach->resolution_crt = 0x01;
} else if ((mach->shadow_set & 0x03) == 0x02) {
mach->crt_resolution = 0x02;
mach_log("CRT Shadow Set 2: 1024x768.\n");
mach->resolution_crt = 0x02;
}
if (ATI_MACH32) {
if ((mach->shadow_set & 0x300) == 0x000) {
mach_log("Load both SRC/DST GE Offset/Pitch.\n");
mach->accel.ge_offset_lo = 0;
mach->accel.ge_offset_hi = 0;
}
}
break;
@@ -3675,7 +3747,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
if (!mach->pci_bus)
mach->linear_base = (mach->memory_aperture & 0xff00) << 12;
if ((dev->local & 0xff) >= 0x01)
if (ATI_GRAPHICS_ULTRA || ATI_MACH32)
mach32_updatemapping(mach, svga);
break;
@@ -3729,7 +3801,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
else {
WRITE8(port, mach->accel.ext_ge_config, val);
}
if ((dev->local & 0xff) >= 0x02) {
if (ATI_MACH32) {
if (mach->accel.crt_pitch & 0xff)
dev->ext_crt_pitch = mach->accel.crt_pitch & 0xff;
@@ -4166,11 +4238,11 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in
case 4:
case 6:
if (dev->accel.sy < 0)
dev->data_available = 0;
dev->data_available2 = 0;
break;
default:
if (!dev->accel.sy)
dev->data_available = 0;
dev->data_available2 = 0;
break;
}
}
@@ -4407,46 +4479,46 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in
case 0xdaee:
if (len == 2) {
if ((dev->local & 0xff) >= 0x02)
if (ATI_MACH32)
temp = mach->accel.src_x;
} else {
if ((dev->local & 0xff) >= 0x02)
if (ATI_MACH32)
temp = mach->accel.src_x & 0xff;
}
break;
case 0xdaef:
if (len == 1) {
if ((dev->local & 0xff) >= 0x02)
if (ATI_MACH32)
temp = mach->accel.src_x >> 8;
}
break;
case 0xdeee:
if (len == 2) {
if ((dev->local & 0xff) >= 0x02)
if (ATI_MACH32)
temp = mach->accel.src_y;
} else {
if ((dev->local & 0xff) >= 0x02)
if (ATI_MACH32)
temp = mach->accel.src_y & 0xff;
}
break;
case 0xdeef:
if (len == 1) {
if ((dev->local & 0xff) >= 0x02)
if (ATI_MACH32)
temp = mach->accel.src_y >> 8;
}
break;
case 0xfaee:
if (len == 2) {
if ((dev->local & 0xff) >= 0x02) {
if (ATI_MACH32) {
if (mach->pci_bus)
temp = 0x0017;
else
temp = 0x22f7;
}
} else {
if ((dev->local & 0xff) >= 0x02) {
if (ATI_MACH32) {
if (mach->pci_bus)
temp = 0x17;
else
@@ -4456,7 +4528,7 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in
break;
case 0xfaef:
if (len == 1) {
if ((dev->local & 0xff) >= 0x02) {
if (ATI_MACH32) {
if (mach->pci_bus)
temp = 0x00;
else
@@ -4509,10 +4581,10 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev)
if (cmd == 6) {
if ((dev->subsys_cntl & INT_GE_BSY) &&
!(dev->subsys_stat & INT_GE_BSY) &&
(dev->accel.dx_ibm >= clip_l) &&
(dev->accel.dx_ibm <= clip_r_ibm) &&
(dev->accel.dy_ibm >= clip_t) &&
(dev->accel.dy_ibm <= clip_b_ibm))
(dev->accel.dx >= clip_l) &&
(dev->accel.dx <= clip_r_ibm) &&
(dev->accel.dy >= clip_t) &&
(dev->accel.dy <= clip_b_ibm))
temp |= INT_GE_BSY;
} else {
if ((dev->subsys_cntl & INT_GE_BSY) &&
@@ -4604,7 +4676,7 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev)
case 0x36ee:
case 0x36ef:
if ((dev->local & 0xff) >= 0x02) {
if (ATI_MACH32) {
READ8(port, mach->misc);
if (!(port & 1)) {
temp &= ~0x0c;
@@ -4662,6 +4734,7 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev)
temp = 0x0000;
}
} else {
mach_log("ScratchPad0=%x.\n", mach->accel.scratch0);
if (mach->accel.scratch0 == 0x1234)
temp = 0x0000;
}
@@ -5148,7 +5221,7 @@ mach32_write(uint32_t addr, uint8_t val, void *priv)
return;
}
if ((((dev->local & 0xff) >= 0x02) && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) {
if ((ATI_MACH32 && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) {
addr <<= 1;
switch (addr & 0x06) {
case 0x00:
@@ -5188,7 +5261,7 @@ mach32_writew(uint32_t addr, uint16_t val, void *priv)
return;
}
if ((((dev->local & 0xff) >= 0x02) && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) {
if ((ATI_MACH32 && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) {
addr <<= 1;
if (addr & 0x04) {
mach32_write_common(addr - 2, val & 0x0f, 0, mach, svga);
@@ -5223,7 +5296,7 @@ mach32_writel(uint32_t addr, uint32_t val, void *priv)
return;
}
if ((((dev->local & 0xff) >= 0x02) && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) {
if ((ATI_MACH32 && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) {
addr <<= 1;
mach32_write_common(addr, val & 0x0f, 0, mach, svga);
mach32_write_common(addr + 1, (val >> 4) & 0x0f, 0, mach, svga);
@@ -5639,7 +5712,7 @@ mach32_read(uint32_t addr, void *priv)
(void) xga_read_test(addr, svga);
addr = (addr & svga->banked_mask) + svga->read_bank;
if ((((dev->local & 0xff) >= 0x02) && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) {
if ((ATI_MACH32 && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) {
addr <<= 1;
switch (addr & 0x06) {
case 0x00:
@@ -5676,7 +5749,7 @@ mach32_readw(uint32_t addr, void *priv)
(void) xga_read_test(addr, svga);
addr = (addr & svga->banked_mask) + svga->read_bank;
if ((((dev->local & 0xff) >= 0x02) && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) {
if ((ATI_MACH32 && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) {
addr <<= 1;
if (addr & 0x04) {
ret = mach32_read_common(addr - 2, 0, mach, svga) & 0x0f;
@@ -5708,7 +5781,7 @@ mach32_readl(uint32_t addr, void *priv)
(void) xga_read_test(addr, svga);
addr = (addr & svga->banked_mask) + svga->read_bank;
if ((((dev->local & 0xff) >= 0x02) && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) {
if ((ATI_MACH32 && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) {
addr <<= 1;
ret = mach32_read_common(addr, 0, mach, svga) & 0x0f;
ret |= (mach32_read_common(addr + 1, 0, mach, svga) << 4);
@@ -5998,7 +6071,7 @@ mach32_updatemapping(mach_t *mach, svga_t *svga)
case 0xC: /*32k at B8000*/
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
svga->banked_mask = 0x7fff;
if (((dev->local & 0xff) >= 0x02) && !(dev->accel.advfunc_cntl & 0x01) && !(mach->accel.clock_sel & 0x01)) {
if (ATI_MACH32 && !(dev->accel.advfunc_cntl & 0x01) && !(mach->accel.clock_sel & 0x01)) {
if ((svga->gdcreg[6] & 0x01) || (svga->attrregs[0x10] & 0x01)) {
if (svga->attrregs[0x10] & 0x40) {
dev->vendor_mode = 0;
@@ -6035,7 +6108,7 @@ mach32_updatemapping(mach_t *mach, svga_t *svga)
mem_mapping_disable(&mach->mmio_linear_mapping);
}
if ((dev->local & 0xff) >= 0x02) {
if (ATI_MACH32) {
if (dev->on && dev->vendor_mode) {
mach_log("Mach32 banked mapping.\n");
mem_mapping_disable(&svga->mapping);
@@ -6216,6 +6289,7 @@ ati8514_io_set(svga_t *svga)
io_sethandler(0x7eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0x82ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0x86ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0x8aee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0x8eee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0x92ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0x96ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
@@ -6238,6 +6312,7 @@ ati8514_io_set(svga_t *svga)
io_sethandler(0xdeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0xe2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0xe6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0xeaee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0xeeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0xf2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
io_sethandler(0xf6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga);
@@ -6331,6 +6406,7 @@ mach_io_remove(mach_t *mach)
io_removehandler(0x7eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_removehandler(0x82ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_removehandler(0x86ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_removehandler(0x8aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_removehandler(0x8eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_removehandler(0x92ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_removehandler(0x96ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
@@ -6353,6 +6429,7 @@ mach_io_remove(mach_t *mach)
io_removehandler(0xdeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_removehandler(0xe2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_removehandler(0xe6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_removehandler(0xeaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_removehandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_removehandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
io_removehandler(0xf6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach);
@@ -6817,7 +6894,7 @@ mach8_init(const device_t *info)
dev->vram_512k_8514 = dev->vram_amount == 512;
dev->accel.cmd_back = 1;
if ((dev->local & 0xff) >= 0x02) {
if (ATI_MACH32) {
if (mach->pci_bus) {
if (mach->has_bios) {
rom_init(&mach->bios_rom,
@@ -6852,7 +6929,7 @@ mach8_init(const device_t *info)
0xc0000, 0x8000, 0x7fff,
0, MEM_MAPPING_EXTERNAL);
if ((dev->local & 0xff) >= 0x02) {
if (ATI_MACH32) {
svga_init(info, svga, mach, dev->vram_amount << 10, /*default: 2MB for Mach32*/
mach_recalctimings,
mach_in, mach_out,
@@ -6940,7 +7017,7 @@ mach8_init(const device_t *info)
mach_io_set(mach);
mach->accel.cmd_type = -2;
if ((dev->local & 0xff) >= 0x02) {
if (ATI_MACH32) {
svga->decode_mask = (4 << 20) - 1;
mach->cursor_col_1 = 0xff;
mach->ext_cur_col_1_r = 0xff;
@@ -6985,13 +7062,21 @@ ati8514_init(svga_t *svga, void *ext8514, void *dev8514)
mach_t *mach = (mach_t *) ext8514;
ibm8514_t *dev = (ibm8514_t *) dev8514;
/*Init as 1024x768 87hz interlaced first, per 8514/A.*/
dev->on = 0;
dev->ext_pitch = 1024;
dev->ext_crt_pitch = 0x80;
dev->accel_bpp = 8;
dev->rowoffset = 0x80;
dev->hdisp = 1024;
dev->vdisp = 768;
dev->hdisped = 0x7f;
dev->v_disp = 0x05ff;
dev->htotal = 0x9d;
dev->v_total_reg = 0x0668;
dev->v_sync_start = 0x0600;
dev->disp_cntl = 0x33;
mach->accel.clock_sel = 0x1c;
mach->shadow_set = 0x02;
mach->crt_resolution = 0x02;
io_sethandler(0x02ea, 4, ati8514_in, NULL, NULL, ati8514_out, NULL, NULL, svga);
ati8514_io_set(svga);

View File

@@ -67,8 +67,10 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
ega_t *ega = (ega_t *) priv;
uint8_t o;
uint8_t old;
uint8_t gdcmask = (ega->actual_type == EGA_SUPEREGA) ? 0xff : 0x0f;
uint8_t crtcmask = (ega->actual_type == EGA_SUPEREGA) ? 0xff : 0x1f;
int type = ega_type;
int atype = ega->actual_type;
uint8_t gdcmask = (ega_type == EGA_SUPEREGA) ? 0xff : 0x0f;
uint8_t crtcmask = (atype == EGA_SUPEREGA) ? 0xff : 0x1f;
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1))
addr ^= 0x60;
@@ -94,7 +96,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
case 0x3c0:
case 0x3c1:
if (ega->actual_type == EGA_SUPEREGA)
if (atype == EGA_SUPEREGA)
val &= 0x7f; /* Bit 7 indicates the flipflop status (read only) */
if (!ega->attrff) {
ega->attraddr = val & 31;
@@ -110,7 +112,8 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
ega->attrregs[ega->attraddr & 31] = val;
if (ega->attraddr < 16)
ega->fullchange = changeframecount;
if (ega->attraddr == 0x10 || ega->attraddr == 0x14 || ega->attraddr < 0x10) {
int is_attr14 = ega->chipset && (ega->attraddr == 0x14);
if ((ega->attraddr == 0x10) || is_attr14 || (ega->attraddr < 0x10)) {
for (uint8_t c = 0; c < 16; c++) {
if (ega->chipset) {
if (ega->attrregs[0x10] & 0x80)
@@ -143,12 +146,13 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
ega->pallook = ega->vres ? pallook16 : pallook64;
ega->vidclock = val & 4;
ega->miscout = val;
ega->overscan_color = ega->vres ? pallook16[ega->attrregs[0x11] & 0x0f] : pallook64[ega->attrregs[0x11] & 0x3f];
ega->overscan_color = ega->vres ? pallook16[ega->attrregs[0x11] & 0x0f] :
pallook64[ega->attrregs[0x11] & 0x3f];
io_removehandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
if (!(val & 1))
io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
ega_recalctimings(ega);
if ((ega_type == EGA_TYPE_COMPAQ) && !(val & 0x02))
if ((type == EGA_TYPE_COMPAQ) && !(val & 0x02))
mem_mapping_disable(&ega->mapping);
else switch (ega->gdcreg[6] & 0xc) {
case 0x0: /*128k at A0000*/
@@ -198,7 +202,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
}
break;
case 0x3c6:
if (ega_type == EGA_TYPE_COMPAQ)
if (type == EGA_TYPE_COMPAQ)
ega->ctl_mode = val;
break;
case 0x3ce:
@@ -219,7 +223,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
ega->chain2_read = val & 0x10;
break;
case 6:
if ((ega_type == EGA_TYPE_COMPAQ) && !(ega->miscout & 0x02))
if ((type == EGA_TYPE_COMPAQ) && !(ega->miscout & 0x02))
mem_mapping_disable(&ega->mapping);
else switch (val & 0xc) {
case 0x0: /*128k at A0000*/
@@ -265,28 +269,34 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
if (ega->chipset)
ega->crtcreg = val & 0x3f;
else
ega->crtcreg = val & crtcmask;
ega->crtcreg = val;
return;
case 0x3d1:
case 0x3d5:
case 0x3d5: {
int idx = ega->crtcreg;
if (ega->chipset) {
if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80) && !(ega->regs[0xb4] & 0x80))
return;
if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80) && !(ega->regs[0xb4] & 0x80))
val = (ega->crtc[7] & ~0x10) | (val & 0x10);
} else {
if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80))
idx &= crtcmask;
if ((idx >= 0x19) & (idx <= 0xf6))
return;
if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80))
if ((idx < 7) && (ega->crtc[0x11] & 0x80))
return;
if ((idx == 7) && (ega->crtc[0x11] & 0x80))
val = (ega->crtc[7] & ~0x10) | (val & 0x10);
}
old = ega->crtc[ega->crtcreg];
ega->crtc[ega->crtcreg] = val;
old = ega->crtc[idx];
ega->crtc[idx] = val;
if (old != val) {
if (ega->crtcreg < 0xe || ega->crtcreg > 0x10) {
if ((ega->crtcreg == 0xc) || (ega->crtcreg == 0xd)) {
if ((idx < 0xe) || (idx > 0x10)) {
if ((idx == 0xc) || (idx == 0xd)) {
ega->fullchange = 3;
ega->ma_latch = ((ega->crtc[0xc] << 8) | ega->crtc[0xd]) + ((ega->crtc[8] & 0x60) >> 5);
ega->ma_latch = ((ega->crtc[0xc] << 8) | ega->crtc[0xd]) +
((ega->crtc[8] & 0x60) >> 5);
} else {
ega->fullchange = changeframecount;
ega_recalctimings(ega);
@@ -295,7 +305,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv)
}
break;
default:
} default:
break;
}
}
@@ -304,8 +314,11 @@ uint8_t
ega_in(uint16_t addr, void *priv)
{
ega_t *ega = (ega_t *) priv;
uint8_t gdcmask = (ega->actual_type == EGA_SUPEREGA) ? 0xff : 0x0f;
uint8_t ret = 0xff;
uint8_t ret = 0xff;
int type = ega_type;
int atype = ega->actual_type;
uint8_t gdcmask = (atype == EGA_SUPEREGA) ? 0xff : 0x0f;
uint8_t crtcmask = (atype == EGA_SUPEREGA) ? 0xff : 0x1f;
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1))
addr ^= 0x60;
@@ -329,48 +342,68 @@ ega_in(uint16_t addr, void *priv)
break;
case 0x3c0:
if (ega_type == EGA_TYPE_OTHER)
ret = ega->attraddr | ega->attr_palette_enable;
if (ega->actual_type == EGA_SUPEREGA && ega->attrff)
ret |= 0x80; /* Bit 7 indicates the flipflop status (read only) */
break;
case 0x3c1:
if (ega_type == EGA_TYPE_OTHER)
ret = ega->attrregs[ega->attraddr];
if (type == EGA_TYPE_OTHER) {
int data = (atype == EGA_SUPEREGA) ? (ega->attrff & 1) : (addr & 1);
if (data)
ret = ega->attrregs[ega->attraddr];
else
ret = ega->attraddr | ega->attr_palette_enable;
if (atype == EGA_SUPEREGA)
/* Bit 7 indicates the flipflop status (read only) */
ret = (ret & 0x3f) | (ega->attrff ? 0x80 : 0x00);
}
break;
case 0x3c2:
ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00;
break;
case 0x3c4:
if (ega_type == EGA_TYPE_OTHER)
ret = ega->seqaddr;
if (type == EGA_TYPE_OTHER) {
if (atype == EGA_SUPEREGA)
ret = 0x1f | ((ega->miscout & 0x01) << 5);
else
ret = ega->seqaddr;
}
break;
case 0x3c5:
if (ega_type == EGA_TYPE_OTHER)
ret = ega->seqregs[ega->seqaddr & 0xf];
if (type == EGA_TYPE_OTHER) {
if ((ega->seqaddr & 0x0f) > 0x04)
ret = ega->chipset ? ega->seqregs[ega->seqaddr & 0xf] : 0xff;
else
ret = ega->seqregs[ega->seqaddr & 0xf];
}
break;
case 0x3c6:
if (ega_type == EGA_TYPE_COMPAQ)
if (type == EGA_TYPE_COMPAQ)
ret = ega->ctl_mode;
break;
case 0x3c8:
if (ega_type == EGA_TYPE_OTHER)
if (type == EGA_TYPE_OTHER)
ret = 2;
break;
case 0x3cc:
if (ega_type == EGA_TYPE_OTHER)
if (type == EGA_TYPE_OTHER)
ret = ega->miscout;
break;
case 0x3ce:
if (ega_type == EGA_TYPE_OTHER)
if (ega_type == EGA_TYPE_OTHER) {
ret = ega->gdcaddr;
if (atype == EGA_SUPEREGA) {
ret = (ret & 0x0f) | 0xe0;
if ((ega->gdcaddr & 0xe0) == 0xe0)
ret |= 0x10;
}
}
break;
case 0x3cf:
if (ega_type == EGA_TYPE_OTHER) {
if (type == EGA_TYPE_OTHER) {
switch (ega->gdcaddr & gdcmask) {
default:
ret = ega->gdcreg[ega->gdcaddr & gdcmask];
break;
case 0x09 ... 0xf7:
ret = ega->chipset ? ega->gdcreg[ega->gdcaddr & gdcmask] : 0xff;
break;
case 0xf8:
ret = ega->la;
break;
@@ -388,12 +421,18 @@ ega_in(uint16_t addr, void *priv)
break;
case 0x3d0:
case 0x3d4:
if (ega_type == EGA_TYPE_OTHER)
if (ega_type == EGA_TYPE_OTHER) {
ret = ega->crtcreg;
if (atype == EGA_SUPEREGA) {
ret = (ret & 0x1f) | 0xc0;
if ((ega->crtcreg & 0xc0) == 0xc0)
ret |= 0x20;
}
}
break;
case 0x3d1:
case 0x3d5:
switch (ega->crtcreg) {
switch (ega->crtcreg & crtcmask) {
case 0xc:
case 0xd:
case 0xe:
@@ -402,28 +441,33 @@ ega_in(uint16_t addr, void *priv)
break;
case 0x10:
if (ega_type == EGA_TYPE_OTHER)
if (type == EGA_TYPE_OTHER)
ret = ega->crtc[ega->crtcreg];
else
ret = ega->light_pen >> 8;
break;
case 0x11:
if (ega_type == EGA_TYPE_OTHER)
if (type == EGA_TYPE_OTHER)
ret = ega->crtc[ega->crtcreg];
else
ret = ega->light_pen & 0xff;
break;
case 0x19 ... 0xf6:
if (type == EGA_TYPE_OTHER)
ret = ega->chipset ? ega->crtc[ega->crtcreg] : 0xff;
break;
default:
if (ega_type == EGA_TYPE_OTHER)
if (type == EGA_TYPE_OTHER)
ret = ega->crtc[ega->crtcreg];
break;
}
break;
case 0x3da:
ega->attrff = 0;
if (ega_type == EGA_TYPE_COMPAQ) {
if (type == EGA_TYPE_COMPAQ) {
ret = ega->stat & 0xcf;
switch ((ega->attrregs[0x12] >> 4) & 0x03) {
case 0x00:
@@ -629,7 +673,8 @@ ega_recalctimings(ega_t *ega)
disptime = (double) (ega->crtc[0] + 2);
_dispontime = (double) (ega->crtc[1] + 1);
}
if ((ega->actual_type == EGA_SUPEREGA) && (ega->crtc[0xf9] & 0x01)) {
if ((ega->actual_type == EGA_SUPEREGA) && (ega->crtc[0x17] & 0x10) &&
(ega->crtc[0xf9] & 0x01)) {
disptime *= 2.0;
_dispontime *= 2.0;
}
@@ -783,10 +828,7 @@ ega_poll(void *priv)
ega->y_add *= ega->vres + 1;
for (y = 0; y <= ega->vres; y++) {
/* Render scanline */
if (ega->render_override)
ega->render_override(ega->priv_parent);
else
ega->render(ega);
ega->render(ega);
/* Render overscan */
ega->x_add = (overscan_x >> 1);

View File

@@ -107,6 +107,11 @@ ega_render_overscan_right(ega_t *ega)
void
ega_render_text(ega_t *ega)
{
if (ega->render_override) {
ega->render_override(ega->priv_parent);
return;
}
if ((ega->displine + ega->y_add) < 0)
return;

View File

@@ -428,7 +428,8 @@ jega_out(uint16_t addr, uint8_t val, void *priv)
}
} else {
jega->attrregs[jega->attraddr & 31] = val;
if (jega->attraddr < 0x10) {
int is_attr14 = jega->is_vga ? (jega->attraddr == 0x14) : 0;
if (is_attr14 || (jega->attraddr < 0x10)) {
for (uint8_t c = 0; c < 16; c++) {
if (jega->is_vga) {
if (jega->attrregs[0x10] & 0x80)
@@ -464,21 +465,40 @@ jega_out(uint16_t addr, uint8_t val, void *priv)
case 0x3d5:
/* Data */
if (jega->regs_index != RINVALID_INDEX) {
if ((jega->regs_index < 7) && (jega->regs[0x11] & 0x80))
return;
if ((jega->regs_index == 7) && (jega->regs[0x11] & 0x80))
val = (jega->regs[7] & ~0x10) | (val & 0x10);
/*
Do not allow cursor updates if neither master nor slave is
active - the AX Windows 3.0 386 Enhanced Mode DOS grabber
relies on this for the cursor position to behave correctly.
*/
if ((jega->regs_index >= 0x0e) && (jega->regs_index <= 0x0f) && !(jega->regs[RMOD1] & 0x0c))
return;
jega->regs[jega->regs_index] = val;
jega_log("JEGA Out %04X(%02X) %02Xh(%d) %04X:%04X\n", addr, jega->regs_index, val, val, cs >> 4, cpu_state.pc);
switch (jega->regs_index) {
case RMOD1:
/* if the value is changed */
if (jega->is_vga) {
if (val & 0x40)
jega->vga.svga.render_override = NULL;
else
jega->vga.svga.render_override = jega_render_text;
} else {
if (val & 0x40)
jega->ega.render_override = NULL;
else
jega->ega.render_override = jega_render_text;
/*
Do not allow override toggling unless it's on master and
only override the text renderer - the AX Windows 3.0 386
Enhanced Mode DOS grabber relies on this for the grabbing
to behave correctly.
*/
if (val & 0x08) {
if (jega->is_vga) {
if (val & 0x40)
jega->vga.svga.render_override = NULL;
else
jega->vga.svga.render_override = jega_render_text;
} else {
if (val & 0x40)
jega->ega.render_override = NULL;
else
jega->ega.render_override = jega_render_text;
}
}
break;
case RDAGS:

View File

@@ -904,7 +904,7 @@ svga_recalctimings(svga_t *svga)
svga->recalctimings_ex(svga);
if (ibm8514_active && (svga->dev8514 != NULL)) {
if ((dev->local & 0xff) == 0x00)
if (IBM_8514A || ATI_8514A_ULTRA)
ibm8514_recalctimings(svga);
}
@@ -1031,8 +1031,8 @@ svga_recalctimings(svga_t *svga)
if (ibm8514_active && (svga->dev8514 != NULL)) {
if (dev->on) {
disptime8514 = dev->h_total;
_dispontime8514 = (dev->hdisped + 1) * 8;
svga_log("HDISPED 8514=%d, htotal=%02x.\n", (dev->hdisped + 1) << 3, dev->h_total);
_dispontime8514 = dev->h_disp;
svga_log("HTOTAL=%d, HDISP=%d.\n", dev->h_total, dev->h_disp);
}
}
@@ -1176,10 +1176,7 @@ svga_do_render(svga_t *svga)
}
if (!svga->override) {
if (svga->render_override)
svga->render_override(svga->priv_parent);
else
svga->render(svga);
svga->render(svga);
svga->x_add = (svga->monitor->mon_overscan_x >> 1);
svga_render_overscan_left(svga);

View File

@@ -85,18 +85,9 @@ svga_render_blank(svga_t *svga)
break;
}
#if 0
pclog("svga->displine = %i, svga->y_add = %i, svga->x_add = %i\n", svga->displine, svga->y_add, svga->x_add);
#endif
uint32_t *line_ptr = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add];
#if 0
pclog("svga->hdisp = %i, svga->scrollcache = %i, char_width = %i, sizeof(uint32_t) = %i\n", svga->hdisp, svga->scrollcache, char_width, sizeof(uint32_t));
#endif
uint32_t line_width = (uint32_t) (svga->hdisp + svga->scrollcache) * char_width * sizeof(uint32_t);
#if 0
pclog("line_width = %i\n", line_width);
#endif
if ((svga->hdisp + svga->scrollcache) > 0)
memset(line_ptr, 0, line_width);
}
@@ -147,6 +138,11 @@ svga_render_text_40(svga_t *svga)
int bg;
uint32_t addr = 0;
if (svga->render_override) {
svga->render_override(svga->priv_parent);
return;
}
if ((svga->displine + svga->y_add) < 0)
return;
@@ -225,6 +221,11 @@ svga_render_text_80(svga_t *svga)
int bg;
uint32_t addr = 0;
if (svga->render_override) {
svga->render_override(svga->priv_parent);
return;
}
if ((svga->displine + svga->y_add) < 0)
return;