Merge branch '86Box:master' into net-add-tap-backend

This commit is contained in:
Doug Johnson
2025-01-09 19:47:38 -07:00
committed by GitHub
78 changed files with 6726 additions and 4466 deletions

View File

@@ -106,7 +106,7 @@ jobs:
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
- name: Run sonar-scanner
# if: 0
if: 0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

View File

@@ -206,6 +206,7 @@ int video_fullscreen_scale_maximized = 0; /* (C) Whether
also apply when maximized. */
int do_auto_pause = 0; /* (C) Auto-pause the emulator on focus
loss */
int hook_enabled = 1; /* (C) Keyboard hook is enabled */
char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */
int other_ide_present = 0; /* IDE controllers from non-IDE cards are
@@ -452,6 +453,8 @@ delete_nvr_file(uint8_t flash)
fn = NULL;
}
extern void device_find_all_descs(void);
/*
* Perform initial startup of the PC.
*
@@ -561,6 +564,7 @@ usage:
printf("-S or --settings - show only the settings dialog\n");
#endif
printf("-V or --vmname name - overrides the name of the running VM\n");
printf("-W or --nohook - disables keyboard hook (compatibility-only outside Windows)\n");
printf("-X or --clear what - clears the 'what' (cmos/flash/both)\n");
printf("-Y or --donothing - do not show any UI or run the emulation\n");
printf("-Z or --lastvmpath - the last parameter is VM path rather than config\n");
@@ -636,6 +640,8 @@ usage:
dump_missing = 1;
} else if (!strcasecmp(argv[c], "--donothing") || !strcasecmp(argv[c], "-Y")) {
do_nothing = 1;
} else if (!strcasecmp(argv[c], "--nohook") || !strcasecmp(argv[c], "-W")) {
hook_enabled = 0;
} else if (!strcasecmp(argv[c], "--keycodes") || !strcasecmp(argv[c], "-K")) {
if ((c + 1) == argc)
goto usage;

File diff suppressed because it is too large Load Diff

View File

@@ -58,26 +58,38 @@ cdrom_image_log(const char *fmt, ...)
of the audio while audio still plays. With an absolute conversion, the counter is fine. */
#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
static void
image_get_tracks(cdrom_t *dev, int *first, int *last)
{
cd_img_t *img = (cd_img_t *) dev->local;
TMSF tmsf;
cdi_get_audio_tracks(img, first, last, &tmsf);
}
static void
image_get_track_info(cdrom_t *dev, uint32_t track, int end, track_info_t *ti)
{
cd_img_t *img = (cd_img_t *) dev->local;
TMSF tmsf;
track_t *ct = NULL;
cdi_get_audio_track_info(img, end, track, &ti->number, &tmsf, &ti->attr);
for (int i = 0; i < img->tracks_num; i++) {
ct = &(img->tracks[i]);
if (ct->point == track)
break;
}
ti->m = tmsf.min;
ti->s = tmsf.sec;
ti->f = tmsf.fr;
ti->number = ct->point;
if (ct == NULL) {
ti->attr = 0x14;
ti->m = 0;
ti->s = 2;
ti->f = 0;
} else {
uint32_t pos = end ? ct->idx[1].start : (ct->idx[1].start + ct->idx[1].length);
ti->attr = ct->attr;
ti->m = (pos / 75) / 60;
ti->s = (pos / 75) % 60;
ti->f = pos % 75;
}
}
static void
image_get_raw_track_info(cdrom_t *dev, int *num, raw_track_info_t *rti)
{
cdi_get_raw_track_info((cd_img_t *) dev->local, num, (uint8_t *) rti);
}
static void
@@ -99,31 +111,30 @@ image_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc)
subc->rel_f = rel_pos.fr;
cdrom_image_log("image_get_subchannel(): %02X, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n",
subc->attr, subc->track, subc->index, subc->abs_m, subc->abs_s, subc->abs_f, subc->rel_m, subc->rel_s, subc->rel_f);
subc->attr, subc->track, subc->index, subc->abs_m, subc->abs_s, subc->abs_f,
subc->rel_m, subc->rel_s, subc->rel_f);
}
static int
image_get_capacity(cdrom_t *dev)
{
cd_img_t *img = (cd_img_t *) dev->local;
int first_track;
int last_track;
int number;
unsigned char attr;
uint32_t address = 0;
uint32_t lb = 0;
track_t *lo = NULL;
if (!img)
return 0;
cdi_get_audio_tracks_lba(img, &first_track, &last_track, &lb);
for (int c = 0; c <= last_track; c++) {
cdi_get_audio_track_info_lba(img, 0, c + 1, &number, &address, &attr);
if (address > lb)
lb = address;
for (int i = (img->tracks_num - 1); i >= 0; i--) {
if (img->tracks[i].point == 0xa2) {
lo = &(img->tracks[i]);
break;
}
}
if (lo != NULL)
lb = lo->idx[1].start - 1;
return lb;
}
@@ -131,13 +142,9 @@ static int
image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf)
{
cd_img_t *img = (cd_img_t *) dev->local;
uint8_t attr;
TMSF tmsf;
int m;
int s;
int f;
int number;
int track;
if (!img || (dev->cd_status == CD_STATUS_DATA_ONLY))
return 0;
@@ -149,29 +156,18 @@ image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf)
pos = MSFtoLBA(m, s, f) - 150;
}
/* GetTrack requires LBA. */
track = cdi_get_track(img, pos);
if (track == -1)
return 0;
else {
cdi_get_audio_track_info(img, 0, track, &number, &tmsf, &attr);
return attr == AUDIO_TRACK;
}
return cdi_is_audio(img, pos);
}
static int
image_is_track_pre(cdrom_t *dev, uint32_t lba)
{
cd_img_t *img = (cd_img_t *) dev->local;
int track;
/* GetTrack requires LBA. */
track = cdi_get_track(img, lba);
if (!img || (dev->cd_status == CD_STATUS_DATA_ONLY))
return 0;
if (track != -1)
return cdi_get_audio_track_pre(img, track);
return 0;
return cdi_is_pre(img, lba);
}
static int
@@ -183,24 +179,14 @@ image_sector_size(struct cdrom *dev, uint32_t lba)
}
static int
image_read_sector(struct cdrom *dev, int type, uint8_t *b, uint32_t lba)
image_read_sector(struct cdrom *dev, uint8_t *b, uint32_t lba)
{
cd_img_t *img = (cd_img_t *) dev->local;
switch (type) {
case CD_READ_DATA:
return cdi_read_sector(img, b, 0, lba);
case CD_READ_AUDIO:
return cdi_read_sector(img, b, 1, lba);
case CD_READ_RAW:
if (cdi_get_sector_size(img, lba) == 2352)
return cdi_read_sector(img, b, 1, lba);
else
return cdi_read_sector_sub(img, b, lba);
default:
cdrom_image_log("CD-ROM %i: Unknown CD read type\n", dev->id);
return 0;
}
if (cdi_get_sector_size(img, lba) <= 2352)
return cdi_read_sector(img, b, 1, lba);
else
return cdi_read_sector_sub(img, b, lba);
}
static int
@@ -211,10 +197,8 @@ image_track_type(cdrom_t *dev, uint32_t lba)
if (img) {
if (image_is_track_audio(dev, lba, 0))
return CD_TRACK_AUDIO;
else {
if (cdi_is_mode2(img, lba))
return CD_TRACK_MODE2 | cdi_get_mode2_form(img, lba);
}
else if (cdi_is_mode2(img, lba))
return CD_TRACK_MODE2 | cdi_get_mode2_form(img, lba);
}
return 0;
@@ -243,9 +227,8 @@ image_exit(cdrom_t *dev)
}
static const cdrom_ops_t cdrom_image_ops = {
image_get_tracks,
image_get_track_info,
NULL,
image_get_raw_track_info,
image_get_subchannel,
image_is_track_pre,
image_sector_size,
@@ -275,14 +258,13 @@ cdrom_image_open(cdrom_t *dev, const char *fn)
strcpy(dev->image_path, fn);
/* Create new instance of the CDROM_Image class. */
img = (cd_img_t *) malloc(sizeof(cd_img_t));
img = (cd_img_t *) calloc(1, sizeof(cd_img_t));
/* This guarantees that if ops is not NULL, then
neither is the image pointer. */
if (!img)
if (img == NULL)
return image_open_abort(dev);
memset(img, 0, sizeof(cd_img_t));
dev->local = img;
/* Open the image. */
@@ -298,13 +280,16 @@ cdrom_image_open(cdrom_t *dev, const char *fn)
dev->seek_pos = 0;
dev->cd_buflen = 0;
dev->cdrom_capacity = image_get_capacity(dev);
cdrom_image_log("CD-ROM capacity: %i sectors (%" PRIi64 " bytes)\n", dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity) << 11ULL);
cdrom_image_log("CD-ROM capacity: %i sectors (%" PRIi64 " bytes)\n", dev->cdrom_capacity,
((uint64_t) dev->cdrom_capacity) << 11ULL);
#ifdef ENABLE_CDROM_IMAGE_LOG
int cm, cs, cf;
cf = dev->cdrom_capacity % 75;
cs = (dev->cdrom_capacity / 75) % 60;
cm = (dev->cdrom_capacity / 75) / 60;
pclog("CD-ROM capacity: %i sectors (%" PRIi64 " bytes) (time: %02i:%02i:%02i)\n",
dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity - 150ULL) * 2352ULL, cm, cs, cf);
cdrom_image_log("CD-ROM capacity: %i sectors (%" PRIi64 " bytes) (time: %02i:%02i:%02i)\n",
dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity - 150ULL) * 2352ULL, cm, cs, cf);
#endif
/* Attach this handler to the drive. */
dev->ops = &cdrom_image_ops;

File diff suppressed because it is too large Load Diff

View File

@@ -8,9 +8,7 @@
*
* Virtual ISO CD-ROM image back-end.
*
*
*
* Authors: RichardG <richardg867@gmail.com>
* Authors: RichardG, <richardg867@gmail.com>
*
* Copyright 2022 RichardG.
*/

View File

@@ -55,14 +55,6 @@ cdrom_ioctl_log(const char *fmt, ...)
of the audio while audio still plays. With an absolute conversion, the counter is fine. */
#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
static void
ioctl_get_tracks(cdrom_t *dev, int *first, int *last)
{
TMSF tmsf;
plat_cdrom_get_audio_tracks(dev->local, first, last, &tmsf);
}
static void
ioctl_get_track_info(cdrom_t *dev, uint32_t track, int end, track_info_t *ti)
{
@@ -109,7 +101,8 @@ ioctl_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc)
subc->rel_f = rel_pos.fr;
cdrom_ioctl_log("ioctl_get_subchannel(): %02X, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n",
subc->attr, subc->track, subc->index, subc->abs_m, subc->abs_s, subc->abs_f, subc->rel_m, subc->rel_s, subc->rel_f);
subc->attr, subc->track, subc->index, subc->abs_m, subc->abs_s, subc->abs_f,
subc->rel_m, subc->rel_s, subc->rel_f);
}
static int
@@ -157,29 +150,16 @@ ioctl_sector_size(cdrom_t *dev, uint32_t lba)
}
static int
ioctl_read_sector(cdrom_t *dev, int type, uint8_t *b, uint32_t lba)
ioctl_read_sector(cdrom_t *dev, uint8_t *b, uint32_t lba)
{
switch (type) {
case CD_READ_DATA:
cdrom_ioctl_log("cdrom_ioctl_read_sector(): Data.\n");
return plat_cdrom_read_sector(dev->local, b, 0, lba);
case CD_READ_AUDIO:
cdrom_ioctl_log("cdrom_ioctl_read_sector(): Audio.\n");
return plat_cdrom_read_sector(dev->local, b, 1, lba);
case CD_READ_RAW:
cdrom_ioctl_log("cdrom_ioctl_read_sector(): Raw.\n");
return plat_cdrom_read_sector(dev->local, b, 1, lba);
default:
cdrom_ioctl_log("cdrom_ioctl_read_sector(): Unknown CD read type.\n");
break;
}
return 0;
cdrom_ioctl_log("cdrom_ioctl_read_sector(): Raw.\n");
return plat_cdrom_read_sector(dev->local, b, lba);
}
static int
ioctl_track_type(cdrom_t *dev, uint32_t lba)
{
int ret = 0;
int ret = CD_TRACK_UNK_DATA;
if (ioctl_is_track_audio(dev, lba, 0))
ret = CD_TRACK_AUDIO;
@@ -221,7 +201,6 @@ ioctl_exit(cdrom_t *dev)
}
static const cdrom_ops_t cdrom_ioctl_ops = {
ioctl_get_tracks,
ioctl_get_track_info,
ioctl_get_raw_track_info,
ioctl_get_subchannel,

View File

@@ -493,14 +493,26 @@ device_get_name(const device_t *dev, int bus, char *name)
sbus = (dev->flags & DEVICE_AT) ? "ISA16" : "ISA";
else if (dev->flags & DEVICE_CBUS)
sbus = "C-BUS";
else if (dev->flags & DEVICE_PCMCIA)
sbus = "PCMCIA";
else if (dev->flags & DEVICE_MCA)
sbus = "MCA";
else if (dev->flags & DEVICE_HIL)
sbus = "HP HIL";
else if (dev->flags & DEVICE_EISA)
sbus = "EISA";
else if (dev->flags & DEVICE_AT32)
sbus = "AT/32";
else if (dev->flags & DEVICE_OLB)
sbus = "OLB";
else if (dev->flags & DEVICE_VLB)
sbus = "VLB";
else if (dev->flags & DEVICE_PCI)
sbus = "PCI";
else if (dev->flags & DEVICE_CARDBUS)
sbus = "CARDBUS";
else if (dev->flags & DEVICE_USB)
sbus = "USB";
else if (dev->flags & DEVICE_AGP)
sbus = "AGP";
else if (dev->flags & DEVICE_AC97)
@@ -767,13 +779,16 @@ device_is_valid(const device_t *device, int m)
if ((device->flags & DEVICE_ATKBC) && !machine_has_bus(m, MACHINE_BUS_ISA16) && !machine_has_bus(m, MACHINE_BUS_DM_KBC))
return 0;
if ((device->flags & DEVICE_PS2) && !machine_has_bus(m, MACHINE_BUS_PS2_PORTS))
return 0;
if ((device->flags & DEVICE_ISA) && !machine_has_bus(m, MACHINE_BUS_ISA))
return 0;
if ((device->flags & DEVICE_CBUS) && !machine_has_bus(m, MACHINE_BUS_CBUS))
return 0;
if ((device->flags & DEVICE_PCMCIA) && !machine_has_bus(m, MACHINE_BUS_PCMCIA))
if ((device->flags & DEVICE_PCMCIA) && !machine_has_bus(m, MACHINE_BUS_PCMCIA) && !machine_has_bus(m, MACHINE_BUS_ISA))
return 0;
if ((device->flags & DEVICE_MCA) && !machine_has_bus(m, MACHINE_BUS_MCA))
@@ -785,6 +800,9 @@ device_is_valid(const device_t *device, int m)
if ((device->flags & DEVICE_EISA) && !machine_has_bus(m, MACHINE_BUS_EISA))
return 0;
if ((device->flags & DEVICE_AT32) && !machine_has_bus(m, MACHINE_BUS_AT32))
return 0;
if ((device->flags & DEVICE_OLB) && !machine_has_bus(m, MACHINE_BUS_OLB))
return 0;
@@ -794,7 +812,7 @@ device_is_valid(const device_t *device, int m)
if ((device->flags & DEVICE_PCI) && !machine_has_bus(m, MACHINE_BUS_PCI))
return 0;
if ((device->flags & DEVICE_CARDBUS) && !machine_has_bus(m, MACHINE_BUS_CARDBUS))
if ((device->flags & DEVICE_CARDBUS) && !machine_has_bus(m, MACHINE_BUS_CARDBUS) && !machine_has_bus(m, MACHINE_BUS_PCI))
return 0;
if ((device->flags & DEVICE_USB) && !machine_has_bus(m, MACHINE_BUS_USB))
@@ -803,9 +821,6 @@ device_is_valid(const device_t *device, int m)
if ((device->flags & DEVICE_AGP) && !machine_has_bus(m, MACHINE_BUS_AGP))
return 0;
if ((device->flags & DEVICE_PS2) && !machine_has_bus(m, MACHINE_BUS_PS2_PORTS))
return 0;
if ((device->flags & DEVICE_AC97) && !machine_has_bus(m, MACHINE_BUS_AC97))
return 0;

View File

@@ -137,6 +137,8 @@ isapnp_device_config_changed(isapnp_card_t *card, isapnp_device_t *ld)
card->config.mem[i].size = (ld->regs[reg_base + 3] << 16) | (ld->regs[reg_base + 4] << 8);
if (ld->regs[reg_base + 2] & 0x01) /* upper limit */
card->config.mem[i].size -= card->config.mem[i].base;
else
card->config.mem[i].size = (card->config.mem[i].size | 0xff) ^ 0xffffffff;
}
for (uint8_t i = 0; i < 4; i++) {
reg_base = (i == 0) ? 0x76 : (0x80 + (16 * i));
@@ -789,10 +791,25 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size)
break;
}
isapnp_log("ISAPnP: >>%s Memory range %d with %d bytes at %06X-%06X, align %d",
in_df ? ">" : "", mem_range,
*((uint16_t *) &card->rom[i + 10]) << 8, *((uint16_t *) &card->rom[i + 4]) << 8, ((card->rom[i + 3] & 0x4) ? 0 : (*((uint16_t *) &card->rom[i + 4]) << 8)) + (*((uint16_t *) &card->rom[i + 6]) << 8),
(*((uint16_t *) &card->rom[i + 8]) + 1) << 16);
isapnp_log("ISAPnP: >>%s Memory range %d with %d bytes at %06X-%06X to %06X-%06X, align %d",
/* %s */ in_df ? ">" : "",
/* %d */ mem_range,
/* %d */ *((uint16_t *) &card->rom[i + 8]),
/* %06X */ *((uint16_t *) &card->rom[i + 4]) << 8,
/* %06X */ ((card->rom[i + 3] & 0x4) ?
/* High address. */
(*((uint16_t *) &card->rom[i + 10]) << 8) :
/* Range. */
(*((uint16_t *) &card->rom[i + 4]) << 8)) +
(*((uint16_t *) &card->rom[i + 10]) << 8),
/* %06X */ *((uint16_t *) &card->rom[i + 6]) << 8,
/* %06X */ ((card->rom[i + 3] & 0x4) ?
/* High address. */
(*((uint16_t *) &card->rom[i + 10]) << 8) :
/* Range. */
(*((uint16_t *) &card->rom[i + 6]) << 8)) +
(*((uint16_t *) &card->rom[i + 10]) << 8),
/* %d */ *((uint16_t *) &card->rom[i + 8]));
res = 1 << mem_range;
mem_range++;
} else {
@@ -806,9 +823,25 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size)
break;
}
isapnp_log("ISAPnP: >>%s 32-bit memory range %d with %d bytes at %08X-%08X, align %d", in_df ? ">" : "", mem_range_32,
*((uint32_t *) &card->rom[i + 16]) << 8, *((uint32_t *) &card->rom[i + 4]) << 8, ((card->rom[i + 3] & 0x4) ? 0 : (*((uint32_t *) &card->rom[i + 4]) << 8)) + (*((uint32_t *) &card->rom[i + 8]) << 8),
*((uint32_t *) &card->rom[i + 12]));
isapnp_log("ISAPnP: >>%s 32-bit memory range %d with %d bytes at %08X-%08X, align %d",
/* %s */ in_df ? ">" : "",
/* %d */ mem_range_32,
/* %d */ *((uint32_t *) &card->rom[i + 12]),
/* %08X */ *((uint32_t *) &card->rom[i + 4]),
/* %08X */ ((card->rom[i + 3] & 0x4) ?
/* High address. */
*((uint32_t *) &card->rom[i + 16]) :
/* Range. */
*((uint32_t *) &card->rom[i + 4])) +
*((uint32_t *) &card->rom[i + 16]),
/* %08X */ *((uint32_t *) &card->rom[i + 8]),
/* %08X */ ((card->rom[i + 3] & 0x4) ?
/* High address. */
*((uint32_t *) &card->rom[i + 16]) :
/* Range. */
*((uint32_t *) &card->rom[i + 8])) +
*((uint32_t *) &card->rom[i + 16]),
/* %d */ *((uint32_t *) &card->rom[i + 12]));
res = 1 << (4 + mem_range_32);
mem_range_32++;
}

View File

@@ -29,7 +29,9 @@
#include "cpu.h"
int keyboard_scan;
uint16_t scancode_map[768] = { 0 };
int keyboard_scan;
#ifdef _WIN32
/* Windows: F8+F12 */
@@ -386,3 +388,22 @@ keyboard_ismsexit(void)
return ((recv_key_ui[key_prefix_1_1] || recv_key_ui[key_prefix_1_2]) &&
(recv_key_ui[key_uncapture_1] || recv_key_ui[key_uncapture_2]));
}
/* This is so we can disambiguate scan codes that would otherwise conflict and get
passed on incorrectly. */
uint16_t
convert_scan_code(uint16_t scan_code)
{
if ((scan_code & 0xff00) == 0xe000)
scan_code = (scan_code & 0xff) | 0x0100;
if (scan_code == 0xE11D)
scan_code = 0x0100;
/* E0 00 is sent by some USB keyboards for their special keys, as it is an
invalid scan code (it has no untranslated set 2 equivalent), we mark it
appropriately so it does not get passed through. */
else if ((scan_code > 0x01FF) || (scan_code == 0x0100))
scan_code = 0xFFFF;
return scan_code;
}

View File

@@ -552,6 +552,29 @@ esdi_read(uint16_t port, void *priv)
return temp;
}
/**
* Copy a string into a buffer, padding with spaces, and placing characters as
* if they were packed into 16-bit values, stored little-endian.
*
* @param str Destination buffer
* @param src Source string
* @param len Length of destination buffer to fill in. Strings shorter than
* this length will be padded with spaces.
*/
static void
esdi_padstr(char *str, const char *src, const int len)
{
int v;
for (int i = 0; i < len; i++) {
if (*src != '\0')
v = *src++;
else
v = ' ';
str[i ^ 1] = v;
}
}
static void
esdi_callback(void *priv)
{
@@ -811,28 +834,36 @@ format_error:
irq_raise(esdi);
} else {
memset(esdi->buffer, 0x00, 512);
esdi->buffer[0] = 0x44; /* general configuration */
esdi->buffer[1] = drive->real_tracks; /* number of non-removable cylinders */
esdi->buffer[2] = 0; /* number of removable cylinders */
esdi->buffer[3] = drive->real_hpc; /* number of heads */
esdi->buffer[4] = 600; /* number of unformatted bytes/sector */
esdi->buffer[5] = esdi->buffer[4] * drive->real_spt; /* number of unformatted bytes/track */
esdi->buffer[6] = drive->real_spt; /* number of sectors */
esdi->buffer[7] = 0; /*minimum bytes in inter-sector gap*/
esdi->buffer[8] = 0; /* minimum bytes in postamble */
esdi->buffer[9] = 0; /* number of words of vendor status */
/* controller info */
esdi->buffer[20] = 2; /* controller type */
esdi->buffer[21] = 1; /* sector buffer size, in sectors */
esdi->buffer[22] = 0; /* ecc bytes appended */
esdi->buffer[27] = 'D' | ('W' << 8);
esdi->buffer[28] = '0' | ('1' << 8);
esdi->buffer[29] = '7' | ('0' << 8);
esdi->buffer[30] = '-' | ('V' << 8);
esdi->buffer[31] = 'E' | ('S' << 8);
esdi->buffer[31] = 0 | ('1' << 8);
esdi->buffer[47] = 0; /* sectors per interrupt */
esdi->buffer[48] = 0; /* can use double word read/write? */
esdi->buffer[0] = 0x3244; /*
Soft sectored (0x0004),
Fixed drive (0x0040),
Transfer rate > 5 Mbps but <= 10 Mbps (0x0200),
Data strobe offset option (0x1000),
Track offset option (0x2000).
*/
if (drive->real_spt >= 26)
esdi->buffer[0] |= 0x0008; /* Not MFM encoded. */
esdi->buffer[1] = drive->real_tracks; /* Fixed cylinders - the BIOS lists 2 less. */
esdi->buffer[2] = 0; /* Removable cylinders. */
esdi->buffer[3] = drive->real_hpc; /* Heads. */
esdi->buffer[5] = 600; /* Unformatted bytes per sector. */
esdi->buffer[4] = esdi->buffer[5] * drive->real_spt; /* Unformatted bytes per track. */
esdi->buffer[6] = drive->real_spt; /* Sectors per track - the BIOS lists 1 less. */
esdi->buffer[7] = 3088; /* Bytes in inter-sector gap. */
esdi->buffer[8] = 11; /* Byce in sync fileds. */
esdi->buffer[9] = 0xf; /* Number of vendor unique words. */
/* Serial Number */
esdi_padstr((char *) (esdi->buffer + 10), "00000000000000000000", 20);
/* Controller information. */
esdi->buffer[20] = 3; /* Buffer type. */
esdi->buffer[21] = 64; /* Buffer size in 512-byte increments. */
esdi->buffer[22] = 4; /* Bytes of ECC. */
/* Firmware */
esdi_padstr((char *) (esdi->buffer + 23), "REV. A5", 8);
/* Model */
esdi_padstr((char *) (esdi->buffer + 27), "WD1007V", 40);
esdi->buffer[47] = 1; /* Sectors per interrupt. */
esdi->buffer[48] = 0; /* Can use DWord read/write? */
esdi->pos = 0;
esdi->status = STAT_DRQ | STAT_READY | STAT_DSC;
irq_raise(esdi);

View File

@@ -145,7 +145,7 @@ typedef struct mcide_t {
rom_t bios_rom;
} mcide_t;
ide_board_t *ide_boards[IDE_BUS_MAX];
ide_board_t *ide_boards[IDE_BUS_MAX] = { 0 };
static uint8_t ide_ter_pnp_rom[] = {
/* BOX0001, serial 0, dummy checksum (filled in by isapnp_add_card) */
@@ -618,9 +618,12 @@ ide_hd_identify(const ide_t *ide)
if (!ide_boards[ide->board]->force_ata3 && (bm != NULL)) {
ide->buffer[80] = 0x7e; /*ATA-1 to ATA-6 supported*/
ide->buffer[81] = 0x19; /*ATA-6 revision 3a supported*/
} else {
} else
ide->buffer[80] = 0x0e; /*ATA-1 to ATA-3 supported*/
}
ide->buffer[83] = ide->buffer[84] = 0x4000;
ide->buffer[86] = 0x0000;
ide->buffer[87] = 0x4000;
}
static void
@@ -2219,9 +2222,8 @@ ide_callback(void *priv)
ide->sector_pos = 0;
ret = hdd_image_read(ide->hdd_num, ide_get_sector(ide),
ide->tf->secount ? ide->tf->secount : 256, ide->sector_buffer);
} else {
} else
ret = 0;
}
memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512);

View File

