mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 18:08:20 -07:00
Merge branch '86Box:master' into main
This commit is contained in:
@@ -1520,13 +1520,13 @@ track_type_is_valid(UNUSED(uint8_t id), int type, int flags, int audio, int mode
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
read_sector_to_buffer(cdrom_t *dev, uint8_t *rbuf, uint32_t msf, uint32_t lba, int mode2, int len)
|
||||
{
|
||||
uint8_t *bb = rbuf;
|
||||
const int offset = (!!(mode2 & 0x03)) ? 24 : 16;
|
||||
|
||||
dev->ops->read_sector(dev, CD_READ_DATA, rbuf + offset, lba);
|
||||
int ret = dev->ops->read_sector(dev, CD_READ_DATA, rbuf + offset, lba);
|
||||
|
||||
/* Sync bytes */
|
||||
bb[0] = 0;
|
||||
@@ -1546,25 +1546,30 @@ read_sector_to_buffer(cdrom_t *dev, uint8_t *rbuf, uint32_t msf, uint32_t lba, i
|
||||
memset(bb, 0, 280);
|
||||
else if (!mode2)
|
||||
memset(bb, 0, 288);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
read_audio(cdrom_t *dev, uint32_t lba, uint8_t *b)
|
||||
{
|
||||
dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
int ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
|
||||
memcpy(b, raw_buffer, 2352);
|
||||
|
||||
cdrom_sector_size = 2352;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
read_mode1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b)
|
||||
{
|
||||
int ret;
|
||||
if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2048))
|
||||
read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048);
|
||||
ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048);
|
||||
else
|
||||
dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
|
||||
cdrom_sector_size = 0;
|
||||
|
||||
@@ -1610,15 +1615,18 @@ read_mode1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int
|
||||
cdrom_sector_size += 288;
|
||||
b += 288;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
read_mode2_non_xa(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b)
|
||||
{
|
||||
int ret;
|
||||
if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2336))
|
||||
read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2336);
|
||||
ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2336);
|
||||
else
|
||||
dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
|
||||
cdrom_sector_size = 0;
|
||||
|
||||
@@ -1654,15 +1662,18 @@ read_mode2_non_xa(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t m
|
||||
cdrom_sector_size += 2336;
|
||||
b += 2336;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
read_mode2_xa_form1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b)
|
||||
{
|
||||
int ret;
|
||||
if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2048))
|
||||
read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048);
|
||||
ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048);
|
||||
else
|
||||
dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
|
||||
cdrom_sector_size = 0;
|
||||
|
||||
@@ -1705,15 +1716,18 @@ read_mode2_xa_form1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t
|
||||
cdrom_sector_size += 280;
|
||||
b += 280;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
read_mode2_xa_form2(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b)
|
||||
{
|
||||
int ret;
|
||||
if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2324))
|
||||
read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2324);
|
||||
ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2324);
|
||||
else
|
||||
dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
|
||||
|
||||
cdrom_sector_size = 0;
|
||||
|
||||
@@ -1748,6 +1762,8 @@ read_mode2_xa_form2(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t
|
||||
cdrom_sector_size += 2328;
|
||||
b += 2328;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1763,6 +1779,7 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
|
||||
int m;
|
||||
int s;
|
||||
int f;
|
||||
int ret = 0;
|
||||
|
||||
if (dev->cd_status == CD_STATUS_EMPTY)
|
||||
return 0;
|
||||
@@ -1827,21 +1844,21 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
|
||||
return 0;
|
||||
}
|
||||
|
||||
read_audio(dev, lba, temp_b);
|
||||
ret = read_audio(dev, lba, temp_b);
|
||||
} else if (cdrom_sector_type == 2) {
|
||||
if (audio || mode2) {
|
||||
cdrom_log("CD-ROM %i: [Mode 1] Attempting to read a sector of another type\n", dev->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
} else if (cdrom_sector_type == 3) {
|
||||
if (audio || !mode2 || (mode2 & 0x03)) {
|
||||
cdrom_log("CD-ROM %i: [Mode 2 Formless] Attempting to read a sector of another type\n", dev->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
} else if (cdrom_sector_type == 4) {
|
||||
if (audio || !mode2 || ((mode2 & 0x03) != 1)) {
|
||||
cdrom_log("CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a sector of another type\n", dev->id);
|
||||
@@ -1855,7 +1872,7 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
|
||||
return 0;
|
||||
}
|
||||
|
||||
read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
} else if (cdrom_sector_type == 8) {
|
||||
if (audio) {
|
||||
cdrom_log("CD-ROM %i: [Any Data] Attempting to read a data sector from an audio track\n", dev->id);
|
||||
@@ -1863,9 +1880,9 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
|
||||
}
|
||||
|
||||
if (mode2 && ((mode2 & 0x03) == 1))
|
||||
read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
else if (!mode2)
|
||||
read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
else {
|
||||
cdrom_log("CD-ROM %i: [Any Data] Attempting to read a data sector whose cooked size is not 2048 bytes\n", dev->id);
|
||||
return 0;
|
||||
@@ -1873,16 +1890,16 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
|
||||
} else {
|
||||
if (mode2) {
|
||||
if ((mode2 & 0x03) == 0x01)
|
||||
read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
else if ((mode2 & 0x03) == 0x02)
|
||||
read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
else
|
||||
read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
} else {
|
||||
if (audio)
|
||||
read_audio(dev, lba, temp_b);
|
||||
ret = read_audio(dev, lba, temp_b);
|
||||
else
|
||||
read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
ret = read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1914,7 +1931,7 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
|
||||
|
||||
*len = cdrom_sector_size;
|
||||
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Peform a master init on the entire module. */
|
||||
|
||||
@@ -181,13 +181,13 @@ bin_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
|
||||
if (fseeko64(tf->fp, seek, SEEK_SET) == -1) {
|
||||
cdrom_image_backend_log("CDROM: binary_read failed during seek!\n");
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fread(buffer, count, 1, tf->fp) != 1) {
|
||||
cdrom_image_backend_log("CDROM: binary_read failed during read!\n");
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (UNLIKELY(tf->motorola)) {
|
||||
@@ -502,8 +502,8 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
|
||||
if (raw && !track_is_raw) {
|
||||
memset(buffer, 0x00, 2448);
|
||||
const int ret = trk->file->read(trk->file, buffer + offset, seek, length);
|
||||
if (!ret)
|
||||
return 0;
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
/* Construct the rest of the raw sector. */
|
||||
memset(buffer + 1, 0xff, 10);
|
||||
buffer += 12;
|
||||
@@ -534,7 +534,7 @@ cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint3
|
||||
|
||||
for (uint32_t i = 0; i < num; i++) {
|
||||
success = cdi_read_sector(cdi, &buf[i * sector_size], raw, sector + i);
|
||||
if (!success)
|
||||
if (success <= 0)
|
||||
break;
|
||||
/* Based on the DOSBox patch, but check all 8 bytes and makes sure it's not an
|
||||
audio track. */
|
||||
|
||||
@@ -716,8 +716,11 @@ viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
|
||||
}
|
||||
|
||||
/* Read data. */
|
||||
if (entry->file && (fseeko64(entry->file, seek - entry->data_offset, SEEK_SET) != -1))
|
||||
read = fread(buffer, 1, sector_remain, entry->file);
|
||||
if (!entry->file || (fseeko64(entry->file, seek - entry->data_offset, SEEK_SET) == -1))
|
||||
return -1;
|
||||
read = fread(buffer, 1, sector_remain, entry->file);
|
||||
if (sector_remain && !read)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Fill remainder with 00 bytes if needed. */
|
||||
|
||||
@@ -197,7 +197,7 @@ mitsumi_cdrom_read_sector(mcd_t *dev, int first)
|
||||
}
|
||||
cdrom_stop(&cdrom);
|
||||
ret = cdrom_readsector_raw(&cdrom, dev->buf, cdrom.seek_pos, 0, 2, 0x10, (int *) &dev->readcount, 0);
|
||||
if (!ret)
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
if (dev->mode & 0x40) {
|
||||
dev->buf[12] = CD_BCD((dev->readmsf >> 16) & 0xff);
|
||||
|
||||
@@ -110,6 +110,7 @@ typedef struct _isapnp_card_ {
|
||||
} isapnp_card_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t in_isolation;
|
||||
uint8_t reg;
|
||||
uint8_t key_pos : 5;
|
||||
uint16_t read_data_addr;
|
||||
@@ -313,6 +314,8 @@ isapnp_read_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uint
|
||||
|
||||
case 0x05: /* Status */
|
||||
ret = 0x00;
|
||||
if (dev->in_isolation)
|
||||
ret = 0x01;
|
||||
CHECK_CURRENT_CARD();
|
||||
|
||||
isapnp_log("ISAPnP: Query status for CSN %02X\n", card->csn);
|
||||
@@ -485,15 +488,16 @@ isapnp_write_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uin
|
||||
case 0x03: /* Wake[CSN] */
|
||||
isapnp_log("ISAPnP: Wake[%02X]\n", val);
|
||||
card = dev->first_card;
|
||||
if (val == 0)
|
||||
dev->in_isolation |= 1;
|
||||
while (card) {
|
||||
if (card->csn == val) {
|
||||
card->rom_pos = 0;
|
||||
card->id_checksum = isapnp_init_key[0];
|
||||
if (card->state == PNP_STATE_SLEEP)
|
||||
card->state = (val == 0) ? PNP_STATE_ISOLATION : PNP_STATE_CONFIG;
|
||||
} else {
|
||||
} else
|
||||
card->state = PNP_STATE_SLEEP;
|
||||
}
|
||||
|
||||
card = card->next;
|
||||
}
|
||||
@@ -505,6 +509,7 @@ isapnp_write_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uin
|
||||
isapnp_set_csn(dev->isolated_card, val);
|
||||
dev->isolated_card->state = PNP_STATE_CONFIG;
|
||||
dev->isolated_card = NULL;
|
||||
dev->in_isolation = 0;
|
||||
} else {
|
||||
isapnp_log("ISAPnP: Set CSN %02X but no card is isolated\n", val);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/timer.h>
|
||||
|
||||
@@ -606,12 +606,16 @@ esdi_callback(void *priv)
|
||||
} else {
|
||||
if (get_sector(esdi, &addr)) {
|
||||
esdi->error = ERR_ID_NOT_FOUND;
|
||||
read_error:
|
||||
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
||||
irq_raise(esdi);
|
||||
break;
|
||||
}
|
||||
|
||||
hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer);
|
||||
if (hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer) < 0) {
|
||||
esdi->error = ERR_BAD_BLOCK;
|
||||
goto read_error;
|
||||
}
|
||||
esdi->pos = 0;
|
||||
esdi->status = STAT_DRQ | STAT_READY | STAT_DSC;
|
||||
irq_raise(esdi);
|
||||
@@ -628,13 +632,17 @@ esdi_callback(void *priv)
|
||||
} else {
|
||||
if (get_sector(esdi, &addr)) {
|
||||
esdi->error = ERR_ID_NOT_FOUND;
|
||||
write_error:
|
||||
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
||||
irq_raise(esdi);
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer);
|
||||
if (hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer) < 0) {
|
||||
esdi->error = ERR_BAD_BLOCK;
|
||||
goto write_error;
|
||||
}
|
||||
irq_raise(esdi);
|
||||
esdi->secount = (esdi->secount - 1) & 0xff;
|
||||
if (esdi->secount) {
|
||||
@@ -659,13 +667,17 @@ esdi_callback(void *priv)
|
||||
} else {
|
||||
if (get_sector(esdi, &addr)) {
|
||||
esdi->error = ERR_ID_NOT_FOUND;
|
||||
verify_error:
|
||||
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
||||
irq_raise(esdi);
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer);
|
||||
if (hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer) < 0) {
|
||||
esdi->error = ERR_BAD_BLOCK;
|
||||
goto verify_error;
|
||||
}
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
|
||||
next_sector(esdi);
|
||||
esdi->secount = (esdi->secount - 1) & 0xff;
|
||||
@@ -692,12 +704,16 @@ esdi_callback(void *priv)
|
||||
} else {
|
||||
if (get_sector_format(esdi, &addr)) {
|
||||
esdi->error = ERR_ID_NOT_FOUND;
|
||||
format_error:
|
||||
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
|
||||
irq_raise(esdi);
|
||||
break;
|
||||
}
|
||||
|
||||
hdd_image_zero(drive->hdd_num, addr, esdi->secount);
|
||||
if (hdd_image_zero(drive->hdd_num, addr, esdi->secount) < 0) {
|
||||
esdi->error = ERR_BAD_BLOCK;
|
||||
goto format_error;
|
||||
}
|
||||
esdi->status = STAT_READY | STAT_DSC;
|
||||
irq_raise(esdi);
|
||||
}
|
||||
|
||||
@@ -327,6 +327,27 @@ rba_out_of_range(esdi_t *dev)
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
defective_block(esdi_t *dev)
|
||||
{
|
||||
dev->status_len = 9;
|
||||
dev->status_data[0] = dev->command | STATUS_LEN(9) | dev->cmd_dev;
|
||||
dev->status_data[1] = 0x0e01; /*Command block error, invalid parameter*/
|
||||
dev->status_data[2] = 0x0009; /*Defective block*/
|
||||
dev->status_data[3] = 0;
|
||||
dev->status_data[4] = 0;
|
||||
dev->status_data[5] = 0;
|
||||
dev->status_data[6] = 0;
|
||||
dev->status_data[7] = 0;
|
||||
dev->status_data[8] = 0;
|
||||
|
||||
dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL;
|
||||
dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_FAILURE;
|
||||
dev->irq_in_progress = 1;
|
||||
set_irq(dev);
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
complete_command_status(esdi_t *dev)
|
||||
{
|
||||
@@ -423,7 +444,10 @@ esdi_callback(void *priv)
|
||||
if (!dev->data_pos) {
|
||||
if (dev->rba >= drive->sectors)
|
||||
fatal("Read past end of drive\n");
|
||||
hdd_image_read(drive->hdd_num, dev->rba, 1, (uint8_t *) dev->data);
|
||||
if (hdd_image_read(drive->hdd_num, dev->rba, 1, (uint8_t *) dev->data) < 0) {
|
||||
defective_block(dev);
|
||||
return;
|
||||
}
|
||||
cmd_time += hdd_timing_read(&hdd[drive->hdd_num], dev->rba, 1);
|
||||
cmd_time += esdi_mca_get_xfer_time(dev, 1);
|
||||
}
|
||||
@@ -512,7 +536,10 @@ esdi_callback(void *priv)
|
||||
|
||||
if (dev->rba >= drive->sectors)
|
||||
fatal("Write past end of drive\n");
|
||||
hdd_image_write(drive->hdd_num, dev->rba, 1, (uint8_t *) dev->data);
|
||||
if (hdd_image_write(drive->hdd_num, dev->rba, 1, (uint8_t *) dev->data) < 0) {
|
||||
defective_block(dev);
|
||||
return;
|
||||
}
|
||||
cmd_time += hdd_timing_write(&hdd[drive->hdd_num], dev->rba, 1);
|
||||
cmd_time += esdi_mca_get_xfer_time(dev, 1);
|
||||
dev->rba++;
|
||||
|
||||
@@ -2214,8 +2214,10 @@ ide_callback(void *priv)
|
||||
if (ide->do_initial_read) {
|
||||
ide->do_initial_read = 0;
|
||||
ide->sector_pos = 0;
|
||||
hdd_image_read(ide->hdd_num, ide_get_sector(ide),
|
||||
ide->tf->secount ? ide->tf->secount : 256, ide->sector_buffer);
|
||||
ret = hdd_image_read(ide->hdd_num, ide_get_sector(ide),
|
||||
ide->tf->secount ? ide->tf->secount : 256, ide->sector_buffer);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512);
|
||||
@@ -2224,6 +2226,10 @@ ide_callback(void *priv)
|
||||
|
||||
ide->tf->pos = 0;
|
||||
ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
|
||||
if (ret < 0) {
|
||||
ide_log("IDE %i: Read aborted (image read error)\n", ide->channel);
|
||||
err = UNC_ERR;
|
||||
}
|
||||
|
||||
ide_irq_raise(ide);
|
||||
|
||||
@@ -2245,11 +2251,13 @@ ide_callback(void *priv)
|
||||
ide->sector_pos = ide->tf->secount;
|
||||
else
|
||||
ide->sector_pos = 256;
|
||||
hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer);
|
||||
|
||||
ide->tf->pos = 0;
|
||||
|
||||
if (!ide_boards[ide->board]->force_ata3 && bm->dma) {
|
||||
if (hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer) < 0) {
|
||||
ide_log("IDE %i: DMA read aborted (image read error)\n", ide->channel);
|
||||
err = UNC_ERR;
|
||||
} else if (!ide_boards[ide->board]->force_ata3 && bm->dma) {
|
||||
/* We should not abort - we should simply wait for the host to start DMA. */
|
||||
ret = bm->dma(ide->sector_buffer, ide->sector_pos * 512, 0, bm->priv);
|
||||
if (ret == 2) {
|
||||
@@ -2292,8 +2300,10 @@ ide_callback(void *priv)
|
||||
if (ide->do_initial_read) {
|
||||
ide->do_initial_read = 0;
|
||||
ide->sector_pos = 0;
|
||||
hdd_image_read(ide->hdd_num, ide_get_sector(ide),
|
||||
ide->tf->secount ? ide->tf->secount : 256, ide->sector_buffer);
|
||||
ret = hdd_image_read(ide->hdd_num, ide_get_sector(ide),
|
||||
ide->tf->secount ? ide->tf->secount : 256, ide->sector_buffer);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512);
|
||||
@@ -2302,6 +2312,10 @@ ide_callback(void *priv)
|
||||
ide->tf->pos = 0;
|
||||
|
||||
ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
|
||||
if (ret < 0) {
|
||||
ide_log("IDE %i: Read aborted (image read error)\n", ide->channel);
|
||||
err = UNC_ERR;
|
||||
}
|
||||
if (!ide->blockcount)
|
||||
ide_irq_raise(ide);
|
||||
ide->blockcount++;
|
||||
@@ -2320,7 +2334,7 @@ ide_callback(void *priv)
|
||||
else if (!ide->tf->lba && (ide->cfg_spt == 0))
|
||||
err = IDNF_ERR;
|
||||
else {
|
||||
hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
|
||||
ret = hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
|
||||
ide_irq_raise(ide);
|
||||
ide->tf->secount--;
|
||||
if (ide->tf->secount) {
|
||||
@@ -2332,6 +2346,8 @@ ide_callback(void *priv)
|
||||
ide->tf->atastat = DRDY_STAT | DSC_STAT;
|
||||
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
|
||||
}
|
||||
if (ret < 0)
|
||||
err = UNC_ERR;
|
||||
}
|
||||
ide_log("Write: %02X, %i, %08X, %" PRIi64 "\n", err, ide->hdd_num, ide->lba_addr, sector);
|
||||
break;
|
||||
@@ -2360,12 +2376,14 @@ ide_callback(void *priv)
|
||||
return;
|
||||
} else if (ret == 1) {
|
||||
/* DMA successful */
|
||||
ide_log("IDE %i: DMA write successful\n", ide->channel);
|
||||
ret = hdd_image_write(ide->hdd_num, ide_get_sector(ide),
|
||||
ide->sector_pos, ide->sector_buffer);
|
||||
|
||||
hdd_image_write(ide->hdd_num, ide_get_sector(ide),
|
||||
ide->sector_pos, ide->sector_buffer);
|
||||
ide_log("IDE %i: DMA write %ssuccessful\n", ide->channel, (ret < 0) ? "un" : "");
|
||||
|
||||
ide->tf->atastat = DRDY_STAT | DSC_STAT;
|
||||
if (ret < 0)
|
||||
err = UNC_ERR;
|
||||
|
||||
ide_irq_raise(ide);
|
||||
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
|
||||
@@ -2393,7 +2411,7 @@ ide_callback(void *priv)
|
||||
else if (!ide->tf->lba && (ide->cfg_spt == 0))
|
||||
err = IDNF_ERR;
|
||||
else {
|
||||
hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
|
||||
ret = hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
|
||||
ide->blockcount++;
|
||||
if (ide->blockcount >= ide->blocksize || ide->tf->secount == 1) {
|
||||
ide->blockcount = 0;
|
||||
@@ -2408,6 +2426,8 @@ ide_callback(void *priv)
|
||||
ide->tf->atastat = DRDY_STAT | DSC_STAT;
|
||||
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
|
||||
}
|
||||
if (ret < 0)
|
||||
err = UNC_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2431,9 +2451,11 @@ ide_callback(void *priv)
|
||||
else if (!ide->tf->lba && (ide->cfg_spt == 0))
|
||||
err = IDNF_ERR;
|
||||
else {
|
||||
hdd_image_zero(ide->hdd_num, ide_get_sector_format(ide), ide->tf->secount);
|
||||
ret = hdd_image_zero(ide->hdd_num, ide_get_sector_format(ide), ide->tf->secount);
|
||||
|
||||
ide->tf->atastat = DRDY_STAT | DSC_STAT;
|
||||
if (ret < 0)
|
||||
err = UNC_ERR;
|
||||
ide_irq_raise(ide);
|
||||
|
||||
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1);
|
||||
|
||||
@@ -585,12 +585,16 @@ do_callback(void *priv)
|
||||
do_seek(mfm);
|
||||
if (get_sector(mfm, &addr)) {
|
||||
mfm->error = ERR_ID_NOT_FOUND;
|
||||
read_error:
|
||||
mfm->status = STAT_READY | STAT_DSC | STAT_ERR;
|
||||
irq_raise(mfm);
|
||||
break;
|
||||
}
|
||||
|
||||
hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) mfm->buffer);
|
||||
if (hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) mfm->buffer) < 0) {
|
||||
mfm->error = ERR_BAD_BLOCK;
|
||||
goto read_error;
|
||||
}
|
||||
|
||||
mfm->pos = 0;
|
||||
mfm->status = STAT_DRQ | STAT_READY | STAT_DSC;
|
||||
@@ -604,12 +608,16 @@ do_callback(void *priv)
|
||||
do_seek(mfm);
|
||||
if (get_sector(mfm, &addr)) {
|
||||
mfm->error = ERR_ID_NOT_FOUND;
|
||||
write_error:
|
||||
mfm->status = STAT_READY | STAT_DSC | STAT_ERR;
|
||||
irq_raise(mfm);
|
||||
break;
|
||||
}
|
||||
|
||||
hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *) mfm->buffer);
|
||||
if (hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *) mfm->buffer) < 0) {
|
||||
mfm->error = ERR_BAD_BLOCK;
|
||||
goto write_error;
|
||||
}
|
||||
irq_raise(mfm);
|
||||
mfm->secount = (mfm->secount - 1) & 0xff;
|
||||
|
||||
|
||||
@@ -715,6 +715,7 @@ st506_callback(void *priv)
|
||||
dev->head, dev->sector, dev->count);
|
||||
|
||||
if (!get_sector(dev, drive, &addr)) {
|
||||
read_error_start:
|
||||
st506_error(dev, dev->error);
|
||||
st506_complete(dev);
|
||||
return;
|
||||
@@ -722,8 +723,11 @@ st506_callback(void *priv)
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1);
|
||||
|
||||
/* Read data from the image. */
|
||||
hdd_image_read(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->buff);
|
||||
if (hdd_image_read(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->buff) < 0) {
|
||||
dev->error = ERR_UNC_ERR;
|
||||
goto read_error_start;
|
||||
}
|
||||
|
||||
/* Set up the data transfer. */
|
||||
dev->buff_pos = 0;
|
||||
@@ -765,6 +769,7 @@ st506_callback(void *priv)
|
||||
next_sector(dev, drive);
|
||||
|
||||
if (!get_sector(dev, drive, &addr)) {
|
||||
read_error_sent:
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||
st506_error(dev, dev->error);
|
||||
st506_complete(dev);
|
||||
@@ -772,8 +777,11 @@ st506_callback(void *priv)
|
||||
}
|
||||
|
||||
/* Read data from the image. */
|
||||
hdd_image_read(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->buff);
|
||||
if (hdd_image_read(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->buff) < 0) {
|
||||
dev->error = ERR_UNC_ERR;
|
||||
goto read_error_sent;
|
||||
}
|
||||
|
||||
/* Set up the data transfer. */
|
||||
dev->buff_pos = 0;
|
||||
@@ -856,6 +864,7 @@ st506_callback(void *priv)
|
||||
|
||||
case STATE_RECEIVED_DATA:
|
||||
if (!get_sector(dev, drive, &addr)) {
|
||||
write_error:
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||
st506_error(dev, dev->error);
|
||||
st506_complete(dev);
|
||||
@@ -863,8 +872,11 @@ st506_callback(void *priv)
|
||||
}
|
||||
|
||||
/* Write data to image. */
|
||||
hdd_image_write(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->buff);
|
||||
if (hdd_image_write(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->buff) < 0) {
|
||||
dev->error = ERR_UNC_ERR;
|
||||
goto write_error;
|
||||
}
|
||||
|
||||
if (--dev->count == 0) {
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||
@@ -1156,8 +1168,12 @@ st506_callback(void *priv)
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1);
|
||||
|
||||
/* Write data to image. */
|
||||
hdd_image_write(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->buff);
|
||||
if (hdd_image_write(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->buff) < 0) {
|
||||
st506_error(dev, ERR_UNC_ERR);
|
||||
st506_complete(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
if (--dev->count == 0) {
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0);
|
||||
|
||||
@@ -408,8 +408,9 @@ do_fmt:
|
||||
break;
|
||||
|
||||
/* Write the block to the image. */
|
||||
hdd_image_write(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->sector_buf);
|
||||
if (hdd_image_write(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->sector_buf) < 0)
|
||||
dev->sense = ERR_BADTRK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,6 +523,7 @@ hdc_callback(void *priv)
|
||||
do_send:
|
||||
/* Get address of sector to load. */
|
||||
if (get_sector(dev, drive, &addr)) {
|
||||
read_error:
|
||||
/* De-activate the status icon. */
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0);
|
||||
dev->comp |= COMP_ERR;
|
||||
@@ -530,8 +532,11 @@ do_send:
|
||||
}
|
||||
|
||||
/* Read the block from the image. */
|
||||
hdd_image_read(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->sector_buf);
|
||||
if (hdd_image_read(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->sector_buf) < 0) {
|
||||
dev->sense = ERR_BADTRK;
|
||||
goto read_error;
|
||||
}
|
||||
|
||||
/* Ready to transfer the data out. */
|
||||
dev->state = STATE_SDATA;
|
||||
@@ -673,6 +678,7 @@ do_recv:
|
||||
|
||||
/* Get address of sector to write. */
|
||||
if (get_sector(dev, drive, &addr)) {
|
||||
write_error:
|
||||
/* De-activate the status icon. */
|
||||
ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0);
|
||||
|
||||
@@ -682,8 +688,11 @@ do_recv:
|
||||
}
|
||||
|
||||
/* Write the block to the image. */
|
||||
hdd_image_write(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->sector_buf);
|
||||
if (hdd_image_write(drive->hdd_num, addr, 1,
|
||||
(uint8_t *) dev->sector_buf) < 0) {
|
||||
dev->sense = ERR_BADTRK;
|
||||
goto write_error;
|
||||
}
|
||||
|
||||
dev->buf_idx = 0;
|
||||
if (--dev->count == 0) {
|
||||
|
||||
@@ -184,6 +184,9 @@ hdd_image_calc_chs(uint32_t *c, uint32_t *h, uint32_t *s, uint32_t size)
|
||||
static int
|
||||
prepare_new_hard_disk(uint8_t id, uint64_t full_size)
|
||||
{
|
||||
if (!hdd_images[id].file)
|
||||
return -1;
|
||||
|
||||
uint64_t target_size = (full_size + hdd_images[id].base) - ftello64(hdd_images[id].file);
|
||||
|
||||
#ifndef __unix__
|
||||
@@ -390,7 +393,9 @@ retry_vhd:
|
||||
} else {
|
||||
/* Failed for another reason */
|
||||
hdd_image_log("Failed for another reason\n");
|
||||
return 0;
|
||||
hdd_images[id].type = HDD_IMAGE_RAW;
|
||||
hdd_images[id].last_sector = (uint32_t) (((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks)) - 1;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (image_is_hdi(fn)) {
|
||||
@@ -500,7 +505,7 @@ retry_vhd:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
hdd_image_seek(uint8_t id, uint32_t sector)
|
||||
{
|
||||
off64_t addr = sector;
|
||||
@@ -508,29 +513,40 @@ hdd_image_seek(uint8_t id, uint32_t sector)
|
||||
|
||||
hdd_images[id].pos = sector;
|
||||
if (hdd_images[id].type != HDD_IMAGE_VHD) {
|
||||
if (fseeko64(hdd_images[id].file, addr + hdd_images[id].base, SEEK_SET) == -1)
|
||||
fatal("hdd_image_seek(): Error seeking\n");
|
||||
if (!hdd_images[id].file || (fseeko64(hdd_images[id].file, addr + hdd_images[id].base, SEEK_SET) == -1)) {
|
||||
hdd_image_log("hdd_image_seek(): Error seeking\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
int non_transferred_sectors;
|
||||
size_t num_read;
|
||||
|
||||
if (hdd_images[id].type == HDD_IMAGE_VHD) {
|
||||
non_transferred_sectors = mvhd_read_sectors(hdd_images[id].vhd, sector, count, buffer);
|
||||
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
|
||||
hdd_images[id].vhd->error = 0;
|
||||
non_transferred_sectors = mvhd_read_sectors(hdd_images[id].vhd, sector, count, buffer);
|
||||
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
|
||||
if (hdd_images[id].vhd->error)
|
||||
return -1;
|
||||
} else {
|
||||
if (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) {
|
||||
fatal("Hard disk image %i: Read error during seek\n", id);
|
||||
return;
|
||||
if (!hdd_images[id].file || (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1)) {
|
||||
hdd_image_log("Hard disk image %i: Read error during seek\n", id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
num_read = fread(buffer, 512, count, hdd_images[id].file);
|
||||
hdd_images[id].pos = sector + num_read;
|
||||
if (num_read < count)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -554,32 +570,40 @@ hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
transfer_sectors = sectors - sector;
|
||||
|
||||
hdd_image_read(id, sector, transfer_sectors, buffer);
|
||||
if (hdd_image_read(id, sector, transfer_sectors, buffer) < 0)
|
||||
return -1;
|
||||
|
||||
if (count != transfer_sectors)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
int non_transferred_sectors;
|
||||
size_t num_write;
|
||||
|
||||
if (hdd_images[id].type == HDD_IMAGE_VHD) {
|
||||
non_transferred_sectors = mvhd_write_sectors(hdd_images[id].vhd, sector, count, buffer);
|
||||
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
|
||||
hdd_images[id].vhd->error = 0;
|
||||
non_transferred_sectors = mvhd_write_sectors(hdd_images[id].vhd, sector, count, buffer);
|
||||
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
|
||||
if (hdd_images[id].vhd->error)
|
||||
return -1;
|
||||
} else {
|
||||
if (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) {
|
||||
fatal("Hard disk image %i: Write error during seek\n", id);
|
||||
return;
|
||||
if (!hdd_images[id].file || (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1)) {
|
||||
hdd_image_log("Hard disk image %i: Write error during seek\n", id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
num_write = fwrite(buffer, 512, count, hdd_images[id].file);
|
||||
fflush(hdd_images[id].file);
|
||||
hdd_images[id].pos = sector + num_write;
|
||||
fflush(hdd_images[id].file);
|
||||
if (num_write < count)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -591,25 +615,29 @@ hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
transfer_sectors = sectors - sector;
|
||||
|
||||
hdd_image_write(id, sector, transfer_sectors, buffer);
|
||||
if (hdd_image_write(id, sector, transfer_sectors, buffer) < 0)
|
||||
return -1;
|
||||
|
||||
if (count != transfer_sectors)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count)
|
||||
{
|
||||
if (hdd_images[id].type == HDD_IMAGE_VHD) {
|
||||
hdd_images[id].vhd->error = 0;
|
||||
int non_transferred_sectors = mvhd_format_sectors(hdd_images[id].vhd, sector, count);
|
||||
hdd_images[id].pos = sector + count - non_transferred_sectors - 1;
|
||||
if (hdd_images[id].vhd->error)
|
||||
return -1;
|
||||
} else {
|
||||
memset(empty_sector, 0, 512);
|
||||
|
||||
if (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) {
|
||||
fatal("Hard disk image %i: Zero error during seek\n", id);
|
||||
return;
|
||||
if (!hdd_images[id].file || (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1)) {
|
||||
hdd_image_log("Hard disk image %i: Zero error during seek\n", id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
@@ -617,11 +645,14 @@ hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count)
|
||||
break;
|
||||
|
||||
hdd_images[id].pos = sector + i;
|
||||
fwrite(empty_sector, 512, 1, hdd_images[id].file);
|
||||
if (!fwrite(empty_sector, 512, 1, hdd_images[id].file))
|
||||
return -1;
|
||||
}
|
||||
|
||||
fflush(hdd_images[id].file);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -115,6 +115,7 @@ typedef struct MVHDSparseHeader {
|
||||
struct MVHDMeta {
|
||||
FILE* f;
|
||||
bool readonly;
|
||||
bool error;
|
||||
char filename[MVHD_MAX_PATH_BYTES];
|
||||
struct MVHDMeta* parent;
|
||||
MVHDFooter footer;
|
||||
@@ -271,7 +272,7 @@ struct MVHDMeta* mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t
|
||||
* \param [in] f File to write sectors to
|
||||
* \param [in] sector_count The number of sectors to write
|
||||
*/
|
||||
void mvhd_write_empty_sectors(FILE* f, int sector_count);
|
||||
bool mvhd_write_empty_sectors(FILE* f, int sector_count);
|
||||
|
||||
/**
|
||||
* \brief Read a fixed VHD image
|
||||
|
||||
@@ -82,15 +82,18 @@ check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int *tra
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
mvhd_write_empty_sectors(FILE *f, int sector_count)
|
||||
{
|
||||
uint8_t zero_bytes[MVHD_SECTOR_SIZE] = {0};
|
||||
|
||||
for (int i = 0; i < sector_count; i++)
|
||||
fwrite(zero_bytes, sizeof zero_bytes, 1, f);
|
||||
for (int i = 0; i < sector_count; i++) {
|
||||
if (!fwrite(zero_bytes, sizeof zero_bytes, 1, f))
|
||||
return 0;
|
||||
}
|
||||
|
||||
fflush(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,7 +110,8 @@ read_sect_bitmap(MVHDMeta *vhdm, int blk)
|
||||
{
|
||||
if (vhdm->block_offset[blk] != MVHD_SPARSE_BLK) {
|
||||
mvhd_fseeko64(vhdm->f, (uint64_t)vhdm->block_offset[blk] * MVHD_SECTOR_SIZE, SEEK_SET);
|
||||
(void) !fread(vhdm->bitmap.curr_bitmap, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE, 1, vhdm->f);
|
||||
if (!fread(vhdm->bitmap.curr_bitmap, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE, 1, vhdm->f))
|
||||
vhdm->error = 1;
|
||||
} else
|
||||
memset(vhdm->bitmap.curr_bitmap, 0, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE);
|
||||
|
||||
@@ -124,8 +128,10 @@ write_curr_sect_bitmap(MVHDMeta* vhdm)
|
||||
{
|
||||
if (vhdm->bitmap.curr_block >= 0) {
|
||||
int64_t abs_offset = (int64_t)vhdm->block_offset[vhdm->bitmap.curr_block] * MVHD_SECTOR_SIZE;
|
||||
mvhd_fseeko64(vhdm->f, abs_offset, SEEK_SET);
|
||||
fwrite(vhdm->bitmap.curr_bitmap, MVHD_SECTOR_SIZE, vhdm->bitmap.sector_count, vhdm->f);
|
||||
if (mvhd_fseeko64(vhdm->f, abs_offset, SEEK_SET) == -1)
|
||||
vhdm->error = 1;
|
||||
if (!fwrite(vhdm->bitmap.curr_bitmap, MVHD_SECTOR_SIZE, vhdm->bitmap.sector_count, vhdm->f))
|
||||
vhdm->error = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,8 +147,10 @@ write_bat_entry(MVHDMeta *vhdm, int blk)
|
||||
uint64_t table_offset = vhdm->sparse.bat_offset + ((uint64_t)blk * sizeof *vhdm->block_offset);
|
||||
uint32_t offset = mvhd_to_be32(vhdm->block_offset[blk]);
|
||||
|
||||
mvhd_fseeko64(vhdm->f, table_offset, SEEK_SET);
|
||||
fwrite(&offset, sizeof offset, 1, vhdm->f);
|
||||
if (mvhd_fseeko64(vhdm->f, table_offset, SEEK_SET) == -1)
|
||||
vhdm->error = 1;
|
||||
if (!fwrite(&offset, sizeof offset, 1, vhdm->f))
|
||||
vhdm->error = 1;
|
||||
fflush(vhdm->f);
|
||||
}
|
||||
|
||||
@@ -173,7 +181,8 @@ create_block(MVHDMeta *vhdm, int blk)
|
||||
if (!mvhd_is_conectix_str(footer)) {
|
||||
/* Oh dear. We use the header instead, since something has gone wrong at the footer */
|
||||
mvhd_fseeko64(vhdm->f, 0, SEEK_SET);
|
||||
(void) !fread(footer, sizeof footer, 1, vhdm->f);
|
||||
if (!fread(footer, sizeof footer, 1, vhdm->f))
|
||||
vhdm->error = 1;
|
||||
mvhd_fseeko64(vhdm->f, 0, SEEK_END);
|
||||
}
|
||||
|
||||
@@ -182,20 +191,25 @@ create_block(MVHDMeta *vhdm, int blk)
|
||||
/* Yikes! We're supposed to be on a sector boundary. Add some padding */
|
||||
int64_t padding_amount = ((int64_t) MVHD_SECTOR_SIZE) - (abs_offset % MVHD_SECTOR_SIZE);
|
||||
uint8_t zero_byte = 0;
|
||||
for (int i = 0; i < padding_amount; i++)
|
||||
fwrite(&zero_byte, sizeof zero_byte, 1, vhdm->f);
|
||||
for (int i = 0; i < padding_amount; i++) {
|
||||
if (!fwrite(&zero_byte, sizeof zero_byte, 1, vhdm->f))
|
||||
vhdm->error = 1;
|
||||
}
|
||||
abs_offset += padding_amount;
|
||||
}
|
||||
|
||||
uint32_t sect_offset = (uint32_t)(abs_offset / MVHD_SECTOR_SIZE);
|
||||
int blk_size_sectors = vhdm->sparse.block_sz / MVHD_SECTOR_SIZE;
|
||||
mvhd_write_empty_sectors(vhdm->f, vhdm->bitmap.sector_count + blk_size_sectors);
|
||||
if (!mvhd_write_empty_sectors(vhdm->f, vhdm->bitmap.sector_count + blk_size_sectors))
|
||||
vhdm->error = 1;
|
||||
|
||||
/* Add a bit of padding. That's what Windows appears to do, although it's not strictly necessary... */
|
||||
mvhd_write_empty_sectors(vhdm->f, 5);
|
||||
if (!mvhd_write_empty_sectors(vhdm->f, 5))
|
||||
vhdm->error = 1;
|
||||
|
||||
/* And we finish with the footer */
|
||||
fwrite(footer, sizeof footer, 1, vhdm->f);
|
||||
if (!fwrite(footer, sizeof footer, 1, vhdm->f))
|
||||
vhdm->error = 1;
|
||||
|
||||
/* We no longer have a sparse block. Update that BAT! */
|
||||
vhdm->block_offset[blk] = sect_offset;
|
||||
@@ -214,8 +228,10 @@ mvhd_fixed_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff
|
||||
check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors);
|
||||
|
||||
addr = ((int64_t) offset) * MVHD_SECTOR_SIZE;
|
||||
mvhd_fseeko64(vhdm->f, addr, SEEK_SET);
|
||||
(void) !fread(out_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f);
|
||||
if (mvhd_fseeko64(vhdm->f, addr, SEEK_SET) == -1)
|
||||
vhdm->error = 1;
|
||||
if (!fread(out_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f))
|
||||
vhdm->error = 1;
|
||||
|
||||
return truncated_sectors;
|
||||
}
|
||||
@@ -245,17 +261,20 @@ mvhd_sparse_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buf
|
||||
prev_blk = blk;
|
||||
if (vhdm->bitmap.curr_block != blk) {
|
||||
read_sect_bitmap(vhdm, blk);
|
||||
mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR);
|
||||
if (mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR) == -1)
|
||||
vhdm->error = 1;
|
||||
} else {
|
||||
addr = (((int64_t) vhdm->block_offset[blk]) + vhdm->bitmap.sector_count + sib) *
|
||||
MVHD_SECTOR_SIZE;
|
||||
mvhd_fseeko64(vhdm->f, addr, SEEK_SET);
|
||||
if (mvhd_fseeko64(vhdm->f, addr, SEEK_SET) == -1)
|
||||
vhdm->error = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (VHD_TESTBIT(vhdm->bitmap.curr_bitmap, sib))
|
||||
(void) !fread(buff, MVHD_SECTOR_SIZE, 1, vhdm->f);
|
||||
else {
|
||||
if (VHD_TESTBIT(vhdm->bitmap.curr_bitmap, sib)) {
|
||||
if (!fread(buff, MVHD_SECTOR_SIZE, 1, vhdm->f))
|
||||
vhdm->error = 1;
|
||||
} else {
|
||||
memset(buff, 0, MVHD_SECTOR_SIZE);
|
||||
mvhd_fseeko64(vhdm->f, MVHD_SECTOR_SIZE, SEEK_CUR);
|
||||
}
|
||||
@@ -301,6 +320,10 @@ mvhd_diff_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff)
|
||||
mvhd_sparse_read(curr_vhdm, s, 1, buff);
|
||||
else
|
||||
mvhd_fixed_read(curr_vhdm, s, 1, buff);
|
||||
if (curr_vhdm->error) {
|
||||
curr_vhdm->error = 0;
|
||||
vhdm->error = 1;
|
||||
}
|
||||
|
||||
curr_vhdm = vhdm;
|
||||
buff += MVHD_SECTOR_SIZE;
|
||||
@@ -320,8 +343,10 @@ mvhd_fixed_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_buff
|
||||
check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors);
|
||||
|
||||
addr = (int64_t)offset * MVHD_SECTOR_SIZE;
|
||||
mvhd_fseeko64(vhdm->f, addr, SEEK_SET);
|
||||
fwrite(in_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f);
|
||||
if (mvhd_fseeko64(vhdm->f, addr, SEEK_SET) == -1)
|
||||
vhdm->error = 1;
|
||||
if (!fwrite(in_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f))
|
||||
vhdm->error = 1;
|
||||
fflush(vhdm->f);
|
||||
|
||||
return truncated_sectors;
|
||||
@@ -364,16 +389,19 @@ mvhd_sparse_diff_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *i
|
||||
if (blk != prev_blk) {
|
||||
if (vhdm->bitmap.curr_block != blk) {
|
||||
read_sect_bitmap(vhdm, blk);
|
||||
mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR);
|
||||
if (mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR) == -1)
|
||||
vhdm->error = 1;
|
||||
} else {
|
||||
addr = (((int64_t) vhdm->block_offset[blk]) + vhdm->bitmap.sector_count + sib) *
|
||||
MVHD_SECTOR_SIZE;
|
||||
mvhd_fseeko64(vhdm->f, addr, SEEK_SET);
|
||||
if (mvhd_fseeko64(vhdm->f, addr, SEEK_SET) == -1)
|
||||
vhdm->error = 1;
|
||||
}
|
||||
prev_blk = blk;
|
||||
}
|
||||
|
||||
fwrite(buff, MVHD_SECTOR_SIZE, 1, vhdm->f);
|
||||
if (!fwrite(buff, MVHD_SECTOR_SIZE, 1, vhdm->f))
|
||||
vhdm->error = 1;
|
||||
VHD_SETBIT(vhdm->bitmap.curr_bitmap, sib);
|
||||
buff += MVHD_SECTOR_SIZE;
|
||||
}
|
||||
|
||||
@@ -874,6 +874,24 @@ mo_write_protected(mo_t *dev)
|
||||
mo_cmd_error(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
mo_write_error(mo_t *dev)
|
||||
{
|
||||
mo_sense_key = SENSE_MEDIUM_ERROR;
|
||||
mo_asc = ASC_WRITE_ERROR;
|
||||
mo_ascq = 0;
|
||||
mo_cmd_error(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
mo_read_error(mo_t *dev)
|
||||
{
|
||||
mo_sense_key = SENSE_MEDIUM_ERROR;
|
||||
mo_asc = ASC_UNRECOVERED_READ_ERROR;
|
||||
mo_ascq = 0;
|
||||
mo_cmd_error(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
mo_invalid_lun(mo_t *dev)
|
||||
{
|
||||
@@ -928,7 +946,7 @@ mo_blocks(mo_t *dev, int32_t *len, UNUSED(int first_batch), int out)
|
||||
|
||||
if (!dev->sector_len) {
|
||||
mo_command_complete(dev);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mo_log("%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", dev->requested_blocks, dev->sector_pos);
|
||||
@@ -942,20 +960,31 @@ mo_blocks(mo_t *dev, int32_t *len, UNUSED(int first_batch), int out)
|
||||
*len = dev->requested_blocks * dev->drv->sector_size;
|
||||
|
||||
for (int i = 0; i < dev->requested_blocks; i++) {
|
||||
if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos * dev->drv->sector_size) + (i * dev->drv->sector_size), SEEK_SET) == 1)
|
||||
break;
|
||||
if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos * dev->drv->sector_size) + (i * dev->drv->sector_size), SEEK_SET) == -1) {
|
||||
if (out)
|
||||
mo_write_error(dev);
|
||||
else
|
||||
mo_read_error(dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (feof(dev->drv->fp))
|
||||
break;
|
||||
|
||||
if (out) {
|
||||
if (fwrite(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size)
|
||||
fatal("mo_blocks(): Error writing data\n");
|
||||
if (fwrite(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) {
|
||||
mo_log("mo_blocks(): Error writing data\n");
|
||||
mo_write_error(dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fflush(dev->drv->fp);
|
||||
} else {
|
||||
if (fread(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size)
|
||||
fatal("mo_blocks(): Error reading data\n");
|
||||
if (fread(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) {
|
||||
mo_log("mo_blocks(): Error reading data\n");
|
||||
mo_read_error(dev);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1433,7 +1462,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb)
|
||||
ret = mo_blocks(dev, &alloc_length, 1, 0);
|
||||
if (ret <= 0) {
|
||||
mo_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->packet_status = (ret < 0) ? PHASE_ERROR : PHASE_COMPLETE;
|
||||
dev->callback = 20.0 * MO_TIME;
|
||||
mo_set_callback(dev);
|
||||
mo_buf_free(dev);
|
||||
|
||||
@@ -1048,6 +1048,24 @@ zip_write_protected(zip_t *dev)
|
||||
zip_cmd_error(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
zip_write_error(zip_t *dev)
|
||||
{
|
||||
zip_sense_key = SENSE_MEDIUM_ERROR;
|
||||
zip_asc = ASC_WRITE_ERROR;
|
||||
zip_ascq = 0;
|
||||
zip_cmd_error(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
zip_read_error(zip_t *dev)
|
||||
{
|
||||
zip_sense_key = SENSE_MEDIUM_ERROR;
|
||||
zip_asc = ASC_UNRECOVERED_READ_ERROR;
|
||||
zip_ascq = 0;
|
||||
zip_cmd_error(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
zip_invalid_lun(zip_t *dev)
|
||||
{
|
||||
@@ -1111,7 +1129,7 @@ zip_blocks(zip_t *dev, int32_t *len, UNUSED(int first_batch), int out)
|
||||
|
||||
if (!dev->sector_len) {
|
||||
zip_command_complete(dev);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
zip_log("%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", dev->requested_blocks, dev->sector_pos);
|
||||
@@ -1125,20 +1143,31 @@ zip_blocks(zip_t *dev, int32_t *len, UNUSED(int first_batch), int out)
|
||||
*len = dev->requested_blocks << 9;
|
||||
|
||||
for (int i = 0; i < dev->requested_blocks; i++) {
|
||||
if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos << 9) + (i << 9), SEEK_SET) == 1)
|
||||
break;
|
||||
if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos << 9) + (i << 9), SEEK_SET) == -1) {
|
||||
if (out)
|
||||
zip_write_error(dev);
|
||||
else
|
||||
zip_read_error(dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (feof(dev->drv->fp))
|
||||
break;
|
||||
|
||||
if (out) {
|
||||
if (fwrite(dev->buffer + (i << 9), 1, 512, dev->drv->fp) != 512)
|
||||
fatal("zip_blocks(): Error writing data\n");
|
||||
if (fwrite(dev->buffer + (i << 9), 1, 512, dev->drv->fp) != 512) {
|
||||
zip_log("zip_blocks(): Error writing data\n");
|
||||
zip_write_error(dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fflush(dev->drv->fp);
|
||||
} else {
|
||||
if (fread(dev->buffer + (i << 9), 1, 512, dev->drv->fp) != 512)
|
||||
fatal("zip_blocks(): Error reading data\n");
|
||||
if (fread(dev->buffer + (i << 9), 1, 512, dev->drv->fp) != 512) {
|
||||
zip_log("zip_blocks(): Error reading data\n");
|
||||
zip_read_error(dev);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1551,7 +1580,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb)
|
||||
ret = zip_blocks(dev, &alloc_length, 1, 0);
|
||||
if (ret <= 0) {
|
||||
zip_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->packet_status = (ret < 0) ? PHASE_ERROR : PHASE_COMPLETE;
|
||||
dev->callback = 20.0 * ZIP_TIME;
|
||||
zip_set_callback(dev);
|
||||
zip_buf_free(dev);
|
||||
|
||||
@@ -197,12 +197,12 @@ extern int hdd_is_valid(int c);
|
||||
|
||||
extern void hdd_image_init(void);
|
||||
extern int hdd_image_load(int id);
|
||||
extern void hdd_image_seek(uint8_t id, uint32_t sector);
|
||||
extern void hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer);
|
||||
extern int hdd_image_seek(uint8_t id, uint32_t sector);
|
||||
extern int hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer);
|
||||
extern int hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer);
|
||||
extern void hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer);
|
||||
extern int hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer);
|
||||
extern int hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer);
|
||||
extern void hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count);
|
||||
extern int hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count);
|
||||
extern int hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count);
|
||||
extern uint32_t hdd_image_get_last_sector(uint8_t id);
|
||||
extern uint32_t hdd_image_get_pos(uint8_t id);
|
||||
|
||||
@@ -189,6 +189,7 @@
|
||||
/* SCSI Sense Keys */
|
||||
#define SENSE_NONE 0
|
||||
#define SENSE_NOT_READY 2
|
||||
#define SENSE_MEDIUM_ERROR 3
|
||||
#define SENSE_ILLEGAL_REQUEST 5
|
||||
#define SENSE_UNIT_ATTENTION 6
|
||||
|
||||
@@ -196,6 +197,8 @@
|
||||
#define ASC_NONE 0x00
|
||||
#define ASC_AUDIO_PLAY_OPERATION 0x00
|
||||
#define ASC_NOT_READY 0x04
|
||||
#define ASC_WRITE_ERROR 0x0c
|
||||
#define ASC_UNRECOVERED_READ_ERROR 0x11
|
||||
#define ASC_ILLEGAL_OPCODE 0x20
|
||||
#define ASC_LBA_OUT_OF_RANGE 0x21
|
||||
#define ASC_INV_FIELD_IN_CMD_PACKET 0x24
|
||||
@@ -212,6 +215,7 @@
|
||||
#define ASCQ_NONE 0x00
|
||||
#define ASCQ_UNIT_IN_PROCESS_OF_BECOMING_READY 0x01
|
||||
#define ASCQ_INITIALIZING_COMMAND_REQUIRED 0x02
|
||||
#define ASCQ_CIRC_UNRECOVERED_ERROR 0x06
|
||||
#define ASCQ_CAPACITY_DATA_CHANGED 0x09
|
||||
#define ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS 0x11
|
||||
#define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12
|
||||
|
||||
@@ -52,7 +52,7 @@ typedef struct ibm8514_t {
|
||||
int type;
|
||||
int local;
|
||||
int bpp;
|
||||
int on[2];
|
||||
int on;
|
||||
int accel_bpp;
|
||||
|
||||
uint32_t vram_size;
|
||||
@@ -102,6 +102,8 @@ typedef struct ibm8514_t {
|
||||
uint16_t frgd_mix;
|
||||
uint16_t multifunc_cntl;
|
||||
uint16_t multifunc[16];
|
||||
uint16_t clip_right;
|
||||
uint16_t clip_bottom;
|
||||
int16_t clip_left;
|
||||
int16_t clip_top;
|
||||
uint8_t pix_trans[2];
|
||||
@@ -112,8 +114,6 @@ typedef struct ibm8514_t {
|
||||
int x3;
|
||||
int y1;
|
||||
int y2;
|
||||
int sys_cnt;
|
||||
int sys_cnt2;
|
||||
int temp_cnt;
|
||||
int16_t cx;
|
||||
int16_t cx_back;
|
||||
@@ -127,20 +127,14 @@ typedef struct ibm8514_t {
|
||||
int16_t err;
|
||||
uint32_t src;
|
||||
uint32_t dest;
|
||||
uint32_t newsrc_blt;
|
||||
uint32_t newdest_blt;
|
||||
uint32_t newdest_in;
|
||||
uint32_t newdest_out;
|
||||
uint8_t *writemono;
|
||||
uint8_t *nibbleset;
|
||||
int x_count;
|
||||
int xx_count;
|
||||
int y_count;
|
||||
int input;
|
||||
int input2;
|
||||
int output;
|
||||
int output2;
|
||||
|
||||
uint16_t cur_x_bit12;
|
||||
uint16_t cur_y_bit12;
|
||||
int ssv_len;
|
||||
uint8_t ssv_dir;
|
||||
uint8_t ssv_draw;
|
||||
@@ -156,7 +150,6 @@ typedef struct ibm8514_t {
|
||||
} accel;
|
||||
|
||||
uint16_t test;
|
||||
int vendor_mode[2];
|
||||
int h_blankstart;
|
||||
int h_blank_end_val;
|
||||
int hblankstart;
|
||||
@@ -205,13 +198,16 @@ typedef struct ibm8514_t {
|
||||
int hsync_width;
|
||||
int htotal;
|
||||
int hdisp;
|
||||
int hdisp2;
|
||||
int hdisped;
|
||||
int sc;
|
||||
int vsyncstart;
|
||||
int vsyncwidth;
|
||||
int vtotal;
|
||||
int v_disp;
|
||||
int v_disp2;
|
||||
int vdisp;
|
||||
int vdisp2;
|
||||
int disp_cntl;
|
||||
int interlace;
|
||||
uint8_t subsys_cntl;
|
||||
@@ -227,6 +223,11 @@ typedef struct ibm8514_t {
|
||||
int ext_pitch;
|
||||
int ext_crt_pitch;
|
||||
int extensions;
|
||||
int linear;
|
||||
int _4bpp;
|
||||
uint32_t vram_amount;
|
||||
int vram_512k_8514;
|
||||
PALETTE _8514pal;
|
||||
|
||||
latch8514_t latch;
|
||||
} ibm8514_t;
|
||||
|
||||
25
src/include/86box/vid_8514a_device.h
Normal file
25
src/include/86box/vid_8514a_device.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Emulation of the 8514/A card from IBM for the MCA bus and
|
||||
* generic ISA bus clones without vendor extensions.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: TheCollector1995
|
||||
*
|
||||
* Copyright 2024 TheCollector1995.
|
||||
*/
|
||||
#ifndef VIDEO_8514A_DEVICE_H
|
||||
#define VIDEO_8514A_DEVICE_H
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t ibm8514_mca_device;
|
||||
extern const device_t gen8514_isa_device;
|
||||
#endif
|
||||
#endif /*VIDEO_XGA_DEVICE_H*/
|
||||
@@ -41,8 +41,6 @@ typedef struct mach_t {
|
||||
int ramdac_type;
|
||||
int old_mode;
|
||||
|
||||
uint32_t memory;
|
||||
|
||||
uint16_t config1;
|
||||
uint16_t config2;
|
||||
|
||||
@@ -73,9 +71,7 @@ typedef struct mach_t {
|
||||
uint8_t bank_r;
|
||||
uint16_t shadow_set;
|
||||
uint16_t shadow_cntl;
|
||||
int ext_on[2];
|
||||
int extended_mode;
|
||||
int compat_mode;
|
||||
int override_resolution;
|
||||
|
||||
struct {
|
||||
uint8_t line_idx;
|
||||
@@ -84,6 +80,12 @@ typedef struct mach_t {
|
||||
uint8_t patt_len;
|
||||
uint8_t pix_trans[2];
|
||||
uint8_t eeprom_control;
|
||||
uint8_t alu_bg_fn;
|
||||
uint8_t alu_fg_fn;
|
||||
uint16_t clip_left;
|
||||
uint16_t clip_right;
|
||||
uint16_t clip_top;
|
||||
uint16_t clip_bottom;
|
||||
uint16_t dest_x_end;
|
||||
uint16_t dest_x_start;
|
||||
uint16_t dest_y_end;
|
||||
@@ -102,14 +104,14 @@ typedef struct mach_t {
|
||||
uint16_t ge_offset_hi;
|
||||
uint16_t linedraw_opt;
|
||||
uint16_t max_waitstates;
|
||||
uint8_t patt_data_idx;
|
||||
uint8_t patt_data[0x18];
|
||||
uint16_t scan_to_x;
|
||||
uint16_t scratch0;
|
||||
uint16_t scratch1;
|
||||
uint16_t test;
|
||||
uint16_t pattern;
|
||||
uint16_t test2;
|
||||
int patt_data_idx_reg;
|
||||
int patt_data_idx;
|
||||
int src_y_dir;
|
||||
int cmd_type;
|
||||
int block_write_mono_pattern_enable;
|
||||
@@ -144,9 +146,8 @@ typedef struct mach_t {
|
||||
int stepx;
|
||||
int stepy;
|
||||
int src_stepx;
|
||||
uint8_t color_pattern[16];
|
||||
uint8_t color_pattern_full[32];
|
||||
uint16_t color_pattern_word[8];
|
||||
uint8_t mono_pattern_normal[16];
|
||||
uint8_t color_pattern[32];
|
||||
int mono_pattern[8][8];
|
||||
uint32_t ge_offset;
|
||||
uint32_t crt_offset;
|
||||
|
||||
@@ -369,6 +369,7 @@ uint32_t svga_mask_addr(uint32_t addr, svga_t *svga);
|
||||
uint32_t svga_mask_changedaddr(uint32_t addr, svga_t *svga);
|
||||
|
||||
void svga_doblit(int wx, int wy, svga_t *svga);
|
||||
void svga_poll(void *priv);
|
||||
|
||||
enum {
|
||||
RAMDAC_6BIT = 0,
|
||||
@@ -396,6 +397,9 @@ extern void att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv
|
||||
extern uint8_t att498_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga);
|
||||
extern float av9194_getclock(int clock, void *priv);
|
||||
|
||||
extern void bt481_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga);
|
||||
extern uint8_t bt481_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga);
|
||||
|
||||
extern void bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga);
|
||||
extern uint8_t bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga);
|
||||
extern void bt48x_recalctimings(void *priv, svga_t *svga);
|
||||
@@ -452,6 +456,7 @@ extern const device_t att491_ramdac_device;
|
||||
extern const device_t att492_ramdac_device;
|
||||
extern const device_t att498_ramdac_device;
|
||||
extern const device_t av9194_device;
|
||||
extern const device_t bt481_ramdac_device;
|
||||
extern const device_t bt484_ramdac_device;
|
||||
extern const device_t att20c504_ramdac_device;
|
||||
extern const device_t bt485_ramdac_device;
|
||||
|
||||
@@ -31,13 +31,11 @@ typedef struct xga_hwcursor_t {
|
||||
} xga_hwcursor_t;
|
||||
|
||||
typedef struct xga_t {
|
||||
mem_mapping_t membios_mapping;
|
||||
mem_mapping_t memio_mapping;
|
||||
mem_mapping_t linear_mapping;
|
||||
mem_mapping_t video_mapping;
|
||||
rom_t bios_rom;
|
||||
rom_t membios_rom;
|
||||
rom_t vga_bios_rom;
|
||||
rom_t bios_rom2;
|
||||
xga_hwcursor_t hwcursor;
|
||||
xga_hwcursor_t hwcursor_latch;
|
||||
PALETTE extpal;
|
||||
@@ -153,6 +151,7 @@ typedef struct xga_t {
|
||||
int a5_test;
|
||||
int type;
|
||||
int bus;
|
||||
int busy;
|
||||
|
||||
uint32_t linear_base;
|
||||
uint32_t linear_size;
|
||||
|
||||
@@ -207,7 +207,7 @@ plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector)
|
||||
plat_cdrom_close();
|
||||
dummy_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size);
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -13,7 +13,7 @@ msgid "&Keyboard requires capture"
|
||||
msgstr "&Teclado requer captura"
|
||||
|
||||
msgid "&Right CTRL is left ALT"
|
||||
msgstr "CTRL &direito é o ALT esquerdo"
|
||||
msgstr "&CTRL direito é o ALT esquerdo"
|
||||
|
||||
msgid "&Hard Reset..."
|
||||
msgstr "&Reinicialização completa..."
|
||||
@@ -79,7 +79,7 @@ msgid "Use target framerate:"
|
||||
msgstr "Usar taxa de quadros alvo:"
|
||||
|
||||
msgid "VSync"
|
||||
msgstr "VSync (sincronização virtual)"
|
||||
msgstr "VSync (sincronização vertical)"
|
||||
|
||||
msgid "Shaders"
|
||||
msgstr "Shaders"
|
||||
@@ -163,7 +163,7 @@ msgid "Apply fullscreen stretch mode when maximized"
|
||||
msgstr "Aplicar modo de ampliação em tela cheia quando maximizado"
|
||||
|
||||
msgid "E&GA/(S)VGA settings"
|
||||
msgstr "Configurações E&GA/(S)VGA"
|
||||
msgstr "Configurações de E&GA/(S)VGA"
|
||||
|
||||
msgid "&Inverted VGA monitor"
|
||||
msgstr "Monitor VGA &invertido"
|
||||
@@ -172,7 +172,7 @@ msgid "VGA screen &type"
|
||||
msgstr "&Tipo de tela VGA"
|
||||
|
||||
msgid "RGB &Color"
|
||||
msgstr "&Cores RGB"
|
||||
msgstr "&Cor RGB"
|
||||
|
||||
msgid "&RGB Grayscale"
|
||||
msgstr "Tons de cinza &RGB"
|
||||
@@ -337,7 +337,7 @@ msgid "Settings"
|
||||
msgstr "Configurações"
|
||||
|
||||
msgid "Specify Main Window Dimensions"
|
||||
msgstr "Especifique as dimensões da janela principal"
|
||||
msgstr "Especificar dimensões da janela principal"
|
||||
|
||||
msgid "OK"
|
||||
msgstr "OK"
|
||||
@@ -625,7 +625,7 @@ msgid "Cassette"
|
||||
msgstr "Cassete"
|
||||
|
||||
msgid "Vision Systems LBA Enhancer"
|
||||
msgstr "Aprimorador de Sistema Vision para LBA"
|
||||
msgstr "Vision Systems LBA Enhancer"
|
||||
|
||||
msgid "Hard disks:"
|
||||
msgstr "Discos rígidos:"
|
||||
@@ -981,6 +981,9 @@ msgstr "Não reiniciar"
|
||||
msgid "CD-ROM images"
|
||||
msgstr "Imagens de CD-ROM"
|
||||
|
||||
msgid "Host CD/DVD Drive (%1)"
|
||||
msgstr "Unidade de CD/DVD do anfitrião (%1)"
|
||||
|
||||
msgid "%1 Device Configuration"
|
||||
msgstr "Configuração do dispositivo %1"
|
||||
|
||||
@@ -1279,4 +1282,4 @@ msgid "WinBox is no longer supported"
|
||||
msgstr "O WinBox não é mais suportado"
|
||||
|
||||
msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use."
|
||||
msgstr "O desenvolvimento do gerenciador WinBox foi interrompido em 2022 devido à falta de mantenedores. À medida que direcionamos nossos esforços para tornar o 86Box ainda melhor, tomamos a decisão de não oferecer mais suporte ao WinBox como gerenciador.\n\nNão serão mais fornecidas atualizações através do WinBox, e você poderá encontrar comportamentos incorretos caso continue a usá-lo com versões mais recentes do 86Box. Quaisquer relatórios de bugs relacionados ao comportamento do WinBox serão fechados como inválidos.\n\nAcesse 86box.net para obter uma lista de outros gerenciadores que você pode usar."
|
||||
msgstr "O desenvolvimento do gerenciador WinBox foi interrompido em 2022 devido à falta de mantenedores. À medida que direcionamos nossos esforços para tornar o 86Box ainda melhor, tomamos a decisão de não oferecer mais suporte ao WinBox como gerenciador.\n\nNão serão mais fornecidas atualizações através do WinBox, e você poderá encontrar comportamentos incorretos caso continue a usá-lo com versões mais recentes do 86Box. Quaisquer relatórios de erros relacionados ao comportamento do WinBox serão fechados como inválidos.\n\nAcesse 86box.net para obter uma lista de outros gerenciadores que você pode usar."
|
||||
|
||||
@@ -24,6 +24,7 @@ extern "C" {
|
||||
#include <86box/device.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_8514a_device.h>
|
||||
#include <86box/vid_xga_device.h>
|
||||
}
|
||||
|
||||
@@ -53,6 +54,7 @@ SettingsDisplay::save()
|
||||
// TODO
|
||||
for (uint8_t i = 1; i < GFXCARD_MAX; i ++)
|
||||
gfxcard[i] = ui->comboBoxVideoSecondary->currentData().toInt();
|
||||
|
||||
voodoo_enabled = ui->checkBoxVoodoo->isChecked() ? 1 : 0;
|
||||
ibm8514_standalone_enabled = ui->checkBox8514->isChecked() ? 1 : 0;
|
||||
xga_standalone_enabled = ui->checkBoxXga->isChecked() ? 1 : 0;
|
||||
@@ -127,6 +129,16 @@ SettingsDisplay::on_pushButtonConfigureVoodoo_clicked()
|
||||
DeviceConfig::ConfigureDevice(&voodoo_device, 0, qobject_cast<Settings *>(Settings::settings));
|
||||
}
|
||||
|
||||
void
|
||||
SettingsDisplay::on_pushButtonConfigure8514_clicked()
|
||||
{
|
||||
if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) {
|
||||
DeviceConfig::ConfigureDevice(&ibm8514_mca_device, 0, qobject_cast<Settings *>(Settings::settings));
|
||||
} else {
|
||||
DeviceConfig::ConfigureDevice(&gen8514_isa_device, 0, qobject_cast<Settings *>(Settings::settings));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SettingsDisplay::on_pushButtonConfigureXga_clicked()
|
||||
{
|
||||
@@ -166,6 +178,8 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index)
|
||||
ui->checkBox8514->setEnabled(machineSupports8514);
|
||||
ui->checkBox8514->setChecked(ibm8514_standalone_enabled && machineSupports8514);
|
||||
|
||||
ui->pushButtonConfigure8514->setEnabled(ui->checkBox8514->isEnabled() && ui->checkBox8514->isChecked());
|
||||
|
||||
ui->checkBoxXga->setEnabled(machineSupportsXga);
|
||||
ui->checkBoxXga->setChecked(xga_standalone_enabled && machineSupportsXga);
|
||||
|
||||
@@ -238,6 +252,12 @@ SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state)
|
||||
ui->pushButtonConfigureVoodoo->setEnabled(state == Qt::Checked);
|
||||
}
|
||||
|
||||
void
|
||||
SettingsDisplay::on_checkBox8514_stateChanged(int state)
|
||||
{
|
||||
ui->pushButtonConfigure8514->setEnabled(state == Qt::Checked);
|
||||
}
|
||||
|
||||
void
|
||||
SettingsDisplay::on_checkBoxXga_stateChanged(int state)
|
||||
{
|
||||
|
||||
@@ -29,9 +29,11 @@ private slots:
|
||||
|
||||
private slots:
|
||||
void on_checkBoxVoodoo_stateChanged(int state);
|
||||
void on_checkBox8514_stateChanged(int state);
|
||||
void on_checkBoxXga_stateChanged(int state);
|
||||
void on_comboBoxVideo_currentIndexChanged(int index);
|
||||
void on_pushButtonConfigureVoodoo_clicked();
|
||||
void on_pushButtonConfigure8514_clicked();
|
||||
void on_pushButtonConfigureXga_clicked();
|
||||
void on_pushButtonConfigure_clicked();
|
||||
|
||||
|
||||
@@ -106,6 +106,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QPushButton" name="pushButtonConfigure8514">
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QPushButton" name="pushButtonConfigureXga">
|
||||
<property name="text">
|
||||
|
||||
@@ -342,7 +342,7 @@ plat_cdrom_get_sector_size(UNUSED(uint32_t sector))
|
||||
int
|
||||
plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector)
|
||||
{
|
||||
BOOL status;
|
||||
int status;
|
||||
long size = 0;
|
||||
int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
|
||||
|
||||
@@ -370,7 +370,7 @@ plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector)
|
||||
plat_cdrom_close();
|
||||
win_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size);
|
||||
|
||||
return (size == buflen) && (status > 0);
|
||||
return (status > 0) ? (size == buflen) : -1;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1244,6 +1244,15 @@ scsi_cdrom_not_ready(scsi_cdrom_t *dev)
|
||||
scsi_cdrom_cmd_error(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
scsi_cdrom_circ_error(scsi_cdrom_t *dev)
|
||||
{
|
||||
scsi_cdrom_sense_key = SENSE_MEDIUM_ERROR;
|
||||
scsi_cdrom_asc = ASC_UNRECOVERED_READ_ERROR;
|
||||
scsi_cdrom_ascq = ASCQ_CIRC_UNRECOVERED_ERROR;
|
||||
scsi_cdrom_cmd_error(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
scsi_cdrom_invalid_lun(scsi_cdrom_t *dev)
|
||||
{
|
||||
@@ -1367,6 +1376,9 @@ scsi_cdrom_read_data(scsi_cdrom_t *dev, int msf, int type, int flags, int32_t *l
|
||||
if (!ret) {
|
||||
scsi_cdrom_illegal_mode(dev);
|
||||
return 0;
|
||||
} else if (ret < 0) {
|
||||
scsi_cdrom_circ_error(dev);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1404,7 +1416,7 @@ scsi_cdrom_read_blocks(scsi_cdrom_t *dev, int32_t *len, int first_batch, int ven
|
||||
scsi_cdrom_log("Read %i bytes of blocks...\n", *len);
|
||||
|
||||
if (ret == -1)
|
||||
return 0;
|
||||
return ret;
|
||||
else if (!ret || (!first_batch && (dev->old_len != *len))) {
|
||||
if (!first_batch && (dev->old_len != *len))
|
||||
scsi_cdrom_illegal_mode(dev);
|
||||
@@ -2207,7 +2219,7 @@ begin:
|
||||
|
||||
if (ret <= 0) {
|
||||
scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->packet_status = (ret < 0) ? PHASE_ERROR : PHASE_COMPLETE;
|
||||
dev->callback = 20.0 * CDROM_TIME;
|
||||
scsi_cdrom_set_callback(dev);
|
||||
scsi_cdrom_buf_free(dev);
|
||||
|
||||
@@ -647,6 +647,24 @@ scsi_disk_bus_master_error(scsi_common_t *sc)
|
||||
scsi_disk_cmd_error(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
scsi_disk_write_error(scsi_disk_t *dev)
|
||||
{
|
||||
scsi_disk_sense_key = SENSE_MEDIUM_ERROR;
|
||||
scsi_disk_asc = ASC_WRITE_ERROR;
|
||||
scsi_disk_ascq = 0;
|
||||
scsi_disk_cmd_error(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
scsi_disk_read_error(scsi_disk_t *dev)
|
||||
{
|
||||
scsi_disk_sense_key = SENSE_MEDIUM_ERROR;
|
||||
scsi_disk_asc = ASC_UNRECOVERED_READ_ERROR;
|
||||
scsi_disk_ascq = 0;
|
||||
scsi_disk_cmd_error(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
scsi_disk_invalid_lun(scsi_disk_t *dev)
|
||||
{
|
||||
@@ -727,10 +745,17 @@ scsi_disk_blocks(scsi_disk_t *dev, int32_t *len, UNUSED(int first_batch), int ou
|
||||
*len = dev->requested_blocks << 9;
|
||||
|
||||
for (int i = 0; i < dev->requested_blocks; i++) {
|
||||
if (out)
|
||||
hdd_image_write(dev->id, dev->sector_pos + i, 1, dev->temp_buffer + (i << 9));
|
||||
else
|
||||
hdd_image_read(dev->id, dev->sector_pos + i, 1, dev->temp_buffer + (i << 9));
|
||||
if (out) {
|
||||
if (hdd_image_write(dev->id, dev->sector_pos + i, 1, dev->temp_buffer + (i << 9)) < 0) {
|
||||
scsi_disk_write_error(dev);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (hdd_image_read(dev->id, dev->sector_pos + i, 1, dev->temp_buffer + (i << 9)) < 0) {
|
||||
scsi_disk_read_error(dev);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scsi_disk_log("%s %i bytes of blocks...\n", out ? "Written" : "Read", *len);
|
||||
@@ -1040,7 +1065,7 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb)
|
||||
ret = scsi_disk_blocks(dev, &alloc_length, 1, 0);
|
||||
if (ret <= 0) {
|
||||
scsi_disk_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->packet_status = (ret < 0) ? PHASE_ERROR : PHASE_COMPLETE;
|
||||
dev->callback = 20.0 * SCSI_TIME;
|
||||
scsi_disk_set_callback(dev);
|
||||
scsi_disk_buf_free(dev);
|
||||
@@ -1501,7 +1526,8 @@ scsi_disk_phase_data_out(scsi_common_t *sc)
|
||||
dev->temp_buffer[6] = (s >> 8) & 0xff;
|
||||
dev->temp_buffer[7] = s & 0xff;
|
||||
}
|
||||
hdd_image_write(dev->id, i, 1, dev->temp_buffer);
|
||||
if (hdd_image_write(dev->id, i, 1, dev->temp_buffer) < 0)
|
||||
scsi_disk_write_error(dev);
|
||||
}
|
||||
break;
|
||||
case GPCMD_MODE_SELECT_6:
|
||||
|
||||
@@ -19,7 +19,7 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c
|
||||
vid_sigma.c vid_wy700.c vid_ega.c vid_ega_render.c vid_svga.c vid_8514a.c
|
||||
vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c
|
||||
vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.c vid_ati68875_ramdac.c
|
||||
vid_ati68860_ramdac.c vid_bt48x_ramdac.c vid_chips_69000.c
|
||||
vid_ati68860_ramdac.c vid_bt481_ramdac.c vid_bt48x_ramdac.c vid_chips_69000.c
|
||||
vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c
|
||||
vid_et3000.c vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c
|
||||
vid_et4000w32.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -74,16 +74,16 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga)
|
||||
|
||||
switch (addr) {
|
||||
case 0:
|
||||
svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2ec : 0x3c8, val, svga);
|
||||
svga_out((dev && dev->on) ? 0x2ec : 0x3c8, val, svga);
|
||||
break;
|
||||
case 1:
|
||||
svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2ed : 0x3c9, val, svga);
|
||||
svga_out((dev && dev->on) ? 0x2ed : 0x3c9, val, svga);
|
||||
break;
|
||||
case 2:
|
||||
svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2ea : 0x3c6, val, svga);
|
||||
svga_out((dev && dev->on) ? 0x2ea : 0x3c6, val, svga);
|
||||
break;
|
||||
case 3:
|
||||
svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2eb : 0x3c7, val, svga);
|
||||
svga_out((dev && dev->on) ? 0x2eb : 0x3c7, val, svga);
|
||||
break;
|
||||
default:
|
||||
ramdac->regs[addr & 0xf] = val;
|
||||
@@ -181,16 +181,16 @@ ati68860_ramdac_in(uint16_t addr, void *priv, svga_t *svga)
|
||||
|
||||
switch (addr) {
|
||||
case 0:
|
||||
temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2ec : 0x3c8, svga);
|
||||
temp = svga_in((dev && dev->on) ? 0x2ec : 0x3c8, svga);
|
||||
break;
|
||||
case 1:
|
||||
temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2ed : 0x3c9, svga);
|
||||
temp = svga_in((dev && dev->on) ? 0x2ed : 0x3c9, svga);
|
||||
break;
|
||||
case 2:
|
||||
temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2ea : 0x3c6, svga);
|
||||
temp = svga_in((dev && dev->on) ? 0x2ea : 0x3c6, svga);
|
||||
break;
|
||||
case 3:
|
||||
temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2eb : 0x3c7, svga);
|
||||
temp = svga_in((dev && dev->on) ? 0x2eb : 0x3c7, svga);
|
||||
break;
|
||||
case 4:
|
||||
case 8:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
160
src/video/vid_bt481_ramdac.c
Normal file
160
src/video/vid_bt481_ramdac.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Emulation of the Brooktree BT481 true colour RAMDAC
|
||||
* family.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: TheCollector1995.
|
||||
*
|
||||
* Copyright 2024 TheCollector1995.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
|
||||
typedef struct bt481_ramdac_t {
|
||||
int state;
|
||||
uint8_t cmd;
|
||||
} bt481_ramdac_t;
|
||||
|
||||
static void
|
||||
bt481_ramdac_command(uint8_t val, void *priv, svga_t *svga)
|
||||
{
|
||||
bt481_ramdac_t *ramdac = (bt481_ramdac_t *) priv;
|
||||
ramdac->cmd = val;
|
||||
pclog("RAMDAC CMD=%02x.\n", val);
|
||||
switch ((ramdac->cmd >> 4) & 0x0f) {
|
||||
default:
|
||||
case 0x00:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 0x08:
|
||||
case 0x0a:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 0x09:
|
||||
case 0x0c:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 0x0e:
|
||||
case 0x0f:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
|
||||
void
|
||||
bt481_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga)
|
||||
{
|
||||
bt481_ramdac_t *ramdac = (bt481_ramdac_t *) priv;
|
||||
uint8_t rs = (addr & 0x03) | ((!!rs2) << 2);
|
||||
|
||||
switch (rs) {
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x07:
|
||||
svga_out(addr, val, svga);
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x02:
|
||||
pclog("RAMDAC Write State=%x.\n", ramdac->state);
|
||||
switch (ramdac->state) {
|
||||
case 4:
|
||||
bt481_ramdac_command(val, ramdac, svga);
|
||||
break;
|
||||
default:
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x06:
|
||||
bt481_ramdac_command(val, ramdac, svga);
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
bt481_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga)
|
||||
{
|
||||
bt481_ramdac_t * ramdac = (bt481_ramdac_t *) priv;
|
||||
uint8_t temp = 0xff;
|
||||
uint8_t rs = (addr & 0x03) | ((!!rs2) << 2);
|
||||
|
||||
switch (rs) {
|
||||
case 0x02:
|
||||
case 0x06:
|
||||
switch (ramdac->state) {
|
||||
case 4:
|
||||
temp = ramdac->cmd;
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, svga);
|
||||
ramdac->state++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
temp = svga_in(addr, svga);
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
pclog("RAMDAC IN=%02x, ret=%02x.\n", rs, temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
static void *
|
||||
bt481_ramdac_init(const device_t *info)
|
||||
{
|
||||
bt481_ramdac_t *ramdac = (bt481_ramdac_t *) malloc(sizeof(bt481_ramdac_t));
|
||||
memset(ramdac, 0, sizeof(bt481_ramdac_t));
|
||||
|
||||
return ramdac;
|
||||
}
|
||||
|
||||
static void
|
||||
bt481_ramdac_close(void *priv)
|
||||
{
|
||||
bt481_ramdac_t *ramdac = (bt481_ramdac_t *) priv;
|
||||
|
||||
if (ramdac)
|
||||
free(ramdac);
|
||||
}
|
||||
|
||||
const device_t bt481_ramdac_device = {
|
||||
.name = "Brooktree Bt481 RAMDAC",
|
||||
.internal_name = "bt481_ramdac",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = bt481_ramdac_init,
|
||||
.close = bt481_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -303,7 +303,7 @@ paradise_remap(paradise_t *paradise)
|
||||
void
|
||||
paradise_recalctimings(svga_t *svga)
|
||||
{
|
||||
const paradise_t *paradise = (paradise_t *) svga->priv;
|
||||
paradise_t *paradise = (paradise_t *) svga->priv;
|
||||
|
||||
svga->lowres = !(svga->gdcreg[0x0e] & 0x01);
|
||||
|
||||
@@ -337,15 +337,11 @@ paradise_recalctimings(svga_t *svga)
|
||||
svga->hdisp >>= 1;
|
||||
if (svga->hdisp == 788)
|
||||
svga->hdisp += 12;
|
||||
if (svga->hdisp == 800)
|
||||
svga->ma_latch -= 3;
|
||||
} else if (svga->bpp == 15) {
|
||||
svga->render = svga_render_15bpp_highres;
|
||||
svga->hdisp >>= 1;
|
||||
if (svga->hdisp == 788)
|
||||
svga->hdisp += 12;
|
||||
if (svga->hdisp == 800)
|
||||
svga->ma_latch -= 3;
|
||||
} else
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
|
||||
@@ -366,6 +362,11 @@ paradise_write(uint32_t addr, uint8_t val, void *priv)
|
||||
uint32_t prev_addr;
|
||||
uint32_t prev_addr2;
|
||||
|
||||
if (!(svga->attrregs[0x10] & 0x40)) {
|
||||
svga_write(addr, val, svga);
|
||||
return;
|
||||
}
|
||||
|
||||
addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3];
|
||||
|
||||
/*Could be done in a better way but it works.*/
|
||||
@@ -399,6 +400,11 @@ paradise_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
uint32_t prev_addr;
|
||||
uint32_t prev_addr2;
|
||||
|
||||
if (!(svga->attrregs[0x10] & 0x40)) {
|
||||
svga_writew(addr, val, svga);
|
||||
return;
|
||||
}
|
||||
|
||||
addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3];
|
||||
|
||||
/*Could be done in a better way but it works.*/
|
||||
@@ -432,6 +438,9 @@ paradise_read(uint32_t addr, void *priv)
|
||||
uint32_t prev_addr;
|
||||
uint32_t prev_addr2;
|
||||
|
||||
if (!(svga->attrregs[0x10] & 0x40))
|
||||
return svga_read(addr, svga);
|
||||
|
||||
addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3];
|
||||
|
||||
/*Could be done in a better way but it works.*/
|
||||
@@ -465,6 +474,9 @@ paradise_readw(uint32_t addr, void *priv)
|
||||
uint32_t prev_addr;
|
||||
uint32_t prev_addr2;
|
||||
|
||||
if (!(svga->attrregs[0x10] & 0x40))
|
||||
return svga_readw(addr, svga);
|
||||
|
||||
addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3];
|
||||
|
||||
/*Could be done in a better way but it works.*/
|
||||
|
||||
1476
src/video/vid_s3.c
1476
src/video/vid_s3.c
File diff suppressed because it is too large
Load Diff
@@ -149,13 +149,13 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
|
||||
case 2:
|
||||
index = dev->dac_addr & 0xff;
|
||||
dev->dac_b = val;
|
||||
svga->vgapal[index].r = dev->dac_r;
|
||||
svga->vgapal[index].g = dev->dac_g;
|
||||
svga->vgapal[index].b = dev->dac_b;
|
||||
dev->_8514pal[index].r = dev->dac_r;
|
||||
dev->_8514pal[index].g = dev->dac_g;
|
||||
dev->_8514pal[index].b = dev->dac_b;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
dev->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b);
|
||||
dev->pallook[index] = makecol32(dev->_8514pal[index].r, dev->_8514pal[index].g, dev->_8514pal[index].b);
|
||||
else
|
||||
dev->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], video_6to8[svga->vgapal[index].g & 0x3f], video_6to8[svga->vgapal[index].b & 0x3f]);
|
||||
dev->pallook[index] = makecol32(video_6to8[dev->_8514pal[index].r & 0x3f], video_6to8[dev->_8514pal[index].g & 0x3f], video_6to8[dev->_8514pal[index].b & 0x3f]);
|
||||
dev->dac_pos = 0;
|
||||
dev->dac_addr = (dev->dac_addr + 1) & 0xff;
|
||||
break;
|
||||
@@ -221,11 +221,8 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x3c3:
|
||||
if (xga_active && xga)
|
||||
xga->on = (val & 0x01) ? 0 : 1;
|
||||
if (ibm8514_active && dev) {
|
||||
dev->on[0] = (val & 0x01) ? 0 : 1;
|
||||
if (dev->local & 0xff)
|
||||
dev->on[1] = dev->on[0];
|
||||
}
|
||||
if (ibm8514_active && dev)
|
||||
dev->on = (val & 0x01) ? 0 : 1;
|
||||
|
||||
svga_log("3C3: VGA ON = %d.\n", val & 0x01);
|
||||
vga_on = val & 0x01;
|
||||
@@ -399,24 +396,24 @@ svga_in(uint16_t addr, void *priv)
|
||||
case 0:
|
||||
dev->dac_pos++;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
ret = svga->vgapal[index].r;
|
||||
ret = dev->_8514pal[index].r;
|
||||
else
|
||||
ret = svga->vgapal[index].r & 0x3f;
|
||||
ret = dev->_8514pal[index].r & 0x3f;
|
||||
break;
|
||||
case 1:
|
||||
dev->dac_pos++;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
ret = svga->vgapal[index].g;
|
||||
ret = dev->_8514pal[index].g;
|
||||
else
|
||||
ret = svga->vgapal[index].g & 0x3f;
|
||||
ret = dev->_8514pal[index].g & 0x3f;
|
||||
break;
|
||||
case 2:
|
||||
dev->dac_pos = 0;
|
||||
dev->dac_addr = (dev->dac_addr + 1) & 0xff;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
ret = svga->vgapal[index].b;
|
||||
ret = dev->_8514pal[index].b;
|
||||
else
|
||||
ret = svga->vgapal[index].b & 0x3f;
|
||||
ret = dev->_8514pal[index].b & 0x3f;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -551,11 +548,11 @@ svga_set_ramdac_type(svga_t *svga, int type)
|
||||
for (int c = 0; c < 256; c++) {
|
||||
if (ibm8514_active && dev) {
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
dev->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b);
|
||||
dev->pallook[c] = makecol32(dev->_8514pal[c].r, dev->_8514pal[c].g, dev->_8514pal[c].b);
|
||||
else
|
||||
dev->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4,
|
||||
(svga->vgapal[c].g & 0x3f) * 4,
|
||||
(svga->vgapal[c].b & 0x3f) * 4);
|
||||
dev->pallook[c] = makecol32((dev->_8514pal[c].r & 0x3f) * 4,
|
||||
(dev->_8514pal[c].g & 0x3f) * 4,
|
||||
(dev->_8514pal[c].b & 0x3f) * 4);
|
||||
}
|
||||
if (xga_active && xga) {
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
@@ -829,7 +826,7 @@ svga_recalctimings(svga_t *svga)
|
||||
|
||||
#ifdef TBD
|
||||
if (ibm8514_active && (svga->dev8514 != NULL)) {
|
||||
if (dev->on[0] || dev->on[1]) {
|
||||
if (dev->on) {
|
||||
uint32_t dot8514 = dev->h_blankstart;
|
||||
uint32_t adj_dot8514 = dev->h_blankstart;
|
||||
uint32_t eff_mask8514 = 0x0000003f;
|
||||
@@ -867,7 +864,7 @@ svga_recalctimings(svga_t *svga)
|
||||
|
||||
crtcconst = svga->clock * svga->char_width;
|
||||
if (ibm8514_active && (svga->dev8514 != NULL)) {
|
||||
if (dev->on[0] || dev->on[1])
|
||||
if (dev->on)
|
||||
crtcconst8514 = svga->clock8514;
|
||||
}
|
||||
|
||||
@@ -912,7 +909,7 @@ svga_recalctimings(svga_t *svga)
|
||||
_dispontime = svga->hdisp_time;
|
||||
|
||||
if (ibm8514_active && (svga->dev8514 != NULL)) {
|
||||
if (dev->on[0] || dev->on[1]) {
|
||||
if (dev->on) {
|
||||
disptime8514 = dev->h_total ? dev->h_total : TIMER_USEC;
|
||||
_dispontime8514 = dev->hdisped;
|
||||
}
|
||||
@@ -935,7 +932,7 @@ svga_recalctimings(svga_t *svga)
|
||||
svga->dispofftime = TIMER_USEC;
|
||||
|
||||
if (ibm8514_active && (svga->dev8514 != NULL)) {
|
||||
if (dev->on[0] || dev->on[1]) {
|
||||
if (dev->on) {
|
||||
_dispofftime8514 = disptime8514 - _dispontime8514;
|
||||
_dispontime8514 *= crtcconst8514;
|
||||
_dispofftime8514 *= crtcconst8514;
|
||||
@@ -1464,9 +1461,10 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv)
|
||||
if (!linear) {
|
||||
xga_write_test(addr, val, svga);
|
||||
addr = svga_decode_addr(svga, addr, 1);
|
||||
|
||||
if (addr == 0xffffffff)
|
||||
if (addr == 0xffffffff) {
|
||||
svga_log("WriteCommon Over.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(svga->gdcreg[6] & 1))
|
||||
@@ -1498,8 +1496,10 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv)
|
||||
if (svga->translate_address)
|
||||
addr = svga->translate_address(addr, priv);
|
||||
|
||||
if (addr >= svga->vram_max)
|
||||
if (addr >= svga->vram_max) {
|
||||
svga_log("WriteBankedOver=%08x, val=%02x.\n", addr & svga->vram_mask, val);
|
||||
return;
|
||||
}
|
||||
|
||||
addr &= svga->vram_mask;
|
||||
|
||||
@@ -1651,7 +1651,6 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv)
|
||||
if (!linear) {
|
||||
(void) xga_read_test(addr, svga);
|
||||
addr = svga_decode_addr(svga, addr, 0);
|
||||
|
||||
if (addr == 0xffffffff)
|
||||
return 0xff;
|
||||
}
|
||||
@@ -1873,6 +1872,8 @@ svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, void *priv)
|
||||
cycles -= svga->monitor->mon_video_timing_write_w;
|
||||
|
||||
if (!linear) {
|
||||
xga_write_test(addr, val & 0xff, svga);
|
||||
xga_write_test(addr + 1, val >> 8, svga);
|
||||
addr = svga_decode_addr(svga, addr, 1);
|
||||
|
||||
if (addr == 0xffffffff)
|
||||
@@ -1929,6 +1930,10 @@ svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *priv)
|
||||
cycles -= svga->monitor->mon_video_timing_write_l;
|
||||
|
||||
if (!linear) {
|
||||
xga_write_test(addr, val & 0xff, svga);
|
||||
xga_write_test(addr + 1, (val >> 8) & 0xff, svga);
|
||||
xga_write_test(addr + 2, (val >> 16) & 0xff, svga);
|
||||
xga_write_test(addr + 3, (val >> 24) & 0xff, svga);
|
||||
addr = svga_decode_addr(svga, addr, 1);
|
||||
|
||||
if (addr == 0xffffffff)
|
||||
@@ -1961,6 +1966,7 @@ svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *priv)
|
||||
}
|
||||
if (addr >= svga->vram_max)
|
||||
return;
|
||||
|
||||
addr &= svga->vram_mask;
|
||||
|
||||
svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount;
|
||||
@@ -2006,7 +2012,6 @@ svga_readw_common(uint32_t addr, uint8_t linear, void *priv)
|
||||
|
||||
if (!linear) {
|
||||
addr = svga_decode_addr(svga, addr, 0);
|
||||
|
||||
if (addr == 0xffffffff)
|
||||
return 0xffff;
|
||||
}
|
||||
@@ -2053,7 +2058,6 @@ svga_readl_common(uint32_t addr, uint8_t linear, void *priv)
|
||||
|
||||
if (!linear) {
|
||||
addr = svga_decode_addr(svga, addr, 0);
|
||||
|
||||
if (addr == 0xffffffff)
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
@@ -54,6 +54,13 @@ static void xga_render_4bpp(svga_t *svga);
|
||||
static void xga_render_8bpp(svga_t *svga);
|
||||
static void xga_render_16bpp(svga_t *svga);
|
||||
|
||||
static void xga_write(uint32_t addr, uint8_t val, void *priv);
|
||||
static void xga_writew(uint32_t addr, uint16_t val, void *priv);
|
||||
static void xga_writel(uint32_t addr, uint32_t val, void *priv);
|
||||
static uint8_t xga_read(uint32_t addr, void *priv);
|
||||
static uint16_t xga_readw(uint32_t addr, void *priv);
|
||||
static uint32_t xga_readl(uint32_t addr, void *priv);
|
||||
|
||||
int xga_active = 0;
|
||||
|
||||
#ifdef ENABLE_XGA_LOG
|
||||
@@ -184,7 +191,7 @@ xga_updatemapping(svga_t *svga)
|
||||
xga_log("XGA: Extended Graphics mode.\n");
|
||||
switch (xga->aperture_cntl) {
|
||||
case 0:
|
||||
xga_log("XGA: No 64KB aperture: 1MB=%x, 4MB=%x.\n", xga->base_addr_1mb, xga->linear_base);
|
||||
xga_log("XGA: No 64KB aperture: 1MB=%x, 4MB=%x, SVGA Mapping Base=%x.\n", xga->base_addr_1mb, xga->linear_base, svga->mapping.base);
|
||||
if (xga->base_addr_1mb) {
|
||||
mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000);
|
||||
mem_mapping_enable(&xga->linear_mapping);
|
||||
@@ -194,18 +201,39 @@ xga_updatemapping(svga_t *svga)
|
||||
} else
|
||||
mem_mapping_disable(&xga->linear_mapping);
|
||||
|
||||
mem_mapping_disable(&xga->video_mapping);
|
||||
mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
switch (svga->gdcreg[6] & 0xc) {
|
||||
case 0x0: /*128k at A0000*/
|
||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
|
||||
svga->banked_mask = 0xffff;
|
||||
break;
|
||||
case 0x4: /*64k at A0000*/
|
||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||
svga->banked_mask = 0xffff;
|
||||
break;
|
||||
case 0x8: /*32k at B0000*/
|
||||
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
|
||||
svga->banked_mask = 0x7fff;
|
||||
break;
|
||||
case 0xC: /*32k at B8000*/
|
||||
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
|
||||
svga->banked_mask = 0x7fff;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
xga_log("XGA: 64KB aperture at A0000.\n");
|
||||
mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000);
|
||||
mem_mapping_enable(&xga->video_mapping);
|
||||
mem_mapping_set_handler(&svga->mapping, xga_read, xga_readw, xga_readl, xga_write, xga_writew, xga_writel);
|
||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||
xga->banked_mask = 0xffff;
|
||||
break;
|
||||
case 2:
|
||||
xga_log("XGA: 64KB aperture at B0000.\n");
|
||||
mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000);
|
||||
mem_mapping_enable(&xga->video_mapping);
|
||||
mem_mapping_set_handler(&svga->mapping, xga_read, xga_readw, xga_readl, xga_write, xga_writew, xga_writel);
|
||||
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x10000);
|
||||
xga->banked_mask = 0xffff;
|
||||
break;
|
||||
default:
|
||||
@@ -244,7 +272,7 @@ xga_recalctimings(svga_t *svga)
|
||||
|
||||
xga->ma_latch = xga->disp_start_addr;
|
||||
|
||||
xga_log("XGA ClkSel1 = %d, ClkSel2 = %02x.\n", (xga->clk_sel_1 >> 2) & 3, xga->clk_sel_2 & 0x80);
|
||||
xga_log("XGA ClkSel1 = %d, ClkSel2 = %02x, dispcntl2=%02x.\n", (xga->clk_sel_1 >> 2) & 3, xga->clk_sel_2 & 0x80, xga->disp_cntl_2 & 0xc0);
|
||||
switch ((xga->clk_sel_1 >> 2) & 3) {
|
||||
case 0:
|
||||
xga_log("HDISP VGA0 = %d, XGA = %d.\n", svga->hdisp, xga->h_disp);
|
||||
@@ -798,19 +826,10 @@ xga_ext_inb(uint16_t addr, void *priv)
|
||||
#define READW(addr, dat) \
|
||||
dat = *(uint16_t *) &xga->vram[(addr) & (xga->vram_mask)];
|
||||
|
||||
#define READW_INV(addr, dat) \
|
||||
dat = xga->vram[(addr + 1) & (xga->vram_mask)]; \
|
||||
dat |= (xga->vram[(addr) & (xga->vram_mask)] << 8);
|
||||
|
||||
#define WRITEW(addr, dat) \
|
||||
*(uint16_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \
|
||||
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
|
||||
|
||||
#define WRITEW_INV(addr, dat) \
|
||||
xga->vram[((addr + 1)) & (xga->vram_mask)] = dat & 0xff; \
|
||||
xga->vram[((addr)) & (xga->vram_mask)] = dat >> 8; \
|
||||
xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount;
|
||||
|
||||
#define ROP(mix, d, s) \
|
||||
{ \
|
||||
switch ((mix) ? (xga->accel.frgd_mix & 0x1f) : (xga->accel.bkgd_mix & 0x1f)) { \
|
||||
@@ -884,7 +903,7 @@ xga_ext_inb(uint16_t addr, void *priv)
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width)
|
||||
xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, uint32_t base, int width)
|
||||
{
|
||||
const xga_t *xga = (xga_t *) svga->xga;
|
||||
uint32_t addr = base;
|
||||
@@ -903,27 +922,20 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b
|
||||
} else
|
||||
byte = mem_readb_phys(addr);
|
||||
|
||||
if (xga->linear_endian_reverse)
|
||||
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);
|
||||
}
|
||||
bits = 7 - (x & 7);
|
||||
|
||||
xga_log("0. AccessMode=%02x, SRCMAP=%02x, DSTMAP=%02x, PAT=%02x.\n", xga->access_mode & 0x0f, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), (xga->accel.px_map_format[xga->accel.pat_src] & 0x08));
|
||||
if (!(xga->accel.px_map_format[xga->accel.src_map] & 0x08) && !(xga->accel.px_map_format[xga->accel.dst_map] & 0x08)) {
|
||||
if (((xga->accel.px_map_format[xga->accel.src_map] & 0x07) >= 0x02) && ((xga->accel.px_map_format[xga->accel.dst_map] & 0x07) >= 0x02) && (xga->accel.pat_src <= 2))
|
||||
bits ^= 7;
|
||||
}
|
||||
|
||||
px = (byte >> bits) & 1;
|
||||
return px;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width, UNUSED(int usesrc))
|
||||
xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width)
|
||||
{
|
||||
xga_t *xga = (xga_t *) svga->xga;
|
||||
uint32_t addr = base;
|
||||
@@ -935,7 +947,7 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
|
||||
if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff)))
|
||||
skip = 1;
|
||||
|
||||
switch (xga->accel.px_map_format[map] & 7) {
|
||||
switch (xga->accel.px_map_format[map] & 0x07) {
|
||||
case 0: /*1-bit*/
|
||||
addr += (y * (width >> 3));
|
||||
addr += (x >> 3);
|
||||
@@ -944,14 +956,12 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
|
||||
} else
|
||||
byte = mem_readb_phys(addr);
|
||||
|
||||
if (xga->linear_endian_reverse)
|
||||
xga_log("1. AccessMode=%02x, SRCMAP=%02x, DSTMAP=%02x, PAT=%02x.\n", xga->access_mode & 0x0f, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->accel.pat_src);
|
||||
if ((xga->accel.px_map_format[xga->accel.src_map] & 0x08) && !(xga->access_mode & 0x08))
|
||||
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;
|
||||
return px;
|
||||
case 2: /*4-bit*/
|
||||
@@ -975,17 +985,19 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
|
||||
case 4: /*16-bit*/
|
||||
addr += (y * (width << 1));
|
||||
addr += (x << 1);
|
||||
if (xga->linear_endian_reverse) {
|
||||
byte = mem_readw_phys(addr);
|
||||
if ((xga->access_mode & 7) == 4)
|
||||
byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8);
|
||||
else if (xga->access_mode & 8)
|
||||
byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8);
|
||||
} else {
|
||||
if (xga->access_mode & 0x08) {
|
||||
if (!skip) {
|
||||
READW(addr, byte);
|
||||
} else
|
||||
byte = mem_readb_phys(addr) | (mem_readb_phys(addr + 1) << 8);
|
||||
byte = mem_readw_phys(addr);
|
||||
} else {
|
||||
if (!skip) {
|
||||
READW(addr, byte);
|
||||
} else {
|
||||
byte = mem_readw_phys(addr);
|
||||
if ((xga->access_mode & 0x07) == 0x04)
|
||||
byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8);
|
||||
}
|
||||
}
|
||||
return byte;
|
||||
|
||||
@@ -1007,7 +1019,7 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
|
||||
if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff)))
|
||||
skip = 1;
|
||||
|
||||
switch (xga->accel.px_map_format[map] & 7) {
|
||||
switch (xga->accel.px_map_format[map] & 0x07) {
|
||||
case 0: /*1-bit*/
|
||||
addr += (y * (width >> 3));
|
||||
addr += (x >> 3);
|
||||
@@ -1016,15 +1028,16 @@ 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->access_mode & 0x08)
|
||||
mask = 1 << (7 - (x & 7));
|
||||
} else {
|
||||
if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) {
|
||||
else {
|
||||
if ((xga->accel.px_map_format[map] & 0x08) || (xga->accel.px_map_format[xga->accel.src_map] & 0x08)) {
|
||||
xga_log("2. AccessMode=%02x, SRCMAP=%02x, DSTMAP=%02x, PAT=%02x.\n", xga->access_mode & 0x0f, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[map] & 0x0f), xga->accel.pat_src);
|
||||
mask = 1 << (x & 7);
|
||||
} else {
|
||||
} else
|
||||
mask = 1 << (7 - (x & 7));
|
||||
}
|
||||
}
|
||||
|
||||
byte = (byte & ~mask) | ((pixel ? 0xff : 0) & mask);
|
||||
if (pixel & 1) {
|
||||
if (!skip) {
|
||||
@@ -1044,18 +1057,14 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
|
||||
addr += (x >> 1);
|
||||
if (!skip) {
|
||||
READ(addr, byte);
|
||||
} else {
|
||||
} else
|
||||
byte = mem_readb_phys(addr);
|
||||
}
|
||||
|
||||
if (xga->linear_endian_reverse)
|
||||
if (xga->accel.px_map_format[map] & 0x08)
|
||||
mask = 0x0f << ((x & 1) << 2);
|
||||
else
|
||||
mask = 0x0f << ((1 - (x & 1)) << 2);
|
||||
else {
|
||||
if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8))
|
||||
mask = 0x0f << ((x & 1) << 2);
|
||||
else
|
||||
mask = 0x0f << ((1 - (x & 1)) << 2);
|
||||
}
|
||||
|
||||
byte = (byte & ~mask) | (pixel & mask);
|
||||
if (!skip) {
|
||||
WRITE(addr, byte);
|
||||
@@ -1073,14 +1082,16 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
|
||||
case 4: /*16-bit*/
|
||||
addr += (y * width << 1);
|
||||
addr += (x << 1);
|
||||
if (xga->linear_endian_reverse) {
|
||||
if ((xga->access_mode & 7) == 4)
|
||||
pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8);
|
||||
else if (xga->access_mode & 8)
|
||||
pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8);
|
||||
if (xga->access_mode & 0x08) {
|
||||
if (!skip) {
|
||||
WRITEW(addr, pixel);
|
||||
}
|
||||
} else {
|
||||
if (!skip) {
|
||||
WRITEW(addr, pixel);
|
||||
} else {
|
||||
if ((xga->access_mode & 0x07) == 0x04)
|
||||
pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8);
|
||||
}
|
||||
}
|
||||
mem_writew_phys(addr, pixel);
|
||||
@@ -1109,11 +1120,11 @@ xga_short_stroke(svga_t *svga, uint8_t ssv)
|
||||
int dirx = 0;
|
||||
int diry = 0;
|
||||
|
||||
dx = xga->accel.dst_map_x & 0x1fff;
|
||||
dx = xga->accel.dst_map_x;
|
||||
if (xga->accel.dst_map_x >= 0x1800)
|
||||
dx |= ~0x17ff;
|
||||
|
||||
dy = xga->accel.dst_map_y & 0x1fff;
|
||||
dy = xga->accel.dst_map_y;
|
||||
if (xga->accel.dst_map_y >= 0x1800)
|
||||
dy |= ~0x17ff;
|
||||
|
||||
@@ -1159,8 +1170,8 @@ xga_short_stroke(svga_t *svga, uint8_t ssv)
|
||||
while (y >= 0) {
|
||||
if (xga->accel.command & 0xc0) {
|
||||
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.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0);
|
||||
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color;
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1);
|
||||
|
||||
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;
|
||||
@@ -1179,8 +1190,8 @@ xga_short_stroke(svga_t *svga, uint8_t ssv)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0);
|
||||
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color;
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1);
|
||||
|
||||
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;
|
||||
@@ -1237,11 +1248,11 @@ xga_line_draw_write(svga_t *svga)
|
||||
cx = xga->accel.src_map_x & 0xfff;
|
||||
cy = xga->accel.src_map_y & 0xfff;
|
||||
|
||||
dx = xga->accel.dst_map_x & 0x1fff;
|
||||
dx = xga->accel.dst_map_x;
|
||||
if (xga->accel.dst_map_x >= 0x1800)
|
||||
dx |= ~0x17ff;
|
||||
|
||||
dy = xga->accel.dst_map_y & 0x1fff;
|
||||
dy = xga->accel.dst_map_y;
|
||||
if (xga->accel.dst_map_y >= 0x1800)
|
||||
dy |= ~0x17ff;
|
||||
|
||||
@@ -1270,8 +1281,8 @@ xga_line_draw_write(svga_t *svga)
|
||||
if (xga->accel.command & 0xc0) {
|
||||
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 (draw_pixel) {
|
||||
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0);
|
||||
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color;
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1);
|
||||
|
||||
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))) {
|
||||
ROP(1, dest_dat, src_dat);
|
||||
@@ -1281,8 +1292,8 @@ xga_line_draw_write(svga_t *svga)
|
||||
}
|
||||
} else {
|
||||
if (draw_pixel) {
|
||||
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0);
|
||||
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color;
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1);
|
||||
|
||||
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))) {
|
||||
ROP(1, dest_dat, src_dat);
|
||||
@@ -1330,8 +1341,8 @@ xga_line_draw_write(svga_t *svga)
|
||||
while (y >= 0) {
|
||||
if (xga->accel.command & 0xc0) {
|
||||
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.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0);
|
||||
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color;
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1);
|
||||
|
||||
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;
|
||||
@@ -1346,8 +1357,8 @@ xga_line_draw_write(svga_t *svga)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color;
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0);
|
||||
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color;
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1);
|
||||
|
||||
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;
|
||||
@@ -1437,12 +1448,12 @@ 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;
|
||||
dx = xga->accel.dst_map_x & 0x1fff;
|
||||
dy = xga->accel.dst_map_y & 0x1fff;
|
||||
dx = xga->accel.dst_map_x;
|
||||
dy = xga->accel.dst_map_y;
|
||||
if (xga->accel.dst_map_x >= 0x1800)
|
||||
dx |= ~0x17ff;
|
||||
if (xga->accel.dst_map_y >= 0x1800)
|
||||
dy -= 0x1800;
|
||||
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);
|
||||
|
||||
@@ -1465,7 +1476,7 @@ xga_bitblt(svga_t *svga)
|
||||
else {
|
||||
if ((dstwidth == (xga->h_disp - 1)) && (srcwidth == 1)) {
|
||||
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))
|
||||
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0a) && (xga->accel.px_map_format[xga->accel.src_map] >= 0x0a))
|
||||
xga->accel.pattern = 1;
|
||||
}
|
||||
}
|
||||
@@ -1486,8 +1497,8 @@ xga_bitblt(svga_t *svga)
|
||||
while (xga->accel.y >= 0) {
|
||||
if (xga->accel.command & 0xc0) {
|
||||
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, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0);
|
||||
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) : frgdcol;
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1);
|
||||
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);
|
||||
@@ -1497,8 +1508,8 @@ xga_bitblt(svga_t *svga)
|
||||
}
|
||||
} else {
|
||||
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);
|
||||
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) : frgdcol;
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1);
|
||||
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);
|
||||
@@ -1518,7 +1529,7 @@ xga_bitblt(svga_t *svga)
|
||||
if (xga->accel.x < 0) {
|
||||
xga->accel.x = xga->accel.blt_width & 0xfff;
|
||||
|
||||
dx = xga->accel.dst_map_x & 0x1fff;
|
||||
dx = xga->accel.dst_map_x;
|
||||
if (xga->accel.dst_map_x >= 0x1800)
|
||||
dx |= ~0x17ff;
|
||||
xga->accel.sx = xga->accel.src_map_x & 0xfff;
|
||||
@@ -1549,12 +1560,12 @@ xga_bitblt(svga_t *svga)
|
||||
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)) {
|
||||
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px <= 7) && (xga->accel.py <= 3))
|
||||
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0a) && (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)) {
|
||||
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) {
|
||||
if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0a) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) {
|
||||
if ((patwidth >= 7) && ((xga->accel.command & 0xc0) == 0x40))
|
||||
xga->accel.pattern = 0;
|
||||
else
|
||||
@@ -1585,15 +1596,15 @@ xga_bitblt(svga_t *svga)
|
||||
|
||||
if ((((xga->accel.command >> 24) & 0x0f) == 0x0a) && ((xga->accel.bkgd_mix & 0x1f) == 5)) {
|
||||
while (xga->accel.y >= 0) {
|
||||
mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1);
|
||||
mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, patbase, patwidth + 1);
|
||||
if (mix)
|
||||
xga->accel.filling = !xga->accel.filling;
|
||||
|
||||
if (xga->accel.command & 0xc0) {
|
||||
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;
|
||||
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) : frgdcol;
|
||||
if (xga->accel.filling) {
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, 1024, 0);
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, 1024);
|
||||
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);
|
||||
@@ -1605,9 +1616,9 @@ xga_bitblt(svga_t *svga)
|
||||
}
|
||||
} else {
|
||||
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;
|
||||
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) : frgdcol;
|
||||
if (xga->accel.filling) {
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, 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);
|
||||
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);
|
||||
@@ -1628,7 +1639,7 @@ xga_bitblt(svga_t *svga)
|
||||
xga->accel.y--;
|
||||
xga->accel.x = xga->accel.blt_width & 0xfff;
|
||||
|
||||
dx = xga->accel.dst_map_x & 0x1fff;
|
||||
dx = xga->accel.dst_map_x;
|
||||
if (xga->accel.dst_map_x >= 0x1800)
|
||||
dx |= ~0x17ff;
|
||||
|
||||
@@ -1647,16 +1658,16 @@ xga_bitblt(svga_t *svga)
|
||||
}
|
||||
} else {
|
||||
while (xga->accel.y >= 0) {
|
||||
mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1);
|
||||
mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, patbase, patwidth + 1);
|
||||
|
||||
if (xga->accel.command & 0xc0) {
|
||||
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;
|
||||
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) : 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;
|
||||
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) : bkgdcol;
|
||||
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, 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);
|
||||
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);
|
||||
@@ -1667,11 +1678,11 @@ xga_bitblt(svga_t *svga)
|
||||
} else {
|
||||
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;
|
||||
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) : 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;
|
||||
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) : bkgdcol;
|
||||
|
||||
dest_dat = xga_accel_read_map_pixel(svga, dx, 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);
|
||||
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);
|
||||
@@ -1693,7 +1704,7 @@ xga_bitblt(svga_t *svga)
|
||||
xga->accel.y--;
|
||||
xga->accel.x = xga->accel.blt_width & 0xfff;
|
||||
|
||||
dx = xga->accel.dst_map_x & 0x1fff;
|
||||
dx = xga->accel.dst_map_x;
|
||||
if (xga->accel.dst_map_x >= 0x1800)
|
||||
dx |= ~0x17ff;
|
||||
|
||||
@@ -1800,6 +1811,10 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len)
|
||||
|
||||
case 0x1c:
|
||||
xga->accel.px_map_format[xga->accel.px_map_idx] = val;
|
||||
if (val & 0x08)
|
||||
xga_log("Big Endian Pixel Format=%d, AccessMode=%x.\n", xga->accel.px_map_idx, xga->access_mode & 0x08);
|
||||
else
|
||||
xga_log("Little Endian Pixel Format=%d, AccessMode=%x.\n", xga->accel.px_map_idx, xga->access_mode & 0x08);
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
@@ -2155,6 +2170,7 @@ exec_command:
|
||||
xga->accel.pat_src = ((xga->accel.command >> 12) & 0x0f);
|
||||
xga->accel.dst_map = ((xga->accel.command >> 16) & 0x0f);
|
||||
xga->accel.src_map = ((xga->accel.command >> 20) & 0x0f);
|
||||
xga_log("PATMAP=%x, DSTMAP=%x, SRCMAP=%x.\n", xga->accel.px_map_format[xga->accel.pat_src], xga->accel.px_map_format[xga->accel.dst_map], xga->accel.px_map_format[xga->accel.src_map]);
|
||||
|
||||
#ifdef ENABLE_XGA_LOG
|
||||
if (xga->accel.pat_src)
|
||||
@@ -2531,29 +2547,21 @@ xga_render_4bpp(svga_t *svga)
|
||||
|
||||
xga->lastline_draw = xga->displine;
|
||||
|
||||
for (int x = 0; x <= xga->h_disp; x += 16) {
|
||||
for (int x = 0; x <= xga->h_disp; x += 8) {
|
||||
dat = *(uint32_t *) (&xga->vram[xga->ma & xga->vram_mask]);
|
||||
p[0] = xga->pallook[dat & 0x0f];
|
||||
p[1] = xga->pallook[(dat >> 4) & 0x0f];
|
||||
p[2] = xga->pallook[(dat >> 8) & 0x0f];
|
||||
p[3] = xga->pallook[(dat >> 12) & 0x0f];
|
||||
p[4] = xga->pallook[(dat >> 16) & 0x0f];
|
||||
p[5] = xga->pallook[(dat >> 20) & 0x0f];
|
||||
p[6] = xga->pallook[(dat >> 24) & 0x0f];
|
||||
p[7] = xga->pallook[(dat >> 28) & 0x0f];
|
||||
p[1] = xga->pallook[(dat >> 8) & 0x0f];
|
||||
p[2] = xga->pallook[(dat >> 16) & 0x0f];
|
||||
p[3] = xga->pallook[(dat >> 24) & 0x0f];
|
||||
|
||||
dat = *(uint32_t *) (&xga->vram[(xga->ma + 4) & xga->vram_mask]);
|
||||
p[8] = xga->pallook[dat & 0x0f];
|
||||
p[9] = xga->pallook[(dat >> 4) & 0x0f];
|
||||
p[10] = xga->pallook[(dat >> 8) & 0x0f];
|
||||
p[11] = xga->pallook[(dat >> 12) & 0x0f];
|
||||
p[12] = xga->pallook[(dat >> 16) & 0x0f];
|
||||
p[13] = xga->pallook[(dat >> 20) & 0x0f];
|
||||
p[14] = xga->pallook[(dat >> 24) & 0x0f];
|
||||
p[15] = xga->pallook[(dat >> 28) & 0x0f];
|
||||
dat = *(uint32_t *) (&xga->vram[(xga->ma + 2) & xga->vram_mask]);
|
||||
p[4] = xga->pallook[dat & 0x0f];
|
||||
p[5] = xga->pallook[(dat >> 8) & 0x0f];
|
||||
p[6] = xga->pallook[(dat >> 16) & 0x0f];
|
||||
p[7] = xga->pallook[(dat >> 24) & 0x0f];
|
||||
|
||||
xga->ma += 8;
|
||||
p += 16;
|
||||
p += 8;
|
||||
}
|
||||
xga->ma &= xga->vram_mask;
|
||||
}
|
||||
@@ -2643,7 +2651,8 @@ xga_write_test(uint32_t addr, uint8_t val, void *priv)
|
||||
xga_t *xga = (xga_t *) svga->xga;
|
||||
|
||||
if (xga_active && xga) {
|
||||
if (((xga->op_mode & 7) >= 1) && (xga->aperture_cntl >= 1)) {
|
||||
if (((xga->op_mode & 7) >= 1) && xga->aperture_cntl) {
|
||||
xga_log("WriteAddr=%05x.\n", addr);
|
||||
if (val == 0xa5) { /*Memory size test of XGA*/
|
||||
xga->test = val;
|
||||
if (addr == 0xa0001)
|
||||
@@ -2653,28 +2662,39 @@ xga_write_test(uint32_t addr, uint8_t val, void *priv)
|
||||
|
||||
xga->on = 0;
|
||||
vga_on = 1;
|
||||
xga->disp_cntl_2 = 0;
|
||||
xga_log("XGA test1 addr=%05x, test=%02x.\n", addr, xga->a5_test);
|
||||
} else if (val == 0x5a) {
|
||||
xga->test = val;
|
||||
xga->on = 0;
|
||||
vga_on = 1;
|
||||
xga->disp_cntl_2 = 0;
|
||||
xga_log("XGA test2 addr = %05x.\n", addr);
|
||||
} else if ((addr == 0xa0000) || (addr == 0xa0010)) {
|
||||
addr += xga->write_bank;
|
||||
xga->vram[addr & xga->vram_mask] = val;
|
||||
xga_log("XGA Linear endian reverse write, val = %02x, addr = %05x, banked mask = %04x, a5test=%d.\n", val, addr, svga->banked_mask, xga->a5_test);
|
||||
if (!xga->a5_test)
|
||||
xga->linear_endian_reverse = 1;
|
||||
}
|
||||
} else {
|
||||
} else if (xga->aperture_cntl) {
|
||||
xga->on = 0;
|
||||
vga_on = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xga_write_banked(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *) priv;
|
||||
xga_t *xga = (xga_t *) svga->xga;
|
||||
|
||||
if (xga->access_mode & 0x08) {
|
||||
if ((xga->access_mode & 0x07) == 0x04)
|
||||
addr ^= 1;
|
||||
}
|
||||
|
||||
xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount;
|
||||
xga->vram[addr & xga->vram_mask] = val;
|
||||
}
|
||||
|
||||
static void
|
||||
xga_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -2689,33 +2709,45 @@ xga_write(uint32_t addr, uint8_t val, void *priv)
|
||||
|
||||
cycles -= svga->monitor->mon_video_timing_write_b;
|
||||
|
||||
if (xga->access_mode & 8) {
|
||||
if ((xga->access_mode & 7) == 4)
|
||||
addr ^= 1;
|
||||
}
|
||||
|
||||
xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount;
|
||||
xga->vram[addr & xga->vram_mask] = val;
|
||||
xga_write_banked(addr, val, svga);
|
||||
}
|
||||
|
||||
static void
|
||||
xga_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *) priv;
|
||||
svga_t *svga = (svga_t *) priv;
|
||||
xga_t *xga = (xga_t *) svga->xga;
|
||||
|
||||
xga_write(addr, val & 0xff, svga);
|
||||
xga_write(addr + 1, val >> 8, svga);
|
||||
addr &= xga->banked_mask;
|
||||
addr += xga->write_bank;
|
||||
|
||||
if (addr >= xga->vram_size)
|
||||
return;
|
||||
|
||||
cycles -= svga->monitor->mon_video_timing_write_w;
|
||||
|
||||
xga_write_banked(addr, val & 0xff, svga);
|
||||
xga_write_banked(addr + 1, val >> 8, svga);
|
||||
}
|
||||
|
||||
static void
|
||||
xga_writel(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *) priv;
|
||||
svga_t *svga = (svga_t *) priv;
|
||||
xga_t *xga = (xga_t *) svga->xga;
|
||||
|
||||
xga_write(addr, val & 0xff, svga);
|
||||
xga_write(addr + 1, (val >> 8) & 0xff, svga);
|
||||
xga_write(addr + 2, (val >> 16) & 0xff, svga);
|
||||
xga_write(addr + 3, (val >> 24) & 0xff, svga);
|
||||
addr &= xga->banked_mask;
|
||||
addr += xga->write_bank;
|
||||
|
||||
if (addr >= xga->vram_size)
|
||||
return;
|
||||
|
||||
cycles -= svga->monitor->mon_video_timing_write_l;
|
||||
|
||||
xga_write_banked(addr, val & 0xff, svga);
|
||||
xga_write_banked(addr + 1, val >> 8, svga);
|
||||
xga_write_banked(addr + 2, val >> 16, svga);
|
||||
xga_write_banked(addr + 3, val >> 24, svga);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
@@ -2726,7 +2758,7 @@ xga_read_test(uint32_t addr, void *priv)
|
||||
uint8_t ret = 0x00;
|
||||
|
||||
if (xga_active && xga) {
|
||||
if (((xga->op_mode & 7) >= 1) && (xga->aperture_cntl >= 1)) {
|
||||
if (((xga->op_mode & 7) >= 1) && xga->aperture_cntl) {
|
||||
if (xga->test == 0xa5) { /*Memory size test of XGA*/
|
||||
if (addr == 0xa0001) {
|
||||
ret = xga->test;
|
||||
@@ -2753,7 +2785,7 @@ xga_read_test(uint32_t addr, void *priv)
|
||||
addr += xga->read_bank;
|
||||
return xga->vram[addr & xga->vram_mask];
|
||||
}
|
||||
} else {
|
||||
} else if (xga->aperture_cntl) {
|
||||
xga->on = 0;
|
||||
vga_on = 1;
|
||||
}
|
||||
@@ -2762,12 +2794,29 @@ xga_read_test(uint32_t addr, void *priv)
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
xga_read(uint32_t addr, void *priv)
|
||||
xga_read_banked(uint32_t addr, void *priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *) priv;
|
||||
xga_t *xga = (xga_t *) svga->xga;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (xga->access_mode & 0x08) {
|
||||
if ((xga->access_mode & 0x07) == 0x04)
|
||||
addr ^= 1;
|
||||
}
|
||||
|
||||
ret = xga->vram[addr & xga->vram_mask];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
xga_read(uint32_t addr, void *priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *) priv;
|
||||
xga_t *xga = (xga_t *) svga->xga;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr &= xga->banked_mask;
|
||||
addr += xga->read_bank;
|
||||
|
||||
@@ -2778,13 +2827,7 @@ xga_read(uint32_t addr, void *priv)
|
||||
|
||||
cycles -= svga->monitor->mon_video_timing_read_b;
|
||||
|
||||
if (xga->access_mode & 8) {
|
||||
if ((xga->access_mode & 7) == 4)
|
||||
addr ^= 1;
|
||||
}
|
||||
|
||||
ret = xga->vram[addr & xga->vram_mask];
|
||||
|
||||
ret = xga_read_banked(addr, svga);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2792,11 +2835,21 @@ static uint16_t
|
||||
xga_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *) priv;
|
||||
xga_t *xga = (xga_t *) svga->xga;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
ret = xga_read(addr, svga);
|
||||
ret |= (xga_read(addr + 1, svga) << 8);
|
||||
addr &= xga->banked_mask;
|
||||
addr += xga->read_bank;
|
||||
|
||||
if (addr >= xga->vram_size) {
|
||||
xga_log("Over Read ADDR=%x.\n", addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
cycles -= svga->monitor->mon_video_timing_read_w;
|
||||
|
||||
ret = xga_read_banked(addr, svga);
|
||||
ret |= (xga_read_banked(addr + 1, svga) << 8);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2804,13 +2857,23 @@ static uint32_t
|
||||
xga_readl(uint32_t addr, void *priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *) priv;
|
||||
xga_t *xga = (xga_t *) svga->xga;
|
||||
uint32_t ret = 0xffffffff;
|
||||
|
||||
ret = xga_read(addr, svga);
|
||||
ret |= (xga_read(addr + 1, svga) << 8);
|
||||
ret |= (xga_read(addr + 2, svga) << 16);
|
||||
ret |= (xga_read(addr + 3, svga) << 24);
|
||||
addr &= xga->banked_mask;
|
||||
addr += xga->read_bank;
|
||||
|
||||
if (addr >= xga->vram_size) {
|
||||
xga_log("Over Read ADDR=%x.\n", addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
cycles -= svga->monitor->mon_video_timing_read_l;
|
||||
|
||||
ret = xga_read_banked(addr, svga);
|
||||
ret |= (xga_read_banked(addr + 1, svga) << 8);
|
||||
ret |= (xga_read_banked(addr + 2, svga) << 16);
|
||||
ret |= (xga_read_banked(addr + 3, svga) << 24);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2820,6 +2883,7 @@ xga_write_linear(uint32_t addr, uint8_t val, void *priv)
|
||||
svga_t *svga = (svga_t *) priv;
|
||||
xga_t *xga = (xga_t *) svga->xga;
|
||||
|
||||
xga_log("WrtieLL XGA=%d.\n", xga->on);
|
||||
if (!xga->on) {
|
||||
svga_write_linear(addr, val, svga);
|
||||
return;
|
||||
@@ -2834,12 +2898,9 @@ xga_write_linear(uint32_t addr, uint8_t val, void *priv)
|
||||
|
||||
cycles -= svga->monitor->mon_video_timing_write_b;
|
||||
|
||||
if (xga->linear_endian_reverse) {
|
||||
if ((xga->access_mode & 7) == 4) {
|
||||
if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4)
|
||||
addr ^= 1;
|
||||
} else if (xga->access_mode & 8) {
|
||||
if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4)
|
||||
if (!(xga->access_mode & 0x08)) {
|
||||
if ((xga->access_mode & 0x07) == 0x04) {
|
||||
if ((xga->accel.px_map_format[xga->accel.dst_map] & 0x07) == 0x04)
|
||||
addr ^= 1;
|
||||
}
|
||||
}
|
||||
@@ -2899,12 +2960,9 @@ xga_read_linear(uint32_t addr, void *priv)
|
||||
|
||||
cycles -= svga->monitor->mon_video_timing_read_b;
|
||||
|
||||
if (xga->linear_endian_reverse) {
|
||||
if ((xga->access_mode & 7) == 4) {
|
||||
if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4)
|
||||
addr ^= 1;
|
||||
} else if (xga->access_mode & 8) {
|
||||
if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4)
|
||||
if (!(xga->access_mode & 0x08)) {
|
||||
if ((xga->access_mode & 0x07) == 0x04) {
|
||||
if ((xga->accel.px_map_format[xga->accel.dst_map] & 0x07) == 0x04)
|
||||
addr ^= 1;
|
||||
}
|
||||
}
|
||||
@@ -3145,11 +3203,12 @@ xga_mca_write(int port, uint8_t val, void *priv)
|
||||
mem_mapping_disable(&xga->memio_mapping);
|
||||
xga->on = 0;
|
||||
vga_on = 1;
|
||||
xga->linear_endian_reverse = 0;
|
||||
xga->a5_test = 0;
|
||||
|
||||
/* Save the MCA register value. */
|
||||
xga->pos_regs[port & 7] = val;
|
||||
if (!(xga->pos_regs[4] & 1)) /*MCA 4MB addressing on systems with more than 16MB of memory*/
|
||||
xga->pos_regs[4] |= 1;
|
||||
|
||||
if (xga->pos_regs[2] & 1) {
|
||||
xga->instance = (xga->pos_regs[2] & 0x0e) >> 1;
|
||||
@@ -3184,15 +3243,10 @@ static void
|
||||
xga_mca_reset(void *priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *) priv;
|
||||
xga_t *xga = (xga_t *) svga->xga;
|
||||
|
||||
mem_mapping_disable(&xga->memio_mapping);
|
||||
xga->on = 0;
|
||||
vga_on = 1;
|
||||
xga_log("MCA Reset.\n");
|
||||
mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
xga_mca_write(0x102, 0, svga);
|
||||
xga->linear_endian_reverse = 0;
|
||||
xga->a5_test = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3207,8 +3261,8 @@ xga_reset(void *priv)
|
||||
|
||||
xga->on = 0;
|
||||
vga_on = 1;
|
||||
xga->linear_endian_reverse = 0;
|
||||
xga->a5_test = 0;
|
||||
mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
@@ -3345,8 +3399,11 @@ xga_pos_out(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 0x0104:
|
||||
xga_log("104Write=%02x.\n", val);
|
||||
if ((xga->pos_idx & 3) == 0)
|
||||
if ((xga->pos_idx & 3) == 0) {
|
||||
xga->pos_regs[4] = val;
|
||||
if (!(xga->pos_regs[4] & 0x01)) /*4MB addressing on systems with more than 15MB of memory*/
|
||||
xga->pos_regs[4] |= 0x01;
|
||||
}
|
||||
break;
|
||||
case 0x0105:
|
||||
xga_log("105Write=%02x.\n", val);
|
||||
@@ -3405,7 +3462,6 @@ xga_init(const device_t *info)
|
||||
xga->on = 0;
|
||||
xga->hwcursor.cur_xsize = 64;
|
||||
xga->hwcursor.cur_ysize = 64;
|
||||
xga->linear_endian_reverse = 0;
|
||||
xga->a5_test = 0;
|
||||
|
||||
if (info->flags & DEVICE_MCA) {
|
||||
@@ -3431,15 +3487,13 @@ xga_init(const device_t *info)
|
||||
xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000);
|
||||
xga->instance = (xga->pos_regs[2] & 0x0e) >> 1;
|
||||
xga->pos_regs[2] |= 0x01;
|
||||
if (mem_size >= 16384) {
|
||||
xga->pos_regs[4] |= 0x01;
|
||||
xga->pos_regs[4] |= 0x01;
|
||||
if (mem_size >= 15360)
|
||||
xga->pos_regs[5] = 0;
|
||||
} else {
|
||||
else {
|
||||
xga->pos_regs[5] = ((mem_size * 64) >> 0x10) + 1;
|
||||
if (xga->pos_regs[5] == 0x10) {
|
||||
if (xga->pos_regs[5] == 0x10)
|
||||
xga->pos_regs[5] = 0x00;
|
||||
xga->pos_regs[4] |= 0x01;
|
||||
}
|
||||
}
|
||||
xga->base_addr_1mb = (xga->pos_regs[5] & 0x0f) << 20;
|
||||
xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22);
|
||||
@@ -3450,9 +3504,6 @@ xga_init(const device_t *info)
|
||||
}
|
||||
}
|
||||
|
||||
mem_mapping_add(&xga->video_mapping, 0, 0, xga_read, xga_readw, xga_readl,
|
||||
xga_write, xga_writew, xga_writel,
|
||||
NULL, MEM_MAPPING_EXTERNAL, svga);
|
||||
mem_mapping_add(&xga->linear_mapping, 0, 0, xga_read_linear, xga_readw_linear, xga_readl_linear,
|
||||
xga_write_linear, xga_writew_linear, xga_writel_linear,
|
||||
NULL, MEM_MAPPING_EXTERNAL, svga);
|
||||
|
||||
Reference in New Issue
Block a user