@@ -458,3 +458,17 @@ const device_t ide_w83769f_pci_34_device = {
.config = NULL
};
const device_t ide_w83769f_pci_single_channel_device = {
.name = "Winbond W83769F PCI (Single Channel)",
.internal_name = "ide_w83769f_pci_single_channel",
.flags = DEVICE_PCI,
.local = 0x200b4,
.init = w83769f_init,
.close = w83769f_close,
.reset = w83769f_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -407,18 +407,118 @@ hdd_zones_init(hard_disk_t *hdd)
static hdd_preset_t hdd_speed_presets[] = {
// clang-format off
{ .name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 },
{ .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 },
{ .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 },
{ .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 },
{ .name = "[1996] 5400 RPM", .internal_name = "1996_5400rpm", .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 },
{ .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 },
{ .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 },
{ .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 },
{ .name = "Conner CP3024", .internal_name = "CP3024", .model = "Conner Peripherals 20MB - CP3024", .zones = 1, .avg_spt = 33, .heads = 2, .rpm = 3500, .full_stroke_ms = 50, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 8, .max_multiple = 8 },
{ .name = "Conner CP3044", .internal_name = "CP3044", .model = "Conner Peripherals 40MB - CP3044", .zones = 1, .avg_spt = 40, .heads = 2, .rpm = 3500, .full_stroke_ms = 50, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 8, .max_multiple = 8 },
{ .name = "Conner CP3104", .internal_name = "CP3104", .model = "Conner Peripherals 104MB - CP3104", .zones = 1, .avg_spt = 33, .heads = 8, .rpm = 3500, .full_stroke_ms = 45, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 8, .max_multiple = 8 },
// clang-format on
{ .name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 },
{ .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 },
{ .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 },
{ .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 },
{ .name = "[1996] 5400 RPM", .internal_name = "1996_5400rpm", .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 },
{ .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 },
{ .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 },
{ .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 },
{ .name = "[PIO IDE] IBM WDA-L42", .internal_name = "WDAL42", .model = "IBM-WDA-L42", .zones = 1, .avg_spt = 85, .heads = 2, .rpm = 3600, .full_stroke_ms = 33, .track_seek_ms = 2.5, .rcache_num_seg = 1, .rcache_seg_size = 32, .max_multiple = 1 },
{ .name = "[ATA-1] Conner CP3024", .internal_name = "CP3024", .model = "Conner Peripherals 20MB - CP3024", .zones = 1, .avg_spt = 33, .heads = 2, .rpm = 3500, .full_stroke_ms = 50, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 8, .max_multiple = 8 }, // Needed for GRiDcase 1520 to work
{ .name = "[ATA-1] Conner CP3044", .internal_name = "CP3044", .model = "Conner Peripherals 40MB - CP3044", .zones = 1, .avg_spt = 40, .heads = 2, .rpm = 3500, .full_stroke_ms = 50, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 8, .max_multiple = 8 }, // Needed for GRiDcase 1520 to work
{ .name = "[ATA-1] Conner CP3104", .internal_name = "CP3104", .model = "Conner Peripherals 104MB - CP3104", .zones = 1, .avg_spt = 33, .heads = 8, .rpm = 3500, .full_stroke_ms = 45, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 8, .max_multiple = 8 }, // Needed for GRiDcase 1520 to work
{ .name = "[ATA-1] HP Kittyhawk", .internal_name = "C3014A", .model = "HP C3014A", .zones = 6, .avg_spt = 180, .heads = 3, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 },
{ .name = "[ATA-1] IBM H3256-A3", .internal_name = "H3256A3", .model = "IBM-H3256-A3", .zones = 1, .avg_spt = 140, .heads = 2, .rpm = 3600, .full_stroke_ms = 32, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 8 },
{ .name = "[ATA-1] IBM H3342-A4", .internal_name = "H3342A4", .model = "IBM-H3342-A4", .zones = 1, .avg_spt = 140, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 8 },
{ .name = "[ATA-1] Kalok KL343", .internal_name = "KL343", .model = "KALOK KL-343", .zones = 1, .avg_spt = 280, .heads = 6, .rpm = 3600, .full_stroke_ms = 50, .track_seek_ms = 2, .rcache_num_seg = 1, .rcache_seg_size = 8, .max_multiple = 8 },
{ .name = "[ATA-1] Kalok KL3100", .internal_name = "KL3100", .model = "KALOK KL-3100", .zones = 1, .avg_spt = 200, .heads = 6, .rpm = 3662, .full_stroke_ms = 50, .track_seek_ms = 2, .rcache_num_seg = 1, .rcache_seg_size = 32, .max_multiple = 8 },
{ .name = "[ATA-1] Maxtor 7060AT", .internal_name = "7060AT", .model = "Maxtor 7060AT", .zones = 1, .avg_spt = 162, .heads = 2, .rpm = 3524, .full_stroke_ms = 30, .track_seek_ms = 3.6, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 },
{ .name = "[ATA-1] Maxtor 7131AT", .internal_name = "7131AT", .model = "Maxtor 7131AT", .zones = 2, .avg_spt = 154, .heads = 2, .rpm = 3551, .full_stroke_ms = 27, .track_seek_ms = 4.5, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 },
{ .name = "[ATA-1] Maxtor 7213AT", .internal_name = "7213AT", .model = "Maxtor 7213AT", .zones = 4, .avg_spt = 155, .heads = 4, .rpm = 3551, .full_stroke_ms = 28, .track_seek_ms = 6.5, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 },
{ .name = "[ATA-1] Maxtor 7245AT", .internal_name = "7245AT", .model = "Maxtor 7245AT", .zones = 4, .avg_spt = 149, .heads = 4, .rpm = 3551, .full_stroke_ms = 27, .track_seek_ms = 4.4, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 8 },
{ .name = "[ATA-1] Quantum ProDrive LPS 105", .internal_name = "LPS105AT", .model = "QUANTUM PRODRIVE 105", .zones = 1, .avg_spt = 170, .heads = 2, .rpm = 3662, .full_stroke_ms = 45, .track_seek_ms = 5, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 },
{ .name = "[ATA-1] Quantum ProDrive LPS 120AT", .internal_name = "GM12A012", .model = "QUANTUM PRODRIVE 120AT", .zones = 1, .avg_spt = 150, .heads = 2, .rpm = 3605, .full_stroke_ms = 45, .track_seek_ms = 4, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 },
{ .name = "[ATA-1] Seagate ST3243A", .internal_name = "ST3243A", .model = "ST3243A", .zones = 1, .avg_spt = 140, .heads = 4, .rpm = 3811, .full_stroke_ms = 32, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 8 },
{ .name = "[ATA-1] Western Digital Caviar 140", .internal_name = "WDAC140", .model = "WDC WDAC140-50", .zones = 4, .avg_spt = 170, .heads = 2, .rpm = 3551, .full_stroke_ms = 28, .track_seek_ms = 6, .rcache_num_seg = 8, .rcache_seg_size = 8, .max_multiple = 8 },
{ .name = "[ATA-1] Western Digital Caviar 280", .internal_name = "WDAC280", .model = "WDC WDAC280-00", .zones = 4, .avg_spt = 170, .heads = 4, .rpm = 3595, .full_stroke_ms = 28, .track_seek_ms = 6, .rcache_num_seg = 8, .rcache_seg_size = 32, .max_multiple = 8 },
{ .name = "[ATA-1] Western Digital Caviar 1210", .internal_name = "WDAC1210", .model = "WDC WDAC1210-21F", .zones = 4, .avg_spt = 130, .heads = 2, .rpm = 3314, .full_stroke_ms = 33, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 },
{ .name = "[ATA-1] Western Digital Caviar 2120", .internal_name = "WDAC2120", .model = "WDC WDAC2120-00M", .zones = 4, .avg_spt = 140, .heads = 2, .rpm = 3605, .full_stroke_ms = 28, .track_seek_ms = 2.8, .rcache_num_seg = 8, .rcache_seg_size = 32, .max_multiple = 8 },
{ .name = "[ATA-2] IBM DBOA-2720", .internal_name = "DBOA2720", .model = "IBM-DBOA-2720", .zones = 2, .avg_spt = 135, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 8 },
{ .name = "[ATA-2] IBM DeskStar 4 (DCAA-32880)", .internal_name = "DCAA32880", .model = "IBM-DCAA-32880", .zones = 8, .avg_spt = 85, .heads = 2, .rpm = 5400, .full_stroke_ms = 19, .track_seek_ms = 1.7, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 16 },
{ .name = "[ATA-2] IBM DeskStar 4 (DCAA-33610)", .internal_name = "DCAA33610", .model = "IBM-DCAA-33610", .zones = 8, .avg_spt = 85, .heads = 3, .rpm = 5400, .full_stroke_ms = 19, .track_seek_ms = 1.7, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 16 },
{ .name = "[ATA-2] IBM DeskStar 4 (DCAA-34330)", .internal_name = "DCAA34330", .model = "IBM-DCAA-34330", .zones = 8, .avg_spt = 85, .heads = 3, .rpm = 5400, .full_stroke_ms = 19, .track_seek_ms = 1.7, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 16 },
{ .name = "[ATA-2] Maxtor 7540AV", .internal_name = "7540AV", .model = "Maxtor 7540AV", .zones = 2, .avg_spt = 120, .heads = 4, .rpm = 3551, .full_stroke_ms = 31, .track_seek_ms = 4.3, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 8 },
{ .name = "[ATA-2] Maxtor 7546AT", .internal_name = "7546AT", .model = "Maxtor 7546AT", .zones = 2, .avg_spt = 100, .heads = 4, .rpm = 4500, .full_stroke_ms = 28, .track_seek_ms = 2.3, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 },
{ .name = "[ATA-2] Maxtor 7850AV", .internal_name = "7850AV", .model = "Maxtor 7850AV", .zones = 4, .avg_spt = 120, .heads = 4, .rpm = 3551, .full_stroke_ms = 31, .track_seek_ms = 3.7, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 8 },
{ .name = "[ATA-2] Maxtor 71336AP", .internal_name = "71336AP", .model = "Maxtor 71336AP", .zones = 4, .avg_spt = 105, .heads = 4, .rpm = 4480, .full_stroke_ms = 12, .track_seek_ms = 3.4, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-2] Quantum Bigfoot 1.2AT", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT BF1.2A", .zones = 2, .avg_spt = 155, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-2] Quantum Bigfoot (CY4320A)", .internal_name = "CY4320A", .model = "QUANTUM BIGFOOT_CY4320A", .zones = 2, .avg_spt = 130, .heads = 2, .rpm = 4000, .full_stroke_ms = 29, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, // from Hardcore Windows NT Final Segment by Kugee
{ .name = "[ATA-2] Quantum Fireball 640AT", .internal_name = "FB64A341", .model = "QUANTUM FIREBALL 640AT", .zones = 2, .avg_spt = 120, .heads = 2, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3.1, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 },
{ .name = "[ATA-2] Quantum Fireball TM1080AT", .internal_name = "TM10A462", .model = "QUANTUM FIREBALL TM1.0A", .zones = 2, .avg_spt = 120, .heads = 2, .rpm = 4500, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 },
{ .name = "[ATA-2] Quantum Fireball TM1.2AT", .internal_name = "TM12A012", .model = "QUANTUM FIREBALL TM1.2A", .zones = 4, .avg_spt = 120, .heads = 2, .rpm = 4500, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 },
{ .name = "[ATA-2] Quantum Fireball ST3.2AT", .internal_name = "ST32A461", .model = "QUANTUM FIREBALL ST3.2A", .zones = 4, .avg_spt = 100, .heads = 4, .rpm = 5400, .full_stroke_ms = 21, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-2] Quantum Fireball CR4.3AT", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 110, .heads = 2, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 },
{ .name = "[ATA-2] Quantum Fireball EX5.1AT", .internal_name = "EX51A012", .model = "QUANTUM FIREBALL EX5.1A", .zones = 8, .avg_spt = 110, .heads = 4, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 },
{ .name = "[ATA-2] Samsung PLS-31274A", .internal_name = "PLS31274A", .model = "SAMSUNG PLS-31274A", .zones = 4, .avg_spt = 110, .heads = 4, .rpm = 4500, .full_stroke_ms = 45, .track_seek_ms = 4.5, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 },
{ .name = "[ATA-2] Samsung Winner-1", .internal_name = "WNR31601A", .model = "SAMSUNG WNR-31601A", .zones = 8, .avg_spt = 110, .heads = 4, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-2] Seagate Medalist (ST3780A)", .internal_name = "ST3780A", .model = "ST3780A", .zones = 8, .avg_spt = 120, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 16 },
{ .name = "[ATA-2] Seagate Medalist (ST31220A)", .internal_name = "ST31220A", .model = "ST31220A", .zones = 8, .avg_spt = 140, .heads = 6, .rpm = 4500, .full_stroke_ms = 27, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 16 },
{ .name = "[ATA-2] Seagate Medalist 210xe", .internal_name = "ST3250A", .model = "ST3250A", .zones = 4, .avg_spt = 148, .heads = 2, .rpm = 3811, .full_stroke_ms = 30, .track_seek_ms = 4.1, .rcache_num_seg = 8, .rcache_seg_size = 120, .max_multiple = 8 },
{ .name = "[ATA-2] Seagate Medalist 275xe", .internal_name = "ST3295A", .model = "ST3295A", .zones = 4, .avg_spt = 130, .heads = 2, .rpm = 3811, .full_stroke_ms = 30, .track_seek_ms = 3.4, .rcache_num_seg = 3, .rcache_seg_size = 120, .max_multiple = 8 },
{ .name = "[ATA-2] Seagate Medalist 545xe", .internal_name = "ST3660A", .model = "ST3660A", .zones = 4, .avg_spt = 130, .heads = 4, .rpm = 3811, .full_stroke_ms = 34, .track_seek_ms = 3.4, .rcache_num_seg = 8, .rcache_seg_size = 120, .max_multiple = 8 },
{ .name = "[ATA-2] Seagate Medalist 640xe", .internal_name = "ST3630A", .model = "ST3630A", .zones = 4, .avg_spt = 130, .heads = 4, .rpm = 3811, .full_stroke_ms = 34, .track_seek_ms = 3.5, .rcache_num_seg = 8, .rcache_seg_size = 120, .max_multiple = 8 },
{ .name = "[ATA-2] Seagate Medalist 850xe", .internal_name = "ST3850A", .model = "ST3850A", .zones = 8, .avg_spt = 150, .heads = 4, .rpm = 3811, .full_stroke_ms = 34, .track_seek_ms = 3.8, .rcache_num_seg = 8, .rcache_seg_size = 120, .max_multiple = 8 },
{ .name = "[ATA-2] Seagate Medalist 1270SL", .internal_name = "ST51270A", .model = "ST51270A", .zones = 8, .avg_spt = 105, .heads = 3, .rpm = 5736, .full_stroke_ms = 25, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-2] Seagate Medalist 3240", .internal_name = "ST33240A", .model = "ST33240A", .zones = 16, .avg_spt = 125, .heads = 8, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-2] Toshiba MK2101MAN (HDD2616)", .internal_name = "HDD2616", .model = "TOSHIBA MK2101MAN", .zones = 8, .avg_spt = 130, .heads = 10, .rpm = 4200, .full_stroke_ms = 36, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-2] Western Digital Caviar 2540", .internal_name = "WDAC2540", .model = "WDC WDAC2540-00H", .zones = 4, .avg_spt = 250, .heads = 2, .rpm = 4500, .full_stroke_ms = 12, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 },
{ .name = "[ATA-2] Western Digital Caviar 2850", .internal_name = "WDAC2850", .model = "WDC WDAC2850-00F", .zones = 4, .avg_spt = 230, .heads = 2, .rpm = 5200, .full_stroke_ms = 12, .track_seek_ms = 4, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 },
{ .name = "[ATA-2] Western Digital Caviar 11000", .internal_name = "WDAC11000", .model = "WDC WDAC11000-00H", .zones = 4, .avg_spt = 120, .heads = 2, .rpm = 5200, .full_stroke_ms = 12, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 },
{ .name = "[ATA-2] Western Digital Caviar 21200", .internal_name = "WDAC21200", .model = "WDC WDAC21200-00H", .zones = 4, .avg_spt = 110, .heads = 4, .rpm = 5200, .full_stroke_ms = 39, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 },
{ .name = "[ATA-2] Western Digital Caviar 21600", .internal_name = "WDAC21600", .model = "WDC WDAC21600-00H", .zones = 8, .avg_spt = 140, .heads = 4, .rpm = 5200, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 },
{ .name = "[ATA-2] Western Digital Caviar 22000", .internal_name = "AC22000", .model = "WDC AC22000-32LA", .zones = 8, .avg_spt = 130, .heads = 3, .rpm = 5200, .full_stroke_ms = 33, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 },
{ .name = "[ATA-2] Western Digital Caviar 22100", .internal_name = "WDAC22100", .model = "WDC WDAC22100-18H", .zones = 8, .avg_spt = 140, .heads = 4, .rpm = 5200, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-2] Western Digital Caviar 31200", .internal_name = "WDAC31200", .model = "WDC WDAC31200-00F", .zones = 8, .avg_spt = 110, .heads = 4, .rpm = 4500, .full_stroke_ms = 12, .track_seek_ms = 4, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 16 },
{ .name = "[ATA-3] Fujitsu MPA3017AT", .internal_name = "MPA3017AT", .model = "FUJITSU MPA3017AT", .zones = 5, .avg_spt = 95, .heads = 2, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-3] Fujitsu MPA3026AT", .internal_name = "MPA3026AT", .model = "FUJITSU MPA3026AT", .zones = 8, .avg_spt = 95, .heads = 3, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-3] Fujitsu MPA3035AT", .internal_name = "MPA3035AT", .model = "FUJITSU MPA3035AT", .zones = 11, .avg_spt = 95, .heads = 4, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-3] Fujitsu MPA3043AT", .internal_name = "MPA3043AT", .model = "FUJITSU MPA3043AT", .zones = 15, .avg_spt = 95, .heads = 5, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-3] Fujitsu MPA3052AT", .internal_name = "MPA3052AT", .model = "FUJITSU MPA3052AT", .zones = 16, .avg_spt = 95, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-3] Samsung Voyager 6", .internal_name = "SV0844A", .model = "SAMSUNG SV0844A", .zones = 8, .avg_spt = 105, .heads = 4, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-3] Samsung Winner 5X", .internal_name = "WU33205A", .model = "SAMSUNG WU33205A", .zones = 16, .avg_spt = 100, .heads = 4, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-3] Seagate Medalist 1720", .internal_name = "ST31720A", .model = "ST31720A", .zones = 4, .avg_spt = 120, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 2, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-3] Seagate Medalist 2132", .internal_name = "ST32132A", .model = "ST32132A", .zones = 8, .avg_spt = 125, .heads = 6, .rpm = 4500, .full_stroke_ms = 30, .track_seek_ms = 2.3, .rcache_num_seg = 8, .rcache_seg_size = 120, .max_multiple = 16 },
{ .name = "[ATA-3] Western Digital Caviar 21700", .internal_name = "WDAC21700", .model = "WDC WDAC21700-40H", .zones = 8, .avg_spt = 85, .heads = 3, .rpm = 5200, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, // Apple Computer OEM only, not retail version
{ .name = "[ATA-4] Fujitsu MPB3021AT", .internal_name = "MPB3021AT", .model = "FUJITSU MPB3021AT", .zones = 7, .avg_spt = 100, .heads = 3, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 16 },
{ .name = "[ATA-4] Fujitsu MPD3043AT", .internal_name = "MPD3043AT", .model = "FUJITSU MPD3043AT", .zones = 5, .avg_spt = 95, .heads = 2, .rpm = 5400, .full_stroke_ms = 29, .track_seek_ms = 1.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 },
{ .name = "[ATA-4] Fujitsu MPD3064AT", .internal_name = "MPD3064AT", .model = "FUJITSU MPD3064AT", .zones = 7, .avg_spt = 95, .heads = 3, .rpm = 5400, .full_stroke_ms = 30, .track_seek_ms = 1.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 },
{ .name = "[ATA-4] Fujitsu MPD3084AT", .internal_name = "MPD3084AT", .model = "FUJITSU MPD3084AT", .zones = 7, .avg_spt = 95, .heads = 4, .rpm = 5400, .full_stroke_ms = 19, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 16 },
{ .name = "[ATA-4] Fujitsu MPE3064AT", .internal_name = "MPE3064AT", .model = "FUJITSU MPE3064AT", .zones = 7, .avg_spt = 95, .heads = 2, .rpm = 5400, .full_stroke_ms = 30, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-4] Maxtor DiamondMax 2160", .internal_name = "86480D6", .model = "Maxtor 86480D6", .zones = 8, .avg_spt = 97, .heads = 4, .rpm = 5200, .full_stroke_ms = 18, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-4] Maxtor DiamondMax 2880", .internal_name = "90432D3", .model = "Maxtor 90432D3", .zones = 16, .avg_spt = 90, .heads = 3, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 32 },
{ .name = "[ATA-4] Maxtor DiamondMax 3400", .internal_name = "90644D3", .model = "Maxtor 90644D3", .zones = 16, .avg_spt = 90, .heads = 3, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 0.9, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 32 },
{ .name = "[ATA-4] Maxtor DiamondMax 4320 (90432D2)", .internal_name = "90432D2", .model = "Maxtor 90432D2", .zones = 16, .avg_spt = 90, .heads = 2, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 0.9, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
{ .name = "[ATA-4] Maxtor DiamondMax 4320 (90845D4)", .internal_name = "90845D4", .model = "Maxtor 90845D4", .zones = 16, .avg_spt = 90, .heads = 3, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 0.9, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
{ .name = "[ATA-4] Maxtor DiamondMax Plus 6800 (90683U2)", .internal_name = "90683U2", .model = "Maxtor 90683U2", .zones = 16, .avg_spt = 90, .heads = 2, .rpm = 7200, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
{ .name = "[ATA-4] Maxtor DiamondMax Plus 6800 (91024U3)", .internal_name = "91024U3", .model = "Maxtor 91024U3", .zones = 16, .avg_spt = 90, .heads = 3, .rpm = 7200, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
{ .name = "[ATA-4] Maxtor DiamondMax Plus 6800 (91366U4)", .internal_name = "91366U4", .model = "Maxtor 91366U4", .zones = 16, .avg_spt = 90, .heads = 4, .rpm = 7200, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
{ .name = "[ATA-4] Maxtor DiamondMax Plus 6800 (92049U6)", .internal_name = "92049U6", .model = "Maxtor 92049U6", .zones = 16, .avg_spt = 90, .heads = 6, .rpm = 7200, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
{ .name = "[ATA-4] Maxtor DiamondMax Plus 6800 (92732U8)", .internal_name = "92732U8", .model = "Maxtor 92732U8", .zones = 16, .avg_spt = 90, .heads = 8, .rpm = 7200, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
{ .name = "[ATA-4] Quantum Bigfoot TX4.3AT", .internal_name = "TX043A011", .model = "QUANTUM BIGFOOT TX4.3A", .zones = 2, .avg_spt = 120, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 },
{ .name = "[ATA-4] Seagate Medalist 2122", .internal_name = "ST32122A", .model = "ST32122A", .zones = 16, .avg_spt = 115, .heads = 2, .rpm = 4500, .full_stroke_ms = 23, .track_seek_ms = 3.8, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-4] Seagate Medalist 3321", .internal_name = "ST33221A", .model = "ST33221A", .zones = 16, .avg_spt = 110, .heads = 4, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 1.7, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-4] Seagate Medalist 4321", .internal_name = "ST34321A", .model = "ST34321A", .zones = 16, .avg_spt = 110, .heads = 4, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-4] Seagate Medalist 6531", .internal_name = "ST36531A", .model = "ST36531A", .zones = 16, .avg_spt = 115, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 1.7, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 16 },
{ .name = "[ATA-4] Seagate Medalist 8420", .internal_name = "ST38420A", .model = "ST38420A", .zones = 16, .avg_spt = 90, .heads = 2, .rpm = 5400, .full_stroke_ms = 16, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-4] Toshiba MK4006MAV", .internal_name = "MK4006MAV", .model = "TOSHIBA MK4006MAV", .zones = 8, .avg_spt = 130, .heads = 6, .rpm = 4200, .full_stroke_ms = 25, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-4] Western Digital Caviar 14300", .internal_name = "AC14300", .model = "WDC AC14300-00RT", .zones = 16, .avg_spt = 95, .heads = 2, .rpm = 5400, .full_stroke_ms = 21, .track_seek_ms = 5.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 },
{ .name = "[ATA-4] Western Digital Caviar 23200", .internal_name = "AC23200", .model = "WDC AC23200-00LB", .zones = 16, .avg_spt = 110, .heads = 4, .rpm = 5400, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 32 },
{ .name = "[ATA-4] Western Digital Caviar 26400", .internal_name = "AC26400", .model = "WDC AC26400-00RN", .zones = 16, .avg_spt = 95, .heads = 5, .rpm = 5400, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-4] Western Digital Caviar 33200", .internal_name = "AC33200", .model = "WDC AC33200-00LA", .zones = 16, .avg_spt = 110, .heads = 5, .rpm = 5200, .full_stroke_ms = 40, .track_seek_ms = 3, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
{ .name = "[ATA-5] IBM Travelstar 6GN", .internal_name = "DARA206000", .model = "IBM-DARA-206000", .zones = 12, .avg_spt = 92, .heads = 2, .rpm = 4200, .full_stroke_ms = 31, .track_seek_ms = 4, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-5] IBM Travelstar 9GN", .internal_name = "DARA209000", .model = "IBM-DARA-209000", .zones = 12, .avg_spt = 92, .heads = 3, .rpm = 4200, .full_stroke_ms = 31, .track_seek_ms = 4, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-5] IBM/Hitachi Travelstar 12GN", .internal_name = "DARA212000", .model = "IBM-DARA-212000", .zones = 12, .avg_spt = 92, .heads = 4, .rpm = 4200, .full_stroke_ms = 31, .track_seek_ms = 4, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, // Either Hitachi or IBM OEM
{ .name = "[ATA-5] Maxtor DiamondMax VL 17", .internal_name = "90871U2", .model = "Maxtor 90871U2", .zones = 16, .avg_spt = 90, .heads = 3, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 0.9, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 },
{ .name = "[ATA-5] Maxtor DiamondMax VL 20", .internal_name = "91021U2", .model = "Maxtor 91021U2", .zones = 16, .avg_spt = 95, .heads = 2, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-5] Samsung SpinPoint V6800 (SV0682D)", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 8, .avg_spt = 95, .heads = 2, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1.3, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-5] Samsung SpinPoint V6800 (SV1023D)", .internal_name = "SV1023D", .model = "SAMSUNG SV1023D", .zones = 8, .avg_spt = 95, .heads = 3, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1.3, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-5] Seagate U8 - 4.3gb", .internal_name = "ST34313A", .model = "ST34313A", .zones = 16, .avg_spt = 89, .heads = 1, .rpm = 5400, .full_stroke_ms = 25, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-5] Seagate U8 - 8.4gb", .internal_name = "ST38410A", .model = "ST38410A", .zones = 16, .avg_spt = 89, .heads = 2, .rpm = 5400, .full_stroke_ms = 25, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-5] Western Digital Caviar 102AA", .internal_name = "WD102AA", .model = "WDC WD102AA-00ANA0", .zones = 16, .avg_spt = 95, .heads = 8, .rpm = 5400, .full_stroke_ms = 12, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 },
{ .name = "[ATA-5] Western Digital Expert", .internal_name = "WD135BA", .model = "WDC WD135BA-60AK", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 1920, .max_multiple = 32 },
// clang-format on
};
int

View File

@@ -665,6 +665,19 @@ dma_ps2_read(uint16_t addr, UNUSED(void *priv))
temp = dma_c->arb_level;
break;
case 9: /*Set DMA mask*/
dma_m |= (1 << dma_ps2.xfr_channel);
break;
case 0xa: /*Reset DMA mask*/
dma_m &= ~(1 << dma_ps2.xfr_channel);
break;
case 0xb:
if (!(dma_m & (1 << dma_ps2.xfr_channel)))
dma_ps2_run(dma_ps2.xfr_channel);
break;
default:
fatal("Bad XFR Read command %i channel %i\n", dma_ps2.xfr_command, dma_ps2.xfr_channel);
}
@@ -767,6 +780,19 @@ dma_ps2_write(uint16_t addr, uint8_t val, UNUSED(void *priv))
dma_c->arb_level = val;
break;
case 9: /*Set DMA mask*/
dma_m |= (1 << dma_ps2.xfr_channel);
break;
case 0xa: /*Reset DMA mask*/
dma_m &= ~(1 << dma_ps2.xfr_channel);
break;
case 0xb:
if (!(dma_m & (1 << dma_ps2.xfr_channel)))
dma_ps2_run(dma_ps2.xfr_channel);
break;
default:
fatal("Bad XFR command %i channel %i val %02x\n", dma_ps2.xfr_command, dma_ps2.xfr_channel, val);
}

View File

@@ -294,7 +294,7 @@ fdd_type_invert_densel(int type)
int ret;
if (drive_types[type].flags & FLAG_PS2)
ret = !!strstr(machine_getname(), "PS/");
ret = (!!strstr(machine_getname(), "PS/1")) || (!!strstr(machine_getname(), "PS/2"));
else
ret = drive_types[type].flags & FLAG_INVERT_DENSEL;

View File

@@ -1075,9 +1075,14 @@ jump_if_fdf:
dev->sectors = 19;
dev->tracks = 80;
} else if (size <= 1638400) { /*HD 1024 sector*/
#ifdef SYNTH_FORMAT
dev->sectors = 10;
dev->tracks = 80;
dev->sector_size = 3;
#else
/* Prefer 20 512-byte sectors per track, used by the OpenStep 4.0 Pre-Release 1 boot disk. */
dev->sectors = 20;
#endif
dev->tracks = 80;
} else if (size <= 1720320) { /*DMF (Windows 95) */
dev->sectors = 21;
dev->tracks = 80;
@@ -1088,9 +1093,14 @@ jump_if_fdf:
dev->sectors = 21;
dev->tracks = 82;
} else if (size <= 1802240) { /*HD 1024 sector*/
dev->sectors = 22;
dev->tracks = 80;
#ifdef SYNTH_FORMAT
dev->sectors = 11;
dev->sector_size = 3;
#else
/* Prefer 22 512-byte sectors per track. */
dev->sectors = 22;
#endif
dev->tracks = 80;
} else if (size == 1884160) { /*XDF (OS/2 Warp)*/
dev->sectors = 23;
dev->tracks = 80;
@@ -1110,12 +1120,12 @@ jump_if_fdf:
dev->sectors = 42;
dev->tracks = 80;
#if 0
} else if (size <= 3440640) { /*HD 1024 sector*/
} else if (size <= 3440640) { /*ED 1024 sector*/
dev->sectors = 21;
dev->tracks = 80;
dev->sector_size = 3;
#endif
} else if (size <= 3604480) { /*HD 1024 sector*/
} else if (size <= 3604480) { /*ED 1024 sector*/
dev->sectors = 22;
dev->tracks = 80;
dev->sector_size = 3;

View File

@@ -674,6 +674,20 @@ const device_t gameport_pnp_device = {
.config = NULL
};
const device_t gameport_pnp_1io_device = {
.name = "Game port (Plug and Play only, 1 I/O port)",
.internal_name = "gameport_pnp_1io",
.flags = 0,
.local = GAMEPORT_1ADDR,
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t gameport_pnp_6io_device = {
.name = "Game port (Plug and Play only, 6 I/O ports)",
.internal_name = "gameport_pnp_6io",

View File

@@ -165,6 +165,7 @@ extern _Atomic double mouse_y_error; /* Mouse error accumulator - Y */
#endif
extern int pit_mode; /* (C) force setting PIT mode */
extern int fm_driver; /* (C) select FM sound driver */
extern int hook_enabled; /* (C) Keyboard hook is enabled */
/* Keyboard variables for future key combination redefinition. */
extern uint16_t key_prefix_1_1;

View File

@@ -28,6 +28,7 @@
#define CD_STATUS_TRANSITION 0x40
#define CD_STATUS_MEDIUM_CHANGED 0x80
#define CD_TRACK_UNK_DATA 0x10
#define CD_TRACK_AUDIO 0x08
#define CD_TRACK_MODE2 0x04
@@ -85,6 +86,7 @@ enum
CDROM_TYPE_TOSHIBA_5302TA_0305,
CDROM_TYPE_TOSHIBA_5702B_TA70,
CDROM_TYPE_CHINON_CDS431_H42,
CDROM_TYPE_CHINON_CDX435_M62,
CDROM_TYPE_DEC_RRD45_0436,
CDROM_TYPE_MATSHITA_501_10b,
CDROM_TYPE_NEC_25_10a,
@@ -93,6 +95,7 @@ enum
CDROM_TYPE_NEC_77_106,
CDROM_TYPE_NEC_211_100,
CDROM_TYPE_NEC_464_105,
CDROM_TYPE_ShinaKen_DM3x1S_104,
CDROM_TYPE_SONY_CDU541_10i,
CDROM_TYPE_SONY_CDU561_18k,
CDROM_TYPE_SONY_CDU76S_100,
@@ -101,7 +104,8 @@ enum
CDROM_TYPE_PLEXTOR_PX32TS_103,
CDROM_TYPE_TEAC_CD50_100,
CDROM_TYPE_TEAC_R55S_10R,
CDROM_TYPE_TEXEL_DMXX24_100,
CDROM_TYPE_TEXEL_DM3024_100,
CDROM_TYPE_TEXEL_DM3028_106,
CDROM_TYPE_TOSHIBA_XM_3433,
CDROM_TYPE_TOSHIBA_XM3201B_3232,
CDROM_TYPE_TOSHIBA_XM3301TA_0272,
@@ -146,30 +150,33 @@ static const struct
{ "SONY", "CD-ROM CDU311", "3.0h", "SONY CD-ROM CDU311 3.0h", "SONY_CD-ROM_CDU311_3.0h", BUS_TYPE_IDE },
{ "TOSHIBA", "CD-ROM XM-5302TA", "0305", "TOSHIBA CD-ROM XM-5302TA 0305", "TOSHIBA_CD-ROM_XM-5302TA_0305", BUS_TYPE_IDE },
{ "TOSHIBA", "CD-ROM XM-5702B", "TA70", "TOSHIBA CD-ROM XM-5702B TA70", "TOSHIBA_CD-ROM_XM-5702B_TA70", BUS_TYPE_IDE },
{ "CHINON", "CD-ROM CDS-431", "H42 ", "CHINON CD-ROM CDS-431 H42", "CHINON_CD-ROM_CDS-431_H42", BUS_TYPE_SCSI },
{ "DEC", "RRD45 (C) DEC", "0436", "DEC RRD45 0436", "DEC_RRD45_0436", BUS_TYPE_SCSI },
{ "MATSHITA", "CD-ROM CR-501", "1.0b", "MATSHITA CD-ROM CR-501 1.0b", "MATSHITA_CD-ROM_CR-501_1.0b", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:25", "1.0a", "NEC CD-ROM DRIVE:25 1.0a", "NEC_CD-ROM_DRIVE25_1.0a", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:38", "1.00", "NEC CD-ROM DRIVE:38 1.00", "NEC_CD-ROM_DRIVE38_1.00", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:75", "1.03", "NEC CD-ROM DRIVE:75 1.03", "NEC_CD-ROM_DRIVE75_1.03", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:77", "1.06", "NEC CD-ROM DRIVE:77 1.06", "NEC_CD-ROM_DRIVE77_1.06", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:211", "1.00", "NEC CD-ROM DRIVE:211 1.00", "NEC_CD-ROM_DRIVE211_1.00", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:464", "1.05", "NEC CD-ROM DRIVE:464 1.05", "NEC_CD-ROM_DRIVE464_1.05", BUS_TYPE_SCSI },
{ "SONY", "CD-ROM CDU-541", "1.0i", "SONY CD-ROM CDU-541 1.0i", "SONY_CD-ROM_CDU-541_1.0i", BUS_TYPE_SCSI },
{ "SONY", "CD-ROM CDU-561", "1.8k", "SONY CD-ROM CDU-561 1.8k", "SONY_CD-ROM_CDU-561_1.8k", BUS_TYPE_SCSI },
{ "SONY", "CD-ROM CDU-76S", "1.00", "SONY CD-ROM CDU-76S 1.00", "SONY_CD-ROM_CDU-76S_1.00", BUS_TYPE_SCSI },
{ "PHILIPS", "CDD2600", "1.07", "PHILIPS CDD2600 1.07", "PHILIPS_CDD2600_1.07", BUS_TYPE_SCSI },
{ "PIONEER", "CD-ROM DRM-604X", "2403", "PIONEER CD-ROM DRM-604X 2403", "PIONEER_CD-ROM_DRM-604X_2403", BUS_TYPE_SCSI },
{ "PLEXTOR", "CD-ROM PX-32TS", "1.03", "PLEXTOR CD-ROM PX-32TS 1.03", "PLEXTOR_CD-ROM_PX-32TS_1.03", BUS_TYPE_SCSI },
{ "TEAC", "CD 50", "1.00", "TEAC CD 50 1.00", "TEAC_CD_50_1.00", BUS_TYPE_SCSI },
{ "TEAC", "CD-ROM R55S", "1.0R", "TEAC CD-ROM R55S 1.0R", "TEAC_CD-ROM_R55S_1.0R", BUS_TYPE_SCSI },
{ "TEXEL", "CD-ROM DM-XX24", "1.00", "TEXEL CD-ROM DM-XX24 1.00", "TEXEL_CD-ROM_DM-XX24_1.00", BUS_TYPE_SCSI },
{ "TOSHIBA", "CD-ROM DRIVE:XM", "3433", "TOSHIBA CD-ROM DRIVE:XM 3433", "TOSHIBA_CD-ROM_DRIVEXM_3433", BUS_TYPE_SCSI },
{ "TOSHIBA", "CD-ROM XM-3201B", "3232", "TOSHIBA CD-ROM XM-3201B 3232", "TOSHIBA_CD-ROM_XM-3201B_3232", BUS_TYPE_SCSI },
{ "TOSHIBA", "CD-ROM XM-3301TA", "0272", "TOSHIBA CD-ROM XM-3301TA 0272", "TOSHIBA_CD-ROM_XM-3301TA_0272", BUS_TYPE_SCSI },
{ "TOSHIBA", "CD-ROM XM-5701TA", "3136", "TOSHIBA CD-ROM XM-5701TA 3136", "TOSHIBA_CD-ROM_XM-5701TA_3136", BUS_TYPE_SCSI },
{ "TOSHIBA", "DVD-ROM SD-M1401", "1008", "TOSHIBA DVD-ROM SD-M1401 1008", "TOSHIBA_DVD-ROM_SD-M1401_1008", BUS_TYPE_SCSI },
{ "", "", "", "", "", BUS_TYPE_NONE },
{ "CHINON", "CD-ROM CDS-431", "H42 ", "[SCSI-1] CHINON CD-ROM CDS-431 H42", "CHINON_CD-ROM_CDS-431_H42", BUS_TYPE_SCSI },
{ "CHINON", "CD-ROM CDX-435", "M62 ", "[SCSI-1] CHINON CD-ROM CDX-435 M62", "CHINON_CD-ROM_CDX-435_M62", BUS_TYPE_SCSI },
{ "DEC", "RRD45 (C) DEC", "0436", "[SCSI-1] DEC RRD45 0436", "DEC_RRD45_0436", BUS_TYPE_SCSI },
{ "MATSHITA", "CD-ROM CR-501", "1.0b", "[SCSI-1] MATSHITA CD-ROM CR-501 1.0b", "MATSHITA_CD-ROM_CR-501_1.0b", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:25", "1.0a", "[SCSI-1] NEC CD-ROM DRIVE:25 1.0a", "NEC_CD-ROM_DRIVE25_1.0a", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:38", "1.00", "[SCSI-2] NEC CD-ROM DRIVE:38 1.00", "NEC_CD-ROM_DRIVE38_1.00", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:75", "1.03", "[SCSI-1] NEC CD-ROM DRIVE:75 1.03", "NEC_CD-ROM_DRIVE75_1.03", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:77", "1.06", "[SCSI-1] NEC CD-ROM DRIVE:77 1.06", "NEC_CD-ROM_DRIVE77_1.06", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:211", "1.00", "[SCSI-2] NEC CD-ROM DRIVE:211 1.00", "NEC_CD-ROM_DRIVE211_1.00", BUS_TYPE_SCSI },
{ "NEC", "CD-ROM DRIVE:464", "1.05", "[SCSI-2] NEC CD-ROM DRIVE:464 1.05", "NEC_CD-ROM_DRIVE464_1.05", BUS_TYPE_SCSI },
{ "ShinaKen", "CD-ROM DM-3x1S", "1.04", "[SCSI-1] ShinaKen CD-ROM DM-3x1S 1.04", "ShinaKen_CD-ROM_DM-3x1S_1.04", BUS_TYPE_SCSI },
{ "SONY", "CD-ROM CDU-541", "1.0i", "[SCSI-1] SONY CD-ROM CDU-541 1.0i", "SONY_CD-ROM_CDU-541_1.0i", BUS_TYPE_SCSI },
{ "SONY", "CD-ROM CDU-561", "1.8k", "[SCSI-2] SONY CD-ROM CDU-561 1.8k", "SONY_CD-ROM_CDU-561_1.8k", BUS_TYPE_SCSI },
{ "SONY", "CD-ROM CDU-76S", "1.00", "[SCSI-2] SONY CD-ROM CDU-76S 1.00", "SONY_CD-ROM_CDU-76S_1.00", BUS_TYPE_SCSI },
{ "PHILIPS", "CDD2600", "1.07", "[SCSI-2] PHILIPS CDD2600 1.07", "PHILIPS_CDD2600_1.07", BUS_TYPE_SCSI },
{ "PIONEER", "CD-ROM DRM-604X", "2403", "[SCSI-2] PIONEER CD-ROM DRM-604X 2403", "PIONEER_CD-ROM_DRM-604X_2403", BUS_TYPE_SCSI },
{ "PLEXTOR", "CD-ROM PX-32TS", "1.03", "[SCSI-2] PLEXTOR CD-ROM PX-32TS 1.03", "PLEXTOR_CD-ROM_PX-32TS_1.03", BUS_TYPE_SCSI },
{ "TEAC", "CD 50", "1.00", "[SCSI-2] TEAC CD 50 1.00", "TEAC_CD_50_1.00", BUS_TYPE_SCSI },
{ "TEAC", "CD-ROM R55S", "1.0R", "[SCSI-2] TEAC CD-ROM R55S 1.0R", "TEAC_CD-ROM_R55S_1.0R", BUS_TYPE_SCSI },
{ "TEXEL", "CD-ROM DM-3024", "1.00", "[SCSI-1] TEXEL CD-ROM DM-3024 1.00", "TEXEL_CD-ROM_DM-3024_1.00", BUS_TYPE_SCSI },
{ "TEXEL", "CD-ROM DM-3028", "1.06", "[SCSI-2] TEXEL CD-ROM DM-3028 1.06", "TEXEL_CD-ROM_DM-3028_1.06", BUS_TYPE_SCSI },
{ "TOSHIBA", "CD-ROM DRIVE:XM", "3433", "[SCSI-2] TOSHIBA CD-ROM DRIVE:XM 3433", "TOSHIBA_CD-ROM_DRIVEXM_3433", BUS_TYPE_SCSI },
{ "TOSHIBA", "CD-ROM XM-3201B", "3232", "[SCSI-1] TOSHIBA CD-ROM XM-3201B 3232", "TOSHIBA_CD-ROM_XM-3201B_3232", BUS_TYPE_SCSI },
{ "TOSHIBA", "CD-ROM XM-3301TA", "0272", "[SCSI-2] TOSHIBA CD-ROM XM-3301TA 0272", "TOSHIBA_CD-ROM_XM-3301TA_0272", BUS_TYPE_SCSI },
{ "TOSHIBA", "CD-ROM XM-5701TA", "3136", "[SCSI-2] TOSHIBA CD-ROM XM-5701TA 3136", "TOSHIBA_CD-ROM_XM-5701TA_3136", BUS_TYPE_SCSI },
{ "TOSHIBA", "DVD-ROM SD-M1401", "1008", "[SCSI-2] TOSHIBA DVD-ROM SD-M1401 1008", "TOSHIBA_DVD-ROM_SD-M1401_1008", BUS_TYPE_SCSI },
{ "", "", "", "", "", BUS_TYPE_NONE },
};
/* To shut up the GCC compilers. */
@@ -211,13 +218,12 @@ typedef struct raw_track_info_t {
/* Define the various CD-ROM drive operations (ops). */
typedef struct cdrom_ops_t {
void (*get_tracks)(struct cdrom *dev, int *first, int *last);
void (*get_track_info)(struct cdrom *dev, uint32_t track, int end, track_info_t *ti);
void (*get_raw_track_info)(struct cdrom *dev, int *num, raw_track_info_t *rti);
void (*get_subchannel)(struct cdrom *dev, uint32_t lba, subchannel_t *subc);
int (*is_track_pre)(struct cdrom *dev, uint32_t lba);
int (*sector_size)(struct cdrom *dev, uint32_t lba);
int (*read_sector)(struct cdrom *dev, int type, uint8_t *b, uint32_t lba);
int (*read_sector)(struct cdrom *dev, uint8_t *b, uint32_t lba);
int (*track_type)(struct cdrom *dev, uint32_t lba);
int (*ext_medium_changed)(struct cdrom *dev);
void (*exit)(struct cdrom *dev);
@@ -255,6 +261,7 @@ typedef struct cdrom {
uint32_t seek_diff;
uint32_t cd_end;
uint32_t type;
uint32_t sector_size;
int cd_buflen;
int audio_op;
@@ -270,7 +277,9 @@ typedef struct cdrom {
uint32_t (*get_volume)(void *p, int channel);
uint32_t (*get_channel)(void *p, int channel);
int16_t cd_buffer[BUF_SIZE];
int16_t cd_buffer[BUF_SIZE];
uint8_t subch_buffer[96];
} cdrom_t;
extern cdrom_t cdrom[CDROM_NUM];
@@ -296,7 +305,8 @@ extern void cdrom_audio_pause_resume(cdrom_t *dev, uint8_t resume);
extern uint8_t cdrom_audio_scan(cdrom_t *dev, uint32_t pos, int type);
extern uint8_t cdrom_get_audio_status_pioneer(cdrom_t *dev, uint8_t *b);
extern uint8_t cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf);
extern uint8_t cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf);
extern uint8_t cdrom_get_current_status(cdrom_t *dev);
extern void cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf);
extern void cdrom_get_current_subchannel_sony(cdrom_t *dev, uint8_t *b, int msf);
extern void cdrom_get_current_subcodeq(cdrom_t *dev, uint8_t *b);
extern uint8_t cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b);
@@ -315,6 +325,7 @@ extern void cdrom_seek(cdrom_t *dev, uint32_t pos, uint8_t vendor_type);
extern void cdrom_close_handler(uint8_t id);
extern void cdrom_insert(uint8_t id);
extern void cdrom_exit(uint8_t id);
extern int cdrom_is_empty(uint8_t id);
extern void cdrom_eject(uint8_t id);
extern void cdrom_reload(uint8_t id);

View File

@@ -6,16 +6,15 @@
*
* This file is part of the 86Box distribution.
*
* CD-ROM image file handling module header , translated to C
* from cdrom_dosbox.h.
* CD-ROM image file handling module header.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* The DOSBox Team, <unknown>
* RichardG, <richardg867@gmail.com>
* Cacodemon345
*
* Copyright 2016-2020 Miran Grca.
* Copyright 2017-2020 Fred N. van Kempen.
* Copyright 2002-2020 The DOSBox Team.
* Copyright 2016-2025 Miran Grca.
* Copyright 2016-2025 Miran Grca.
* Copyright 2024-2025 Cacodemon345.
*/
#ifndef CDROM_IMAGE_BACKEND_H
#define CDROM_IMAGE_BACKEND_H
@@ -57,71 +56,59 @@ typedef struct track_file_t {
int motorola;
} track_file_t;
#define BLOCK_EMPTY 0 /* Empty block. */
#define BLOCK_ZERO 1 /* Block not in the file, return all 0x00's. */
#define BLOCK_NORMAL 2 /* Block in the file. */
#define INDEX_SPECIAL -2 /* Track A0h onwards. */
#define INDEX_NONE -1 /* Empty block. */
#define INDEX_ZERO 0 /* Block not in the file, return all 0x00's. */
#define INDEX_NORMAL 1 /* Block in the file. */
#define BLOCK_NONE ((uint64_t) -1LL)
typedef struct track_block_t {
/* Is the current block in the file? If not, return all 0x00's. */
int type;
typedef struct track_index_t {
/* Is the current block in the file? If not, return all 0x00's. -1 means not yet loaded. */
int32_t type;
/* The amount of bytes to skip at the beginning of each sector. */
int skip;
int32_t skip;
/* Starting and ending sector LBA - negative in order to accomodate LBA -150 to -1
to read the pregap of track 1. */
int64_t start_sector;
int64_t end_sector;
/* Starting and ending offset in the file. */
uint64_t start_offs;
uint64_t end_offs;
} track_block_t;
typedef struct track_t {
int pregap_len; /* Pre-gap - not in file. */
int index0_len; /* Pre-gap - in file. */
int postgap_len; /* Post-gap - not in file. */
int blocks_num; /* Number of blocks. */
int number;
int track_number;
int attr;
int sector_size;
int mode2;
int form;
int pre;
int noskip; /* Do not skip by 8 bytes.*/
uint64_t start;
uint64_t length;
uint64_t skip;
track_block_t blocks[256];
uint64_t file_start;
uint64_t file_length;
track_file_t *file;
} track_index_t;
typedef struct track_t {
uint8_t session;
uint8_t attr;
uint8_t tno;
uint8_t point;
uint8_t extra[4];
uint8_t mode;
uint8_t form;
uint8_t pad;
uint8_t skip;
uint32_t sector_size;
track_index_t idx[3];
} track_t;
typedef struct cd_img_t {
int tracks_num;
track_t *tracks;
int32_t tracks_num;
track_t *tracks;
} cd_img_t;
/* Binary file functions. */
extern void cdi_close(cd_img_t *cdi);
extern int cdi_set_device(cd_img_t *cdi, const char *path);
extern void cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out);
extern void cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out);
extern int cdi_get_audio_track_pre(cd_img_t *cdi, int track);
extern int cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num, TMSF *start, uint8_t *attr);
extern int cdi_get_audio_track_info_lba(cd_img_t *cdi, int end, int track, int *track_num, uint32_t *start, uint8_t *attr);
extern int cdi_get_track(cd_img_t *cdi, uint32_t sector);
extern int cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos);
extern void cdi_get_raw_track_info(cd_img_t *cdi, int *num, uint8_t *buffer);
extern int cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track,
uint8_t *index, TMSF *rel_pos, TMSF *abs_pos);
extern int cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector);
extern int cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint32_t num);
extern int cdi_read_sector_sub(cd_img_t *cdi, uint8_t *buffer, uint32_t sector);
extern int cdi_get_sector_size(cd_img_t *cdi, uint32_t sector);
extern int cdi_is_audio(cd_img_t *cdi, uint32_t sector);
extern int cdi_is_pre(cd_img_t *cdi, uint32_t sector);
extern int cdi_is_mode2(cd_img_t *cdi, uint32_t sector);
extern int cdi_get_mode2_form(cd_img_t *cdi, uint32_t sector);
extern int cdi_load_iso(cd_img_t *cdi, const char *filename);
extern int cdi_load_cue(cd_img_t *cdi, const char *cuefile);
extern int cdi_has_data_track(cd_img_t *cdi);
extern int cdi_has_audio_track(cd_img_t *cdi);
extern void cdi_close(cd_img_t *cdi);
extern int cdi_set_device(cd_img_t *cdi, const char *path);
/* Virtual ISO functions. */
extern int viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count);

View File

@@ -127,6 +127,7 @@ extern const device_t gameport_20d_device;
extern const device_t gameport_20f_device;
extern const device_t gameport_tm_acm_device;
extern const device_t gameport_pnp_device;
extern const device_t gameport_pnp_1io_device;
extern const device_t gameport_pnp_6io_device;
extern const device_t gameport_sio_device;
extern const device_t gameport_sio_1io_device;

View File

@@ -89,6 +89,7 @@ extern const device_t ide_w83769f_vlb_device; /* Winbond W8376
extern const device_t ide_w83769f_vlb_34_device; /* Winbond W83769F VLB (Port 34h) */
extern const device_t ide_w83769f_pci_device; /* Winbond W83769F PCI */
extern const device_t ide_w83769f_pci_34_device; /* Winbond W83769F PCI (Port 34h) */
extern const device_t ide_w83769f_pci_single_channel_device; /* Winbond W83769F PCI (Only primary channel) */
extern const device_t ide_ter_device;
extern const device_t ide_ter_pnp_device;

View File

@@ -194,8 +194,10 @@ typedef struct scancode {
extern "C" {
#endif
extern uint8_t keyboard_mode;
extern int keyboard_scan;
extern uint8_t keyboard_mode;
extern int keyboard_scan;
extern uint16_t scancode_map[768];
extern void (*keyboard_send)(uint16_t val);
extern void kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val));
@@ -288,6 +290,9 @@ extern uint8_t kbc_at_dev_queue_pos(atkbc_dev_t *dev, uint8_t main);
extern void kbc_at_dev_queue_add(atkbc_dev_t *dev, uint8_t val, uint8_t main);
extern void kbc_at_dev_reset(atkbc_dev_t *dev, int do_fa);
extern atkbc_dev_t *kbc_at_dev_init(uint8_t inst);
/* This is so we can disambiguate scan codes that would otherwise conflict and get
passed on incorrectly. */
extern uint16_t convert_scan_code(uint16_t scan_code);
#ifdef __cplusplus
}

View File

@@ -450,6 +450,7 @@ extern int machine_at_mr286_init(const machine_t *);
extern int machine_at_neat_init(const machine_t *);
extern int machine_at_neat_ami_init(const machine_t *);
extern int machine_at_ataripc4_init(const machine_t *);
extern int machine_at_quadt386sx_init(const machine_t *);
@@ -593,6 +594,7 @@ extern int machine_at_pcm5330_init(const machine_t *);
extern int machine_at_ecs486_init(const machine_t *);
extern int machine_at_hot433a_init(const machine_t *);
extern int machine_at_pl4600c_init(const machine_t *);
extern int machine_at_atc1415_init(const machine_t *);
extern int machine_at_actionpc2600_init(const machine_t *);
extern int machine_at_actiontower8400_init(const machine_t *);
@@ -631,6 +633,7 @@ extern int machine_at_valuepointp60_init(const machine_t *);
extern int machine_at_revenge_init(const machine_t *);
extern int machine_at_586is_init(const machine_t *);
extern int machine_at_pb520r_init(const machine_t *);
extern int machine_at_m5pi_init(const machine_t *);
extern int machine_at_excalibur_init(const machine_t *);
@@ -643,6 +646,7 @@ extern int machine_at_p5sp4_init(const machine_t *);
extern int machine_at_plato_init(const machine_t *);
extern int machine_at_dellplato_init(const machine_t *);
extern int machine_at_ambradp90_init(const machine_t *);
extern int machine_at_p54np4_init(const machine_t *);
extern int machine_at_586ip_init(const machine_t *);
extern int machine_at_tek932_init(const machine_t *);
@@ -842,6 +846,7 @@ extern int machine_at_6via90ap_init(const machine_t *);
extern int machine_at_s1857_init(const machine_t *);
extern int machine_at_p6bap_init(const machine_t *);
extern int machine_at_p6bat_init(const machine_t *);
extern int machine_at_prosignias31x_bx_init(const machine_t *);
/* m_at_misc.c */
extern int machine_at_vpc2007_init(const machine_t *);
@@ -912,6 +917,7 @@ extern int machine_xt86_init(const machine_t *);
extern int machine_xt_americxt_init(const machine_t *);
extern int machine_xt_amixt_init(const machine_t *);
extern int machine_xt_ataripc3_init(const machine_t *);
extern int machine_xt_dtk_init(const machine_t *);
extern int machine_xt_jukopc_init(const machine_t *);
extern int machine_xt_openxt_init(const machine_t *);

View File

@@ -121,7 +121,6 @@ typedef struct mo_drive_t {
uint32_t medium_size;
uint32_t base;
uint16_t sector_size;
} mo_drive_t;
typedef struct mo_t {
@@ -139,17 +138,6 @@ typedef struct mo_t {
uint8_t current_cdb[16];
uint8_t sense[256];
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t features;
uint8_t phase;
uint16_t request_length;
uint8_t status;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
@@ -172,6 +160,8 @@ typedef struct mo_t {
uint32_t packet_len;
double callback;
uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen);
} mo_t;
extern mo_t *mo[MO_NUM];

View File

@@ -53,13 +53,12 @@ extern void plat_cdrom_get_raw_track_info(void *local, int *num, raw_track_i
extern int plat_cdrom_is_track_audio(void *local, uint32_t sector);
extern int plat_cdrom_is_track_pre(void *local, uint32_t sector);
extern uint32_t plat_cdrom_get_last_block(void *local);
extern void plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out);
extern int plat_cdrom_get_audio_track_info(void *local, int end, int track, int *track_num, TMSF *start,
uint8_t *attr);
extern int plat_cdrom_get_audio_sub(void *local, uint32_t sector, uint8_t *attr, uint8_t *track,
uint8_t *index, TMSF *rel_pos, TMSF *abs_pos);
extern int plat_cdrom_get_sector_size(void *local, uint32_t sector);
extern int plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector);
extern int plat_cdrom_read_sector(void *local, uint8_t *buffer, uint32_t sector);
extern void plat_cdrom_eject(void *local);
extern void plat_cdrom_close(void *local);
extern int plat_cdrom_set_drive(void *local, const char *drv);

View File

@@ -38,17 +38,6 @@ typedef struct scsi_cdrom_t {
uint8_t current_cdb[16];
uint8_t sense[256];
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t features;
uint8_t phase;
uint16_t request_length;
uint8_t status;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
uint8_t id;
uint8_t cur_lun;
uint8_t early;
@@ -72,9 +61,12 @@ typedef struct scsi_cdrom_t {
double callback;
uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen);
int sony_vendor;
mode_sense_pages_t ms_pages_saved_sony;
mode_sense_pages_t ms_drive_status_pages_saved;
int sony_vendor;
} scsi_cdrom_t;
#endif

View File

@@ -100,43 +100,54 @@
#define GPCMD_WRITE_AND_VERIFY_12 0xae
#define GPCMD_VERIFY_12 0xaf
#define GPCMD_PLAY_CD_OLD 0xb4
#define GPCMD_READ_CD_OLD 0xb8
#define GPCMD_READ_CD_OLD 0xb8 /* Should be equivalent to 0xbe */
#define GPCMD_READ_CD_MSF 0xb9
#define GPCMD_AUDIO_SCAN 0xba
#define GPCMD_SET_SPEED 0xbb
#define GPCMD_PLAY_CD 0xbc
#define GPCMD_PLAY_CD 0xbc /* At some point, this was READ CD, according to the
ATAPI specification */
#define GPCMD_MECHANISM_STATUS 0xbd
#define GPCMD_READ_CD 0xbe
#define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to 86Box. */
#define GPCMD_EJECT_CHINON 0xc0 /* Chinon Vendor Unique command */
#define GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA 0xc0 /* Toshiba Vendor Unique command */
#define GPCMD_UNKNOWN_SONY 0xc0 /* Sony Vendor Unique command */
#define GPCMD_SET_ADDRESS_FORMAT_SONY 0xc0 /* Sony Vendor Unique command */
#define GPCMD_MAGAZINE_EJECT_PIONEER 0xc0 /* Pioneer Vendor Unique command */
#define GPCMD_PLAY_AUDIO_TOSHIBA 0xc1 /* Toshiba Vendor Unique command */
#define GPCMD_READ_TOC_SONY 0xc1 /* Sony Vendor Unique command */
#define GPCMD_READ_TOC_PIONEER 0xc1 /* Pioneer Vendor Unique command */
#define GPCMD_PAUSE_RESUME_ALT 0xc2
#define GPCMD_READ_SUBCHANNEL_MATSUSHITA 0xc2 /* Matsushita Vendor Unique command */
#define GPCMD_READ_SUBCHANNEL_SONY 0xc2 /* Sony Vendor Unique command */
#define GPCMD_STILL_TOSHIBA 0xc2 /* Toshiba Vendor Unique command */
#define GPCMD_READ_SUBCODEQ_PIONEER 0xc2 /* Pioneer Vendor Unique command */
#define GPCMD_READ_TOC_MATSUSHITA 0xc3 /* Matsushita Vendor Unique command */
#define GPCMD_READ_HEADER_SONY 0xc3 /* Sony Vendor Unique command */
#define GPCMD_SET_STOP_TIME_TOSHIBA 0xc3 /* Toshiba Vendor Unique command */
#define GPCMD_READ_HEADER_MATSUSHITA 0xc4 /* Matsushita Vendor Unique command */
#define GPCMD_PLAYBACK_STATUS_TOSHIBA 0xc4 /* Sony Vendor Unique command */
#define GPCMD_PLAYBACK_STATUS_SONY 0xc4 /* Sony Vendor Unique command */
#define GPCMD_CADDY_EJECT_TOSHIBA 0xc4 /* Toshiba Vendor Unique command */
#define GPCMD_PAUSE_SONY 0xc5 /* Sony Vendor Unique command */
#define GPCMD_PLAY_AUDIO_MATSUSHITA 0xc5 /* Matsushita Vendor Unique command */
#define GPCMD_UNKNOWN_SCSI2_NEC 0xc5 /* NEC Vendor Unique Command */
#define GPCMD_STOP_CHINON 0xc6 /* Chinon Vendor Unique command */
#define GPCMD_PLAT_TRACK_SONY 0xc6 /* Sony Vendor Unique command */
#define GPCMD_PLAY_TRACK_SONY 0xc6 /* Sony Vendor Unique command */
#define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA 0xc6 /* Toshiba Vendor Unique command */
#define GPCMD_PLAY_AUDIO_MSF_MATSUSHITA 0xc7 /* Matsushita Vendor Unique command*/
#define GPCMD_PLAY_MSF_SONY 0xc7 /* Sony Vendor Unique command*/
#define GPCMD_READ_DISC_INFORMATION_TOSHIBA 0xc7 /* Toshiba Vendor Unique command */
#define GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA 0xc8 /* Matsushita Vendor Unique command */
#define GPCMD_PLAY_AUDIO_SONY 0xc8 /* Sony Vendor Unique command */
#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA 0xc9 /*Matsushita Vendor Unique command */
#define GPCMD_AUDIO_TRACK_SEARCH_PIONEER 0xc8 /* Pioneer Vendor Unique command */
#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA 0xc9 /* Matsushita Vendor Unique command */
#define GPCMD_PLAYBACK_CONTROL_SONY 0xc9 /* Sony Vendor Unique command */
#define GPCMD_PLAY_AUDIO_PIONEER 0xc9 /* Pioneer Vendor Unique command */
#define GPCMD_PAUSE_PIONEER 0xca /* Pioneer Vendor Unique command */
#define GPCMD_PAUSE_RESUME_MATSUSHITA 0xcb /* Matsushita Vendor Unique command */
#define GPCMD_STOP_PIONEER 0xcb /* Pioneer Vendor Unique command */
#define GPCMD_PLAYBACK_STATUS_PIONEER 0xcc /* Pioneer Vendor Unique command */
#define GPCMD_SCAN_PIONEER 0xcd /* Should be equivalent to 0xba */
#define GPCMD_READ_CD_MSF_OLD 0xd5 /* Should be equivalent to 0xb9 */
#define GPCMD_AUDIO_TRACK_SEARCH_NEC 0xd8 /* NEC Vendor Unique command */
#define GPCMD_PLAY_AUDIO_NEC 0xd9 /* NEC Vendor Unique command */
#define GPCMD_STILL_NEC 0xda /* NEC Vendor Unique command */
@@ -145,6 +156,7 @@
#define GPCMD_CADDY_EJECT_NEC 0xdc /* NEC Vendor Unique command */
#define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC 0xdd /* NEC Vendor Unique command */
#define GPCMD_READ_DISC_INFORMATION_NEC 0xde /* NEC Vendor Unique command */
#define GPCMD_DRIVE_STATUS_PIONEER 0xe0 /* Pioneer Vendor Unique command */
#define GPCMD_PLAY_AUDIO_12_MATSUSHITA 0xe5 /* Matsushita Vendor Unique command */
#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA 0xe9 /* Matsushita Vendor Unique command */
@@ -366,17 +378,6 @@ typedef struct scsi_common_s {
uint8_t current_cdb[16];
uint8_t sense[256];
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t features;
uint8_t phase;
uint16_t request_length;
uint8_t status;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
@@ -399,6 +400,8 @@ typedef struct scsi_common_s {
uint32_t packet_len;
double callback;
uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen);
} scsi_common_t;
typedef struct scsi_device_t {

View File

@@ -31,17 +31,6 @@ typedef struct scsi_disk_t {
uint8_t current_cdb[16];
uint8_t sense[256];
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t features;
uint8_t phase;
uint16_t request_length;
uint8_t status;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
@@ -64,6 +53,8 @@ typedef struct scsi_disk_t {
uint32_t packet_len;
double callback;
uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen);
} scsi_disk_t;
extern scsi_disk_t *scsi_disk[HDD_NUM];

View File

@@ -0,0 +1,22 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Ensoniq AudioPCI family emulation.
*
* Authors: Cacodemon345
*
* Copyright 2024-2025 Cacodemon345.
*/
struct akm4531_t
{
unsigned char registers[256];
};
typedef struct akm4531_t akm4531_t;
double akm4531_apply_master_vol(unsigned short sample);

View File

@@ -11,9 +11,11 @@
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* TheCollector1995, <mariogplayer@gmail.com>
* Jasmine Iwanek, <jriwanek@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
* Copyright 2024-2025 Jasmine Iwanek.
*/
#ifndef SOUND_SND_SB_H
@@ -27,15 +29,19 @@
enum {
SADLIB = 1, /* No DSP */
SB1, /* DSP v1.05 */
SB15, /* DSP v2.00 */
SB2, /* DSP v2.01 - needed for high-speed DMA */
SBPRO, /* DSP v3.00 */
SBPRO2, /* DSP v3.02 + OPL3 */
SB16, /* DSP v4.05 + OPL3 */
SBAWE32, /* DSP v4.12 + OPL3 */
SBAWE32PNP, /* DSP v4.13 + OPL3 */
SBAWE64 /* DSP v4.16 + OPL3 */
SB_DSP_105, /* DSP v1.05, Original CT1320 (Also known as CT1310) */
SB_DSP_200, /* DSP v2.00 */
SB_DSP_201, /* DSP v2.01 - needed for high-speed DMA, Seen on CT1350B with CT1336 */
SB_DSP_202, /* DSP v2.02 - Seen on CT1350B with CT1336A */
SBPRO_DSP_300, /* DSP v3.00 */
SBPRO2_DSP_302, /* DSP v3.02 + OPL3 */
SB16_DSP_404, /* DSP v4.05 + OPL3 */
SB16_DSP_405, /* DSP v4.05 + OPL3 */
SB16_DSP_406, /* DSP v4.06 + OPL3 */
SB16_DSP_411, /* DSP v4.11 + OPL3 */
SBAWE32_DSP_412, /* DSP v4.12 + OPL3 */
SBAWE32_DSP_413, /* DSP v4.13 + OPL3 */
SBAWE64_DSP_416 /* DSP v4.16 + OPL3 */
};
/* SB 2.0 CD version */
@@ -182,6 +188,7 @@ typedef struct sb_t {
void *gameport;
int pnp;
int has_ide;
uint8_t pos_regs[8];
uint8_t pnp_rom[512];
@@ -195,6 +202,12 @@ typedef struct sb_t {
void (*opl_mix)(void*, double*, double*);
} sb_t;
typedef struct goldfinch_t {
emu8k_t emu8k;
uint8_t pnp_rom[512];
} goldfinch_t;
extern void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *priv);
extern uint8_t sb_ct1345_mixer_read(uint16_t addr, void *priv);
extern void sb_ct1345_mixer_reset(sb_t *sb);

View File

@@ -109,6 +109,8 @@ extern void givealbuffer_wt(const void *buf);
extern void givealbuffer_cd(const void *buf);
#define sb_vibra16c_onboard_relocate_base sb_vibra16s_onboard_relocate_base
#define sb_vibra16cl_onboard_relocate_base sb_vibra16s_onboard_relocate_base
#define sb_vibra16xv_onboard_relocate_base sb_vibra16s_onboard_relocate_base
extern void sb_vibra16s_onboard_relocate_base(uint16_t new_addr, void *priv);
#ifdef EMU_DEVICE_H
@@ -143,20 +145,26 @@ extern const device_t sb_pro_v2_device;
extern const device_t sb_pro_mcv_device;
extern const device_t sb_pro_compat_device;
extern const device_t sb_16_device;
extern const device_t sb_vibra16s_onboard_device;
extern const device_t sb_vibra16s_device;
extern const device_t sb_vibra16xv_device;
extern const device_t sb_vibra16c_onboard_device;
extern const device_t sb_vibra16c_device;
extern const device_t sb_vibra16cl_onboard_device;
extern const device_t sb_vibra16cl_device;
extern const device_t sb_vibra16s_onboard_device;
extern const device_t sb_vibra16s_device;
extern const device_t sb_vibra16xv_onboard_device;
extern const device_t sb_vibra16xv_device;
extern const device_t sb_16_pnp_device;
extern const device_t sb_16_pnp_ide_device;
extern const device_t sb_16_compat_device;
extern const device_t sb_16_compat_nompu_device;
extern const device_t sb_16_reply_mca_device;
extern const device_t sb_goldfinch_device;
extern const device_t sb_32_pnp_device;
extern const device_t sb_awe32_device;
extern const device_t sb_awe32_pnp_device;
extern const device_t sb_awe64_value_device;
extern const device_t sb_awe64_device;
extern const device_t sb_awe64_ide_device;
extern const device_t sb_awe64_gold_device;
/* Crystal CS423x */
@@ -177,6 +185,7 @@ extern const device_t ess_soundpiper_32_mca_device;
extern const device_t ess_chipchat_16_mca_device;
/* Ensoniq AudioPCI */
extern const device_t es1370_device;
extern const device_t es1371_device;
extern const device_t es1371_onboard_device;
extern const device_t es1373_device;

View File

@@ -138,6 +138,7 @@ typedef struct ibm8514_t {
int output2;
int ssv_len;
int ssv_len_back;
uint8_t ssv_dir;
uint8_t ssv_draw;
int odd_in;

View File

@@ -2157,6 +2157,12 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params,
addbyte(0xc2);
}
addbyte(0xf3); /*MOVQ XMM15(colbfog), XMM0 */
addbyte(0x44);
addbyte(0x0f);
addbyte(0x7e);
addbyte(0xf8);
if (params->fogMode & FOG_ENABLE) {
if (params->fogMode & FOG_CONSTANT) {
addbyte(0x66); /*MOVD XMM3, params->fogColor[ESI]*/
@@ -2580,17 +2586,17 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params,
addbyte(0xef);
addbyte(0xe4);
break;
case AFUNC_ASATURATE:
addbyte(0x66); /*PMULLW XMM4, XMM11(minus_254)*/
case AFUNC_ACOLORBEFOREFOG:
addbyte(0x66); /*PMULLW XMM4, XMM15(colbfog)*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xd5);
addbyte(0xe3);
addbyte(0xe7);
addbyte(0xf3); /*MOVQ XMM5, XMM4*/
addbyte(0x0f);
addbyte(0x7e);
addbyte(0xec);
addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/
addbyte(0x66); /*PADDW XMM4, R10(alookup)[1*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xfd);
@@ -2610,6 +2616,7 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params,
addbyte(0x71);
addbyte(0xd4);
addbyte(8);
break;
}
switch (src_afunc) {
@@ -2762,7 +2769,36 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params,
addbyte(0xef);
addbyte(0xc0);
break;
case AFUNC_ACOLORBEFOREFOG:
case AFUNC_ASATURATE:
addbyte(0x66); /*PMULLW XMM0, XMM11(minus_254)*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xd5);
addbyte(0xc3);
addbyte(0xf3); /*MOVQ XMM5, XMM0*/
addbyte(0x0f);
addbyte(0x7e);
addbyte(0xe8);
addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/
addbyte(0x41);
addbyte(0x0f);
addbyte(0xfd);
addbyte(0x42);
addbyte(8 * 2);
addbyte(0x66); /*PSRLW XMM5, 8*/
addbyte(0x0f);
addbyte(0x71);
addbyte(0xd5);
addbyte(8);
addbyte(0x66); /*PADDW XMM0, XMM5*/
addbyte(0x0f);
addbyte(0xfd);
addbyte(0xc5);
addbyte(0x66); /*PSRLW XMM0, 8*/
addbyte(0x0f);
addbyte(0x71);
addbyte(0xd0);
addbyte(8);
break;
}

View File

@@ -210,11 +210,10 @@ void voodoo_codegen_close(voodoo_t *voodoo);
newdest_g = (dest_g * (255 - dest_a)) / 255; \
newdest_b = (dest_b * (255 - dest_a)) / 255; \
break; \
case AFUNC_ASATURATE: \
_a = MIN(src_a, 1 - dest_a); \
newdest_r = (dest_r * _a) / 255; \
newdest_g = (dest_g * _a) / 255; \
newdest_b = (dest_b * _a) / 255; \
case AFUNC_ACOLORBEFOREFOG: \
newdest_r = (dest_r * colbfog_r) / 255; \
newdest_g = (dest_g * colbfog_g) / 255; \
newdest_b = (dest_b * colbfog_b) / 255; \
break; \
} \
\
@@ -254,8 +253,11 @@ void voodoo_codegen_close(voodoo_t *voodoo);
src_g = (src_g * (255 - dest_a)) / 255; \
src_b = (src_b * (255 - dest_a)) / 255; \
break; \
case AFUNC_ACOLORBEFOREFOG: \
fatal("AFUNC_ACOLORBEFOREFOG\n"); \
case AFUNC_ASATURATE: \
_a = MIN(src_a, 255 - dest_a); \
src_r = (dest_r * _a) / 255; \
src_g = (dest_g * _a) / 255; \
src_b = (dest_b * _a) / 255; \
break; \
} \
\

View File

@@ -85,17 +85,6 @@ typedef struct zip_t {
uint8_t current_cdb[16];
uint8_t sense[256];
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t features;
uint8_t phase;
uint16_t request_length;
uint8_t status;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
@@ -118,6 +107,8 @@ typedef struct zip_t {
uint32_t packet_len;
double callback;
uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen);
} zip_t;
extern zip_t *zip[ZIP_NUM];

View File

@@ -13,10 +13,12 @@
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <https://pcem-emulator.co.uk/>
* Jasmine Iwanek, <jriwanek@gmail.com>
*
* Copyright 2017-2020 Fred N. van Kempen.
* Copyright 2016-2020 Miran Grca.
* Copyright 2008-2020 Sarah Walker.
* Copyright 2025 Jasmine Iwanek.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,7 +38,6 @@
* Boston, MA 02111-1307
* USA.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
@@ -53,6 +54,7 @@
#include <86box/fdc_ext.h>
#include <86box/nvr.h>
#include <86box/gameport.h>
#include <86box/ibm_5161.h>
#include <86box/keyboard.h>
#include <86box/lpt.h>
#include <86box/rom.h>
@@ -149,10 +151,41 @@ machine_at_ps2_ide_init(const machine_t *model)
device_add(&ide_isa_device);
}
static const device_config_t ibmat_config[] = {
// clang-format off
{
.name = "enable_5161",
.description = "IBM 5161 Expansion Unit",
.type = CONFIG_BINARY,
.default_int = 0
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
const device_t ibmat_device = {
.name = " IBM AT Devices",
.internal_name = "ibmat_device",
.flags = 0,
.local = 0,
.init = NULL,
.close = NULL,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = ibmat_config
};
int
machine_at_ibm_init(const machine_t *model)
{
int ret;
int ret;
uint8_t enable_5161;
device_context(model->device);
enable_5161 = machine_get_config_int("enable_5161");
device_context_restore();
ret = bios_load_interleaved("roms/machines/ibmat/62x0820.u27",
"roms/machines/ibmat/62x0821.u47",
@@ -163,6 +196,9 @@ machine_at_ibm_init(const machine_t *model)
machine_at_ibm_common_init(model);
if (enable_5161)
device_add(&ibm_5161_device);
return ret;
}
@@ -218,10 +254,41 @@ machine_at_ibmatpx_init(const machine_t *model)
return ret;
}
static const device_config_t ibmxt286_config[] = {
// clang-format off
{
.name = "enable_5161",
.description = "IBM 5161 Expansion Unit",
.type = CONFIG_BINARY,
.default_int = 0
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
const device_t ibmxt286_device = {
.name = "IBM XT Model 286 Devices",
.internal_name = "ibmxt286_device",
.flags = 0,
.local = 0,
.init = NULL,
.close = NULL,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = ibmxt286_config
};
int
machine_at_ibmxt286_init(const machine_t *model)
{
int ret;
int ret;
uint8_t enable_5161;
device_context(model->device);
enable_5161 = machine_get_config_int("enable_5161");
device_context_restore();
ret = bios_load_interleaved("roms/machines/ibmxt286/bios_5162_21apr86_u34_78x7460_27256.bin",
"roms/machines/ibmxt286/bios_5162_21apr86_u35_78x7461_27256.bin",
@@ -232,6 +299,9 @@ machine_at_ibmxt286_init(const machine_t *model)
machine_at_ibm_common_init(model);
if (enable_5161)
device_add(&ibm_5161_device);
return ret;
}

View File

@@ -212,6 +212,37 @@ machine_at_neat_ami_init(const machine_t *model)
return ret;
}
// TODO
// Onboard Paradise PVGA1A-JK VGA Graphics
// Data Technology Corporation DTC7187 RLL Controller (Optional)
int
machine_at_ataripc4_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved("roms/machines/ataripc4/AMI_PC4X_1.7_EVEN.BIN",
"roms/machines/ataripc4/AMI_PC4X_1.7_ODD.BIN",
#if 0
ret = bios_load_interleaved("roms/machines/ataripc4/ami_pc4x_1.7_even.bin",
"roms/machines/ataripc4/ami_pc4x_1.7_odd.bin",
#endif
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&neat_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&keyboard_at_ami_device);
return ret;
}
int
machine_at_px286_init(const machine_t *model)
{

View File

@@ -48,6 +48,7 @@
#include <86box/hwm.h>
#include <86box/machine.h>
#include <86box/plat_unused.h>
#include <86box/sound.h>
int
machine_at_acc386_init(const machine_t *model)
@@ -1962,6 +1963,48 @@ machine_at_hot433a_init(const machine_t *model)
return ret;
}
int
machine_at_pl4600c_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/pl4600c/SST29EE010.BIN",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* Slot 01 */
pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); /* Slot 02 */
pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); /* Onboard */
pci_register_slot(0x13, PCI_CARD_VIDEO, 0, 0, 0, 0); /* Onboard */
device_add(&umc_hb4_device);
device_add(&umc_8886af_device);
device_add(&um8663af_device);
device_add(&sst_flash_29ee010_device);
device_add(&keyboard_ps2_ami_pci_device);
if (gfxcard[0] == VID_INTERNAL)
device_add(&gd5430_onboard_pci_device);
if (sound_card_current[0] == SOUND_INTERNAL)
device_add(&ess_1688_device);
if (fdc_current[0] == FDC_INTERNAL){
fdd_set_turbo(0, 1);
fdd_set_turbo(1, 1);
}
return ret;
}
int
machine_at_atc1415_init(const machine_t *model)
{

View File

@@ -74,6 +74,46 @@ machine_at_s370slm_init(const machine_t *model)
return ret;
}
int
machine_at_prosignias31x_bx_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/prosignias31x_bx/p6bxt-ap-092600.bin",
0x000c0000, 262144, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init_ex(model, 2);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0c, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0d, PCI_CARD_SOUND, 4, 3, 2, 1); /* assumed */
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&w83977ef_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&winbond_flash_w29c020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
device_add(&gl520sm_2d_device); /* fans: CPU, Chassis; temperature: System */
hwm_values.temperatures[0] += 2; /* System offset */
hwm_values.temperatures[1] += 2; /* CPU offset */
hwm_values.voltages[0] = 3300; /* Vcore and 3.3V are swapped */
hwm_values.voltages[2] = hwm_get_vcore();
if (sound_card_current[0] == SOUND_INTERNAL)
device_add(&cmi8738_onboard_device);
return ret;
}
int
machine_at_s1857_init(const machine_t *model)
{

View File

@@ -126,7 +126,6 @@ machine_at_p5mp3_init(const machine_t *model)
return ret;
machine_at_common_init(model);
device_add(&ide_pci_device);
pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
@@ -355,6 +354,36 @@ machine_at_pb520r_init(const machine_t *model)
return ret;
}
int
machine_at_m5pi_init(const machine_t *model)
{
int ret;
ret = bios_load_linear_inverted("roms/machines/m5pi/M5PI10R.BIN",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0);
pci_register_slot(0x0f, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0c, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&i430lx_device);
device_add(&sio_zb_device);
device_add(&keyboard_ps2_phoenix_device);
device_add(&ide_w83769f_pci_single_channel_device);
device_add(&fdc37c665_ide_sec_device);
device_add(&intel_flash_bxt_ami_device);
return ret;
}
int
machine_at_excalibur_init(const machine_t *model)
{

View File

@@ -97,6 +97,36 @@ machine_at_ambradp90_init(const machine_t *model)
return ret;
}
int
machine_at_p54np4_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/p54np4/asus-642accdebcb75833703472.bin",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 03 = Slot 1 */
pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */
pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 05 = Slot 3 */
pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 06 = Slot 4 */
pci_register_slot(0x07, PCI_CARD_SCSI, 1, 2, 3, 4); /* 07 = SCSI */
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&i430nx_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&fdc37c665_ide_pri_device);
device_add(&ncr53c810_onboard_pci_device);
device_add(&intel_flash_bxt_device);
return ret;
}
int
machine_at_586ip_init(const machine_t *model)
{

View File

@@ -1,3 +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.
*
* Standard PC/AT implementation.
*
*
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <https://pcem-emulator.co.uk/>
* Jasmine Iwanek, <jriwanek@gmail.com>
*
* Copyright 2017-2020 Fred N. van Kempen.
* Copyright 2016-2020 Miran Grca.
* Copyright 2008-2020 Sarah Walker.
* Copyright 2025 Jasmine Iwanek.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
@@ -37,14 +59,54 @@ machine_xt_common_init(const machine_t *model, int fixed_floppy)
standalone_gameport_type = &gameport_device;
}
static const device_config_t ibmpc_config[] = {
// clang-format off
{
.name = "enable_5161",
.description = "IBM 5161 Expansion Unit",
.type = CONFIG_BINARY,
.default_int = 0
},
{
.name = "enable_basic",
.description = "IBM Cassette Basic",
.type = CONFIG_BINARY,
.default_int = 1
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
const device_t ibmpc_device = {
.name = "IBM PC (1981) Device",
.internal_name = "ibmpc_device",
.flags = 0,
.local = 0,
.init = NULL,
.close = NULL,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = ibmpc_config
};
int
machine_pc_init(const machine_t *model)
{
int ret;
int ret;
uint8_t enable_5161;
uint8_t enable_basic;
device_context(model->device);
enable_5161 = machine_get_config_int("enable_5161");
enable_basic = machine_get_config_int("enable_basic");
device_context_restore();
ret = bios_load_linear("roms/machines/ibmpc/BIOS_5150_24APR81_U33.BIN",
0x000fe000, 40960, 0);
if (ret) {
if (enable_basic && ret) {
bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U29 - 5700019.bin",
0x000f6000, 8192, 0);
bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U30 - 5700027.bin",
@@ -62,18 +124,88 @@ machine_pc_init(const machine_t *model)
machine_xt_common_init(model, 0);
if (enable_5161)
device_add(&ibm_5161_device);
return ret;
}
static const device_config_t ibmpc82_config[] = {
// clang-format off
{
.name = "bios",
.description = "BIOS Version",
.type = CONFIG_BIOS,
.default_string = "ibm5150_1501476",
.default_int = 0,
.file_filter = "",
.spinner = { 0 },
.bios = {
{ .name = "1501476 (10/27/82)", .internal_name = "ibm5150_1501476", .bios_type = BIOS_NORMAL,
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/ibmpc82/BIOS_5150_27OCT82_1501476_U33.BIN", "" } },
{ .name = "5000024 (08/16/82)", .internal_name = "ibm5150_5000024", .bios_type = BIOS_NORMAL,
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/ibmpc82/BIOS_5150_16AUG82_5000024_U33.BIN", "" } },
// The following are Diagnostic ROMs.
{ .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL,
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } },
{ .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL,
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } },
{ .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL,
.files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } },
{ .files_no = 0 }
},
},
{
.name = "enable_5161",
.description = "IBM 5161 Expansion Unit",
.type = CONFIG_BINARY,
.default_int = 1
},
{
.name = "enable_basic",
.description = "IBM Cassette Basic",
.type = CONFIG_BINARY,
.default_int = 1
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
const device_t ibmpc82_device = {
.name = "IBM PC (1982) Devices",
.internal_name = "ibmpc82_device",
.flags = 0,
.local = 0,
.init = NULL,
.close = NULL,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = ibmpc82_config
};
int
machine_pc82_init(const machine_t *model)
{
int ret;
int ret2;
int ret = 0;
int ret2;
uint8_t enable_5161;
uint8_t enable_basic;
const char* fn;
ret = bios_load_linear("roms/machines/ibmpc82/pc102782.bin",
0x000fe000, 40960, 0);
if (ret) {
/* No ROMs available. */
if (!device_available(model->device))
return ret;
device_context(model->device);
enable_5161 = machine_get_config_int("enable_5161");
enable_basic = machine_get_config_int("enable_basic");
fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0);
ret = bios_load_linear(fn, 0x000fe000, 40960, 0);
device_context_restore();
if (enable_basic && ret) {
ret2 = bios_load_aux_linear("roms/machines/ibmpc82/ibm-basic-1.10.rom",
0x000f6000, 32768, 0);
if (!ret2) {
@@ -92,17 +224,51 @@ machine_pc82_init(const machine_t *model)
return ret;
device_add(&keyboard_pc82_device);
device_add(&ibm_5161_device);
machine_xt_common_init(model, 0);
if (enable_5161)
device_add(&ibm_5161_device);
return ret;
}
static const device_config_t ibmxt_config[] = {
// clang-format off
{
.name = "enable_5161",
.description = "IBM 5161 Expansion Unit",
.type = CONFIG_BINARY,
.default_int = 1
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
const device_t ibmxt_device = {
.name = "IBM XT (1982) Device",
.internal_name = "ibmxt_device",
.flags = 0,
.local = 0,
.init = NULL,
.close = NULL,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = ibmxt_config
};
int
machine_xt_init(const machine_t *model)
{
int ret;
int ret;
uint8_t enable_5161;
uint8_t enable_basic;
device_context(model->device);
enable_5161 = machine_get_config_int("enable_5161");
device_context_restore();
ret = bios_load_linear("roms/machines/ibmxt/xt.rom",
0x000f0000, 65536, 0);
@@ -120,12 +286,13 @@ machine_xt_init(const machine_t *model)
if (bios_only || !ret)
return ret;
device_add(&keyboard_xt_device);
device_add(&ibm_5161_device);
machine_xt_common_init(model, 0);
if (enable_5161)
device_add(&ibm_5161_device);
return ret;
}
@@ -147,10 +314,41 @@ machine_genxt_init(const machine_t *model)
return ret;
}
static const device_config_t ibmxt86_config[] = {
// clang-format off
{
.name = "enable_5161",
.description = "IBM 5161 Expansion Unit",
.type = CONFIG_BINARY,
.default_int = 1
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
const device_t ibmxt86_device = {
.name = "IBM XT (1986) Device",
.internal_name = "ibmxt86_device",
.flags = 0,
.local = 0,
.init = NULL,
.close = NULL,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = ibmxt86_config
};
int
machine_xt86_init(const machine_t *model)
{
int ret;
int ret;
uint8_t enable_5161;
device_context(model->device);
enable_5161 = machine_get_config_int("enable_5161");
device_context_restore();
ret = bios_load_linear("roms/machines/ibmxt86/BIOS_5160_09MAY86_U18_59X7268_62X0890_27256_F800.BIN",
0x000fe000, 65536, 0x6000);
@@ -165,10 +363,12 @@ machine_xt86_init(const machine_t *model)
return ret;
device_add(&keyboard_xt86_device);
device_add(&ibm_5161_device);
machine_xt_common_init(model, 0);
if (enable_5161)
device_add(&ibm_5161_device);
return ret;
}
@@ -212,6 +412,31 @@ machine_xt_amixt_init(const machine_t *model)
return ret;
}
// TODO
// Onboard EGA Graphics (NSI Logic EVC315-S on early boards STMicroelectronics EGA on later revisions)
// RTC
// Adaptec ACB-2072 RLL Controller Card (Optional)
// Atari PCM1 Mouse Support
int
machine_xt_ataripc3_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN",
0x000f8000, 32768, 0);
#if 0
ret = bios_load_linear("roms/machines/ataripc3/c101701-004 308.u61",
0x000f8000, 0x8000, 0);
#endif
if (bios_only || !ret)
return ret;
machine_xt_clone_init(model, 0);
return ret;
}
int
machine_xt_znic_init(const machine_t *model)
{

View File

@@ -15,9 +15,11 @@
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* Jasmine Iwanek, <jriwanek@gmail.com>
*
* Copyright 2016-2020 Miran Grca.
* Copyright 2017-2020 Fred N. van Kempen.
* Copyright 2025 Jasmine Iwanek.
*/
#include <stdio.h>
#include <stdint.h>
@@ -55,6 +57,12 @@ extern const device_t vid_device_sl;
extern const device_t t1200_video_device;
extern const device_t compaq_plasma_device;
extern const device_t ps1_2011_device;
extern const device_t ibmpc_device;
extern const device_t ibmpc82_device;
extern const device_t ibmxt_device;
extern const device_t ibmxt86_device;
extern const device_t ibmat_device;
extern const device_t ibmxt286_device;
const machine_filter_t machine_types[] = {
{ "None", MACHINE_TYPE_NONE },
@@ -243,7 +251,7 @@ const machine_t machines[] = {
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.device = &ibmpc_device,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
@@ -282,7 +290,7 @@ const machine_t machines[] = {
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.device = &ibmpc82_device,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
@@ -360,7 +368,7 @@ const machine_t machines[] = {
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.device = &ibmxt_device,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
@@ -399,7 +407,7 @@ const machine_t machines[] = {
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.device = &ibmxt86_device,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
@@ -484,6 +492,45 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
{
.name = "[8088] Atari PC 3",
.internal_name = "ataripc3",
.type = MACHINE_TYPE_8088,
.chipset = MACHINE_CHIPSET_DISCRETE,
.init = machine_xt_ataripc3_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_8088,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_PC,
.flags = MACHINE_FDC,
.ram = {
.min = 64,
.max = 640,
.step = 64
},
.nvrmask = 0,
.kbc_device = &keyboard_xtclone_device,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL, //&fdc_xt_device,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
{
.name = "[8088] Bondwell BW230",
.internal_name = "bw230",
@@ -2634,7 +2681,7 @@ const machine_t machines[] = {
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.device = &ibmat_device,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
@@ -2754,7 +2801,7 @@ const machine_t machines[] = {
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.device = &ibmxt286_device,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
@@ -3405,6 +3452,45 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
{
.name = "[NEAT] Atari PC 4",
.internal_name = "ataripc4",
.type = MACHINE_TYPE_286,
.chipset = MACHINE_CHIPSET_NEAT,
.init = machine_at_ataripc4_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_286,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_AT,
.flags = MACHINE_FDC,
.ram = {
.min = 512,
.max = 8192,
.step = 128
},
.nvrmask = 127,
.kbc_device = &keyboard_at_ami_device,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL, //&fdc_at_device,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* This has "AMI KEYBOARD BIOS", most likely 'F'. */
{
.name = "[NEAT] DataExpert 286",
@@ -4348,9 +4434,9 @@ const machine_t machines[] = {
.max_voltage = 0,
.min_multi = 0,
.max_multi = 0,
},
.bus_flags = MACHINE_PS2,
.bus_flags = MACHINE_PS2,
.flags = MACHINE_IDE | MACHINE_VIDEO , /* Machine has internal OTI 077 Video card*/
.ram = {
.min = 2048,
@@ -8668,6 +8754,47 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* Compaq Presario 7100 / 7200 Series, using MiTAC/Trigon PL4600C (486). */
/* Has a VIA VT82C42N KBC. */
{
.name = "[UMC 8881] Compaq Presario 7100/7200 Series 486",
.internal_name = "pl4600c",
.type = MACHINE_TYPE_486_S3,
.chipset = MACHINE_CHIPSET_UMC_UM8881,
.init = machine_at_pl4600c_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET3,
.block = CPU_BLOCK_NONE,
.min_bus = 0,
.max_bus = 0,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_PCI,
.flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_APM,
.ram = {
.min = 1024,
.max = 65536,
.step = 1024
},
.nvrmask = 255,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = &gd5430_onboard_pci_device,
.snd_device = &ess_1688_device,
.net_device = NULL
},
/* Has a VIA VT82C406 KBC+RTC that likely has identical commands to the VT82C42N. */
{
.name = "[VIA VT82C496G] DFI G486VPA",
@@ -9366,6 +9493,46 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* The M5Pi appears to have a Phoenix MultiKey KBC firmware according to photos. */
{
.name = "[i430LX] Micronics M5Pi",
.internal_name = "m5pi",
.type = MACHINE_TYPE_SOCKET4,
.chipset = MACHINE_CHIPSET_INTEL_430LX,
.init = machine_at_m5pi_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET4,
.block = CPU_BLOCK_NONE,
.min_bus = 60000000,
.max_bus = 66666667,
.min_voltage = 5000,
.max_voltage = 5000,
.min_multi = MACHINE_MULTIPLIER_FIXED,
.max_multi = MACHINE_MULTIPLIER_FIXED
},
.bus_flags = MACHINE_PCI,
.flags = MACHINE_IDE_DUAL | MACHINE_APM,
.ram = {
.min = 2048,
.max = 131072,
.step = 2048
},
.nvrmask = 127,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* OPTi 596/597 */
/* This uses an AMI KBC firmware in PS/2 mode (it sends command A5 with the
@@ -9658,6 +9825,46 @@ const machine_t machines[] = {
.net_device = NULL
},
/* Has AMI 'H' KBC firmware. */
{
.name = "[i430NX] ASUS PCI/I-P54NP4",
.internal_name = "p54np4",
.type = MACHINE_TYPE_SOCKET5,
.chipset = MACHINE_CHIPSET_INTEL_430NX,
.init = machine_at_p54np4_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SOCKET5_7,
.block = CPU_BLOCK_NONE,
.min_bus = 60000000,
.max_bus = 66666667,
.min_voltage = 3520,
.max_voltage = 3520,
.min_multi = 1.5,
.max_multi = 1.5
},
.bus_flags = MACHINE_PS2_PCI,
.flags = MACHINE_IDE | MACHINE_SCSI | MACHINE_APM,
.ram = {
.min = 2048,
.max = 524288,
.step = 2048
},
.nvrmask = 127,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* Has AMI 'H' KBC firmware. */
{
.name = "[i430NX] Gigabyte GA-586IP",
.internal_name = "586ip",
@@ -15130,6 +15337,47 @@ const machine_t machines[] = {
/* Slot 1/Socket 370 machines */
/* 440BX */
/* OEM version of ECS P6BXT-A+ REV 1.3x/2.2x. Has a Winbond W83977EF Super
I/O chip with on-chip KBC with AMIKey-2 KBC firmware.*/
{
.name = "[i440BX] Compaq ProSignia S316/318 (Intel)",
.internal_name = "prosignias31x_bx",
.type = MACHINE_TYPE_SLOT1_370,
.chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133,
.init = machine_at_prosignias31x_bx_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_SLOT1 | CPU_PKG_SOCKET370,
.block = CPU_BLOCK(CPU_PENTIUMPRO, CPU_CYRIX3S), /* Instability issues with PPro, and garbled text in POST with Cyrix */
.min_bus = 66666667,
.max_bus = 100000000,
.min_voltage = 1300,
.max_voltage = 3500,
.min_multi = 1.5,
.max_multi = 8.0
},
.bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB,
.flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB,
.ram = {
.min = 8192,
.max = 786432,
.step = 8192
},
.nvrmask = 255,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = &cmi8738_onboard_device,
.net_device = NULL
},
/* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC
firmware. */
{

View File

@@ -75,40 +75,46 @@
# include <winsock2.h>
#endif
static const device_t *net_cards[] = {
&device_none,
&device_internal,
&threec501_device,
&threec503_device,
&pcnet_am79c960_device,
&pcnet_am79c961_device,
&de220p_device,
&ne1000_compat_device,
&ne2000_compat_device,
&ne2000_compat_8bit_device,
&ne1000_device,
&ne2000_device,
&pcnet_am79c960_eb_device,
&rtl8019as_device,
&wd8003e_device,
&wd8003eb_device,
&wd8013ebt_device,
&plip_device,
&ethernext_mc_device,
&wd8003eta_device,
&wd8003ea_device,
&wd8013epa_device,
&pcnet_am79c973_device,
&pcnet_am79c970a_device,
&dec_tulip_device,
&rtl8029as_device,
&rtl8139c_plus_device,
&dec_tulip_21140_device,
&dec_tulip_21140_vpc_device,
&dec_tulip_21040_device,
&pcnet_am79c960_vlb_device,
&modem_device,
NULL
typedef struct {
const device_t *device;
} NETWORK_CARD;
static const NETWORK_CARD net_cards[] = {
// clang-format off
{ &device_none },
{ &device_internal },
{ &threec501_device },
{ &threec503_device },
{ &pcnet_am79c960_device },
{ &pcnet_am79c961_device },
{ &de220p_device },
{ &ne1000_compat_device },
{ &ne2000_compat_device },
{ &ne2000_compat_8bit_device },
{ &ne1000_device },
{ &ne2000_device },
{ &pcnet_am79c960_eb_device },
{ &rtl8019as_device },
{ &wd8003e_device },
{ &wd8003eb_device },
{ &wd8013ebt_device },
{ &plip_device },
{ &ethernext_mc_device },
{ &wd8003eta_device },
{ &wd8003ea_device },
{ &wd8013epa_device },
{ &pcnet_am79c973_device },
{ &pcnet_am79c970a_device },
{ &dec_tulip_device },
{ &rtl8029as_device },
{ &rtl8139c_plus_device },
{ &dec_tulip_21140_device },
{ &dec_tulip_21140_vpc_device },
{ &dec_tulip_21040_device },
{ &pcnet_am79c960_vlb_device },
{ &modem_device },
{ NULL }
// clang-format on
};
netcard_conf_t net_cards_conf[NET_CARD_MAX];
@@ -587,7 +593,7 @@ network_reset(void)
net_card_current = i;
if (net_cards_conf[i].device_num > NET_INTERNAL)
device_add_inst(net_cards[net_cards_conf[i].device_num], i + 1);
device_add_inst(net_cards[net_cards_conf[i].device_num].device, i + 1);
}
}
@@ -718,8 +724,8 @@ network_available(void)
int
network_card_available(int card)
{
if (net_cards[card])
return (device_available(net_cards[card]));
if (net_cards[card].device)
return (device_available(net_cards[card].device));
return 1;
}
@@ -728,24 +734,24 @@ network_card_available(int card)
const device_t *
network_card_getdevice(int card)
{
return (net_cards[card]);
return (net_cards[card].device);
}
/* UI */
int
network_card_has_config(int card)
{
if (!net_cards[card])
if (!net_cards[card].device)
return 0;
return (device_has_config(net_cards[card]) ? 1 : 0);
return (device_has_config(net_cards[card].device) ? 1 : 0);
}
/* UI */
const char *
network_card_get_internal_name(int card)
{
return device_get_internal_name(net_cards[card]);
return device_get_internal_name(net_cards[card].device);
}
/* UI */
@@ -754,8 +760,8 @@ network_card_get_from_internal_name(char *s)
{
int c = 0;
while (net_cards[c] != NULL) {
if (!strcmp(net_cards[c]->internal_name, s))
while (net_cards[c].device != NULL) {
if (!strcmp(net_cards[c].device->internal_name, s))
return c;
c++;
}

View File

@@ -144,23 +144,6 @@ plat_cdrom_ext_medium_changed(void *local)
return ret;
}
void
plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_read_toc(ioctl);
*st_track = 1;
*end = 1;
lead_out->min = 0;
lead_out->sec = 0;
lead_out->fr = 2;
dummy_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n",
*st_track, *end, lead_out->min, lead_out->sec, lead_out->fr);
}
/* This replaces both Info and EndInfo, they are specified by a variable. */
int
plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
@@ -218,18 +201,14 @@ plat_cdrom_get_sector_size(UNUSED(void *local), UNUSED(uint32_t sector))
}
int
plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector)
plat_cdrom_read_sector(void *local, uint8_t *buffer, uint32_t sector)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_open(ioctl);
if (raw)
/* Raw */
dummy_cdrom_ioctl_log("Raw\n");
else
/* Cooked */
dummy_cdrom_ioctl_log("Cooked\n");
/* Raw */
dummy_cdrom_ioctl_log("Raw\n");
plat_cdrom_close(ioctl);

View File

@@ -43,10 +43,12 @@ Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin)
#endif
#ifdef Q_OS_WINDOWS
# include "qt_rendererstack.hpp"
# include "qt_winrawinputfilter.hpp"
# include "qt_winmanagerfilter.hpp"
# include <86box/win.h>
# include <shobjidl.h>
# include <windows.h>
#endif
extern "C" {
@@ -81,6 +83,7 @@ extern QElapsedTimer elapsed_timer;
extern MainWindow *main_window;
extern "C" {
#include <86box/keyboard.h>
#include <86box/timer.h>
#include <86box/nvr.h>
extern int qt_nvr_save(void);
@@ -88,6 +91,177 @@ extern int qt_nvr_save(void);
void qt_set_sequence_auto_mnemonic(bool b);
#ifdef Q_OS_WINDOWS
static void
keyboard_getkeymap()
{
const LPCSTR keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout";
const LPCSTR valueName = "Scancode Map";
unsigned char buf[32768];
DWORD bufSize;
HKEY hKey;
int j;
UINT32 *bufEx2;
int scMapCount;
UINT16 *bufEx;
int scancode_unmapped;
int scancode_mapped;
/* First, prepare the default scan code map list which is 1:1.
* Remappings will be inserted directly into it.
* 512 bytes so this takes less memory, bit 9 set means E0
* prefix.
*/
for (j = 0; j < 512; j++)
scancode_map[j] = j;
/* Get the scan code remappings from:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */
bufSize = 32768;
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) {
if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) {
bufEx2 = (UINT32 *) buf;
scMapCount = bufEx2[2];
if ((bufSize != 0) && (scMapCount != 0)) {
bufEx = (UINT16 *) (buf + 12);
for (j = 0; j < scMapCount * 2; j += 2) {
/* Each scan code is 32-bit: 16 bits of remapped scan code,
and 16 bits of original scan code. */
scancode_unmapped = bufEx[j + 1];
scancode_mapped = bufEx[j];
scancode_unmapped = convert_scan_code(scancode_unmapped);
scancode_mapped = convert_scan_code(scancode_mapped);
/* Ignore source scan codes with prefixes other than E1
that are not E1 1D. */
if (scancode_unmapped != 0xFFFF)
scancode_map[scancode_unmapped] = scancode_mapped;
}
}
}
RegCloseKey(hKey);
}
}
void
win_keyboard_handle(uint32_t scancode, int up, int e0, int e1)
{
/* If it's not a scan code that starts with 0xE1 */
if (e1) {
if (scancode == 0x1D) {
scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would
otherwise be E0 00 but that is invalid
anyway).
Also, take a potential mapping into
account. */
} else
scancode = 0xFFFF;
if (scancode != 0xFFFF)
keyboard_input(!up, scancode);
} else {
if (e0)
scancode |= 0x100;
/* Translate the scan code to 9-bit */
scancode = convert_scan_code(scancode);
/* Remap it according to the list from the Registry */
if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) {
// pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]);
scancode = scancode_map[scancode];
}
/* If it's not 0xFFFF, send it to the emulated
keyboard.
We use scan code 0xFFFF to mean a mapping that
has a prefix other than E0 and that is not E1 1D,
which is, for our purposes, invalid. */
/* Translate right CTRL to left ALT if the user has so
chosen. */
if ((scancode == 0x11d) && rctrl_is_lalt)
scancode = 0x038;
/* Normal scan code pass through, pass it through as is if
it's not an invalid scan code. */
if (scancode != 0xFFFF)
keyboard_input(!up, scancode);
main_window->checkFullscreenHotkey();
}
}
static LRESULT CALLBACK
emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
LPKBDLLHOOKSTRUCT lpKdhs = (LPKBDLLHOOKSTRUCT) lParam;
/* Checks if CTRL was pressed. */
BOOL bCtrlDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1);
BOOL is_over_window = (GetForegroundWindow() == ((HWND) main_window->winId()));
BOOL ret = TRUE;
static int last = 0;
if (show_second_monitors) for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) {
const auto &secondaryRenderer = main_window->renderers[monitor_index];
is_over_window = is_over_window || ((secondaryRenderer != nullptr) &&
(GetForegroundWindow() == ((HWND) secondaryRenderer->winId())));
}
if ((nCode < 0) || (nCode != HC_ACTION) || !is_over_window)
return CallNextHookEx(NULL, nCode, wParam, lParam);
else if ((lpKdhs->scanCode == 0x01) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
ret = TRUE;
else if ((lpKdhs->scanCode == 0x01) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
ret = TRUE;
else if ((lpKdhs->scanCode == 0x0f) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
ret = TRUE;
else if ((lpKdhs->scanCode == 0x0f) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
ret = TRUE;
else if ((lpKdhs->scanCode == 0x39) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
ret = TRUE;
else if ((lpKdhs->scanCode == 0x3e) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
ret = TRUE;
else if ((lpKdhs->scanCode == 0x49) && bCtrlDown && !(lpKdhs->flags & LLKHF_UP))
ret = TRUE;
else if ((lpKdhs->scanCode >= 0x5b) && (lpKdhs->scanCode <= 0x5d) && (lpKdhs->flags & LLKHF_EXTENDED))
ret = TRUE;
else
ret = CallNextHookEx(NULL, nCode, wParam, lParam);
if (lpKdhs->scanCode == 0x00000045) {
if ((lpKdhs->flags & LLKHF_EXTENDED) && (lpKdhs->vkCode == 0x00000090)) {
/* NumLock. */
lpKdhs->flags &= ~LLKHF_EXTENDED;
} else if (!(lpKdhs->flags & LLKHF_EXTENDED) && (lpKdhs->vkCode == 0x00000013)) {
/* Pause - send E1 1D. */
win_keyboard_handle(0xe1, 0, 0, 0);
win_keyboard_handle(0x1d, LLKHF_UP, 0, 0);
}
} else if (!last && (lpKdhs->scanCode == 0x00000036))
/* Non-fake right shift. */
lpKdhs->flags &= ~LLKHF_EXTENDED;
if (lpKdhs->scanCode == 0x00000236)
last = 1;
else if (last && (lpKdhs->scanCode == 0x00000036))
last = 0;
win_keyboard_handle(lpKdhs->scanCode, lpKdhs->flags & LLKHF_UP, lpKdhs->flags & LLKHF_EXTENDED, 0);
return ret;
}
#endif
#ifdef Q_OS_WINDOWS
static HHOOK llhook = NULL;
#endif
void
main_thread_fn()
{
@@ -149,7 +323,7 @@ main_thread_fn()
if (dopause)
ack_pause();
std::this_thread::sleep_for(std::chrono::milliseconds(1));
plat_delay_ms(1);
}
}
@@ -157,7 +331,7 @@ main_thread_fn()
for (uint8_t i = 1; i < GFXCARD_MAX; i ++) {
if (gfxcard[i]) {
ui_deinit_monitor(i);
std::this_thread::sleep_for(std::chrono::milliseconds(500));
plat_delay_ms(500);
}
}
QTimer::singleShot(0, QApplication::instance(), []() { QApplication::processEvents(); QApplication::instance()->quit(); });
@@ -176,6 +350,7 @@ main(int argc, char *argv[])
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
QApplication app(argc, argv);
QLocale::setDefault(QLocale::C);
@@ -193,6 +368,13 @@ main(int argc, char *argv[])
#endif
elapsed_timer.start();
for (size_t i = 0; i < sizeof(scancode_map) / sizeof(scancode_map[0]); i++)
scancode_map[i] = i;
#ifdef Q_OS_WINDOWS
keyboard_getkeymap();
#endif
if (!pc_init(argc, argv)) {
return 0;
}
@@ -340,6 +522,21 @@ main(int argc, char *argv[])
});
}
/* Force raw input if a debugger is present. */
if (IsDebuggerPresent()) {
pclog("WARNING: Debugged detected, forcing raw input\n");
hook_enabled = 0;
}
if (hook_enabled) {
/* Yes, low-level hooks *DO* work with raw input, at least global ones. */
llhook = SetWindowsHookEx(WH_KEYBOARD_LL, emu_LowLevelKeyboardProc, NULL, 0);
atexit([] () -> void {
if (llhook)
UnhookWindowsHookEx(llhook);
});
}
/* Setup raw input */
auto rawInputFilter = WindowsRawInputFilter::Register(main_window);
if (rawInputFilter) {
@@ -392,7 +589,6 @@ main(int argc, char *argv[])
/* Initialize the rendering window, or fullscreen. */
QTimer::singleShot(0, &app, [] {
pc_reset_hard_init();
main_thread = new std::thread(main_thread_fn);
/* Set the PAUSE mode depending on the renderer. */
#ifdef USE_VNC
@@ -401,6 +597,8 @@ main(int argc, char *argv[])
else
#endif
plat_pause(0);
main_thread = new std::thread(main_thread_fn);
});
const auto ret = app.exec();

View File

@@ -336,16 +336,20 @@ MediaHistoryManager::removeMissingImages(device_index_list_t &device_history)
continue;
}
char temp[MAX_IMAGE_PATH_LEN -1] = { 0 };
char temp[MAX_IMAGE_PATH_LEN * 2] = { 0 };
if (path_abs(checked_path.toUtf8().data())) {
if (checked_path.length() > (MAX_IMAGE_PATH_LEN - 1))
fatal("removeMissingImages(): checked_path.length() > 2047\n");
fatal("removeMissingImages(): checked_path.length() > %i\n", MAX_IMAGE_PATH_LEN - 1);
else
snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s", checked_path.toUtf8().constData());
} else
snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path,
path_get_slash(usr_path), checked_path.toUtf8().constData());
} else {
if ((strlen(usr_path) + strlen(path_get_slash(usr_path)) + checked_path.length()) > (MAX_IMAGE_PATH_LEN - 1))
fatal("removeMissingImages(): Combined absolute path length > %i\n", MAX_IMAGE_PATH_LEN - 1);
else
snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path,
path_get_slash(usr_path), checked_path.toUtf8().constData());
}
path_normalize(temp);
QString qstr = QString::fromUtf8(temp);

View File

@@ -524,7 +524,8 @@ MediaMenu::cdromMute(int i)
void
MediaMenu::cdromMount(int i, const QString &filename)
{
QByteArray fn = filename.toUtf8().data();
QByteArray fn = filename.toUtf8().data();
int was_empty = cdrom_is_empty(i);
cdrom_exit(i);
@@ -542,9 +543,14 @@ MediaMenu::cdromMount(int i, const QString &filename)
cdrom_image_open(&(cdrom[i]), fn.data());
/* Signal media change to the emulated machine. */
if (cdrom[i].insert)
if (cdrom[i].insert) {
cdrom[i].insert(cdrom[i].priv);
/* The drive was previously empty, transition directly to UNIT ATTENTION. */
if (was_empty)
cdrom[i].insert(cdrom[i].priv);
}
if (strlen(cdrom[i].image_path) > 0)
ui_sb_update_icon_state(SB_CDROM | i, 0);
else

View File

@@ -160,6 +160,7 @@ SettingsPorts::on_pushButtonSerialPassThru4_clicked()
DeviceConfig::ConfigureDevice(&serial_passthrough_device, 4, qobject_cast<Settings *>(Settings::settings));
}
#if 0
void
SettingsPorts::on_pushButtonSerialPassThru5_clicked()
{
@@ -177,6 +178,7 @@ SettingsPorts::on_pushButtonSerialPassThru7_clicked()
{
DeviceConfig::ConfigureDevice(&serial_passthrough_device, 7, qobject_cast<Settings *>(Settings::settings));
}
#endif
void
SettingsPorts::on_checkBoxSerialPassThru1_clicked(bool checked)
@@ -220,4 +222,4 @@ SettingsPorts::on_checkBoxSerialPassThru7_clicked(bool checked)
{
ui->pushButtonSerialPassThru7->setEnabled(checked);
}
#endif
#endif

View File

@@ -19,45 +19,23 @@ public:
#if 0
private slots:
void on_checkBoxSerialPassThru7_clicked(bool checked);
private slots:
void on_checkBoxSerialPassThru6_clicked(bool checked);
private slots:
void on_checkBoxSerialPassThru5_clicked(bool checked);
#endif
private slots:
void on_checkBoxSerialPassThru4_clicked(bool checked);
private slots:
void on_checkBoxSerialPassThru3_clicked(bool checked);
private slots:
void on_checkBoxSerialPassThru2_clicked(bool checked);
private slots:
void on_checkBoxSerialPassThru1_clicked(bool checked);
private slots:
#if 0
void on_pushButtonSerialPassThru7_clicked();
private slots:
void on_pushButtonSerialPassThru6_clicked();
private slots:
void on_pushButtonSerialPassThru5_clicked();
private slots:
#endif
void on_pushButtonSerialPassThru4_clicked();
private slots:
void on_pushButtonSerialPassThru3_clicked();
private slots:
void on_pushButtonSerialPassThru2_clicked();
private slots:
void on_pushButtonSerialPassThru1_clicked();
private slots:

View File

@@ -56,10 +56,22 @@ extern "C" {
#include <86box/network.h>
#include <86box/machine_status.h>
#ifdef Q_OS_WINDOWS
# include <86box/win.h>
#endif
void
plat_delay_ms(uint32_t count)
{
#ifdef Q_OS_WINDOWS
// On Win32 the accuracy of Sleep() depends on the timer resolution, which can be set by calling timeBeginPeriod
// https://learn.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timebeginperiod
timeBeginPeriod(1);
Sleep(count);
timeEndPeriod(1);
#else
QThread::msleep(count);
#endif
}
wchar_t *

View File

@@ -44,6 +44,8 @@
#include <86box/plat.h>
#include <86box/86box.h>
extern void win_keyboard_handle(uint32_t scancode, int up, int e0, int e1);
#include <array>
#include <memory>
@@ -64,8 +66,10 @@ WindowsRawInputFilter::Register(MainWindow *window)
.hwndTarget = nullptr}
};
if (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE)
return std::unique_ptr<WindowsRawInputFilter>(nullptr);
if (hook_enabled && (RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0])) == FALSE))
return std::unique_ptr<WindowsRawInputFilter>(nullptr);
else if (!hook_enabled && (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE))
return std::unique_ptr<WindowsRawInputFilter>(nullptr);
std::unique_ptr<WindowsRawInputFilter> inputfilter(new WindowsRawInputFilter(window));
@@ -80,11 +84,6 @@ WindowsRawInputFilter::WindowsRawInputFilter(MainWindow *window)
connect(menu, &QMenu::aboutToShow, this, [=]() { menus_open++; });
connect(menu, &QMenu::aboutToHide, this, [=]() { menus_open--; });
}
for (size_t i = 0; i < sizeof(scancode_map) / sizeof(scancode_map[0]); i++)
scancode_map[i] = i;
keyboard_getkeymap();
}
WindowsRawInputFilter::~WindowsRawInputFilter()
@@ -100,7 +99,10 @@ WindowsRawInputFilter::~WindowsRawInputFilter()
.hwndTarget = NULL}
};
RegisterRawInputDevices(rid, 2, sizeof(rid[0]));
if (hook_enabled)
RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0]));
else
RegisterRawInputDevices(rid, 2, sizeof(rid[0]));
}
bool
@@ -158,10 +160,8 @@ WindowsRawInputFilter::handle_input(HRAWINPUT input)
mouse_handle(raw);
break;
case RIM_TYPEHID:
{
win_joystick_handle(raw);
break;
}
win_joystick_handle(raw);
break;
}
}
}
@@ -171,125 +171,10 @@ WindowsRawInputFilter::handle_input(HRAWINPUT input)
void
WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw)
{
USHORT scancode;
RAWKEYBOARD rawKB = raw->data.keyboard;
scancode = rawKB.MakeCode;
/* If it's not a scan code that starts with 0xE1 */
if ((rawKB.Flags & RI_KEY_E1)) {
if (rawKB.MakeCode == 0x1D) {
scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would
otherwise be E0 00 but that is invalid
anyway).
Also, take a potential mapping into
account. */
} else
scancode = 0xFFFF;
if (scancode != 0xFFFF)
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
} else {
if (rawKB.Flags & RI_KEY_E0)
scancode |= 0x100;
/* Translate the scan code to 9-bit */
scancode = convert_scan_code(scancode);
/* Remap it according to the list from the Registry */
if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) {
pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]);
scancode = scancode_map[scancode];
}
/* If it's not 0xFFFF, send it to the emulated
keyboard.
We use scan code 0xFFFF to mean a mapping that
has a prefix other than E0 and that is not E1 1D,
which is, for our purposes, invalid. */
/* Translate right CTRL to left ALT if the user has so
chosen. */
if ((scancode == 0x11d) && rctrl_is_lalt)
scancode = 0x038;
/* Normal scan code pass through, pass it through as is if
it's not an invalid scan code. */
if (scancode != 0xFFFF)
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
window->checkFullscreenHotkey();
}
}
/* This is so we can disambiguate scan codes that would otherwise conflict and get
passed on incorrectly. */
UINT16
WindowsRawInputFilter::convert_scan_code(UINT16 scan_code)
{
if ((scan_code & 0xff00) == 0xe000)
scan_code = (scan_code & 0xff) | 0x0100;
if (scan_code == 0xE11D)
scan_code = 0x0100;
/* E0 00 is sent by some USB keyboards for their special keys, as it is an
invalid scan code (it has no untranslated set 2 equivalent), we mark it
appropriately so it does not get passed through. */
else if ((scan_code > 0x01FF) || (scan_code == 0x0100))
scan_code = 0xFFFF;
return scan_code;
}
void
WindowsRawInputFilter::keyboard_getkeymap()
{
const LPCSTR keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout";
const LPCSTR valueName = "Scancode Map";
unsigned char buf[32768];
DWORD bufSize;
HKEY hKey;
int j;
UINT32 *bufEx2;
int scMapCount;
UINT16 *bufEx;
int scancode_unmapped;
int scancode_mapped;
/* First, prepare the default scan code map list which is 1:1.
* Remappings will be inserted directly into it.
* 512 bytes so this takes less memory, bit 9 set means E0
* prefix.
*/
for (j = 0; j < 512; j++)
scancode_map[j] = j;
/* Get the scan code remappings from:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */
bufSize = 32768;
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) {
if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) {
bufEx2 = (UINT32 *) buf;
scMapCount = bufEx2[2];
if ((bufSize != 0) && (scMapCount != 0)) {
bufEx = (UINT16 *) (buf + 12);
for (j = 0; j < scMapCount * 2; j += 2) {
/* Each scan code is 32-bit: 16 bits of remapped scan code,
and 16 bits of original scan code. */
scancode_unmapped = bufEx[j + 1];
scancode_mapped = bufEx[j];
scancode_unmapped = convert_scan_code(scancode_unmapped);
scancode_mapped = convert_scan_code(scancode_mapped);
/* Ignore source scan codes with prefixes other than E1
that are not E1 1D. */
if (scancode_unmapped != 0xFFFF)
scancode_map[scancode_unmapped] = scancode_mapped;
}
}
}
RegCloseKey(hKey);
}
win_keyboard_handle(rawKB.MakeCode, (rawKB.Flags & RI_KEY_BREAK),
(rawKB.Flags & RI_KEY_E0), (rawKB.Flags & RI_KEY_E1));
}
void

View File

@@ -61,7 +61,6 @@ public:
private:
MainWindow *window;
uint16_t scancode_map[768];
int buttons = 0;
int dx = 0;
int dy = 0;
@@ -73,8 +72,6 @@ private:
void handle_input(HRAWINPUT input);
void keyboard_handle(PRAWINPUT raw);
void mouse_handle(PRAWINPUT raw);
static UINT16 convert_scan_code(UINT16 scan_code);
void keyboard_getkeymap();
};
#endif

View File

@@ -26,6 +26,7 @@
#include "ntddcdrm.h"
#include "ntddscsi.h"
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
@@ -72,12 +73,19 @@ win_cdrom_ioctl_log(const char *fmt, ...)
# define win_cdrom_ioctl_log(fmt, ...)
#endif
static void
plat_cdrom_close_handle(win_cdrom_ioctl_t *ioctl)
{
if (ioctl->handle != NULL)
CloseHandle(ioctl->handle);
}
static int
plat_cdrom_open(void *local)
{
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
plat_cdrom_close(local);
plat_cdrom_close_handle(local);
ioctl->handle = CreateFileW((LPCWSTR) ioctl->path, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
@@ -107,20 +115,47 @@ plat_cdrom_load(void *local)
static int
plat_cdrom_read_normal_toc(win_cdrom_ioctl_t *ioctl, uint8_t *toc_buf)
{
long size = 0;
long size = 0;
PCDROM_TOC_FULL_TOC_DATA cur_full_toc = NULL;
memset(toc_buf, 0x00, 65536);
cur_full_toc = (PCDROM_TOC_FULL_TOC_DATA) calloc(1, 65536);
if (ioctl->blocks_num != 0) {
memset(ioctl->cur_rti, 0x00, ioctl->blocks_num * 11);
ioctl->blocks_num = 0;
}
ioctl->cur_read_toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_TOC;
win_cdrom_ioctl_log("cur_read_toc_ex.Format = %i\n", ioctl->cur_read_toc_ex.Format);
ioctl->cur_read_toc_ex.Msf = 1;
ioctl->cur_read_toc_ex.SessionTrack = 0;
plat_cdrom_open(ioctl);
int temp = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC, NULL, 0, toc_buf, 65535, (LPDWORD) &size, NULL);
int temp = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX, &ioctl->cur_read_toc_ex, 65535,
cur_full_toc, 65535, (LPDWORD) &size, NULL);
plat_cdrom_close(ioctl);
#ifdef ENABLE_WIN_CDROM_IOCTL_LOG
win_cdrom_ioctl_log("temp = %i\n", temp);
if (temp != 0) {
int length = ((cur_full_toc->Length[0] << 8) | cur_full_toc->Length[1]) + 2;
memcpy(toc_buf, cur_full_toc, length);
}
free(cur_full_toc);
#ifdef ENABLE_WIN_CDROM_IOCTL_LOG
PCDROM_TOC toc = (PCDROM_TOC) toc_buf;
const int tracks_num = (((toc->Length[0] << 8) | toc->Length[1]) - 2) / 8;
win_cdrom_ioctl_log("%i tracks\n", tracks_num);
for (int i = 0; i < tracks_num; i++)
win_cdrom_ioctl_log("Track %03i: Point %02X\n", i, (int) toc->TrackData[i].TrackNumber);
win_cdrom_ioctl_log("%i tracks: %02X %02X %02X %02X\n",
tracks_num, toc_buf[0], toc_buf[1], toc_buf[2], toc_buf[3]);
for (int i = 0; i < tracks_num; i++) {
uint8_t *t = (uint8_t *) &toc->TrackData[i];
win_cdrom_ioctl_log("Track %03i: %02X %02X %02X %02X %02X %02X %02X %02X\n",
i, t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7]);
}
#endif
return temp;
@@ -130,10 +165,10 @@ static void
plat_cdrom_read_raw_toc(win_cdrom_ioctl_t *ioctl)
{
long size = 0;
int status;
PCDROM_TOC_FULL_TOC_DATA cur_full_toc = NULL;
memset(ioctl->cur_rti, 0x00, 65536);
cur_full_toc = (PCDROM_TOC_FULL_TOC_DATA) calloc(1, 65536);
if (ioctl->blocks_num != 0) {
memset(ioctl->cur_rti, 0x00, ioctl->blocks_num * 11);
@@ -143,11 +178,11 @@ plat_cdrom_read_raw_toc(win_cdrom_ioctl_t *ioctl)
ioctl->cur_read_toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC;
win_cdrom_ioctl_log("cur_read_toc_ex.Format = %i\n", ioctl->cur_read_toc_ex.Format);
ioctl->cur_read_toc_ex.Msf = 1;
ioctl->cur_read_toc_ex.SessionTrack = 1;
ioctl->cur_read_toc_ex.SessionTrack = 0;
plat_cdrom_open(ioctl);
status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX, &ioctl->cur_read_toc_ex, 65535,
cur_full_toc, 65535, (LPDWORD) &size, NULL);
int status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX, &ioctl->cur_read_toc_ex, 65535,
cur_full_toc, 65535, (LPDWORD) &size, NULL);
plat_cdrom_close(ioctl);
win_cdrom_ioctl_log("status = %i\n", status);
@@ -156,15 +191,21 @@ plat_cdrom_read_raw_toc(win_cdrom_ioctl_t *ioctl)
memcpy(ioctl->cur_rti, cur_full_toc->Descriptors, ioctl->blocks_num * 11);
}
free(cur_full_toc);
#ifdef ENABLE_WIN_CDROM_IOCTL_LOG
win_cdrom_ioctl_log("%i blocks\n", ioctl->blocks_num);
uint8_t *u = (uint8_t *) cur_full_toc;
win_cdrom_ioctl_log("%i blocks: %02X %02X %02X %02X\n",
ioctl->blocks_num, u[0], u[1], u[2], u[3]);
raw_track_info_t *rti = (raw_track_info_t *) ioctl->cur_rti;
for (int i = 0; i < ioctl->blocks_num; i++)
win_cdrom_ioctl_log("Block %03i: Session %03i, Point %02X\n", i, (int) rti[i].session, (int) rti[i].point);
for (int i = 0; i < ioctl->blocks_num; i++) {
uint8_t *t = (uint8_t *) &rti[i];
win_cdrom_ioctl_log("Block %03i: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
i, t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], t[10]);
}
#endif
free(cur_full_toc);
}
void
@@ -206,7 +247,7 @@ plat_cdrom_is_track_audio(void *local, uint32_t sector)
win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X\n",
toc->FirstTrack, toc->LastTrack, cur_td->TrackNumber, c,
cur_td->Control, track_addr, sector);
cur_td->Control, cur_addr, sector);
if ((cur_td->TrackNumber >= toc->FirstTrack) && (cur_td->TrackNumber <= toc->LastTrack) &&
(sector >= cur_addr) && (sector < next_addr)) {
@@ -343,35 +384,20 @@ plat_cdrom_ext_medium_changed(void *local)
memcpy(toc, new_toc, 65535);
if (memcmp(ioctl->path, ioctl->old_path, sizeof(ioctl->path)) != 0)
memcpy(ioctl->old_path, ioctl->path, sizeof(ioctl->path));
} else if (memcmp(&(new_ltd->Address[1]), &(cur_ltd->Address[1]), 3))
} else if (memcmp(&(new_ltd->Address[1]), &(cur_ltd->Address[1]), 3)) {
/* The TOC has changed. */
ioctl->toc_valid = 1;
memcpy(toc, new_toc, 65535);
if (memcmp(ioctl->path, ioctl->old_path, sizeof(ioctl->path)) != 0)
memcpy(ioctl->old_path, ioctl->path, sizeof(ioctl->path));
ret = 1;
}
win_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret);
return ret;
}
void
plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out)
{
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc;
plat_cdrom_read_toc(ioctl);
PTRACK_DATA ltd = &toc->TrackData[toc->LastTrack];
*st_track = 1;
*end = toc->LastTrack;
lead_out->min = ltd->Address[1];
lead_out->sec = ltd->Address[2];
lead_out->fr = ltd->Address[3];
win_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n",
*st_track, *end, lead_out->min, lead_out->sec, lead_out->fr);
}
/* This replaces both Info and EndInfo, they are specified by a variable. */
int
plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
@@ -458,38 +484,61 @@ plat_cdrom_get_sector_size(void *local, UNUSED(uint32_t sector))
}
int
plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector)
plat_cdrom_read_sector(void *local, uint8_t *buffer, uint32_t sector)
{
win_cdrom_ioctl_t * ioctl = (win_cdrom_ioctl_t *) local;
int status;
long size = 0;
int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
typedef struct SCSI_PASS_THROUGH_DIRECT_BUF {
SCSI_PASS_THROUGH_DIRECT spt;
ULONG Filler;
UCHAR SenseBuf[32];
} SCSI_PASS_THROUGH_DIRECT_BUF;
win_cdrom_ioctl_t * ioctl = (win_cdrom_ioctl_t *) local;
int sc_offs = (sector == 0xffffffff) ? 0 : 2352;
unsigned long int unused = 0;
int ret;
SCSI_PASS_THROUGH_DIRECT_BUF req;
memset(&req, 0x00, sizeof(req));
req.Filler = 0;
req.spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
req.spt.CdbLength = 12;
req.spt.DataIn = SCSI_IOCTL_DATA_IN;
req.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_BUF, SenseBuf);
req.spt.SenseInfoLength = sizeof(req.SenseBuf);
req.spt.TimeOutValue = 6;
req.spt.DataTransferLength = 2368;
req.spt.DataBuffer = buffer;
/* Fill in the CDB. */
req.spt.Cdb[0] = 0xbe; /* READ CD */
req.spt.Cdb[1] = 0x00; /* DAP = 0, Any Sector Type. */
req.spt.Cdb[2] = (sector >> 24) & 0xff;
req.spt.Cdb[3] = (sector >> 16) & 0xff;
req.spt.Cdb[4] = (sector >> 8) & 0xff;
req.spt.Cdb[5] = sector & 0xff; /* Starting Logical Block Address. */
req.spt.Cdb[6] = 0x00;
req.spt.Cdb[7] = 0x00;
req.spt.Cdb[8] = 0x01; /* Transfer Length. */
/* If sector is FFFFFFFF, only return the subchannel. */
req.spt.Cdb[9] = (sector == 0xffffffff) ? 0x00 : 0xf8;
req.spt.Cdb[10] = 0x02;
req.spt.Cdb[11] = 0x00;
plat_cdrom_open(ioctl);
if (raw) {
/* Raw */
win_cdrom_ioctl_log("Raw\n");
RAW_READ_INFO in;
in.DiskOffset.LowPart = sector * COOKED_SECTOR_SIZE;
in.DiskOffset.HighPart = 0;
in.SectorCount = 1;
in.TrackMode = CDDA;
status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_RAW_READ, &in, sizeof(in),
buffer, buflen, (LPDWORD) &size, NULL);
} else {
/* Cooked */
win_cdrom_ioctl_log("Cooked\n");
int success = 0;
DWORD newPos = SetFilePointer(ioctl->handle, sector * COOKED_SECTOR_SIZE, 0, FILE_BEGIN);
if (newPos != 0xFFFFFFFF)
success = ReadFile(ioctl->handle, buffer, buflen, (LPDWORD) &size, NULL);
status = (success != 0);
}
ret = DeviceIoControl(ioctl->handle, IOCTL_SCSI_PASS_THROUGH_DIRECT, &req, sizeof(req), &req, sizeof(req),
&unused, NULL);
plat_cdrom_close(ioctl);
win_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size);
return (status > 0) ? (size == buflen) : -1;
/* Construct raw subchannel data from Q only. */
if (ret && (req.spt.DataTransferLength >= 2368))
for (int i = 11; i >= 0; i--)
for (int j = 7; j >= 0; j--)
buffer[2352 + (i * 8) + j] = ((buffer[sc_offs + i] >> (7 - j)) & 0x01) << 6;
win_cdrom_ioctl_log("plat_cdrom_read_scsi_direct: ret = %d, req.spt.DataTransferLength = %lu\n",
ret, req.spt.DataTransferLength);
win_cdrom_ioctl_log("Sense: %08X, %08X\n", req.spt.SenseInfoLength, req.spt.SenseInfoOffset);
return ret && (req.spt.DataTransferLength >= 2368);
}
void
@@ -508,10 +557,8 @@ plat_cdrom_close(void *local)
{
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
if (ioctl->handle != NULL) {
CloseHandle(ioctl->handle);
ioctl->handle = NULL;
}
plat_cdrom_close_handle(ioctl);
ioctl->handle = NULL;
}
int

View File

@@ -678,6 +678,7 @@ aha_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv)
aha_eeprom_save(dev);
dev->rom_addr = config->mem[0].base;
aha_log("Base = %08X, Size = %08X\n", config->mem[0].base, config->mem[0].size);
if (dev->rom_addr) {
mem_mapping_enable(&dev->bios.mapping);
aha_log("SCSI BIOS set to: %08X-%08X\n", dev->rom_addr, dev->rom_addr + config->mem[0].size - 1);
@@ -869,13 +870,12 @@ aha_setmcode(x54x_t *dev)
}
aha1542cp_pnp_rom = (uint8_t *) malloc(dev->pnp_len + 7);
fseek(fp, dev->pnp_offset, SEEK_SET);
(void) !fread(aha1542cp_pnp_rom, dev->pnp_len, 1, fp);
(void) !fread(aha1542cp_pnp_rom, 4, 1, fp);
memset(&(aha1542cp_pnp_rom[4]), 0x00, 5);
fseek(fp, dev->pnp_offset + 4, SEEK_SET);
(void) !fread(&(aha1542cp_pnp_rom[9]), dev->pnp_len - 4, 1, fp);
/* Even the real AHA-1542CP microcode seem to be flipping bit
4 to not erroneously indicate there is a range length. */
aha1542cp_pnp_rom[0x87] |= 0x04;
/* Patch determined from Dizzy's AHA-1542CP PNP ROM dump. */
aha1542cp_pnp_rom[0x26] = 0x03;
/* Insert the terminator and the checksum byte that will later
be filled in by the isapnp code. */
aha1542cp_pnp_rom[dev->pnp_len + 5] = 0x79;

File diff suppressed because it is too large Load Diff

View File

@@ -114,6 +114,7 @@
#define INTR_FC 0x08
#define INTR_BS 0x10
#define INTR_DC 0x20
#define INTR_ILL 0x40
#define INTR_RST 0x80
#define SEQ_0 0x0
@@ -174,12 +175,11 @@ typedef struct esp_t {
uint8_t bus;
uint8_t id, lun;
Fifo8 cmdfifo;
uint32_t do_cmd;
uint8_t cmdfifo_cdb_offset;
int data_ready;
int32_t xfer_counter;
int dma_enabled;
int32_t xfer_counter;
int dma_enabled;
uint32_t buffer_pos;
uint32_t dma_regs[8];
@@ -198,6 +198,7 @@ typedef struct esp_t {
struct {
uint8_t mode;
uint8_t status;
int interrupt;
int pos;
} dma_86c01;
@@ -239,7 +240,7 @@ static void esp_dma_ti_check(esp_t *dev);
static void esp_nodma_ti_dataout(esp_t *dev);
static void esp_pci_soft_reset(esp_t *dev);
static void esp_pci_hard_reset(esp_t *dev);
static void handle_ti(void *priv);
static void handle_ti(esp_t *dev);
static int
esp_cdb_length(uint8_t *buf)
@@ -253,7 +254,7 @@ esp_cdb_length(uint8_t *buf)
break;
case 1:
case 2:
case 6:
case 6: /*Vendor unique*/
cdb_len = 10;
break;
case 4:
@@ -292,9 +293,11 @@ esp_irq(esp_t *dev, int level)
if (dev->mca) {
if (level) {
picintlevel(1 << dev->irq, &dev->irq_state);
dev->dma_86c01.mode |= 0x40;
esp_log("Raising IRQ...\n");
} else {
picintclevel(1 << dev->irq, &dev->irq_state);
dev->dma_86c01.mode &= ~0x40;
esp_log("Lowering IRQ...\n");
}
} else {
@@ -307,8 +310,8 @@ esp_irq(esp_t *dev, int level)
* DMA_STAT_DONE and the ESP IRQ arriving which is visible to the
* guest that can cause confusion e.g. Linux
*/
if ((dev->dma_regs[DMA_CMD] & DMA_CMD_MASK) == 0x3 &&
dev->dma_regs[DMA_WBC] == 0)
if (((dev->dma_regs[DMA_CMD] & DMA_CMD_MASK) == 0x03) &&
(dev->dma_regs[DMA_WBC] == 0))
dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
} else
dev->dma_regs[DMA_STAT] &= ~DMA_STAT_SCSIINT;
@@ -383,7 +386,7 @@ esp_get_tc(esp_t *dev)
{
uint32_t dmalen;
dmalen = dev->rregs[ESP_TCLO];
dmalen = dev->rregs[ESP_TCLO] & 0xff;
dmalen |= dev->rregs[ESP_TCMID] << 8;
dmalen |= dev->rregs[ESP_TCHI] << 16;
@@ -395,10 +398,11 @@ esp_set_tc(esp_t *dev, uint32_t dmalen)
{
uint32_t old_tc = esp_get_tc(dev);
dev->rregs[ESP_TCLO] = dmalen;
dev->rregs[ESP_TCLO] = dmalen & 0xff;
dev->rregs[ESP_TCMID] = dmalen >> 8;
dev->rregs[ESP_TCHI] = dmalen >> 16;
esp_log("OLDTC=%d, DMALEN=%d.\n", old_tc, dmalen);
if (old_tc && !dmalen)
dev->rregs[ESP_RSTAT] |= STAT_TC;
}
@@ -408,10 +412,11 @@ esp_get_stc(esp_t *dev)
{
uint32_t dmalen;
dmalen = dev->wregs[ESP_TCLO];
dmalen |= dev->wregs[ESP_TCMID] << 8;
dmalen |= dev->wregs[ESP_TCHI] << 16;
dmalen = dev->wregs[ESP_TCLO] & 0xff;
dmalen |= (dev->wregs[ESP_TCMID] << 8);
dmalen |= (dev->wregs[ESP_TCHI] << 16);
esp_log("STCW=%d.\n", dmalen);
return dmalen;
}
@@ -459,25 +464,25 @@ esp_transfer_data(esp_t *dev)
dev->rregs[ESP_RSEQ] = SEQ_CD;
break;
case CMD_SELATNS:
case (CMD_SELATNS | CMD_DMA):
/*
* Initial incoming data xfer is complete so raise command
* completion interrupt
*/
dev->rregs[ESP_RINTR] |= INTR_BS;
dev->rregs[ESP_RSEQ] = SEQ_MO;
break;
case CMD_SELATNS:
case (CMD_SELATNS | CMD_DMA):
/*
* Initial incoming data xfer is complete so raise command
* completion interrupt
*/
dev->rregs[ESP_RINTR] |= INTR_BS;
dev->rregs[ESP_RSEQ] = SEQ_MO;
break;
case CMD_TI:
case (CMD_TI | CMD_DMA):
/*
* Bus service interrupt raised because of initial change to
* DATA phase
*/
dev->rregs[ESP_CMD] = 0;
dev->rregs[ESP_RINTR] |= INTR_BS;
break;
case CMD_TI:
case (CMD_TI | CMD_DMA):
/*
* Bus service interrupt raised because of initial change to
* DATA phase
*/
dev->rregs[ESP_CMD] = 0;
dev->rregs[ESP_RINTR] |= INTR_BS;
break;
}
esp_raise_irq(dev);
@@ -621,16 +626,13 @@ esp_hard_reset(esp_t *dev)
{
memset(dev->rregs, 0, ESP_REGS);
memset(dev->wregs, 0, ESP_REGS);
dev->tchi_written = 0;
dev->ti_size = 0;
fifo8_reset(&dev->fifo);
fifo8_reset(&dev->cmdfifo);
dev->dma = 0;
dev->do_cmd = 0;
dev->tchi_written = 0;
dev->rregs[ESP_CFG1] = dev->mca ? dev->HostID : 7;
esp_log("ESP Reset\n");
for (uint8_t i = 0; i < 16; i++)
scsi_device_reset(&scsi_devices[dev->bus][i]);
timer_stop(&dev->timer);
}
@@ -681,7 +683,7 @@ esp_do_dma(esp_t *dev)
len = esp_get_tc(dev);
switch (esp_get_phase(dev)) {
switch (esp_get_phase(dev)) {
case STAT_MO:
len = MIN(len, fifo8_num_free(&dev->cmdfifo));
if (dev->mca) {
@@ -787,7 +789,6 @@ esp_do_dma(esp_t *dev)
esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, len, WRITE_TO_DEVICE);
esp_set_tc(dev, esp_get_tc(dev) - len);
dev->buffer_pos += len;
dev->xfer_counter -= len;
dev->ti_size += len;
@@ -827,6 +828,7 @@ esp_do_dma(esp_t *dev)
/* Defer until data is available. */
return;
}
if (len > dev->xfer_counter)
len = dev->xfer_counter;
@@ -861,14 +863,6 @@ esp_do_dma(esp_t *dev)
break;
}
if ((dev->xfer_counter <= 0) && !dev->ti_size && esp_get_tc(dev)) {
/* If the guest underflows TC then terminate SCSI request */
esp_log("ESP SCSI Read finished (underflow).\n");
scsi_device_command_phase1(sd);
esp_command_complete(dev, sd->status);
return;
}
if ((dev->xfer_counter <= 0) && (fifo8_num_used(&dev->fifo) < 2)) {
/* Defer until the scsi layer has completed */
if (dev->ti_size <= 0) {
@@ -1241,10 +1235,8 @@ handle_pad(esp_t *dev)
}
static void
handle_ti(void *priv)
handle_ti(esp_t *dev)
{
esp_t *dev = (esp_t *) priv;
if (dev->dma) {
esp_log("ESP Handle TI, do data, minlen = %i\n", esp_get_tc(dev));
esp_do_dma(dev);
@@ -1329,8 +1321,6 @@ esp_callback(void *priv)
handle_pad(dev);
}
}
esp_log("ESP DMA activated = %d, CMD activated = %d, CMD = %02x\n", dev->dma_enabled, dev->do_cmd, (dev->rregs[ESP_CMD] & CMD_CMD));
}
static uint32_t
@@ -1353,13 +1343,15 @@ esp_reg_read(esp_t *dev, uint32_t saddr)
esp_lower_irq(dev);
esp_log("ESP RINTR read old val = %02x\n", ret);
break;
case ESP_TCHI:
/* Return the unique id if the value has never been written */
if (!dev->tchi_written && !dev->mca) {
esp_log("ESP TCHI read id 0x12\n");
ret = TCHI_AM53C974;
} else
ret = dev->rregs[saddr];
case ESP_TCHI: /* Return the unique id if the value has never been written */
if (dev->mca) {
ret = dev->rregs[ESP_TCHI];
} else {
if (!dev->tchi_written)
ret = TCHI_AM53C974;
else
ret = dev->rregs[ESP_TCHI];
}
break;
case ESP_RFLAGS:
ret = fifo8_num_used(&dev->fifo);
@@ -1376,14 +1368,13 @@ static void
esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val)
{
esp_log("Write reg %02x = %02x\n", saddr, val);
switch (saddr) {
case ESP_TCHI:
dev->tchi_written = 1;
fallthrough;
case ESP_TCLO:
case ESP_TCMID:
esp_log("Transfer count regs %02x = %i\n", saddr, val);
esp_log("ESP TCW reg%02x = %02x.\n", saddr, val);
dev->rregs[ESP_RSTAT] &= ~STAT_TC;
break;
case ESP_FIFO:
@@ -1393,14 +1384,18 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val)
esp_do_nodma(dev);
break;
case ESP_CMD:
dev->rregs[saddr] = val;
dev->rregs[ESP_CMD] = val;
if (val & CMD_DMA) {
dev->dma = 1;
/* Reload DMA counter. */
esp_set_tc(dev, esp_get_stc(dev));
if (!esp_get_stc(dev))
esp_set_tc(dev, 0x10000);
if (!esp_get_stc(dev)) {
if (dev->rregs[ESP_CFG2] & 0x40)
esp_set_tc(dev, 0x1000000);
else
esp_set_tc(dev, 0x10000);
}
} else {
dev->dma = 0;
esp_log("ESP Command not for DMA\n");
@@ -1481,6 +1476,8 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val)
}
break;
case ESP_WBUSID:
esp_log("ESP BUS ID=%d.\n", val & BUSID_DID);
break;
case ESP_WSEL:
case ESP_WSYNTP:
case ESP_WSYNO:
@@ -1505,6 +1502,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val)
static void
esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir)
{
uint32_t sg_pos = 0;
uint32_t addr;
int expected_dir;
@@ -1513,31 +1511,58 @@ esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir)
else
expected_dir = WRITE_TO_DEVICE;
esp_log("ESP DMA WBC = %d, addr = %06x, expected direction = %d, dir = %i\n", dev->dma_regs[DMA_WBC], dev->dma_regs[DMA_SPA], expected_dir, dir);
if (dir != expected_dir) {
esp_log("ESP unexpected direction\n");
return;
}
addr = dev->dma_regs[DMA_WAC];
if (dev->dma_regs[DMA_WBC] < len)
len = dev->dma_regs[DMA_WBC];
if (dev->dma_regs[DMA_CMD] & DMA_CMD_MDL) {
if (dev->dma_regs[DMA_STC]) {
if (dev->dma_regs[DMA_WBC] > len)
dev->dma_regs[DMA_WBC] = len;
if (expected_dir)
dma_bm_write(addr, buf, len, 4);
else
dma_bm_read(addr, buf, len, 4);
esp_log("WAC MDL=%08x, STC=%d, ID=%d.\n", dev->dma_regs[DMA_WAC] | (dev->dma_regs[DMA_WMAC] & 0xff000), dev->dma_regs[DMA_STC], dev->id);
for (uint32_t i = 0; i < len; i++) {
addr = dev->dma_regs[DMA_WAC];
esp_log("DMA: Address = %08X, Length = %08X (%02X %02X %02X %02X -> %02X %02X %02X %02X)\n", dev->dma_regs[DMA_SPA], len,
ram[dev->dma_regs[DMA_SPA]], ram[dev->dma_regs[DMA_SPA] + 1], ram[dev->dma_regs[DMA_SPA] + 2], ram[dev->dma_regs[DMA_SPA] + 3],
buf[0], buf[1], buf[2], buf[3]);
if (expected_dir)
dma_bm_write(addr | (dev->dma_regs[DMA_WMAC] & 0xff000), &buf[sg_pos], len, 4);
else
dma_bm_read(addr | (dev->dma_regs[DMA_WMAC] & 0xff000), &buf[sg_pos], len, 4);
/* update status registers */
dev->dma_regs[DMA_WBC] -= len;
dev->dma_regs[DMA_WAC] += len;
if (dev->dma_regs[DMA_WBC] == 0)
dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
sg_pos++;
dev->dma_regs[DMA_WBC]--;
dev->dma_regs[DMA_WAC]++;
if (dev->dma_regs[DMA_WAC] & 0x1000) {
dev->dma_regs[DMA_WAC] = 0;
dev->dma_regs[DMA_WMAC] += 0x1000;
}
if (dev->dma_regs[DMA_WBC] <= 0) {
dev->dma_regs[DMA_WBC] = 0;
dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
}
}
}
} else {
if (dev->dma_regs[DMA_WBC] < len)
len = dev->dma_regs[DMA_WBC];
addr = dev->dma_regs[DMA_WAC];
if (expected_dir)
dma_bm_write(addr, buf, len, 4);
else
dma_bm_read(addr, buf, len, 4);
/* update status registers */
dev->dma_regs[DMA_WBC] -= len;
dev->dma_regs[DMA_WAC] += len;
if (dev->dma_regs[DMA_WBC] == 0)
dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
}
}
static uint32_t
@@ -1566,7 +1591,7 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val)
switch (saddr) {
case DMA_CMD:
dev->dma_regs[saddr] = val;
dev->dma_regs[DMA_CMD] = val;
esp_log("ESP PCI DMA Write CMD = %02x\n", val & DMA_CMD_MASK);
switch (val & DMA_CMD_MASK) {
case 0: /*IDLE*/
@@ -1580,21 +1605,32 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val)
scsi_device_command_stop(&scsi_devices[dev->bus][dev->id]);
break;
case 3: /*START*/
dev->dma_regs[DMA_WAC] = dev->dma_regs[DMA_SPA];
dev->dma_regs[DMA_WMAC] = dev->dma_regs[DMA_SMDLA] & 0xfffffffc;
if (!dev->dma_regs[DMA_STC])
dev->dma_regs[DMA_STC] = 0x1000000;
dev->dma_regs[DMA_WBC] = dev->dma_regs[DMA_STC];
dev->dma_regs[DMA_WAC] = dev->dma_regs[DMA_SPA];
dev->dma_regs[DMA_WMAC] = dev->dma_regs[DMA_SMDLA];
dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_BCMBLT | DMA_STAT_SCSIINT | DMA_STAT_DONE | DMA_STAT_ABORT | DMA_STAT_ERROR | DMA_STAT_PWDN);
esp_dma_enable(dev, 1);
esp_log("PCI DMA enable\n");
esp_log("PCI DMA enable, MDL bit=%02x, SPA=%08x, SMDLA=%08x, STC=%d, ID=%d, SCSICMD=%02x.\n", val & DMA_CMD_MDL, dev->dma_regs[DMA_SPA], dev->dma_regs[DMA_SMDLA], dev->dma_regs[DMA_STC], dev->id, dev->cmdfifo.data[1]);
break;
default: /* can't happen */
abort();
break;
}
break;
case DMA_STC:
dev->dma_regs[DMA_STC] = val;
esp_log("DMASTC PCI write=%08x.\n", val);
break;
case DMA_SPA:
dev->dma_regs[DMA_SPA] = val;
esp_log("DMASPA PCI write=%08x.\n", val);
break;
case DMA_SMDLA:
dev->dma_regs[saddr] = val;
dev->dma_regs[DMA_SMDLA] = val;
esp_log("DMASMDLA PCI write=%08x.\n", val);
break;
case DMA_STAT:
if (dev->sbac & SBAC_STATUS) {
@@ -1629,7 +1665,7 @@ esp_pci_hard_reset(esp_t *dev)
dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_BCMBLT | DMA_STAT_SCSIINT
| DMA_STAT_DONE | DMA_STAT_ABORT
| DMA_STAT_ERROR);
dev->dma_regs[DMA_WMAC] = 0xfffffffd;
dev->dma_regs[DMA_WMAC] = 0xfffffffc;
}
static uint32_t
@@ -1680,7 +1716,7 @@ esp_io_pci_write(esp_t *dev, uint32_t addr, uint32_t val, unsigned int size)
current = dev->wregs[addr >> 2];
} else if (addr < 0x60) {
current = dev->dma_regs[(addr - 0x40) >> 2];
} else if (addr < 0x74) {
} else if (addr == 0x70) {
current = dev->sbac;
}
@@ -2008,7 +2044,7 @@ esp_pci_read(UNUSED(int func), int addr, void *priv)
case 0x07:
return esp_pci_regs[0x07] | 0x02;
case 0x08:
return 0; /*Revision ID*/
return 0x10; /*Revision ID*/
case 0x09:
return 0; /*Programming interface*/
case 0x0A:
@@ -2018,7 +2054,7 @@ esp_pci_read(UNUSED(int func), int addr, void *priv)
case 0x0E:
return 0; /*Header type */
case 0x10:
return (esp_pci_bar[0].addr_regs[0] & 0x80) | 0x01; /*I/O space*/
return esp_pci_bar[0].addr_regs[0] | 0x01; /*I/O space*/
case 0x11:
return esp_pci_bar[0].addr_regs[1];
case 0x12:
@@ -2082,7 +2118,7 @@ esp_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
switch (addr) {
case 0x04:
valxor = (val & 3) ^ esp_pci_regs[addr];
valxor = (val & 0x01) ^ esp_pci_regs[addr];
if (valxor & PCI_COMMAND_IO) {
esp_io_remove(dev, dev->PCIBase, 0x80);
if ((val & PCI_COMMAND_IO) && (dev->PCIBase != 0))
@@ -2215,6 +2251,8 @@ dc390_init(UNUSED(const device_t *info))
}
esp_pci_hard_reset(dev);
for (uint8_t i = 0; i < 16; i++)
scsi_device_reset(&scsi_devices[dev->bus][i]);
timer_add(&dev->timer, esp_callback, dev, 0);
@@ -2240,12 +2278,12 @@ ncr53c9x_in(uint16_t port, void *priv)
break;
case 0x0c:
if (dev->rregs[ESP_RSTAT] & STAT_INT)
if (dev->dma_86c01.mode & 0x40)
dev->dma_86c01.status |= 0x01;
else
dev->dma_86c01.status &= ~0x01;
if ((dev->dma_86c01.mode & 0x40) || dev->dma_enabled)
if (dev->dma_enabled)
dev->dma_86c01.status |= 0x02;
else
dev->dma_86c01.status &= ~0x02;
@@ -2258,7 +2296,7 @@ ncr53c9x_in(uint16_t port, void *priv)
}
}
esp_log("[%04X:%08X]: NCR53c9x DMA read port = %02x, ret = %02x.\n\n", CS, cpu_state.pc, port, ret);
esp_log("[%04X:%08X]: NCR53c9x DMA read port = %02x, ret = %02x, local = %d.\n\n", CS, cpu_state.pc, port, ret, dev->local);
return ret;
}
@@ -2282,7 +2320,7 @@ ncr53c9x_out(uint16_t port, uint16_t val, void *priv)
port &= 0x1f;
esp_log("[%04X:%08X]: NCR53c9x DMA write port = %02x, val = %02x\n", CS, cpu_state.pc, port, val);
esp_log("[%04X:%08X]: NCR53c9x DMA write port = %02x, val = %02x.\n\n", CS, cpu_state.pc, port, val);
if (port >= 0x10)
esp_reg_write(dev, port - 0x10, val);
@@ -2360,6 +2398,8 @@ ncr53c9x_mca_write(int port, uint8_t val, void *priv)
ncr53c9x_outb, ncr53c9x_outw, NULL, dev);
esp_hard_reset(dev);
for (uint8_t i = 0; i < 8; i++)
scsi_device_reset(&scsi_devices[dev->bus][i]);
}
/* Say hello. */
@@ -2377,7 +2417,7 @@ ncr53c9x_mca_feedb(void *priv)
}
static void *
ncr53c9x_mca_init(UNUSED(const device_t *info))
ncr53c9x_mca_init(const device_t *info)
{
esp_t *dev;
@@ -2387,6 +2427,7 @@ ncr53c9x_mca_init(UNUSED(const device_t *info))
dev->bus = scsi_get_bus();
dev->mca = 1;
dev->local = info->local;
fifo8_create(&dev->fifo, ESP_FIFO_SZ);
fifo8_create(&dev->cmdfifo, ESP_CMDFIFO_SZ);
@@ -2396,6 +2437,8 @@ ncr53c9x_mca_init(UNUSED(const device_t *info))
mca_add(ncr53c9x_mca_read, ncr53c9x_mca_write, ncr53c9x_mca_feedb, NULL, dev);
esp_hard_reset(dev);
for (uint8_t i = 0; i < 8; i++)
scsi_device_reset(&scsi_devices[dev->bus][i]);
timer_add(&dev->timer, esp_callback, dev, 0);
@@ -2446,7 +2489,7 @@ const device_t dc390_pci_device = {
};
const device_t am53c974_pci_device = {
.name = "AMD 53c974 PCI",
.name = "AMD 53c974A PCI",
.internal_name = "am53c974",
.flags = DEVICE_PCI,
.local = 1,

View File

@@ -509,6 +509,9 @@ t128_init(const device_t *info)
if (!t128->bios_enabled && !(info->flags & DEVICE_MCA))
t128->status |= 0x80;
if (info->flags & DEVICE_MCA)
t128->status |= 0x08;
if (info->local == 0)
timer_add(&t128->timer, t128_callback, t128, 0);

View File

@@ -34,6 +34,7 @@
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/sio.h>
#include <86box/plat_fallthrough.h>
typedef struct pc87307_t {
uint8_t id;
@@ -323,8 +324,12 @@ pc87307_write(uint16_t port, uint8_t val, void *priv)
}
break;
case 0x60:
if (dev->regs[0x07] == 0x04) {
val &= 0x03;
}
fallthrough;
case 0x62:
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x07;
dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val;
if ((dev->cur_reg == 0x62) && (dev->regs[0x07] != 0x07))
break;
switch (dev->regs[0x07]) {

File diff suppressed because it is too large Load Diff

View File

@@ -1238,7 +1238,7 @@ azt_init(const device_t *info)
fm_driver_get(FM_YMF262, &azt2316a->sb->opl);
sb_dsp_set_real_opl(&azt2316a->sb->dsp, 1);
sb_dsp_init(&azt2316a->sb->dsp, SBPRO2, azt2316a->type, azt2316a);
sb_dsp_init(&azt2316a->sb->dsp, SBPRO2_DSP_302, azt2316a->type, azt2316a);
sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr);
sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq);
sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma);

View File

@@ -497,7 +497,7 @@ cmi8x38_sb_mixer_write(uint16_t addr, uint8_t val, void *priv)
/* Set TDMA channels if auto-detection is enabled. */
if ((dev->io_regs[0x27] & 0x01) && (mixer->index == 0x81)) {
dev->tdma_8 = dev->sb->dsp.sb_8_dmanum;
if (dev->sb->dsp.sb_type >= SB16)
if (dev->sb->dsp.sb_type >= SB16_DSP_404)
dev->tdma_16 = dev->sb->dsp.sb_16_dmanum;
}
} else {
@@ -879,7 +879,7 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv)
dev->sb->dsp.sbleftright_default = !!(val & 0x02);
/* Enable or disable SB16 mode. */
dev->sb->dsp.sb_type = (val & 0x01) ? SBPRO2 : SB16;
dev->sb->dsp.sb_type = (val & 0x01) ? SBPRO2_DSP_302 : SB16_DSP_405;
break;
case 0x22:

View File

@@ -95,15 +95,15 @@ cms_write(uint16_t addr, uint8_t val, void *priv)
int chip = (addr & 2) >> 1;
switch (addr & 0xf) {
case 1:
case 0x1: /* SAA #1 Register Select Port */
cms->addrs[0] = val & 31;
break;
case 3:
case 0x3: /* SAA #2 Register Select Port */
cms->addrs[1] = val & 31;
break;
case 0:
case 2:
case 0x0: /* SAA #1 Data Port */
case 0x2: /* SAA #2 Data Port */
cms_update(cms);
cms->regs[chip][cms->addrs[chip] & 31] = val;
switch (cms->addrs[chip] & 31) {
@@ -145,8 +145,9 @@ cms_write(uint16_t addr, uint8_t val, void *priv)
break;
}
break;
case 0x6:
case 0x7:
case 0x6: /* GameBlaster Write Port */
case 0x7: /* GameBlaster Write Port */
cms->latched_data = val;
break;
@@ -161,14 +162,14 @@ cms_read(uint16_t addr, void *priv)
const cms_t *cms = (cms_t *) priv;
switch (addr & 0xf) {
case 0x1:
case 0x1: /* SAA #1 Register Select Port */
return cms->addrs[0];
case 0x3:
case 0x3: /* SAA #2 Register Select Port */
return cms->addrs[1];
case 0x4:
case 0x4: /* GameBlaster Read port (Always returns 0x7F) */
return 0x7f;
case 0xa:
case 0xb:
case 0xa: /* GameBlaster Read Port */
case 0xb: /* GameBlaster Read Port */
return cms->latched_data;
default:

View File

@@ -394,7 +394,7 @@ optimc_init(const device_t *info)
optimc->fm_type = (info->local & OPTIMC_OPL4) ? FM_YMF278B : FM_YMF262;
sb_dsp_set_real_opl(&optimc->sb->dsp, optimc->fm_type != FM_YMF278B);
sb_dsp_init(&optimc->sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, optimc);
sb_dsp_init(&optimc->sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, optimc);
sb_dsp_setaddr(&optimc->sb->dsp, optimc->cur_addr);
sb_dsp_setirq(&optimc->sb->dsp, optimc->cur_irq);
sb_dsp_setdma8(&optimc->sb->dsp, optimc->cur_dma);

View File

@@ -2314,7 +2314,7 @@ pas16_init(const device_t *info)
pas16->has_scsi = (!pas16->type) || (pas16->type == 0x0f);
fm_driver_get(FM_YMF262, &pas16->opl);
sb_dsp_set_real_opl(&pas16->dsp, 1);
sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16);
sb_dsp_init(&pas16->dsp, SB_DSP_201, SB_SUBTYPE_DEFAULT, pas16);
pas16->mpu = (mpu_t *) malloc(sizeof(mpu_t));
memset(pas16->mpu, 0, sizeof(mpu_t));
mpu401_init(pas16->mpu, 0, 0, M_UART, device_get_config_int("receive_input401"));

File diff suppressed because it is too large Load Diff

View File

@@ -77,13 +77,33 @@ static int sb_commands[256] = {
-1, -1, 0, 0, -1, -1, -1, -1, -1, 1, 2, -1, -1, -1, -1, 0
};
#if 0
// Currently unused, here for reference if ever needed
char sb202_copyright[] = "COPYRIGHT(C) CREATIVE TECHNOLOGY PTE. LTD. (1991) "
#endif
char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
uint16_t sb_dsp_versions[] = { 0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x40c, 0x40d, 0x410 };
uint16_t sb_dsp_versions[] = {
0, /* Pad */
0, /* SADLIB - No DSP */
0x105, /* SB_DSP_105 - SB1/1.5, DSP v1.05 */
0x200, /* SB_DSP_200 - SB1.5/2, DSP v2.00 */
0x201, /* SB_DSP_201 - SB1.5/2, DSP v2.01 - needed for high-speed DMA */
0x202, /* SB_DSP_202 - SB2, DSP v2.02 */
0x300, /* SB_PRO_DSP_300 - SB Pro, DSP v3.00 */
0x302, /* SBPRO2_DSP_302 - SB Pro 2, DSP v3.02 + OPL3 */
0x404, /* SB16_DSP_404 - DSP v4.04 + OPL3 */
0x405, /* SB16_405 - DSP v4.05 + OPL3 */
0x406, /* SB16_406 - DSP v4.06 + OPL3 */
0x40b, /* SB16_411 - DSP v4.11 + OPL3 */
0x40c, /* SBAWE32 - DSP v4.12 + OPL3 */
0x40d, /* SBAWE32PNP - DSP v4.13 + OPL3 */
0x410 /* SBAWE64 - DSP v4.16 + OPL3 */
};
/*These tables were 'borrowed' from DOSBox*/
int8_t scaleMap4[64] = {
0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7,
1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15,
0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7,
1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15,
2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30,
4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60
};
@@ -525,7 +545,7 @@ sb_doreset(sb_dsp_t *dsp)
sb_commands[8] = 1;
sb_commands[9] = 1;
} else {
if (dsp->sb_type >= SB16)
if (dsp->sb_type >= SB16_DSP_404)
sb_commands[8] = 1;
else
sb_commands[8] = -1;
@@ -1206,7 +1226,7 @@ sb_exec_command(sb_dsp_t *dsp)
/* Update 8051 ram with the current DSP command.
See https://github.com/joncampbell123/dosbox-x/issues/1044 */
if (dsp->sb_type >= SB16) {
if (dsp->sb_type >= SB16_DSP_404) {
dsp->sb_8051_ram[0x20] = dsp->sb_command;
}
@@ -1232,15 +1252,15 @@ sb_exec_command(sb_dsp_t *dsp)
switch (dsp->sb_command) {
case 0x01: /* ???? */
if (dsp->sb_type >= SB16)
if (dsp->sb_type >= SB16_DSP_404)
dsp->asp_data_len = dsp->sb_data[0] + (dsp->sb_data[1] << 8) + 1;
break;
case 0x03: /* ASP status */
if (dsp->sb_type >= SB16)
if (dsp->sb_type >= SB16_DSP_404)
sb_add_data(dsp, 0);
break;
case 0x04: /* ASP set mode register */
if (dsp->sb_type >= SB16) {
if (dsp->sb_type >= SB16_DSP_404) {
dsp->sb_asp_mode = dsp->sb_data[0];
if (dsp->sb_asp_mode & 4)
dsp->sb_asp_ram_index = 0;
@@ -1248,7 +1268,7 @@ sb_exec_command(sb_dsp_t *dsp)
} /* else DSP Status (Obsolete) */
break;
case 0x05: /* ASP set codec parameter */
if (dsp->sb_type >= SB16) {
if (dsp->sb_type >= SB16_DSP_404) {
sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]);
}
break;
@@ -1278,9 +1298,9 @@ sb_exec_command(sb_dsp_t *dsp)
sb_dsp_log("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); /* 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen */
break;
}
if (dsp->sb_type == SBAWE64) /* AWE64 has no ASP or a socket for it */
if (dsp->sb_type == SBAWE64_DSP_416) /* AWE64 has no ASP or a socket for it */
sb_add_data(dsp, 0xFF);
else if (dsp->sb_type >= SB16)
else if (dsp->sb_type >= SB16_DSP_404)
sb_add_data(dsp, 0x18);
break;
case 0x09: /* AZTECH mode set */
@@ -1296,7 +1316,7 @@ sb_exec_command(sb_dsp_t *dsp)
}
break;
case 0x0E: /* ASP set register */
if (dsp->sb_type >= SB16) {
if (dsp->sb_type >= SB16_DSP_404) {
dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1];
if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory write */
@@ -1315,7 +1335,7 @@ sb_exec_command(sb_dsp_t *dsp)
}
break;
case 0x0F: /* ASP get register */
if (dsp->sb_type >= SB16) {
if (dsp->sb_type >= SB16_DSP_404) {
if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory read */
if (dsp->sb_asp_mode & 8)
dsp->sb_asp_ram_index = 0;
@@ -1359,11 +1379,11 @@ sb_exec_command(sb_dsp_t *dsp)
}
break;
case 0x1C: /* 8-bit autoinit DMA output */
if (dsp->sb_type >= SB15)
if (dsp->sb_type >= SB_DSP_200)
sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen);
break;
case 0x1F: /* 2-bit ADPCM autoinit output */
if (dsp->sb_type >= SB15) {
if (dsp->sb_type >= SB_DSP_200) {
sb_start_dma(dsp, 1, 1, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv);
dsp->sb_8_length--;
@@ -1388,7 +1408,7 @@ sb_exec_command(sb_dsp_t *dsp)
case 0x28: /* Direct ADC, 8-bit (Burst) */
break;
case 0x2C: /* 8-bit autoinit DMA input */
if (dsp->sb_type >= SB15)
if (dsp->sb_type >= SB_DSP_200)
sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
break;
case 0x30: /* MIDI Polling mode input */
@@ -1405,7 +1425,7 @@ sb_exec_command(sb_dsp_t *dsp)
case 0x33: /* MIDI Read Timestamp Interrupt */
break;
case 0x34: /* MIDI In poll */
if (dsp->sb_type < SB2)
if (dsp->sb_type < SB_DSP_200)
break;
sb_dsp_log("MIDI poll in\n");
dsp->midi_in_poll = 1;
@@ -1413,7 +1433,7 @@ sb_exec_command(sb_dsp_t *dsp)
dsp->uart_irq = 0;
break;
case 0x35: /* MIDI In irq */
if (dsp->sb_type < SB2)
if (dsp->sb_type < SB_DSP_200)
break;
sb_dsp_log("MIDI irq in\n");
dsp->midi_in_poll = 0;
@@ -1432,7 +1452,7 @@ sb_exec_command(sb_dsp_t *dsp)
temp = 256 - dsp->sb_data[0];
temp = 1000000 / temp;
sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho);
if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16))
if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16_DSP_404))
recalc_sb16_filter(0, temp);
dsp->sb_freq = temp;
if (IS_ESS(dsp)) {
@@ -1441,7 +1461,7 @@ sb_exec_command(sb_dsp_t *dsp)
break;
case 0x41: /* Set output sampling rate */
case 0x42: /* Set input sampling rate */
if (dsp->sb_type >= SB16) {
if (dsp->sb_type >= SB16_DSP_404) {
dsp->sblatcho = (double) ((double) TIMER_USEC * (1000000.0 / (double) (dsp->sb_data[1] + (dsp->sb_data[0] << 8))));
sb_dsp_log("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho);
temp = dsp->sb_freq;
@@ -1459,7 +1479,8 @@ sb_exec_command(sb_dsp_t *dsp)
case 0x47: /* Continue Auto-Initialize DMA, 16-bit */
break;
case 0x48: /* Set DSP block transfer size */
dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8);
if (dsp->sb_type >= SB_DSP_200)
dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8);
break;
case 0x65: /* 4-bit ESPCM output with reference */
case 0x64: /* 4-bit ESPCM output */
@@ -1534,7 +1555,7 @@ sb_exec_command(sb_dsp_t *dsp)
}
break;
case 0x7D: /* 4-bit ADPCM autoinit output */
if (dsp->sb_type >= SB15) {
if (dsp->sb_type >= SB_DSP_200) {
sb_start_dma(dsp, 1, 1, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv);
dsp->sb_8_length--;
@@ -1542,7 +1563,7 @@ sb_exec_command(sb_dsp_t *dsp)
}
break;
case 0x7F: /* 2.6-bit ADPCM autoinit output */
if (dsp->sb_type >= SB15) {
if (dsp->sb_type >= SB_DSP_200) {
sb_start_dma(dsp, 1, 1, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv);
dsp->sb_8_length--;
@@ -1555,24 +1576,24 @@ sb_exec_command(sb_dsp_t *dsp)
timer_set_delay_u64(&dsp->output_timer, (uint64_t) trunc(dsp->sblatcho));
break;
case 0x90: /* High speed 8-bit autoinit DMA output */
if (dsp->sb_type >= SB2)
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen);
break;
case 0x91: /* High speed 8-bit single cycle DMA output */
if (dsp->sb_type >= SB2)
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
sb_start_dma(dsp, 1, 0, 0, dsp->sb_8_autolen);
break;
case 0x98: /* High speed 8-bit autoinit DMA input */
if (dsp->sb_type >= SB2)
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_8_autolen);
break;
case 0x99: /* High speed 8-bit single cycle DMA input */
if (dsp->sb_type >= SB2)
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_8_autolen);
break;
case 0xA0: /* Set input mode to mono */
case 0xA8: /* Set input mode to stereo */
if ((dsp->sb_type < SB2) || (dsp->sb_type > SBPRO2))
if ((dsp->sb_type < SBPRO_DSP_300) || (dsp->sb_type > SBPRO2_DSP_302))
break;
/* TODO: Implement. 3.xx-only command. */
break;
@@ -1584,7 +1605,7 @@ sb_exec_command(sb_dsp_t *dsp)
case 0xB5:
case 0xB6:
case 0xB7: /* 16-bit DMA output */
if (dsp->sb_type >= SB16) {
if (dsp->sb_type >= SB16_DSP_404) {
sb_start_dma(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0],
dsp->sb_data[1] + (dsp->sb_data[2] << 8));
dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
@@ -1598,7 +1619,7 @@ sb_exec_command(sb_dsp_t *dsp)
case 0xBD:
case 0xBE:
case 0xBF: /* 16-bit DMA input */
if (dsp->sb_type >= SB16) {
if (dsp->sb_type >= SB16_DSP_404) {
sb_start_dma_i(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0],
dsp->sb_data[1] + (dsp->sb_data[2] << 8));
dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
@@ -1612,7 +1633,7 @@ sb_exec_command(sb_dsp_t *dsp)
case 0xC5:
case 0xC6:
case 0xC7: /* 8-bit DMA output */
if (dsp->sb_type >= SB16) {
if (dsp->sb_type >= SB16_DSP_404) {
sb_start_dma(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0],
dsp->sb_data[1] + (dsp->sb_data[2] << 8));
dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
@@ -1626,7 +1647,7 @@ sb_exec_command(sb_dsp_t *dsp)
case 0xCD:
case 0xCE:
case 0xCF: /* 8-bit DMA input */
if (dsp->sb_type >= SB16) {
if (dsp->sb_type >= SB16_DSP_404) {
sb_start_dma_i(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0],
dsp->sb_data[1] + (dsp->sb_data[2] << 8));
dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
@@ -1638,20 +1659,20 @@ sb_exec_command(sb_dsp_t *dsp)
break;
case 0xD1: /* Speaker on */
if (IS_NOT_ESS(dsp)) {
if (dsp->sb_type < SB15) {
if (dsp->sb_type < SB_DSP_200) {
dsp->sb_8_pause = 1;
sb_stop_dma(dsp);
} else if (dsp->sb_type < SB16)
} else if (dsp->sb_type < SB16_DSP_404)
dsp->muted = 0;
}
dsp->sb_speaker = 1;
break;
case 0xD3: /* Speaker off */
if (IS_NOT_ESS(dsp)) {
if (dsp->sb_type < SB15) {
if (dsp->sb_type < SB_DSP_201) {
dsp->sb_8_pause = 1;
sb_stop_dma(dsp);
} else if (dsp->sb_type < SB16)
} else if (dsp->sb_type < SB16_DSP_404)
dsp->muted = 1;
}
dsp->sb_speaker = 0;
@@ -1661,26 +1682,28 @@ sb_exec_command(sb_dsp_t *dsp)
sb_resume_dma(dsp, 1);
break;
case 0xD5: /* Pause 16-bit DMA */
if (dsp->sb_type >= SB16) {
if (dsp->sb_type >= SB16_DSP_404) {
dsp->sb_16_pause = 1;
sb_stop_dma(dsp);
}
break;
case 0xD6: /* Continue 16-bit DMA */
if (dsp->sb_type >= SB16) {
if (dsp->sb_type >= SB16_DSP_404) {
dsp->sb_16_pause = 0;
sb_resume_dma(dsp, 1);
}
break;
case 0xD8: /* Get speaker status */
sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0);
if (dsp->sb_type >= SB_DSP_200)
sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0);
break;
case 0xD9: /* Exit 16-bit auto-init mode */
if (dsp->sb_type >= SB16)
if (dsp->sb_type >= SB16_DSP_404)
dsp->sb_16_autoinit = 0;
break;
case 0xDA: /* Exit 8-bit auto-init mode */
dsp->sb_8_autoinit = 0;
if (dsp->sb_type >= SB_DSP_200)
dsp->sb_8_autoinit = 0;
break;
case 0xE0: /* DSP identification */
sb_add_data(dsp, ~dsp->sb_data[0]);
@@ -1721,7 +1744,7 @@ sb_exec_command(sb_dsp_t *dsp)
sb_add_data(dsp, dsp->sbe2);
break;
case 0xE3: /* DSP copyright */
if (dsp->sb_type >= SB16) {
if (dsp->sb_type >= SB16_DSP_404) {
c = 0;
while (sb16_copyright[c])
sb_add_data(dsp, sb16_copyright[c++]);
@@ -1782,15 +1805,15 @@ sb_exec_command(sb_dsp_t *dsp)
timer_set_delay_u64(&dsp->irq16_timer, (10ULL * TIMER_USEC));
break;
case 0xF8:
if (dsp->sb_type < SB16)
if (dsp->sb_type < SB16_DSP_404)
sb_add_data(dsp, 0);
break;
case 0xF9: /* SB16 8051 RAM read */
if (dsp->sb_type >= SB16)
if (dsp->sb_type >= SB16_DSP_404)
sb_add_data(dsp, dsp->sb_8051_ram[dsp->sb_data[0]]);
break;
case 0xFA: /* SB16 8051 RAM write */
if (dsp->sb_type >= SB16)
if (dsp->sb_type >= SB16_DSP_404)
dsp->sb_8051_ram[dsp->sb_data[0]] = dsp->sb_data[1];
break;
case 0xFF: /* No, that's not how you program auto-init DMA */
@@ -1800,11 +1823,24 @@ sb_exec_command(sb_dsp_t *dsp)
* http://the.earth.li/~tfm/oldpage/sb_dsp.html
* http://www.synchrondata.com/pheaven/www/area19.htm
* http://www.dcee.net/Files/Programm/Sound/
* 0E3h DSP Copyright SBPro2???
* 0F0h Sine Generator SB
* 0F1h DSP Auxiliary Status (Obsolete) SB-Pro2
* 0F2h IRQ Request, 8-bit SB
* https://github.com/schlae/sb-firmware/blob/master/sbv202.asm
* 008h Halt (Infinate Loop) SB2???
* 018h DMA playback with auto init DMA. SB2???
* 028h Auto-init direct ADC SB2???
* 036h (Timestamp) SB???
* 037h (Timestamp) SB???
* 050h Stops playback of SRAM samples SB???
* 051h Plays back samples stored in SRAM. SB???
* 058h Load data into SRAM SB???
* 059h Fetches the samples and then immediately plays them back. SB???
* 078h Auto-init DMA ADPCM SB2???
* 07Ah 2.6-bit ADPCM SB???
* 0E3h DSP Copyright SBPro2??? (SBPRO2_DSP_302)
* 0F0h Sine Generator SB (SB_DSP_105, DSP20x)
* 0F1h DSP Auxiliary Status (Obsolete) SB-Pro2 (DSP20x, SBPRO2_DSP_302)
* 0F2h IRQ Request, 8-bit SB (SB_DSP_105, DSP20x)
* 0F3h IRQ Request, 16-bit SB16
* 0F4h Perform ROM checksum SB (SB_DSP_105, DSP20x)
* 0FBh DSP Status SB16
* 0FCh DSP Auxiliary Status SB16
* 0FDh DSP Command Status SB16
@@ -1817,7 +1853,7 @@ sb_exec_command(sb_dsp_t *dsp)
/* Update 8051 ram with the last DSP command.
See https://github.com/joncampbell123/dosbox-x/issues/1044 */
if (dsp->sb_type >= SB16)
if (dsp->sb_type >= SB16_DSP_404)
dsp->sb_8051_ram[0x30] = dsp->sb_command;
}
@@ -1836,31 +1872,31 @@ sb_do_reset(sb_dsp_t *dsp, const uint8_t v)
}
void
sb_write(uint16_t a, uint8_t v, void *priv)
sb_write(uint16_t addr, uint8_t val, void *priv)
{
sb_dsp_t *dsp = (sb_dsp_t *) priv;
sb_dsp_log("[%04X:%08X] DSP: [W] %04X = %02X\n", CS, cpu_state.pc, a, v);
sb_dsp_log("[%04X:%08X] DSP: [W] %04X = %02X\n", CS, cpu_state.pc, addr, val);
/* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */
if ((dsp->sb_type < SB16) && (IS_NOT_ESS(dsp) || ((a & 0xF) != 0xE)))
a &= 0xfffe;
if ((dsp->sb_type < SB16_DSP_404) && (IS_NOT_ESS(dsp) || ((addr & 0xF) != 0xE)))
addr &= 0xfffe;
switch (a & 0xF) {
switch (addr & 0xF) {
case 6: /* Reset */
sb_do_reset(dsp, v);
sb_do_reset(dsp, val);
if (!(v & 2) && (dsp->espcm_fifo_reset & 2)) {
if (!(val & 2) && (dsp->espcm_fifo_reset & 2)) {
fifo_reset(dsp->espcm_fifo);
}
dsp->espcm_fifo_reset = v;
dsp->espcm_fifo_reset = val;
dsp->uart_midi = 0;
dsp->uart_irq = 0;
dsp->onebyte_midi = 0;
return;
case 0xC: /* Command/data write */
if (dsp->uart_midi || dsp->onebyte_midi) {
midi_raw_out_byte(v);
midi_raw_out_byte(val);
dsp->onebyte_midi = 0;
return;
}
@@ -1873,8 +1909,8 @@ sb_write(uint16_t a, uint8_t v, void *priv)
return;
}
if (dsp->sb_data_stat == -1) {
dsp->sb_command = v;
if (v == 0x01)
dsp->sb_command = val;
if (val == 0x01)
sb_add_data(dsp, 0);
dsp->sb_data_stat++;
if (IS_AZTECH(dsp)) {
@@ -1901,7 +1937,7 @@ sb_write(uint16_t a, uint8_t v, void *priv)
}
}
} else {
dsp->sb_data[dsp->sb_data_stat++] = v;
dsp->sb_data[dsp->sb_data_stat++] = val;
}
if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1) {
sb_exec_command(dsp);
@@ -1920,17 +1956,17 @@ sb_write(uint16_t a, uint8_t v, void *priv)
}
uint8_t
sb_read(uint16_t a, void *priv)
sb_read(uint16_t addr, void *priv)
{
sb_dsp_t *dsp = (sb_dsp_t *) priv;
uint8_t ret = 0x00;
/* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */
if ((dsp->sb_type < SB16) && (IS_NOT_ESS(dsp) || ((a & 0xF) != 0xF)))
if ((dsp->sb_type < SB16_DSP_404) && (IS_NOT_ESS(dsp) || ((addr & 0xF) != 0xF)))
/* Exception: ESS AudioDrive does not alias port base+0xf */
a &= 0xfffe;
addr &= 0xfffe;
switch (a & 0xf) {
switch (addr & 0xf) {
case 0x6:
if (IS_ESS(dsp)) {
ret = (dsp->espcm_fifo_reset & 0x03) | 0x08 | (dsp->activity & 0xe0);
@@ -1938,6 +1974,14 @@ sb_read(uint16_t a, void *priv)
} else
ret = 0xff;
break;
case 0x7:
case 0xB:
/*
These two ports are tested for random noise by OS/2 Warp 4.0, so
return 0xff to get through said test.
*/
ret = 0xff;
break;
case 0xA: /* Read data */
if (dsp->mpu && dsp->uart_midi)
ret = MPU401_ReadData(dsp->mpu);
@@ -1960,7 +2004,7 @@ sb_read(uint16_t a, void *priv)
if (dsp->state == DSP_S_RESET_WAIT)
dsp->state = DSP_S_NORMAL;
if ((dsp->state == DSP_S_NORMAL) || IS_ESS(dsp)) {
if (dsp->sb_8_enable || dsp->sb_type >= SB16)
if (dsp->sb_8_enable || dsp->sb_type >= SB16_DSP_404)
dsp->busy_count = (dsp->busy_count + 1) & 3;
else
dsp->busy_count = 0;
@@ -1985,7 +2029,7 @@ sb_read(uint16_t a, void *priv)
ret = 0x80;
} else {
sb_dsp_log("SB Write Data Creative read 0xff\n");
if ((dsp->sb_type >= SB2) && (dsp->sb_type < SB16) && IS_NOT_ESS(dsp))
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404) && IS_NOT_ESS(dsp))
ret = 0xaa;
else
ret = 0xff;
@@ -1995,7 +2039,7 @@ sb_read(uint16_t a, void *priv)
ret = 0x00;
} else {
sb_dsp_log("SB Write Data Creative read 0x7f\n");
if ((dsp->sb_type >= SB2) && (dsp->sb_type < SB16) && IS_NOT_ESS(dsp))
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404) && IS_NOT_ESS(dsp))
ret = 0x2a;
else
ret = 0x7f;
@@ -2019,7 +2063,7 @@ sb_read(uint16_t a, void *priv)
ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80;
} else {
sb_dsp_log("SB Read Data Creative read %02X\n", (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff);
if ((dsp->sb_type < SB16) && IS_NOT_ESS(dsp))
if ((dsp->sb_type < SB16_DSP_404) && IS_NOT_ESS(dsp))
ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x2a : 0xaa;
else
ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff;
@@ -2130,11 +2174,11 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent)
/* Default values. Use sb_dsp_setxxx() methods to change. */
dsp->sb_irqnum = 7;
dsp->sb_8_dmanum = 1;
if (type >= SB16)
if (type >= SB16_DSP_404)
dsp->sb_16_dmanum = 5;
else
dsp->sb_16_dmanum = 0xff;
if ((type >= SB16) || IS_ESS(dsp))
if ((type >= SB16_DSP_404) || IS_ESS(dsp))
dsp->sb_16_8_dmanum = 0x1;
dsp->mpu = NULL;
@@ -2166,7 +2210,7 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent)
a set frequency command is sent. */
recalc_sb16_filter(0, 3200 * 2);
}
if (IS_ESS(dsp) || (dsp->sb_type >= SBPRO2)) {
if (IS_ESS(dsp) || (dsp->sb_type >= SBPRO2_DSP_302)) {
/* OPL3 or dual OPL2 is stereo. */
if (dsp->sb_has_real_opl)
recalc_opl_filter(FREQ_49716 * 2);

View File

@@ -122,13 +122,17 @@ static const SOUND_CARD sound_cards[] = {
{ &sb_pro_v2_device },
{ &sb_16_device },
{ &sb_16_pnp_device },
{ &sb_16_pnp_ide_device },
{ &sb_goldfinch_device },
{ &sb_32_pnp_device },
{ &sb_awe32_device },
{ &sb_awe32_pnp_device },
{ &sb_awe64_value_device },
{ &sb_awe64_device },
{ &sb_awe64_ide_device },
{ &sb_awe64_gold_device },
{ &sb_vibra16c_device },
{ &sb_vibra16cl_device },
{ &sb_vibra16s_device },
{ &sb_vibra16xv_device },
{ &ssi2001_device },
@@ -149,6 +153,7 @@ static const SOUND_CARD sound_cards[] = {
{ &ess_soundpiper_32_mca_device },
{ &cmi8338_device },
{ &cmi8738_device },
{ &es1370_device },
{ &es1371_device },
{ &es1373_device },
{ &ct5880_device },

View File

@@ -144,23 +144,6 @@ plat_cdrom_ext_medium_changed(void *local)
return ret;
}
void
plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_read_toc(ioctl);
*st_track = 1;
*end = 1;
lead_out->min = 0;
lead_out->sec = 0;
lead_out->fr = 2;
dummy_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n",
*st_track, *end, lead_out->min, lead_out->sec, lead_out->fr);
}
/* This replaces both Info and EndInfo, they are specified by a variable. */
int
plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
@@ -218,18 +201,14 @@ plat_cdrom_get_sector_size(UNUSED(void *local), UNUSED(uint32_t sector))
}
int
plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector)
plat_cdrom_read_sector(void *local, uint8_t *buffer, uint32_t sector)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_open(ioctl);
if (raw)
/* Raw */
dummy_cdrom_ioctl_log("Raw\n");
else
/* Cooked */
dummy_cdrom_ioctl_log("Cooked\n");
/* Raw */
dummy_cdrom_ioctl_log("Raw\n");
plat_cdrom_close(ioctl);

View File

@@ -43,6 +43,11 @@
#include <86box/vid_ati_mach8.h>
#include "cpu.h"
#ifdef CLAMP
# undef CLAMP
#endif
#define BIOS_MACH8_ROM_PATH "roms/video/mach8/11301113140_4k.BIN"
static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *priv);
@@ -68,6 +73,17 @@ ibm8514_log(const char *fmt, ...)
# define ibm8514_log(fmt, ...)
#endif
static int16_t
CLAMP(int16_t in, int16_t min, int16_t max)
{
if (in < min)
return min;
if (in > max)
return max;
return in;
}
#define WRITE8(addr, var, val) \
switch ((addr) & 1) { \
case 0: \
@@ -416,14 +432,6 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len)
if (len == 2) {
dev->accel.short_stroke = val;
dev->accel.cx = dev->accel.cur_x;
if (dev->accel.cur_x >= 0x600)
dev->accel.cx |= ~0x5ff;
dev->accel.cy = dev->accel.cur_y;
if (dev->accel.cur_y >= 0x600)
dev->accel.cy |= ~0x5ff;
if (dev->accel.cmd & 0x1000) {
ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len);
ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len);
@@ -969,6 +977,7 @@ ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t
dev->accel.ssv_len = ssv & 0x0f;
dev->accel.ssv_dir = ssv & 0xe0;
dev->accel.ssv_draw = ssv & 0x10;
dev->accel.ssv_len_back = dev->accel.ssv_len;
if (ibm8514_cpu_src(svga)) {
dev->data_available = 0;
@@ -1006,6 +1015,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
uint16_t bkgd_color = dev->accel.bkgd_color;
uint32_t old_mix_dat;
int and3 = dev->accel.cur_x & 3;
int poly_src;
if (!dev->bpp) {
compare &= 0xff;
@@ -1121,13 +1131,24 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
old_mix_dat = mix_dat;
if (cmd == 5 || cmd == 1 || (cmd == 2 && (dev->accel.multifunc[0x0a] & 0x06)))
ibm8514_log("CMD=%d, full=%04x, pixcntl=%d, filling=%02x.\n", cmd, dev->accel.cmd, pixcntl, dev->accel.multifunc[0x0a] & 0x06);
/*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled.
When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on
the NOP command)*/
switch (cmd) {
case 0: /*NOP (Short Stroke Vectors)*/
if (dev->accel.ssv_state == 0)
if (dev->accel.ssv_state == 0) {
dev->accel.cx = dev->accel.cur_x;
if (dev->accel.cur_x >= 0x600)
dev->accel.cx |= ~0x5ff;
dev->accel.cy = dev->accel.cur_y;
if (dev->accel.cur_y >= 0x600)
dev->accel.cy |= ~0x5ff;
break;
}
if (dev->accel.cmd & 0x08) {
while (count-- && dev->accel.ssv_len >= 0) {
@@ -1289,7 +1310,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
else
dev->accel.cy--;
if (dev->accel.err_term >= 0) {
if (dev->accel.err_term >= dev->accel.ssv_len_back) {
dev->accel.err_term += dev->accel.destx_distp;
if (dev->accel.cmd & 0x20)
dev->accel.cx++;
@@ -1303,7 +1324,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
else
dev->accel.cx--;
if (dev->accel.err_term >= 0) {
if (dev->accel.err_term >= dev->accel.ssv_len_back) {
dev->accel.err_term += dev->accel.destx_distp;
if (dev->accel.cmd & 0x80)
dev->accel.cy++;
@@ -1454,6 +1475,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
if (!dev->accel.sy) {
dev->accel.cmd_back = 1;
if (!cpu_input) {
dev->accel.cur_x = dev->accel.cx;
dev->accel.cur_y = dev->accel.cy;
}
break;
}
@@ -1505,8 +1530,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
dev->accel.sy--;
}
dev->accel.cur_x = dev->accel.cx;
dev->accel.cur_y = dev->accel.cy;
dev->accel.x_count = 0;
dev->accel.output = 0;
} else { /*Bresenham Line*/
@@ -1580,7 +1603,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
else
dev->accel.cy--;
if (dev->accel.err_term >= 0) {
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) {
dev->accel.err_term += dev->accel.destx_distp;
if (dev->accel.cmd & 0x20)
dev->accel.cx++;
@@ -1594,7 +1617,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
else
dev->accel.cx--;
if (dev->accel.err_term >= 0) {
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) {
dev->accel.err_term += dev->accel.destx_distp;
if (dev->accel.cmd & 0x80)
dev->accel.cy++;
@@ -1673,6 +1696,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
if (!dev->accel.sy) {
dev->accel.cmd_back = 1;
if (!cpu_input) {
dev->accel.cur_x = dev->accel.cx;
dev->accel.cur_y = dev->accel.cy;
}
break;
}
@@ -1682,7 +1709,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
else
dev->accel.cy--;
if (dev->accel.err_term >= 0) {
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) {
dev->accel.err_term += dev->accel.destx_distp;
if (dev->accel.cmd & 0x20)
dev->accel.cx++;
@@ -1696,7 +1723,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
else
dev->accel.cx--;
if (dev->accel.err_term >= 0) {
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) {
dev->accel.err_term += dev->accel.destx_distp;
if (dev->accel.cmd & 0x80)
dev->accel.cy++;
@@ -1709,8 +1736,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat
dev->accel.sy--;
}
}
dev->accel.cur_x = dev->accel.cx;
dev->accel.cur_y = dev->accel.cy;
}
break;
@@ -2283,35 +2308,62 @@ skip_nibble_rect_write:
}
}
} else if ((dev->accel.multifunc[0x0a] & 0x06) == 0x04) { /*Polygon Draw Type A*/
ibm8514_log("Polygon Draw Type A: Clipping: L=%d, R=%d, T=%d, B=%d, C(%d,%d), sx=%d, sy=%d.\n", clip_l, clip_r, clip_t, clip_b, dev->accel.cx, dev->accel.cy, dev->accel.sx, dev->accel.sy);
while (count-- && (dev->accel.sy >= 0)) {
if ((dev->accel.cx >= clip_l) &&
(dev->accel.cx <= clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
READ(dev->accel.dest + dev->accel.cx, mix_dat);
if ((mix_dat & rd_mask_polygon) == rd_mask_polygon)
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = bkgd_color;
break;
case 1:
src_dat = frgd_color;
break;
case 2:
case 3:
src_dat = 0;
break;
default:
break;
}
READ(dev->accel.dest + dev->accel.cx, poly_src);
if ((poly_src & rd_mask_polygon) == rd_mask_polygon)
dev->accel.fill_state ^= 1;
READ(dev->accel.dest + dev->accel.cx, dest_dat);
old_dest_dat = dest_dat;
if (dev->accel.fill_state) {
if (!(rd_mask_polygon & 0x01) && (wrt_mask & 0x01)) {
MIX(mix_dat ^ rd_mask_polygon, dest_dat, mix_dat);
ibm8514_log("Filling c(%d,%d) without bit 0 of rdmask=%02x, wrtmask=%02x, mixdat=%02x, dest=%02x, old=%02x.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask, mix_dat, dest_dat, old_dest_dat);
dest_dat &= ~rd_mask_polygon;
} else if ((rd_mask_polygon & 0x01) && (wrt_mask & 0x01)) {
ibm8514_log("Filling c(%d,%d) with bit 0 of rdmask=%02x, wrtmask=%02x.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask);
dest_dat &= ~(rd_mask_polygon & wrt_mask);
if (rd_mask_polygon & 0x01) {
if (wrt_mask & 0x01) {
dest_dat &= ~(rd_mask_polygon & wrt_mask); /*Fill State On, Write Mask 1, Read Mask 1.*/
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
}
} else {
if (wrt_mask & 0x01) {
MIX(mix_dat & mix_mask, dest_dat, src_dat);
dest_dat &= ~rd_mask_polygon; /*Fill State On, Write Mask 1, Read Mask 0.*/
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
}
}
} else {
if (!(rd_mask_polygon & 0x01) && (wrt_mask & 0x01))
dest_dat &= ~rd_mask_polygon;
else if ((rd_mask_polygon & 0x01) && (wrt_mask & 0x01))
dest_dat &= ~(rd_mask_polygon & wrt_mask);
if (rd_mask_polygon & 0x01) {
if (wrt_mask & 0x01) {
dest_dat &= ~(rd_mask_polygon & wrt_mask); /*Fill State Off, Write Mask 1, Read Mask 1.*/
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
}
} else {
if (wrt_mask & 0x01) {
dest_dat &= ~rd_mask_polygon; /*Fill State Off, Write Mask 1, Read Mask 0.*/
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
}
}
}
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
if ((compare_mode == 0) ||
((compare_mode == 0x10) && (dest_dat >= compare)) ||
((compare_mode == 0x18) && (dest_dat < compare)) ||
@@ -2322,7 +2374,11 @@ skip_nibble_rect_write:
ibm8514_log("Results c(%d,%d):rdmask=%02x, wrtmask=%02x, mix=%02x, destdat=%02x, nowrite=%d.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask, mix_dat, dest_dat, dev->accel.cx_back);
WRITE(dev->accel.dest + dev->accel.cx, dest_dat);
}
}
} else
ibm8514_log("Out of bounds DrawA C(%d,%d).\n", dev->accel.cx, dev->accel.cy);
mix_dat <<= 1;
mix_dat |= 1;
if (dev->accel.cmd & 0x20)
dev->accel.cx++;
@@ -2356,6 +2412,8 @@ skip_nibble_rect_write:
if (dev->accel.sy < 0) {
ibm8514_log(".\n");
dev->accel.cmd_back = 1;
dev->accel.cur_x = dev->accel.cx;
dev->accel.cur_y = dev->accel.cy;
return;
}
}
@@ -2468,7 +2526,7 @@ skip_nibble_rect_write:
else
dev->accel.oldcy = dev->accel.cy - 1;
ibm8514_log("Polygon Boundary activated=%04x, len=%d, cur(%d,%d), frgdmix=%02x, err=%d, clipping: l=%d, r=%d, t=%d, b=%d, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.sy, dev->accel.cx, dev->accel.cy, dev->accel.frgd_mix & 0x1f, dev->accel.err_term, dev->accel.multifunc[2], dev->accel.multifunc[4], dev->accel.clip_top, clip_b, dev->accel.multifunc[0x0a]);
ibm8514_log("Polygon Boundary activated=%04x, len=%d, cur(%d,%d), frgdmix=%02x, err=%d, clipping: l=%d, r=%d, t=%d, b=%d, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.sy, dev->accel.cx, dev->accel.cy, dev->accel.frgd_mix & 0x1f, dev->accel.err_term, clip_l, clip_r, clip_t, clip_b, dev->accel.multifunc[0x0a]);
if (ibm8514_cpu_src(svga)) {
dev->data_available = 0;
@@ -2483,8 +2541,7 @@ skip_nibble_rect_write:
if (dev->accel.cmd & 0x08) { /*Vectored Boundary Line*/
while (count-- && (dev->accel.sy >= 0)) {
if (dev->accel.cx < clip_l)
dev->accel.cx = clip_l;
dev->accel.cx = CLAMP(dev->accel.cx, clip_l, clip_r);
if ((dev->accel.cx >= clip_l) &&
(dev->accel.cx <= clip_r) &&
@@ -2591,11 +2648,10 @@ skip_nibble_rect_write:
}
} else { /*Vectored Bresenham*/
while (count-- && (dev->accel.sy >= 0)) {
if (dev->accel.cx < clip_l)
dev->accel.cx = clip_l;
dev->accel.cx = CLAMP(dev->accel.cx, clip_l, clip_r);
if ((dev->accel.cx >= clip_l) &&
(dev->accel.cx <= clip_r) &&
(dev->accel.cx < clip_r) &&
(dev->accel.cy >= clip_t) &&
(dev->accel.cy <= clip_b)) {
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
@@ -2658,7 +2714,7 @@ skip_nibble_rect_write:
else
dev->accel.cy--;
if (dev->accel.err_term >= 0) {
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt_no_limit) {
dev->accel.err_term += dev->accel.destx_distp;
if (dev->accel.cmd & 0x20)
dev->accel.cx++;
@@ -2673,7 +2729,7 @@ skip_nibble_rect_write:
dev->accel.cx--;
dev->accel.oldcy = dev->accel.cy;
if (dev->accel.err_term >= 0) {
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt_no_limit) {
dev->accel.err_term += dev->accel.destx_distp;
if (dev->accel.cmd & 0x80)
dev->accel.cy++;

View File

@@ -1361,7 +1361,7 @@ gd54xx_in(uint16_t addr, void *priv)
32-bit (Pre-5434)/64-bit (5434 and up) DRAM data bus width
for 2M of memory
*/
ret |= (gd54xx_is_5434(svga)) ? 0x98 : 0x18;
ret |= 0x18;
break;
case 4096:
ret |= 0x98; /*64-bit (5434 and up) DRAM data bus width for 4M of memory*/
@@ -2281,6 +2281,9 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *priv)
if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest &&
!(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) {
if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY))
val = (val >> 8) | (val << 8);
gd54xx_write(addr, val, gd54xx);
gd54xx_write(addr + 1, val >> 8, gd54xx);
return;
@@ -2308,6 +2311,9 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *priv)
if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest &&
!(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) {
if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY))
val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24);
gd54xx_write(addr, val, gd54xx);
gd54xx_write(addr + 1, val >> 8, gd54xx);
gd54xx_write(addr + 2, val >> 16, gd54xx);
@@ -3661,9 +3667,6 @@ gd54xx_mem_sys_src(gd54xx_t *gd54xx, uint32_t cpu_dat, uint32_t count)
mask_shift = 31 - byte_pos;
if (!(gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND))
cpu_dat >>= byte_pos;
else if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
cpu_dat = ((cpu_dat & 0xff000000) >> 24) | ((cpu_dat & 0x00ff0000) >> 8) |
((cpu_dat & 0x0000ff00) << 8) | ((cpu_dat & 0x000000ff) << 24);
} else
mask_shift = 7;

View File

@@ -273,6 +273,7 @@ typedef struct s3_t {
int dat_count;
int b2e8_pix, temp_cnt;
int ssv_len;
int ssv_len_back;
uint8_t ssv_dir;
uint8_t ssv_draw;
uint8_t dat_buf_16bit;
@@ -511,7 +512,7 @@ s3_update_irqs(s3_t *s3)
}
void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, void *priv);
void s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv);
void s3_short_stroke_start(s3_t *s3, uint8_t ssv);
static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3);
#define WRITE8(addr, var, val) \
@@ -922,15 +923,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8);
s3->accel.ssv_state = 1;
s3->accel.cx = s3->accel.cur_x & 0xfff;
s3->accel.cy = s3->accel.cur_y & 0xfff;
if (s3->accel.cmd & 0x1000) {
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff);
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8);
s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff);
s3_short_stroke_start(s3, s3->accel.short_stroke >> 8);
} else {
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8);
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff);
s3_short_stroke_start(s3, s3->accel.short_stroke >> 8);
s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff);
}
break;
@@ -1461,17 +1459,24 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
break;
case 0xe548:
case 0xe6e8:
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16);
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16);
else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val;
} else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val;
break;
case 0xe549:
case 0xe6e9:
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24);
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24);
else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8);
} else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
break;
@@ -1495,6 +1500,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24);
else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8);
s3->accel.multifunc[0xe] ^= 0x10;
}
break;
@@ -1516,17 +1522,24 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
break;
case 0xed48:
case 0xeee8:
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16);
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16);
else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val;
} else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val;
break;
case 0xed49:
case 0xeee9:
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24);
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24);
else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8);
} else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
break;
@@ -1550,6 +1563,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24);
else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8);
s3->accel.multifunc[0xe] ^= 0x10;
}
break;
@@ -1771,15 +1785,12 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val)
s3->accel.short_stroke = val;
s3->accel.ssv_state = 1;
s3->accel.cx = s3->accel.cur_x & 0xfff;
s3->accel.cy = s3->accel.cur_y & 0xfff;
if (s3->accel.cmd & 0x1000) {
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff);
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8);
s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff);
s3_short_stroke_start(s3, s3->accel.short_stroke >> 8);
} else {
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8);
s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff);
s3_short_stroke_start(s3, s3->accel.short_stroke >> 8);
s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff);
}
}
}
@@ -2759,18 +2770,18 @@ s3_out(uint16_t addr, uint8_t val, void *priv)
svga_recalctimings(svga);
} else if (svga->seqaddr == 9) {
svga->seqregs[svga->seqaddr] = val & 0x80;
svga->seqregs[9] = val & 0x80;
s3_io_set(s3);
return;
} else if (svga->seqaddr == 0xa) {
svga->seqregs[svga->seqaddr] = val & 0x80;
svga->seqregs[0xa] = val & 0x80;
return;
} else if (s3->chip >= S3_VISION964) {
if (svga->seqaddr == 0x08) {
svga->seqregs[svga->seqaddr] = val & 0x0f;
if (svga->seqaddr == 8) {
svga->seqregs[8] = val & 0x0f;
return;
} else if ((svga->seqaddr == 0x0d) && (svga->seqregs[0x08] == 0x06)) {
svga->seqregs[svga->seqaddr] = val;
} else if ((svga->seqaddr == 0xd) && (svga->seqregs[8] == 0x06)) {
svga->seqregs[0xd] = val;
svga->dpms = ((s3->chip >= S3_VISION964) && (svga->seqregs[0x0d] & 0x50)) || (svga->crtc[0x56] & ((s3->chip >= S3_TRIO32) ? 0x06 : 0x20));
svga_recalctimings(svga);
return;
@@ -3162,7 +3173,7 @@ s3_in(uint16_t addr, void *priv)
case 0x51:
return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3);
case 0x5c: /* General Output Port Register */
temp = svga->crtc[svga->crtcreg] & 0xa0;
temp = svga->crtc[0x5c] & 0xa0;
if (((svga->miscout >> 2) & 3) == 3)
temp |= svga->crtc[0x42] & 0x0f;
else
@@ -3183,20 +3194,19 @@ s3_in(uint16_t addr, void *priv)
case 0x6b:
s3_log("[%04X:%08X]: Read CRTC6b=%02x.\n", CS, cpu_state.pc, svga->crtc[0x6b]);
if (s3->chip != S3_TRIO64V2) {
if (svga->crtc[0x53] & 0x08) {
if (svga->crtc[0x53] & 0x08)
return (s3->chip == S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe);
} else {
else
return svga->crtc[0x59];
}
} else
return svga->crtc[0x6b];
break;
case 0x6c:
s3_log("[%04X:%08X]: Read CRTC6c=%02x.\n", CS, cpu_state.pc, svga->crtc[0x6c]);
if (s3->chip != S3_TRIO64V2) {
if (svga->crtc[0x53] & 0x08) {
if (svga->crtc[0x53] & 0x08)
return 0x00;
} else
else
return (svga->crtc[0x5a] & 0x80);
} else
return svga->crtc[0x6c];
@@ -4305,6 +4315,7 @@ s3_recalctimings(svga_t *svga)
svga->vram_display_mask = s3->vram_mask;
} else {
svga->vram_display_mask = (svga->crtc[0x32] & 0x40) ? 0x3ffff : s3->vram_mask;
s3_log("CRTC31 bit 0=%x, CRTC32 bit 6=%02x.\n", (svga->crtc[0x31] & 0x01), svga->crtc[0x32] & 0x40);
if (!(svga->crtc[0x31] & 0x01)) { /*Bank Enable bit*/
svga->write_bank = 0;
svga->read_bank = 0;
@@ -4625,6 +4636,7 @@ s3_updatemapping(s3_t *s3)
}
/* Memory mapped I/O. */
s3_log("CRTC53=%02x, SEQREG9=%02x.\n", svga->crtc[0x53] & 0x18, svga->seqregs[9] & 0x80);
if ((svga->crtc[0x53] & 0x10) || (s3->accel.advfunc_cntl & 0x20)) {
mem_mapping_disable(&svga->mapping);
if (s3->chip >= S3_TRIO64V) {
@@ -4644,8 +4656,7 @@ s3_updatemapping(s3_t *s3)
mem_mapping_set_addr(&s3->new_mmio_mapping, s3->linear_base + 0x1000000, 0x20000);
else
mem_mapping_disable(&s3->new_mmio_mapping);
}
else
} else
mem_mapping_disable(&s3->new_mmio_mapping);
}
}
@@ -5501,21 +5512,27 @@ s3_accel_in(uint16_t port, void *priv)
case 0xd2e8:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.ropmix & 0xff;
case 0xd149:
case 0xd2e9:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.ropmix >> 8;
case 0xe548:
case 0xe6e8:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color >> 16;
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color >> 16;
else
temp2 = s3->accel.pat_bg_color & 0xff;
} else
temp2 = s3->accel.pat_bg_color & 0xff;
return temp2;
@@ -5524,37 +5541,53 @@ s3_accel_in(uint16_t port, void *priv)
case 0xe6e9:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color >> 24;
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color >> 24;
else
temp2 = s3->accel.pat_bg_color >> 8;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
} else
temp2 = s3->accel.pat_bg_color >> 8;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
case 0xe54a:
case 0xe6ea:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color & 0xff;
else
temp2 = s3->accel.pat_bg_color >> 16;
if (s3->accel.multifunc[0xe] & 0x200)
temp2 = s3->accel.pat_bg_color >> 16;
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
temp2 = s3->accel.pat_bg_color & 0xff;
else
temp2 = s3->accel.pat_bg_color >> 16;
}
return temp2;
case 0xe54b:
case 0xe6eb:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color >> 8;
else
temp2 = s3->accel.pat_bg_color >> 24;
if (!(s3->accel.multifunc[0xe] & 0x200))
if (s3->accel.multifunc[0xe] & 0x200)
temp2 = s3->accel.pat_bg_color >> 24;
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
temp2 = s3->accel.pat_bg_color >> 8;
else
temp2 = s3->accel.pat_bg_color >> 24;
s3->accel.multifunc[0xe] ^= 0x10;
}
return temp2;
case 0xe948:
@@ -5585,9 +5618,13 @@ s3_accel_in(uint16_t port, void *priv)
case 0xeee8:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color >> 16;
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color >> 16;
else
temp2 = s3->accel.pat_fg_color & 0xff;
} else
temp2 = s3->accel.pat_fg_color & 0xff;
return temp2;
@@ -5596,37 +5633,53 @@ s3_accel_in(uint16_t port, void *priv)
case 0xeee9:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color >> 24;
else
if (s3->bpp == 3) {
if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color >> 24;
else
temp2 = s3->accel.pat_fg_color >> 8;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
} else
temp2 = s3->accel.pat_fg_color >> 8;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
case 0xed4a:
case 0xeeea:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color & 0xff;
else
temp2 = s3->accel.pat_fg_color >> 16;
if (s3->accel.multifunc[0xe] & 0x200)
temp2 = s3->accel.pat_fg_color >> 16;
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
temp2 = s3->accel.pat_fg_color & 0xff;
else
temp2 = s3->accel.pat_fg_color >> 16;
}
return temp2;
case 0xed4b:
case 0xeeeb:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color >> 8;
else
temp2 = s3->accel.pat_fg_color >> 24;
if (!(s3->accel.multifunc[0xe] & 0x200))
if (s3->accel.multifunc[0xe] & 0x200)
temp2 = s3->accel.pat_fg_color >> 24;
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
temp2 = s3->accel.pat_fg_color >> 8;
else
temp2 = s3->accel.pat_fg_color >> 24;
s3->accel.multifunc[0xe] ^= 0x10;
}
return temp2;
case 0xe148:
@@ -7765,19 +7818,16 @@ s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3)
}
void
s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv)
s3_short_stroke_start(s3_t *s3, uint8_t ssv)
{
if (!cpu_input) {
s3->accel.ssv_len = ssv & 0x0f;
s3->accel.ssv_dir = ssv & 0xe0;
s3->accel.ssv_draw = ssv & 0x10;
s3->accel.ssv_len = ssv & 0x0f;
s3->accel.ssv_dir = ssv & 0xe0;
s3->accel.ssv_draw = !!(ssv & 0x10);
if (s3_cpu_src(s3)) {
return; /*Wait for data from CPU*/
}
}
if (s3_cpu_src(s3))
return; /*Wait for data from CPU*/
s3->accel_start(count, cpu_input, mix_dat, cpu_dat, s3);
s3->accel_start(-1, 0, -1, 0, s3);
}
void
@@ -7916,16 +7966,17 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
/*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled.
When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on
the NOP command)*/
if (s3->accel.cmd == 0x41b3 || (cmd == 6))
s3_log("CMD=%d, full=%04x, s3bpp=%x, multifuncE=%03x, sourcedisplay=%x, mmio=%02x, srcbase=%08x, dstbase=%08x, cpu=%04x, mix=%04x, count=%d, rd_mask=%04x, wrt_mask=%04x, width=%d, s=%d,%d, c=%d,%d, d=%d,%d, 16bitcolor=%x, frgdcolor=%04x, bkgdcolor=%04x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, svgabpp=%d.\n", cmd, s3->accel.cmd, s3->bpp, s3->accel.multifunc[0x0e], vram_mask, svga->crtc[0x53] & 0x18, srcbase, dstbase, cpu_dat & 0xffff, mix_dat & 0xffff, count, rd_mask, wrt_mask, s3->width, s3->accel.sx, s3->accel.sy, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->color_16bit, frgd_color, bkgd_color, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, svga->bpp);
s3_log("CMD=%d, full=%04x, s3bpp=%x, multifuncE=%03x, sourcedisplay=%x, mmio=%02x, srcbase=%08x, dstbase=%08x, cpu=%04x, mix=%04x, count=%d, rd_mask=%04x, wrt_mask=%04x, width=%d, s=%d,%d, c=%d,%d, d=%d,%d, 16bitcolor=%x, frgdcolor=%04x, bkgdcolor=%04x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, svgabpp=%d.\n", cmd, s3->accel.cmd, s3->bpp, s3->accel.multifunc[0x0e], vram_mask, svga->crtc[0x53] & 0x18, srcbase, dstbase, cpu_dat & 0xffff, mix_dat & 0xffff, count, rd_mask, wrt_mask, s3->width, s3->accel.sx, s3->accel.sy, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->color_16bit, frgd_color, bkgd_color, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, svga->bpp);
switch (cmd) {
case 0: /*NOP (Short Stroke Vectors)*/
if (s3->accel.ssv_state == 0)
if (s3->accel.ssv_state == 0) {
s3->accel.cx = s3->accel.cur_x & 0xfff;
s3->accel.cy = s3->accel.cur_y & 0xfff;
break;
}
if (s3->accel.cmd & 0x08) /*Radial*/
{
if (s3->accel.cmd & 0x08) { /*Radial*/
while (count-- && s3->accel.ssv_len >= 0) {
if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) {
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
@@ -7979,8 +8030,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
else
cpu_dat >>= 16;
if (!s3->accel.ssv_len)
if (!s3->accel.ssv_len) {
s3->accel.cur_x = s3->accel.cx & 0xfff;
s3->accel.cur_y = s3->accel.cy & 0xfff;
break;
}
switch (s3->accel.ssv_dir & 0xe0) {
case 0x00:
@@ -8020,9 +8074,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
s3->accel.cx &= 0xfff;
s3->accel.cy &= 0xfff;
}
s3->accel.cur_x = s3->accel.cx & 0xfff;
s3->accel.cur_y = s3->accel.cy & 0xfff;
}
break;
@@ -8213,7 +8264,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
else
s3->accel.cy--;
if (s3->accel.err_term >= 0) {
if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) {
s3->accel.err_term += s3->accel.destx_distp;
if (s3->accel.cmd & 0x20)
s3->accel.cx++;
@@ -8227,7 +8278,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
else
s3->accel.cx--;
if (s3->accel.err_term >= 0) {
if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) {
s3->accel.err_term += s3->accel.destx_distp;
if (s3->accel.cmd & 0x80)
s3->accel.cy++;
@@ -8671,7 +8722,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
}
break;
case 7: /*Pattern fill - BitBlt but with source limited to 8x8*/
case 7: /*Pattern fill - BitBlt but with source limited to 8x8*/
if (!cpu_input) /*!cpu_input is trigger to start operation*/
{
s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff;
@@ -8693,12 +8744,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width);
}
if ((s3->accel.cmd & 0x100) && !cpu_input) {
if ((s3->accel.cmd & 0x100) && !cpu_input)
return; /*Wait for data from CPU*/
}
while (count-- && s3->accel.sy >= 0) {
if ((s3->accel.dx) >= clip_l && (s3->accel.dx) <= clip_r && (s3->accel.dy) >= clip_t && (s3->accel.dy) <= clip_b) {
while (count-- && (s3->accel.sy >= 0)) {
if ((s3->accel.dx >= clip_l) && (s3->accel.dx <= clip_r) && (s3->accel.dy >= clip_t) && (s3->accel.dy <= clip_b)) {
if (vram_mask) {
READ(s3->accel.src + s3->accel.cx, mix_dat);
mix_dat = ((mix_dat & rd_mask) == rd_mask);
@@ -8706,10 +8756,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
}
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
case 0:
src_dat = s3->accel.bkgd_color;
src_dat = bkgd_color;
break;
case 1:
src_dat = s3->accel.frgd_color;
src_dat = frgd_color;
break;
case 2:
src_dat = cpu_dat;
@@ -8784,15 +8834,14 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
s3->accel.dy--;
}
s3->accel.dy &= 0xfff;
s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width);
s3->accel.dest = dstbase + s3->accel.dy * s3->width;
s3->accel.sy--;
if (cpu_input) {
if (cpu_input)
return;
}
if (s3->accel.sy < 0) {
s3->accel.destx_distp = s3->accel.dx;
s3->accel.desty_axstp = s3->accel.dy;
@@ -10230,6 +10279,8 @@ s3_init(const device_t *info)
s3->i2c = i2c_gpio_init("ddc_s3");
s3->ddc = ddc_init(i2c_gpio_get_bus(s3->i2c));
s3->accel.multifunc[0xd] = 0xd000;
s3->accel.multifunc[0xe] = 0xe000;
s3->wake_fifo_thread = thread_create_event();
s3->fifo_not_full_event = thread_create_event();

View File

@@ -628,6 +628,8 @@ svga_recalctimings(svga_t *svga)
int hsyncstart;
int hsyncend;
#endif
int old_monitor_overscan_x = svga->monitor->mon_overscan_x;
int old_monitor_overscan_y = svga->monitor->mon_overscan_y;
svga->vtotal = svga->crtc[6];
svga->dispend = svga->crtc[0x12];
@@ -1009,6 +1011,9 @@ svga_recalctimings(svga_t *svga)
svga->dpms_ui = 0;
ui_sb_set_text_w(NULL);
}
if (enable_overscan && (svga->monitor->mon_overscan_x != old_monitor_overscan_x || svga->monitor->mon_overscan_y != old_monitor_overscan_y))
video_force_resize_set_monitor(1, svga->monitor_index);
}
static void

View File

@@ -1095,7 +1095,7 @@ banshee_status(banshee_t *banshee)
int fifo_entries = FIFO_ENTRIES;
int swap_count = voodoo->swap_count;
int written = voodoo->cmd_written + voodoo->cmd_written_fifo;
int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || voodoo->voodoo_busy;
int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || (voodoo->cmdfifo_depth_rd_2 != voodoo->cmdfifo_depth_wr_2) || voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || voodoo->voodoo_busy;
uint32_t ret = 0;
if (fifo_entries < 0x20)
@@ -1117,6 +1117,9 @@ banshee_status(banshee_t *banshee)
if (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr)
ret |= (1 << 11);
if (voodoo->cmdfifo_depth_rd_2 != voodoo->cmdfifo_depth_wr_2)
ret |= (1 << 12);
if (!voodoo->voodoo_busy)
voodoo_wake_fifo_thread(voodoo);

View File

@@ -252,6 +252,9 @@ voodoo_fb_writew(uint32_t addr, uint16_t val, void *priv)
{
rgba8_t write_data = colour_data;
uint16_t new_depth = depth_data;
int colbfog_r = 0;
int colbfog_g = 0;
int colbfog_b = 0;
if (params->fbzMode & FBZ_DEPTH_ENABLE) {
uint16_t old_depth = *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]);
@@ -262,6 +265,10 @@ voodoo_fb_writew(uint32_t addr, uint16_t val, void *priv)
if ((params->fbzMode & FBZ_CHROMAKEY) && write_data.r == params->chromaKey_r && write_data.g == params->chromaKey_g && write_data.b == params->chromaKey_b)
goto skip_pixel;
colbfog_r = write_data.r;
colbfog_g = write_data.g;
colbfog_b = write_data.b;
if (params->fogMode & FOG_ENABLE) {
int32_t z = new_depth << 12;
int64_t w_depth = (int64_t) (int32_t) new_depth;
@@ -438,6 +445,9 @@ voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv)
for (int c = 0; c < count; c++) {
rgba8_t write_data = colour_data[c];
uint16_t new_depth = depth_data[c];
int colbfog_r = 0;
int colbfog_g = 0;
int colbfog_b = 0;
if (params->fbzMode & FBZ_DEPTH_ENABLE) {
uint16_t old_depth = *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]);
@@ -448,6 +458,10 @@ voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv)
if ((params->fbzMode & FBZ_CHROMAKEY) && write_data.r == params->chromaKey_r && write_data.g == params->chromaKey_g && write_data.b == params->chromaKey_b)
goto skip_pixel;
colbfog_r = write_data.r;
colbfog_g = write_data.g;
colbfog_b = write_data.b;
if (params->fogMode & FOG_ENABLE) {
int32_t z = new_depth << 12;
int64_t w_depth = new_depth;

View File

@@ -967,6 +967,9 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *
int src_g = 0;
int src_b = 0;
int src_a = 0;
int colbfog_r = 0;
int colbfog_g = 0;
int colbfog_b = 0;
int msel_r;
int msel_g;
int msel_b;
@@ -1263,6 +1266,10 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *
if (cca_invert_output)
src_a ^= 0xff;
colbfog_r = src_r;
colbfog_g = src_g;
colbfog_b = src_b;
if (params->fogMode & FOG_ENABLE)
APPLY_FOG(src_r, src_g, src_b, state->z, state->ia, state->w);