The great CD-ROM clean-up and rewrite, fixes #5134.

This commit is contained in:
OBattler
2025-01-28 16:26:28 +01:00
parent 1cb17f7a3a
commit 90e1190c92
48 changed files with 9486 additions and 9389 deletions

View File

@@ -21,10 +21,8 @@ pkg_check_modules(SNDFILE REQUIRED IMPORTED_TARGET sndfile)
add_library(cdrom OBJECT
cdrom.c
cdrom_image_backend.c
cdrom_image_viso.c
cdrom_image.c
cdrom_ioctl.c
cdrom_image_viso.c
)
target_link_libraries(86Box PkgConfig::SNDFILE)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,9 @@
#define __STDC_FORMAT_MACROS
#include <ctype.h>
#include <inttypes.h>
#ifdef IMAGE_VISO_LOG
#include <stdarg.h>
#endif
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -29,15 +31,16 @@
#include <sys/stat.h>
#include <time.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/bswap.h>
#include <86box/cdrom_image_backend.h>
#include <86box/cdrom.h>
#include <86box/cdrom_image.h>
#include <86box/cdrom_image_viso.h>
#include <86box/log.h>
#include <86box/path.h>
#include <86box/plat.h>
#include <86box/plat_dir.h>
#include <86box/version.h>
#include <86box/timer.h>
#include <86box/nvr.h>
#ifndef S_ISDIR
@@ -136,29 +139,30 @@ static const char rr_eid[] = "RRIP_1991A"; /* identifiers used in ER field for
static const char rr_edesc[] = "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS.";
static int8_t tz_offset = 0;
#ifdef ENABLE_CDROM_IMAGE_VISO_LOG
int cdrom_image_viso_do_log = ENABLE_CDROM_IMAGE_VISO_LOG;
#ifdef IMAGE_VISO_LOG
int image_viso_do_log = IMAGE_VISO_LOG;
void
cdrom_image_viso_log(const char *fmt, ...)
image_viso_log(void *priv, const char *fmt, ...)
{
va_list ap;
if (cdrom_image_viso_do_log) {
if (image_viso_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
log_out(priv, fmt, ap);
va_end(ap);
}
}
#else
# define cdrom_image_viso_log(fmt, ...)
# define image_viso_log(priv, fmt, ...)
#endif
static size_t
viso_pread(void *ptr, uint64_t offset, size_t size, size_t count, FILE *fp)
viso_pread(void *ptr, const uint64_t offset, const size_t size,
const size_t count, FILE *fp)
{
uint64_t cur_pos = ftello64(fp);
size_t ret = 0;
const uint64_t cur_pos = ftello64(fp);
size_t ret = 0;
if (fseeko64(fp, offset, SEEK_SET) != -1)
ret = fread(ptr, size, count, fp);
fseeko64(fp, cur_pos, SEEK_SET);
@@ -166,10 +170,11 @@ viso_pread(void *ptr, uint64_t offset, size_t size, size_t count, FILE *fp)
}
static size_t
viso_pwrite(const void *ptr, uint64_t offset, size_t size, size_t count, FILE *fp)
viso_pwrite(const void *ptr, const uint64_t offset, const size_t size,
const size_t count, FILE *fp)
{
uint64_t cur_pos = ftello64(fp);
size_t ret = 0;
const uint64_t cur_pos = ftello64(fp);
size_t ret = 0;
if (fseeko64(fp, offset, SEEK_SET) != -1)
ret = fwrite(ptr, size, count, fp);
fseeko64(fp, cur_pos, SEEK_SET);
@@ -691,22 +696,22 @@ viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
/* Close any existing FIFO entry's file. */
viso_entry_t *other_entry = viso->file_fifo[viso->file_fifo_pos];
if (other_entry && other_entry->file) {
cdrom_image_viso_log("VISO: Closing [%s]", other_entry->path);
image_viso_log(viso->tf.log, "Closing [%s]...\n", other_entry->path);
fclose(other_entry->file);
other_entry->file = NULL;
cdrom_image_viso_log("\n");
image_viso_log(viso->tf.log, "Done\n");
}
/* Open file. */
cdrom_image_viso_log("VISO: Opening [%s]", entry->path);
image_viso_log(viso->tf.log, "Opening [%s]...\n", entry->path);
if ((entry->file = fopen(entry->path, "rb"))) {
cdrom_image_viso_log("\n");
image_viso_log(viso->tf.log, "Done\n");
/* Add this entry to the FIFO. */
viso->file_fifo[viso->file_fifo_pos++] = entry;
viso->file_fifo_pos &= (sizeof(viso->file_fifo) / sizeof(viso->file_fifo[0])) - 1;
} else {
cdrom_image_viso_log(" => failed\n");
image_viso_log(viso->tf.log, "Failed\n");
/* Clear any existing FIFO entry. */
viso->file_fifo[viso->file_fifo_pos] = NULL;
@@ -753,12 +758,12 @@ viso_close(void *priv)
if (viso == NULL)
return;
cdrom_image_viso_log("VISO: close()\n");
image_viso_log(viso->tf.log, "close()\n");
/* De-allocate everything. */
if (tf->fp)
fclose(tf->fp);
#ifndef ENABLE_CDROM_IMAGE_VISO_LOG
#ifndef ENABLE_IMAGE_VISO_LOG
remove(nvr_path(viso->tf.fn));
#endif
@@ -777,21 +782,32 @@ viso_close(void *priv)
if (viso->entry_map)
free(viso->entry_map);
if (tf->log != NULL) {
}
free(viso);
}
track_file_t *
viso_init(const char *dirname, int *error)
viso_init(const uint8_t id, const char *dirname, int *error)
{
cdrom_image_viso_log("VISO: init()\n");
/* Initialize our data structure. */
viso_t *viso = (viso_t *) calloc(1, sizeof(viso_t));
uint8_t *data = NULL;
uint8_t *p;
*error = 1;
if (viso == NULL)
goto end;
char n[1024] = { 0 };
sprintf(n, "CD-ROM %i VISO ", id + 1);
viso->tf.log = log_open(n);
image_viso_log(viso->tf.log, "init()\n");
viso->sector_size = VISO_SECTOR_SIZE;
viso->format = VISO_FORMAT_ISO | VISO_FORMAT_JOLIET | VISO_FORMAT_RR;
viso->use_version_suffix = (viso->format & VISO_FORMAT_ISO); /* cleared later if required */
@@ -802,7 +818,7 @@ viso_init(const char *dirname, int *error)
goto end;
/* Open temporary file. */
#ifdef ENABLE_CDROM_IMAGE_VISO_LOG
#ifdef ENABLE_IMAGE_VISO_LOG
strcpy(viso->tf.fn, "viso-debug.iso");
#else
plat_tempfile(viso->tf.fn, "viso", ".tmp");
@@ -812,7 +828,7 @@ viso_init(const char *dirname, int *error)
goto end;
/* Set up directory traversal. */
cdrom_image_viso_log("VISO: Traversing directories:\n");
image_viso_log(viso->tf.log, "Traversing directories:\n");
viso_entry_t *entry;
viso_entry_t *last_entry;
viso_entry_t *dir;
@@ -839,7 +855,7 @@ viso_init(const char *dirname, int *error)
if (!S_ISDIR(dir->stats.st_mode)) /* root is not a directory */
goto end;
dir->parent = dir; /* for the root's path table and .. entries */
cdrom_image_viso_log("[%08X] %s => [root]\n", dir, dir->path);
image_viso_log(viso->tf.log, "[%08X] %s => [root]\n", dir, dir->path);
/* Traverse directories, starting with the root. */
viso_entry_t **dir_entries = NULL;
@@ -889,7 +905,8 @@ viso_init(const char *dirname, int *error)
/* Set basename. */
strcpy(entry->name_short, children_count ? ".." : ".");
cdrom_image_viso_log("[%08X] %s => %s\n", entry, dir->path, entry->name_short);
image_viso_log(viso->tf.log, "[%08X] %s => %s\n", entry,
dir->path, entry->name_short);
}
/* Iterate through this directory's children again, making the entries. */
@@ -897,12 +914,16 @@ viso_init(const char *dirname, int *error)
rewinddir(dirp);
while ((readdir_entry = readdir(dirp))) {
/* Ignore . and .. pseudo-directories. */
if ((readdir_entry->d_name[0] == '.') && ((readdir_entry->d_name[1] == '\0') || (*((uint16_t *) &readdir_entry->d_name[1]) == '.')))
if ((readdir_entry->d_name[0] == '.') &&
((readdir_entry->d_name[1] == '\0') ||
(*((uint16_t *) &readdir_entry->d_name[1]) == '.')))
continue;
/* Add and fill entry. */
entry = dir_entries[children_count++] = (viso_entry_t *) calloc(1, sizeof(viso_entry_t) + dir_path_len + strlen(readdir_entry->d_name) + 2);
if (!entry)
entry = dir_entries[children_count++] =
(viso_entry_t *) calloc(1, sizeof(viso_entry_t) +
dir_path_len + strlen(readdir_entry->d_name) + 2);
if (entry == NULL)
break;
entry->parent = dir;
strcpy(entry->path, dir->path);
@@ -972,10 +993,12 @@ have_eltorito_entry:
continue;
}
cdrom_image_viso_log("[%08X] %s => [%-12s] %s\n", entry, dir->path, entry->name_short, entry->basename);
image_viso_log(viso->tf.log, "[%08X] %s => [%-12s] %s\n", entry,
dir->path, entry->name_short, entry->basename);
}
} else {
cdrom_image_viso_log("VISO: Failed to enumerate [%s], will be empty\n", dir->path);
image_viso_log(viso->tf.log, "Failed to enumerate [%s], will be empty\n",
dir->path);
}
/* Add terminator. */
@@ -1129,13 +1152,17 @@ next_dir:
/* Write El Torito boot descriptor. This is an awkward spot for
that, but the spec requires it to be the second descriptor. */
if (!i && eltorito_entry) {
cdrom_image_viso_log("VISO: Writing El Torito boot descriptor for entry [%08X]\n", eltorito_entry);
image_viso_log(viso->tf.log, "Writing El Torito boot descriptor for "
"entry [%08X]\n", eltorito_entry);
p = data;
if (!(viso->format & VISO_FORMAT_ISO))
VISO_LBE_32(p, ftello64(viso->tf.fp) / viso->sector_size); /* sector offset (HSF only) */
*p++ = 0; /* type */
memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); /* standard ID */
/* Sector offset (HSF only). */
VISO_LBE_32(p, ftello64(viso->tf.fp) / viso->sector_size);
/* Type. */
*p++ = 0;
/* Standard ID. */
memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5);
p += 5;
*p++ = 1; /* version */
@@ -1236,7 +1263,7 @@ next_dir:
/* Write each path table. */
for (int i = 0; i <= ((max_vd << 1) | 1); i++) {
cdrom_image_viso_log("VISO: Generating path table #%d:\n", i);
image_viso_log(viso->tf.log, "Generating path table #%d:\n", i);
/* Save this path table's start offset. */
uint64_t pt_start = ftello64(viso->tf.fp);
@@ -1257,7 +1284,9 @@ next_dir:
continue;
}
cdrom_image_viso_log("[%08X] %s => %s\n", dir, dir->path, ((i & 2) || (dir == viso->root_dir)) ? dir->basename : dir->name_short);
image_viso_log(viso->tf.log, "[%08X] %s => %s\n", dir,
dir->path, ((i & 2) || (dir == viso->root_dir)) ? dir->basename :
dir->name_short);
/* Save this directory's path table index and offset. */
dir->pt_idx = pt_idx;
@@ -1325,7 +1354,7 @@ next_dir:
/* Write directory records for each type. */
int dir_type = VISO_DIR_CURRENT_ROOT;
for (int i = 0; i <= max_vd; i++) {
cdrom_image_viso_log("VISO: Generating directory record set #%d:\n", i);
image_viso_log(viso->tf.log, "Generating directory record set #%d:\n", i);
/* Go through directories. */
dir = viso->root_dir;
@@ -1368,8 +1397,10 @@ next_dir:
if ((entry == eltorito_entry) || (entry == eltorito_dir))
goto next_entry;
cdrom_image_viso_log("[%08X] %s => %s\n", entry, dir->path,
((dir_type == VISO_DIR_PARENT) ? ".." : ((dir_type < VISO_DIR_PARENT) ? "." : (i ? entry->basename : entry->name_short))));
image_viso_log(viso->tf.log, "[%08X] %s => %s\n", entry, dir->path,
((dir_type == VISO_DIR_PARENT) ? ".." :
((dir_type < VISO_DIR_PARENT) ? "." :
(i ? entry->basename : entry->name_short))));
/* Fill directory record. */
viso_fill_dir_record(data, entry, viso, dir_type);
@@ -1436,7 +1467,8 @@ next_entry:
/* Allocate entry map for sector->file lookups. */
size_t orig_sector_size = viso->sector_size;
while (1) {
cdrom_image_viso_log("VISO: Allocating entry map for %zu %zu-byte sectors\n", viso->entry_map_size, viso->sector_size);
image_viso_log(viso->tf.log, "Allocating entry map for %zu %zu-byte sectors\n",
viso->entry_map_size, viso->sector_size);
viso->entry_map = (viso_entry_t **) calloc(viso->entry_map_size, sizeof(viso_entry_t *));
if (viso->entry_map) {
/* Successfully allocated. */
@@ -1477,7 +1509,7 @@ next_entry:
viso->all_sectors = viso->metadata_sectors;
/* Go through files, assigning sectors to them. */
cdrom_image_viso_log("VISO: Assigning sectors to files:\n");
image_viso_log(viso->tf.log, "Assigning sectors to files:\n");
size_t base_factor = viso->sector_size / orig_sector_size;
viso_entry_t *prev_entry = viso->root_dir;
viso_entry_t **entry_map_p = viso->entry_map;
@@ -1522,7 +1554,8 @@ next_entry:
size_t size = entry->stats.st_size / viso->sector_size;
if (entry->stats.st_size % viso->sector_size)
size++; /* round up to the next sector */
cdrom_image_viso_log("[%08X] %s => %zu + %zu sectors\n", entry, entry->path, viso->all_sectors, size);
image_viso_log(viso->tf.log, "[%08X] %s => %zu + %zu sectors\n", entry,
entry->path, viso->all_sectors, size);
/* Allocate sectors to this file. */
viso->all_sectors += size;
@@ -1541,9 +1574,10 @@ next_entry:
viso_pwrite(data, viso->vol_size_offsets[i], 8, 1, viso->tf.fp);
/* Metadata processing is finished, read it back to memory. */
cdrom_image_viso_log("VISO: Reading back %zu %zu-byte sectors of metadata\n", viso->metadata_sectors, viso->sector_size);
image_viso_log(viso->tf.log, "Reading back %zu %zu-byte sectors of metadata\n",
viso->metadata_sectors, viso->sector_size);
viso->metadata = (uint8_t *) calloc(viso->metadata_sectors, viso->sector_size);
if (!viso->metadata)
if (viso->metadata == NULL)
goto end;
fseeko64(viso->tf.fp, 0, SEEK_SET);
size_t metadata_size = viso->metadata_sectors * viso->sector_size;
@@ -1554,7 +1588,7 @@ next_entry:
/* We no longer need the temporary file; close and delete it. */
fclose(viso->tf.fp);
viso->tf.fp = NULL;
#ifndef ENABLE_CDROM_IMAGE_VISO_LOG
#ifndef ENABLE_IMAGE_VISO_LOG
remove(nvr_path(viso->tf.fn));
#endif
@@ -1565,13 +1599,15 @@ end:
/* Set the function pointers. */
viso->tf.priv = viso;
if (!*error) {
cdrom_image_viso_log("VISO: Initialized\n");
image_viso_log(viso->tf.log, "Initialized\n");
viso->tf.read = viso_read;
viso->tf.get_length = viso_get_length;
viso->tf.close = viso_close;
return &viso->tf;
} else {
cdrom_image_viso_log("VISO: Initialization failed\n");
image_viso_log(viso->tf.log, "Initialization failed\n");
if (data)
free(data);
viso_close(&viso->tf);

View File

@@ -1,267 +0,0 @@
/*
* 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.
*
* CD-ROM passthrough support.
*
*
*
* Authors: TheCollector1995, <mariogplayer@gmail.com>,
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2023 TheCollector1995.
* Copyright 2023 Miran Grca.
*/
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/config.h>
#include <86box/path.h>
#include <86box/plat.h>
#include <86box/scsi_device.h>
#include <86box/cdrom.h>
#include <86box/plat_cdrom.h>
#ifdef ENABLE_CDROM_IOCTL_LOG
int cdrom_ioctl_do_log = ENABLE_CDROM_IOCTL_LOG;
void
cdrom_ioctl_log(const char *fmt, ...)
{
va_list ap;
if (cdrom_ioctl_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define cdrom_ioctl_log(fmt, ...)
#endif
/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong:
there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start
of the audio while audio still plays. With an absolute conversion, the counter is fine. */
#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
static void
ioctl_get_track_info(cdrom_t *dev, uint32_t track, int end, track_info_t *ti)
{
TMSF tmsf;
plat_cdrom_get_audio_track_info(dev->local, end, track, &ti->number, &tmsf, &ti->attr);
ti->m = tmsf.min;
ti->s = tmsf.sec;
ti->f = tmsf.fr;
}
static void
ioctl_get_raw_track_info(cdrom_t *dev, int *num, raw_track_info_t *rti)
{
plat_cdrom_get_raw_track_info(dev->local, num, rti);
}
static void
ioctl_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc)
{
TMSF rel_pos;
TMSF abs_pos;
if ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED)) {
const uint32_t trk = plat_cdrom_get_track_start(dev->local, lba, &subc->attr, &subc->track);
FRAMES_TO_MSF(lba + 150, &abs_pos.min, &abs_pos.sec, &abs_pos.fr);
/* Absolute position should be adjusted by 150, not the relative ones. */
FRAMES_TO_MSF(lba - trk, &rel_pos.min, &rel_pos.sec, &rel_pos.fr);
subc->index = 1;
} else
plat_cdrom_get_audio_sub(dev->local, lba, &subc->attr, &subc->track, &subc->index,
&rel_pos, &abs_pos);
subc->abs_m = abs_pos.min;
subc->abs_s = abs_pos.sec;
subc->abs_f = abs_pos.fr;
subc->rel_m = rel_pos.min;
subc->rel_s = rel_pos.sec;
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);
}
static int
ioctl_get_capacity(cdrom_t *dev)
{
int ret;
ret = plat_cdrom_get_last_block(dev->local);
cdrom_ioctl_log("GetCapacity=%x.\n", ret);
return ret;
}
static int
ioctl_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf)
{
int m;
int s;
int f;
if (dev->cd_status == CD_STATUS_DATA_ONLY)
return 0;
if (ismsf) {
m = (pos >> 16) & 0xff;
s = (pos >> 8) & 0xff;
f = pos & 0xff;
pos = MSFtoLBA(m, s, f) - 150;
}
/* GetTrack requires LBA. */
return plat_cdrom_is_track_audio(dev->local, pos);
}
static int
ioctl_is_track_pre(cdrom_t *dev, uint32_t lba)
{
return plat_cdrom_is_track_pre(dev->local, lba);
}
static int
ioctl_sector_size(cdrom_t *dev, uint32_t lba)
{
cdrom_ioctl_log("LBA=%x.\n", lba);
return plat_cdrom_get_sector_size(dev->local, lba);
}
static int
ioctl_read_sector(cdrom_t *dev, uint8_t *b, uint32_t lba)
{
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 = CD_TRACK_UNK_DATA;
if (ioctl_is_track_audio(dev, lba, 0))
ret = CD_TRACK_AUDIO;
cdrom_ioctl_log("cdrom_ioctl_track_type(): %i\n", ret);
return ret;
}
static int
ioctl_ext_medium_changed(cdrom_t *dev)
{
int ret;
if ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED))
ret = 0;
else
ret = plat_cdrom_ext_medium_changed(dev->local);
if (ret == 1) {
dev->cd_status = CD_STATUS_STOPPED;
dev->cdrom_capacity = ioctl_get_capacity(dev);
} else if (ret == -1)
dev->cd_status = CD_STATUS_EMPTY;
return ret;
}
static void
ioctl_exit(cdrom_t *dev)
{
cdrom_ioctl_log("CDROM: ioctl_exit(%s)\n", dev->image_path);
dev->cd_status = CD_STATUS_EMPTY;
plat_cdrom_close(dev->local);
dev->local = NULL;
dev->ops = NULL;
}
static const cdrom_ops_t cdrom_ioctl_ops = {
ioctl_get_track_info,
ioctl_get_raw_track_info,
ioctl_get_subchannel,
ioctl_is_track_pre,
ioctl_sector_size,
ioctl_read_sector,
ioctl_track_type,
ioctl_ext_medium_changed,
ioctl_exit
};
static int
cdrom_ioctl_open_abort(cdrom_t *dev)
{
cdrom_ioctl_close(dev);
dev->ops = NULL;
dev->image_path[0] = 0;
return 1;
}
int
cdrom_ioctl_open(cdrom_t *dev, const char *drv)
{
const char *actual_drv = &(drv[8]);
int local_size = plat_cdrom_get_local_size();
/* Make sure to not STRCPY if the two are pointing
at the same place. */
if (drv != dev->image_path)
strcpy(dev->image_path, drv);
/* Open the image. */
if (strstr(drv, "ioctl://") != drv)
return cdrom_ioctl_open_abort(dev);
cdrom_ioctl_log("actual_drv = %s\n", actual_drv);
if (dev->local == NULL)
dev->local = calloc(1, local_size);
int i = plat_cdrom_set_drive(dev->local, actual_drv);
if (!i)
return cdrom_ioctl_open_abort(dev);
/* All good, reset state. */
dev->cd_status = CD_STATUS_STOPPED;
dev->seek_pos = 0;
dev->cd_buflen = 0;
dev->cdrom_capacity = ioctl_get_capacity(dev);
cdrom_ioctl_log("CD-ROM capacity: %i sectors (%" PRIi64 " bytes)\n",
dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity) << 11ULL);
/* Attach this handler to the drive. */
dev->ops = &cdrom_ioctl_ops;
return 0;
}
void
cdrom_ioctl_close(cdrom_t *dev)
{
cdrom_ioctl_log("CDROM: ioctl_close(%s)\n", dev->image_path);
if (dev && dev->ops && dev->ops->exit)
dev->ops->exit(dev);
}

View File

@@ -118,14 +118,6 @@ typedef struct mcd_t {
int newstat;
} mcd_t;
/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong:
there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start
of the audio while audio still plays. With an absolute conversion, the counter is fine. */
#ifdef MSFtoLBA
#undef MSFtoLBA
#endif
#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
#define CD_BCD(x) (((x) % 10) | (((x) / 10) << 4))
#define CD_DCB(x) ((((x) &0xf0) >> 4) * 10 + ((x) &0x0f))

View File

@@ -29,12 +29,13 @@
*/
#include <inttypes.h>
#ifdef ENABLE_CONFIG_LOG
#include <stdarg.h>
#endif
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
@@ -53,10 +54,8 @@
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/gameport.h>
#include <86box/serial.h>
#include <86box/serial_passthrough.h>
#include <86box/machine.h>
#include <86box/mouse.h>
@@ -300,7 +299,7 @@ load_machine(void)
/* Only copy if a file with the new name doesn't already exist. */
FILE *g = nvr_fopen(new_fn, "rb");
if (!g) {
if (g == NULL) {
FILE *f = nvr_fopen(entry->d_name, "rb");
g = nvr_fopen(new_fn, "wb");
@@ -361,7 +360,7 @@ load_machine(void)
while (!cpu_family_is_eligible(&cpu_families[c], machine)) {
if (cpu_families[c++].package == 0) {
/* End of list. */
fatal("No eligible CPU families for the selected machine\n");
fatal("Configuration: No eligible CPU families for the selected machine\n");
return;
}
}
@@ -441,7 +440,6 @@ load_video(void)
if (free_p) {
free(p);
p = NULL;
free_p = 0;
}
}
@@ -618,7 +616,7 @@ load_sound(void)
memset(temp, '\0', sizeof(temp));
p = ini_section_get_string(cat, "sound_type", "float");
if (strlen(p) > 511)
fatal("load_sound(): strlen(p) > 511\n");
fatal("Configuration: Length of sound_type is more than 511\n");
else
strncpy(temp, p, 511);
if (!strcmp(temp, "float") || !strcmp(temp, "1"))
@@ -847,7 +845,6 @@ load_storage_controllers(void)
if (free_p) {
free(p);
p = NULL;
free_p = 0;
}
ide_ter_enabled = !!ini_section_get_int(cat, "ide_ter", 0);
@@ -866,7 +863,7 @@ load_storage_controllers(void)
if (p[0] != 0x00) {
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511 (cassette_fname)\n");
fatal("Configuration: Length of cassette_file is more than 511\n");
else
strncpy(cassette_fname, p, 511);
} else
@@ -876,7 +873,7 @@ load_storage_controllers(void)
p = ini_section_get_string(cat, "cassette_mode", "load");
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511\n");
fatal("Configuration: Length of cassette_mode is more than 511\n");
else
strncpy(cassette_mode, p, 511);
@@ -887,8 +884,8 @@ load_storage_controllers(void)
if (p) {
if (path_abs(p)) {
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
fatal("load_storage_controllers(): strlen(p) > 2047 "
"(cassette_image_history[%i])\n", i);
fatal("Configuration: Length of cassette_image_history_%02i is more "
"than %i\n", i + 1, MAX_IMAGE_PATH_LEN - 1);
else
snprintf(cassette_image_history[i], MAX_IMAGE_PATH_LEN, "%s", p);
} else
@@ -937,7 +934,8 @@ load_storage_controllers(void)
if (p[0] != 0x00) {
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511 (cart_fns[%i])\n", c);
fatal("Configuration: Length of cartridge_%02i_fn is more than 511\n",
c + 1);
else
strncpy(cart_fns[c], p, 511);
} else
@@ -952,8 +950,8 @@ load_storage_controllers(void)
if (p) {
if (path_abs(p)) {
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
fatal("load_storage_controllers(): strlen(p) > 2047 "
"(cart_image_history[%i][%i])\n", c, i);
fatal("Configuration: Length of cartridge_%02i_image_history_%02i "
"is more than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1);
else
snprintf(cart_image_history[c][i], MAX_IMAGE_PATH_LEN, "%s", p);
} else
@@ -992,8 +990,8 @@ load_hard_disks(void)
sscanf(p, "%u, %u, %u, %i, %s",
&hdd[c].spt, &hdd[c].hpc, &hdd[c].tracks, (int *) &hdd[c].wp, s);
hdd[c].bus = hdd_string_to_bus(s, 0);
switch (hdd[c].bus) {
hdd[c].bus_type = hdd_string_to_bus(s, 0);
switch (hdd[c].bus_type) {
default:
case HDD_BUS_DISABLED:
max_spt = max_hpc = max_tracks = 0;
@@ -1039,7 +1037,7 @@ load_hard_disks(void)
hdd[c].tracks = max_tracks;
sprintf(temp, "hdd_%02i_speed", c + 1);
switch (hdd[c].bus) {
switch (hdd[c].bus_type) {
case HDD_BUS_IDE:
case HDD_BUS_ESDI:
case HDD_BUS_ATAPI:
@@ -1055,28 +1053,28 @@ load_hard_disks(void)
/* MFM/RLL */
sprintf(temp, "hdd_%02i_mfm_channel", c + 1);
if (hdd[c].bus == HDD_BUS_MFM)
if (hdd[c].bus_type == HDD_BUS_MFM)
hdd[c].mfm_channel = !!ini_section_get_int(cat, temp, c & 1);
else
ini_section_delete_var(cat, temp);
/* XTA */
sprintf(temp, "hdd_%02i_xta_channel", c + 1);
if (hdd[c].bus == HDD_BUS_XTA)
if (hdd[c].bus_type == HDD_BUS_XTA)
hdd[c].xta_channel = !!ini_section_get_int(cat, temp, c & 1);
else
ini_section_delete_var(cat, temp);
/* ESDI */
sprintf(temp, "hdd_%02i_esdi_channel", c + 1);
if (hdd[c].bus == HDD_BUS_ESDI)
if (hdd[c].bus_type == HDD_BUS_ESDI)
hdd[c].esdi_channel = !!ini_section_get_int(cat, temp, c & 1);
else
ini_section_delete_var(cat, temp);
/* IDE */
sprintf(temp, "hdd_%02i_ide_channel", c + 1);
if ((hdd[c].bus == HDD_BUS_IDE) || (hdd[c].bus == HDD_BUS_ATAPI)) {
if ((hdd[c].bus_type == HDD_BUS_IDE) || (hdd[c].bus_type == HDD_BUS_ATAPI)) {
sprintf(tmp2, "%01u:%01u", c >> 1, c & 1);
p = ini_section_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%01u", &board, &dev);
@@ -1090,7 +1088,7 @@ load_hard_disks(void)
ini_section_delete_var(cat, temp);
/* SCSI */
if (hdd[c].bus == HDD_BUS_SCSI) {
if (hdd[c].bus_type == HDD_BUS_SCSI) {
sprintf(temp, "hdd_%02i_scsi_location", c + 1);
sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c + 2);
p = ini_section_get_string(cat, temp, tmp2);
@@ -1130,7 +1128,8 @@ load_hard_disks(void)
if (p[0] != 0x00) {
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_hard_disks(): strlen(p) > 511 (hdd[%i].fn)\n", c);
fatal("Configuration: Length of hdd_%02i_fn is more "
"than 511\n", c + 1);
else
strncpy(hdd[c].fn, p, 511);
} else
@@ -1179,12 +1178,12 @@ load_floppy_and_cdrom_drives(void)
char temp[512];
char tmp2[512];
char *p;
char *def_type;
char s[512];
unsigned int board = 0;
unsigned int dev = 0;
int c;
int d = 0;
int count = cdrom_get_type_count();
memset(temp, 0x00, sizeof(temp));
for (c = 0; c < FDD_NUM; c++) {
@@ -1203,7 +1202,7 @@ load_floppy_and_cdrom_drives(void)
if (p[0] != 0x00) {
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 (floppyfns[%i])\n", c);
fatal("Configuration: Length of fdd_%02i_fn is more than 511\n", c + 1);
else
strncpy(floppyfns[c], p, 511);
} else
@@ -1251,8 +1250,8 @@ load_floppy_and_cdrom_drives(void)
if (p) {
if (path_abs(p)) {
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 2047 "
"(fdd_image_history[%i][%i])\n", c, i);
fatal("Configuration: Length of fdd_%02i_image_history_%02i is more "
"than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1);
else
snprintf(fdd_image_history[c][i], MAX_IMAGE_PATH_LEN, "%s", p);
} else
@@ -1284,12 +1283,20 @@ load_floppy_and_cdrom_drives(void)
cdrom[c].speed = ini_section_get_int(cat, temp, 8);
sprintf(temp, "cdrom_%02i_type", c + 1);
def_type = (c == 1) ? "86BOX_CD-ROM_1.00" : "none";
p = ini_section_get_string(cat, temp, def_type);
cdrom_set_type(c, cdrom_get_from_internal_name(p));
if (cdrom_get_type(c) > KNOWN_CDROM_DRIVE_TYPES)
cdrom_set_type(c, KNOWN_CDROM_DRIVE_TYPES);
if (!strcmp(p, def_type))
p = ini_section_get_string(cat, temp, "86cd");
/* TODO: Configuration migration, remove when no longer needed. */
int cdrom_type = cdrom_get_from_internal_name(p);
if (cdrom_type == -1) {
cdrom_type = cdrom_get_from_name(p);
if (cdrom_type == -1)
cdrom_set_type(c, cdrom_get_from_internal_name("86cd"));
else
cdrom_set_type(c, cdrom_type);
} else
cdrom_set_type(c, cdrom_type);
if (cdrom_get_type(c) >= count)
cdrom_set_type(c, count - 1);
if (!strcmp(p, "86cd"))
ini_section_delete_var(cat, temp);
/* Default values, needed for proper operation of the Settings dialog. */
@@ -1347,7 +1354,7 @@ load_floppy_and_cdrom_drives(void)
if (p[0] != 0x00) {
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 (cdrom[%i].image_path)\n", c);
fatal("Configuration: Length of cdrom_%02i_image_path is more than 511\n", c + 1);
else
strncpy(cdrom[c].image_path, p, 511);
} else
@@ -1362,8 +1369,8 @@ load_floppy_and_cdrom_drives(void)
if (p) {
if (path_abs(p)) {
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 2047 "
"(cdrom[%i].image_history[%i])\n", c, i);
fatal("Configuration: Length of cdrom_%02i_image_history_%02i is more "
"than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1);
else
snprintf(cdrom[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s", p);
} else
@@ -1378,6 +1385,12 @@ load_floppy_and_cdrom_drives(void)
sprintf(temp, "cdrom_%02i_parameters", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_speed", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_type", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_ide_channel", c + 1);
ini_section_delete_var(cat, temp);
@@ -1476,8 +1489,7 @@ load_other_removable_devices(void)
if (p[0] != 0x00) {
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_other_removable_devices(): strlen(p) > 511 (zip_drives[%i].image_path)\n",
c);
fatal("Configuration: Length of zip_%02i_image_path is more than 511\n", c + 1);
else
strncpy(zip_drives[c].image_path, p, 511);
} else
@@ -1492,8 +1504,8 @@ load_other_removable_devices(void)
if (p) {
if (path_abs(p)) {
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
fatal("load_other_removable_devices(): strlen(p) > 2047 "
"(zip_drives[%i].image_history[%i])\n", c, i);
fatal("Configuration: Length of zip_%02i_image_history_%02i is more than %i\n",
c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1);
else
snprintf(zip_drives[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s", p);
} else
@@ -1589,8 +1601,7 @@ load_other_removable_devices(void)
if (p[0] != 0x00) {
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_other_removable_devices(): strlen(p) > 511 (mo_drives[%i].image_path)\n",
c);
fatal("Configuration: Length of mo_%02i_image_path is more than 511\n", c + 1);
else
strncpy(mo_drives[c].image_path, p, 511);
} else
@@ -1605,8 +1616,8 @@ load_other_removable_devices(void)
if (p) {
if (path_abs(p)) {
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
fatal("load_other_removable_devices(): strlen(p) > 2047 "
"(mo_drives[%i].image_history[%i])\n", c, i);
fatal("Configuration: Length of mo_%02i_image_history_%02i is more than %i\n",
c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1);
else
snprintf(mo_drives[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s", p);
} else
@@ -1698,7 +1709,7 @@ config_load(void)
config = ini_read(cfg_path);
if (!config) {
if (config == NULL) {
config = ini_new();
config_changed = 1;
@@ -2574,7 +2585,7 @@ save_hard_disks(void)
for (uint8_t c = 0; c < HDD_NUM; c++) {
sprintf(temp, "hdd_%02i_parameters", c + 1);
if (hdd_is_valid(c)) {
p = hdd_bus_to_string(hdd[c].bus, 0);
p = hdd_bus_to_string(hdd[c].bus_type, 0);
sprintf(tmp2, "%u, %u, %u, %i, %s",
hdd[c].spt, hdd[c].hpc, hdd[c].tracks, hdd[c].wp, p);
ini_section_set_string(cat, temp, tmp2);
@@ -2582,25 +2593,26 @@ save_hard_disks(void)
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_mfm_channel", c + 1);
if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_MFM))
if (hdd_is_valid(c) && (hdd[c].bus_type == HDD_BUS_MFM))
ini_section_set_int(cat, temp, hdd[c].mfm_channel);
else
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_xta_channel", c + 1);
if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_XTA))
if (hdd_is_valid(c) && (hdd[c].bus_type == HDD_BUS_XTA))
ini_section_set_int(cat, temp, hdd[c].xta_channel);
else
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_esdi_channel", c + 1);
if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_ESDI))
if (hdd_is_valid(c) && (hdd[c].bus_type == HDD_BUS_ESDI))
ini_section_set_int(cat, temp, hdd[c].esdi_channel);
else
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_ide_channel", c + 1);
if (!hdd_is_valid(c) || ((hdd[c].bus != HDD_BUS_IDE) && (hdd[c].bus != HDD_BUS_ATAPI)))
if (!hdd_is_valid(c) || ((hdd[c].bus_type != HDD_BUS_IDE) &&
(hdd[c].bus_type != HDD_BUS_ATAPI)))
ini_section_delete_var(cat, temp);
else {
sprintf(tmp2, "%01u:%01u", hdd[c].ide_channel >> 1, hdd[c].ide_channel & 1);
@@ -2611,7 +2623,7 @@ save_hard_disks(void)
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_scsi_location", c + 1);
if (hdd[c].bus != HDD_BUS_SCSI)
if (hdd[c].bus_type != HDD_BUS_SCSI)
ini_section_delete_var(cat, temp);
else {
sprintf(tmp2, "%01u:%02u", hdd[c].scsi_id >> 4,
@@ -2643,8 +2655,9 @@ save_hard_disks(void)
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_speed", c + 1);
if (!hdd_is_valid(c) || ((hdd[c].bus != HDD_BUS_ESDI) && (hdd[c].bus != HDD_BUS_IDE) &&
(hdd[c].bus != HDD_BUS_SCSI) && (hdd[c].bus != HDD_BUS_ATAPI)))
if (!hdd_is_valid(c) ||
((hdd[c].bus_type != HDD_BUS_ESDI) && (hdd[c].bus_type != HDD_BUS_IDE) &&
(hdd[c].bus_type != HDD_BUS_SCSI) && (hdd[c].bus_type != HDD_BUS_ATAPI)))
ini_section_delete_var(cat, temp);
else
ini_section_set_string(cat, temp, hdd_preset_get_internal_name(hdd[c].speed_preset));
@@ -2729,11 +2742,12 @@ save_floppy_and_cdrom_drives(void)
ini_section_set_int(cat, temp, cdrom[c].speed);
sprintf(temp, "cdrom_%02i_type", c + 1);
if ((cdrom[c].bus_type == 0) || (cdrom[c].bus_type == CDROM_BUS_MITSUMI))
char *tn = cdrom_get_internal_name(cdrom_get_type(c));
if ((cdrom[c].bus_type == 0) || (cdrom[c].bus_type == CDROM_BUS_MITSUMI) ||
!strcmp(tn, "86cd"))
ini_section_delete_var(cat, temp);
else
ini_section_set_string(cat, temp,
cdrom_get_internal_name(cdrom_get_type(c)));
ini_section_set_string(cat, temp, tn);
sprintf(temp, "cdrom_%02i_parameters", c + 1);
if (cdrom[c].bus_type == 0)

View File

@@ -925,7 +925,7 @@ wd1007vse1_init(UNUSED(const device_t *info))
c = 0;
for (uint8_t d = 0; d < HDD_NUM; d++) {
if ((hdd[d].bus == HDD_BUS_ESDI) && (hdd[d].esdi_channel < ESDI_NUM)) {
if ((hdd[d].bus_type == HDD_BUS_ESDI) && (hdd[d].esdi_channel < ESDI_NUM)) {
loadhd(esdi, hdd[d].esdi_channel, d, hdd[d].fn);
if (++c >= ESDI_NUM)

View File

@@ -1265,7 +1265,7 @@ esdi_init(UNUSED(const device_t *info))
dev->drives[0].present = dev->drives[1].present = 0;
for (c = 0, i = 0; i < HDD_NUM; i++) {
if ((hdd[i].bus == HDD_BUS_ESDI) && (hdd[i].esdi_channel < ESDI_NUM)) {
if ((hdd[i].bus_type == HDD_BUS_ESDI) && (hdd[i].esdi_channel < ESDI_NUM)) {
/* This is an ESDI drive. */
drive = &dev->drives[hdd[i].esdi_channel];

View File

@@ -486,7 +486,7 @@ ide_get_max(const ide_t *ide, const int type)
int ret;
if (ide->type == IDE_ATAPI)
ret = ide->get_max(!IDE_ATAPI_IS_EARLY && ata_4, type);
ret = ide->get_max(ide, !IDE_ATAPI_IS_EARLY && ata_4, type);
else
ret = max[ata_4][type];
@@ -501,7 +501,7 @@ ide_get_timings(const ide_t *ide, const int type)
int ret;
if (ide->type == IDE_ATAPI)
ret = ide->get_timings(!IDE_ATAPI_IS_EARLY && ata_4, type);
ret = ide->get_timings(ide, !IDE_ATAPI_IS_EARLY && ata_4, type);
else
ret = timings[ata_4][type];
@@ -643,7 +643,7 @@ ide_identify(ide_t *ide)
memset(ide->buffer, 0, 512);
if (ide->type == IDE_ATAPI)
ide->identify(ide, !IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 && (bm != NULL));
ide->identify((const ide_t *) ide, !IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 && (bm != NULL));
else if (ide->type == IDE_HDD)
ide_hd_identify(ide);
else {
@@ -973,7 +973,7 @@ ide_atapi_attach(ide_t *ide)
ide->type = IDE_ATAPI;
ide_allocate_buffer(ide);
ide_set_signature(ide);
ide->mdma_mode = (1 << ide->get_max(!IDE_ATAPI_IS_EARLY &&
ide->mdma_mode = (1 << ide->get_max((const ide_t *) ide, !IDE_ATAPI_IS_EARLY &&
!ide_boards[ide->board]->force_ata3 && (bm != NULL), TYPE_PIO));
ide->tf->error = 1;
ide->cfg_spt = ide->cfg_hpc = 0;
@@ -1655,7 +1655,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
ide->sc->callback = 200.0 * IDE_TIME;
if (ide->type == IDE_HDD) {
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1);
uint32_t sec_count;
double wait_time;
if ((val == WIN_READ_DMA) || (val == WIN_READ_DMA_ALT)) {
@@ -1697,7 +1697,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
ide->blockcount = 0;
/* Turn on the activity indicator *here* so that it gets turned on
less times. */
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1);
fallthrough;
case WIN_WRITE:
@@ -1885,7 +1885,7 @@ ide_read_data(ide_t *ide)
ide_set_callback(ide, seek_us + xfer_us);
}
} else
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 0);
}
}
}
@@ -2238,7 +2238,7 @@ ide_callback(void *priv)
ide_irq_raise(ide);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1);
}
break;
@@ -2277,7 +2277,7 @@ ide_callback(void *priv)
ide->tf->atastat = DRDY_STAT | DSC_STAT;
ide_irq_raise(ide);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 0);
} else {
/* Bus master DMAS error, abort the command. */
ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel);
@@ -2346,10 +2346,10 @@ ide_callback(void *priv)
ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
ide->tf->pos = 0;
ide_next_sector(ide);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1);
} else {
ide->tf->atastat = DRDY_STAT | DSC_STAT;
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 0);
}
if (ret < 0)
err = UNC_ERR;
@@ -2391,7 +2391,7 @@ ide_callback(void *priv)
err = UNC_ERR;
ide_irq_raise(ide);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 0);
} else {
/* Bus master DMA error, abort the command. */
ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel);
@@ -2429,7 +2429,7 @@ ide_callback(void *priv)
ide_next_sector(ide);
} else {
ide->tf->atastat = DRDY_STAT | DSC_STAT;
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 0);
}
if (ret < 0)
err = UNC_ERR;
@@ -2446,7 +2446,7 @@ ide_callback(void *priv)
ide->tf->pos = 0;
ide->tf->atastat = DRDY_STAT | DSC_STAT;
ide_irq_raise(ide);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1);
}
break;
@@ -2463,7 +2463,7 @@ ide_callback(void *priv)
err = UNC_ERR;
ide_irq_raise(ide);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1);
}
break;
@@ -2759,7 +2759,7 @@ ide_board_setup(const int board)
c = 0;
for (d = 0; d < HDD_NUM; d++) {
const int is_ide = (hdd[d].bus == HDD_BUS_IDE);
const int is_ide = (hdd[d].bus_type == HDD_BUS_IDE);
const int ch = hdd[d].ide_channel;
const int valid_ch = ((ch >= min_ch) && (ch <= max_ch));

View File

@@ -475,19 +475,22 @@ sff_reset(void *priv)
#endif
for (uint8_t i = 0; i < HDD_NUM; i++) {
if ((hdd[i].bus == HDD_BUS_ATAPI) && (hdd[i].ide_channel < 4) && hdd[i].priv)
if ((hdd[i].bus_type == HDD_BUS_ATAPI) && (hdd[i].ide_channel < 4) && hdd[i].priv)
scsi_disk_reset((scsi_common_t *) hdd[i].priv);
}
for (uint8_t i = 0; i < CDROM_NUM; i++) {
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv)
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) &&
cdrom[i].priv)
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
}
for (uint8_t i = 0; i < ZIP_NUM; i++) {
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel < 4) && zip_drives[i].priv)
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel < 4) &&
zip_drives[i].priv)
zip_reset((scsi_common_t *) zip_drives[i].priv);
}
for (uint8_t i = 0; i < MO_NUM; i++) {
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && mo_drives[i].priv)
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) &&
mo_drives[i].priv)
mo_reset((scsi_common_t *) mo_drives[i].priv);
}

View File

@@ -749,7 +749,7 @@ mfm_init(UNUSED(const device_t *info))
c = 0;
for (uint8_t d = 0; d < HDD_NUM; d++) {
if ((hdd[d].bus == HDD_BUS_MFM) && (hdd[d].mfm_channel < MFM_NUM)) {
if ((hdd[d].bus_type == HDD_BUS_MFM) && (hdd[d].mfm_channel < MFM_NUM)) {
loadhd(mfm, hdd[d].mfm_channel, d, hdd[d].fn);
st506_at_log("WD1003(%d): (%s) geometry %d/%d/%d\n", c, hdd[d].fn,

View File

@@ -1799,7 +1799,7 @@ st506_init(const device_t *info)
st506_xt_log("ST506: looking for disks...\n");
#endif
for (c = 0, i = 0; i < HDD_NUM; i++) {
if ((hdd[i].bus == HDD_BUS_MFM) && (hdd[i].mfm_channel < MFM_NUM)) {
if ((hdd[i].bus_type == HDD_BUS_MFM) && (hdd[i].mfm_channel < MFM_NUM)) {
st506_xt_log("ST506: disk '%s' on channel %i\n",
hdd[i].fn, hdd[i].mfm_channel);
loadhd(dev, hdd[i].mfm_channel, i, hdd[i].fn);

View File

@@ -1038,7 +1038,7 @@ xta_init(const device_t *info)
/* Load any disks for this device class. */
c = 0;
for (uint8_t i = 0; i < HDD_NUM; i++) {
if ((hdd[i].bus == HDD_BUS_XTA) && (hdd[i].xta_channel < max)) {
if ((hdd[i].bus_type == HDD_BUS_XTA) && (hdd[i].xta_channel < max)) {
drive = &dev->drives[hdd[i].xta_channel];
if (!hdd_image_load(i)) {

View File

@@ -123,7 +123,7 @@ hdd_bus_to_string(int bus, UNUSED(int cdrom))
int
hdd_is_valid(int c)
{
if (hdd[c].bus == HDD_BUS_DISABLED)
if (hdd[c].bus_type == HDD_BUS_DISABLED)
return 0;
if (strlen(hdd[c].fn) == 0)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -15,26 +15,34 @@
#ifndef EMU_CDROM_H
#define EMU_CDROM_H
#ifndef EMU_VERSION_H
#include <86box/version.h>
#endif
#define CDROM_NUM 8
#define CD_STATUS_EMPTY 0
#define CD_STATUS_DATA_ONLY 1
#define CD_STATUS_PAUSED 2
#define CD_STATUS_PLAYING 3
#define CD_STATUS_STOPPED 4
#define CD_STATUS_PLAYING_COMPLETED 5
#define CD_STATUS_DVD 2
#define CD_STATUS_PAUSED 4
#define CD_STATUS_PLAYING 5
#define CD_STATUS_STOPPED 6
#define CD_STATUS_PLAYING_COMPLETED 7
#define CD_STATUS_HAS_AUDIO 4
#define CD_STATUS_MASK 7
/* Medium changed flag. */
#define CD_STATUS_TRANSITION 0x40
#define CD_STATUS_MEDIUM_CHANGED 0x80
#define CD_TRACK_UNK_DATA 0x10
#define CD_TRACK_UNK_DATA 0x04
#define CD_TRACK_NORMAL 0x00
#define CD_TRACK_AUDIO 0x08
#define CD_TRACK_CDI 0x10
#define CD_TRACK_XA 0x20
#define CD_TRACK_MODE_MASK 0x30
#define CD_TRACK_MODE2 0x04
#define CD_READ_DATA 0
#define CD_READ_AUDIO 1
#define CD_READ_RAW 2
#define CD_TRACK_MODE2_MASK 0x07
#define CD_TOC_NORMAL 0
#define CD_TOC_SESSION 1
@@ -48,7 +56,34 @@
/* This is so that if/when this is changed to something else,
changing this one define will be enough. */
#define CDROM_EMPTY !dev->host_drive
#define CDROM_EMPTY !dev->host_drive
#define DVD_LAYER_0_SECTORS 0x00210558ULL
#define RAW_SECTOR_SIZE 2352
#define COOKED_SECTOR_SIZE 2048
#define DATA_TRACK 0x14
#define AUDIO_TRACK 0x10
#define CD_FPS 75
#define FRAMES_TO_MSF(f, M, S, F) \
{ \
uint64_t value = f; \
*(F) = (value % CD_FPS) & 0xff; \
value /= CD_FPS; \
*(S) = (value % 60) & 0xff; \
value /= 60; \
*(M) = value & 0xff; \
}
#define MSF_TO_FRAMES(M, S, F) ((M) *60 * CD_FPS + (S) *CD_FPS + (F))
typedef struct SMSF {
uint16_t min;
uint8_t sec;
uint8_t fr;
} TMSF;
#ifdef __cplusplus
extern "C" {
@@ -62,161 +97,126 @@ enum {
CDROM_BUS_USB = 8
};
enum
{
CDROM_TYPE_86BOX_100,
CDROM_TYPE_ASUS_CDS500_141,
CDROM_TYPE_ASUS_CDS520_132,
CDROM_TYPE_AZT_CDA46802I_115,
CDROM_TYPE_BTC_BCD36XH_U10,
CDROM_TYPE_GOLDSTAR_CRD_8160B_314,
CDROM_TYPE_HITACHI_CDR_8130_0020,
CDROM_TYPE_HITACHI_GD7500_A1,
CDROM_TYPE_HLDTST_GCR8526B_101,
CDROM_TYPE_HLDTST_GSA4160_A302,
CDROM_TYPE_KENWOOD_UCR_421_208E,
CDROM_TYPE_LG_CRN8245B_130,
CDROM_TYPE_LG_CRD8322B_106,
CDROM_TYPE_LTN48125S_1S07,
CDROM_TYPE_LTN526D_YSR5,
CDROM_TYPE_MATSHITA_583_107,
CDROM_TYPE_MATSHITA_585_Z18P,
CDROM_TYPE_MATSHITA_587_7S13,
CDROM_TYPE_MATSHITA_588_LS15,
CDROM_TYPE_MATSHITA_571_10e,
CDROM_TYPE_MATSHITA_572_10j,
CDROM_TYPE_MITSUMI_FX4820T_D02A,
CDROM_TYPE_NEC_260_100,
CDROM_TYPE_NEC_260_101,
CDROM_TYPE_NEC_273_420,
CDROM_TYPE_NEC_280_105,
CDROM_TYPE_NEC_280_308,
CDROM_TYPE_NEC_CDR_1900A_100,
CDROM_TYPE_PHILIPS_PCA403CD_U31P,
CDROM_TYPE_SONY_CDU76_10i,
CDROM_TYPE_SONY_CDU311_30h,
CDROM_TYPE_SONY_CDU5225_NYS4,
CDROM_TYPE_TEAC_CD516E_10G,
CDROM_TYPE_TEAC_CD524EA_30D,
CDROM_TYPE_TEAC_CD532E_20A,
CDROM_TYPE_TOSHIBA_5302TA_0305,
CDROM_TYPE_TOSHIBA_5702B_TA70,
CDROM_TYPE_TOSHIBA_6202B_1512,
CDROM_TYPE_TOSHIBA_6402B_1008,
CDROM_TYPE_TOSHIBA_6702B_1007,
CDROM_TYPE_TOSHIBA_M1802_1051,
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,
CDROM_TYPE_NEC_38_103,
CDROM_TYPE_NEC_75_103,
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,
CDROM_TYPE_PHILIPS_CDD2600_107,
CDROM_TYPE_PIONEER_DRM604X_2403,
CDROM_TYPE_PLEXTOR_PX32TS_103,
CDROM_TYPE_TEAC_CD50_100,
CDROM_TYPE_TEAC_R55S_10R,
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,
CDROM_TYPE_TOSHIBA_XM5701TA_3136,
CDROM_TYPE_TOSHIBA_SDM1401_1008,
CDROM_TYPES_NUM
};
#define KNOWN_CDROM_DRIVE_TYPES CDROM_TYPES_NUM
#define BUS_TYPE_IDE CDROM_BUS_ATAPI
#define BUS_TYPE_SCSI CDROM_BUS_SCSI
#define BUS_TYPE_BOTH -2
#define BUS_TYPE_NONE -1
#define CDV EMU_VERSION_EX
static const struct
{
const char vendor[9];
const char model[17];
const char revision[5];
const char *name;
const char *internal_name;
const int bus_type;
const char vendor[9];
const char model[17];
const char revision[5];
const char * internal_name;
const int bus_type;
/* SCSI standard for SCSI (or both) devices, early for IDE. */
const int scsi_std;
const int speed;
const int inquiry_len;
const int caddy;
const int transfer_max[4];
} cdrom_drive_types[] = {
{ "86BOX", "CD-ROM", "1.00", "86BOX CD-ROM 1.00", "86BOX_CD-ROM_1.00", BUS_TYPE_BOTH },
{ "ASUS", "CD-S500/A", "1.41", "ASUS CD-S500/A 1.41", "ASUS_CD-S500A_1.41", BUS_TYPE_IDE },
{ "ASUS", "CD-S520/A4", "1.32", "ASUS CD-S520/A4 1.32", "ASUS_CD-S520A4_1.32", BUS_TYPE_IDE },
{ "AZT", "CDA46802I", "1.15", "AZT CDA46802I 1.15", "AZT_CDA46802I_1.15", BUS_TYPE_IDE },
{ "BTC", "CD-ROM BCD36XH", "U1.0", "BTC CD-ROM BCD36XH U1.0", "BTC_CD-ROM_BCD36XH_U1.0", BUS_TYPE_IDE },
{ "GOLDSTAR", "CRD-8160B", "3.14", "GOLDSTAR CRD-8160B 3.14", "GOLDSTAR_CRD-8160B_3.14", BUS_TYPE_IDE },
{ "HITACHI", "CDR-8130", "0020", "HITACHI CDR-8130 0020", "HITACHI_CDR-8130_0020", BUS_TYPE_IDE },
{ "HITACHI", "GD-7500", "A1 ", "HITACHI GD-7500 A1", "HITACHI_GD-7500_A1", BUS_TYPE_IDE },
{ "HL-DT-ST", "CD-ROM GCR-8526B", "1.01", "HL-DT-ST CD-ROM GCR-8526B 1.01", "HL-DT-ST_CD-ROM_GCR-8526B_1.01", BUS_TYPE_IDE },
{ "HL-DT-ST", "DVDRAM GSA-4160", "A302", "HL-DT-ST DVDRAM GSA-4160 A302", "HL-DT-ST_DVDRAM_GSA-4160_A302", BUS_TYPE_IDE },
{ "KENWOOD", "CD-ROM UCR-421", "208E", "KENWOOD CD-ROM UCR-421 208E", "KENWOOD_CD-ROM_UCR-421_208E", BUS_TYPE_IDE },
{ "LG", "CD-ROM CRN-8245B", "1.30", "LG CD-ROM CRN-8245B 1.30", "LG_CD-ROM_CRN-8245B_1.30", BUS_TYPE_IDE },
{ "LG", "CD-ROM CRD-8322B", "1.06", "LG CD-ROM CRD-8322B 1.06", "LG_CD-ROM_CRD-8322B_1.06", BUS_TYPE_IDE },
{ "LITE-ON", "LTN48125S", "1S07", "LITE-ON LTN48125S 1S07", "LITE-ON_LTN48125S_1S07", BUS_TYPE_IDE },
{ "LITE-ON", "LTN526D", "YSR5", "LITE-ON LTN526D YSR5", "LITE-ON_LTN526D_YSR5", BUS_TYPE_IDE },
{ "MATSHITA", "CD-ROM CR-583", "1.07", "MATSHITA CD-ROM CR-583 1.07", "MATSHITA_CD-ROM_CR-583_1.07", BUS_TYPE_IDE },
{ "MATSHITA", "CD-ROM CR-585", "Z18P", "MATSHITA CD-ROM CR-585 Z18P", "MATSHITA_CD-ROM_CR-585_Z18P", BUS_TYPE_IDE },
{ "MATSHITA", "CD-ROM CR-587", "7S13", "MATSHITA CD-ROM CR-587 7S13", "MATSHITA_CD-ROM_CR-587_7S13", BUS_TYPE_IDE },
{ "MATSHITA", "CD-ROM CR-588", "LS15", "MATSHITA CD-ROM CR-588 LS15", "MATSHITA_CD-ROM_CR-588_LS15", BUS_TYPE_IDE },
{ "MATSHITA", "CR-571", "1.0e", "MATSHITA CR-571 1.0e", "MATSHITA_CR-571_1.0e", BUS_TYPE_IDE },
{ "MATSHITA", "CR-572", "1.0j", "MATSHITA CR-572 1.0j", "MATSHITA_CR-572_1.0j", BUS_TYPE_IDE },
{ "MITSUMI", "CRMC-FX4820T", "D02A", "MITSUMI CRMC-FX4820T D02A", "MITSUMI_CRMC-FX4820T_D02A", BUS_TYPE_IDE },
{ "NEC", "CD-ROM DRIVE:260", "1.00", "NEC CD-ROM DRIVE:260 1.00", "NEC_CD-ROM_DRIVE260_1.00", BUS_TYPE_IDE },
{ "NEC", "CD-ROM DRIVE:260", "1.01", "NEC CD-ROM DRIVE:260 1.01", "NEC_CD-ROM_DRIVE260_1.01", BUS_TYPE_IDE },
{ "NEC", "CD-ROM DRIVE:273", "4.20", "NEC CD-ROM DRIVE:273 4.20", "NEC_CD-ROM_DRIVE273_4.20", BUS_TYPE_IDE },
{ "NEC", "CD-ROM DRIVE:280", "1.05", "NEC CD-ROM DRIVE:280 1.05", "NEC_CD-ROM_DRIVE280_1.05", BUS_TYPE_IDE },
{ "NEC", "CD-ROM DRIVE:280", "3.08", "NEC CD-ROM DRIVE:280 3.08", "NEC_CD-ROM_DRIVE280_3.08", BUS_TYPE_IDE },
{ "NEC", "CDR-1900A", "1.00", "NEC CDR-1900A 1.00", "NEC_CDR-1900A_1.00", BUS_TYPE_IDE },
{ "PHILIPS", "CD-ROM PCA403CD", "U31P", "PHILIPS CD-ROM PCA403CD U31P", "PHILIPS_CD-ROM_PCA403CD_U31P", BUS_TYPE_IDE },
{ "SONY", "CD-ROM CDU76", "1.0i", "SONY CD-ROM CDU76 1.0i", "SONY_CD-ROM_CDU76_1.0i", BUS_TYPE_IDE },
{ "SONY", "CD-ROM CDU311", "3.0h", "SONY CD-ROM CDU311 3.0h", "SONY_CD-ROM_CDU311_3.0h", BUS_TYPE_IDE },
{ "SONY", "CD-ROM CDU5225", "NYS4", "SONY CD-ROM CDU5225 NYS4", "SONY_CD-ROM_CDU5225_NYS4", BUS_TYPE_IDE },
{ "TEAC", "CD-516E", "1.0G", "TEAC CD-516E 1.0G", "TEAC_CD-516E_1.0G", BUS_TYPE_IDE },
{ "TEAC", "CD-524EA", "3.0D", "TEAC CD-524EA 3.0D", "TEAC_CD-524EA_3.0D", BUS_TYPE_IDE },
{ "TEAC", "CD-532E", "2.0A", "TEAC CD-532E 2.0A", "TEAC_CD_532E_2.0A", 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 },
{ "TOSHIBA", "CD-ROM XM-6202B", "1512", "TOSHIBA CD-ROM XM-6202B 1512", "TOSHIBA_CD-ROM_XM-6202B_1512", BUS_TYPE_IDE },
{ "TOSHIBA", "CD-ROM XM-6402B", "1008", "TOSHIBA CD-ROM XM-6402B 1008", "TOSHIBA_CD-ROM_XM-6402B_1008", BUS_TYPE_IDE },
{ "TOSHIBA", "CD-ROM XM-6702B", "1007", "TOSHIBA CD-ROM XM-6702B 1007", "TOSHIBA_CD-ROM_XM-6702B_1007", BUS_TYPE_IDE },
{ "TOSHIBA", "DVD-ROM SD-M1802", "1051", "TOSHIBA DVD-ROM SD-M1802 1051", "TOSHIBA_DVD-ROM_SD-M1802_1051", BUS_TYPE_IDE },
{ "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 },
{ EMU_NAME, "86B_CD", CDV, "86cd", BUS_TYPE_BOTH, 2, -1, 36, 0, { 4, 2, 2, 5 } },
/* SCSI-1 / early ATAPI generic - second on purpose so the later variant is the default. */
{ EMU_NAME, "86B_CD", "1.00", "86cd100", BUS_TYPE_BOTH, 1, -1, 36, 1, { 0, -1, -1, -1 } },
/* No difference from 86BOX CD-ROM, other than name - but enough people have requested such a name to warrant it. */
{ EMU_NAME, "86B_DVD", "4.30", "86dvd", BUS_TYPE_BOTH, 2, -1, 36, 0, { 4, 2, 2, 5 } },
{ "ASUS", "CD-S500/A", "1.41", "asus_500", BUS_TYPE_IDE, 0, 50, 36, 0, { 4, 2, 2, 2 } },
{ "ASUS", "CD-S520/A4", "1.32", "asus_520", BUS_TYPE_IDE, 0, 52, 36, 0, { 4, 2, 2, 2 } },
{ "AZT", "CDA46802I", "1.15", "azt_cda", BUS_TYPE_IDE, 0, 4, 36, 0, { 3, 0, 0, 0 } },
{ "BTC", "CD-ROM BCD36XH", "U1.0", "btc_36xh", BUS_TYPE_IDE, 0, 36, 36, 0, { 4, 2, 2, -1 } },
{ "GOLDSTAR", "CRD-8160B", "3.14", "goldstar", BUS_TYPE_IDE, 0, 16, 36, 0, { 4, 2, 2, -1 } },
/* TODO: Find an IDENTIFY and/or INQUIRY dump. */
{ "GOLDSTAR", "GCD-R560B", "1.00", "goldstar", BUS_TYPE_IDE, 0, 6, 36, 0, { 4, 2, 2, -1 } },
{ "HITACHI", "CDR-8130", "0020", "hitachi_r8130", BUS_TYPE_IDE, 0, 16, 36, 0, { 4, 2, 2, -1 } },
{ "HITACHI", "GD-7500", "A1 ", "hitachi_7500", BUS_TYPE_IDE, 0, 40, 36, 0, { 4, 2, 2, 2 } }, /* DVD. */
{ "HL-DT-ST", "CD-ROM GCR-8526B", "1.01", "hldtst_8526b", BUS_TYPE_IDE, 0, 52, 36, 0, { 4, 2, 2, 2 } },
{ "HL-DT-ST", "DVDRAM GSA-4160", "A302", "hldtst_4160", BUS_TYPE_IDE, 0, 40, 36, 0, { 4, 2, 2, 2 } },
{ "KENWOOD", "CD-ROM UCR-421", "208E", "kenwood_421", BUS_TYPE_IDE, 0, 72, 36, 0, { 4, 2, 2, 4 } },
/*
This is a laptop/notebook drive, as is also evident from the name:
CRN = Notebook, CRD = Desktop.
*/
{ "LG", "CD-ROM CRN-8245B", "1.30", "lg_8245b", BUS_TYPE_IDE, 0, 24, 36, 0, { 4, 2, 2, -1 } },
{ "LG", "CD-ROM CRD-8322B", "1.06", "lg_8322b", BUS_TYPE_IDE, 0, 32, 36, 0, { 4, 2, 2, -1 } },
/* Nothing on Google, deduced 48x from the name. */
{ "LITE-ON", "LTN48125S", "1S07", "liteon_48125s", BUS_TYPE_IDE, 0, 48, 36, 0, { 4, 2, 2, 2 } },
/* Confirmed to be 52x, was the basis for deducing the other one's speed. */
{ "LITE-ON", "LTN526D", "YSR5", "liteon_526d", BUS_TYPE_IDE, 0, 52, 36, 0, { 4, 2, 2, 2 } },
{ "MATSHITA", "CD-ROM CR-583", "1.07", "matshita_583", BUS_TYPE_IDE, 0, 8, 36, 0, { 4, 2, 2, -1 } },
{ "MATSHITA", "CD-ROM CR-585", "Z18P", "matshita_585", BUS_TYPE_IDE, 0, 24, 36, 0, { 4, 2, 2, -1 } },
{ "MATSHITA", "CD-ROM CR-587", "7S13", "matshita_587", BUS_TYPE_IDE, 0, 24, 36, 0, { 4, 2, 2, -1 } },
{ "MATSHITA", "CD-ROM CR-588", "LS15", "matshita_588", BUS_TYPE_IDE, 0, 32, 36, 0, { 4, 2, 2, -1 } },
{ "MATSHITA", "CR-571", "1.0e", "matshita_571", BUS_TYPE_IDE, 0, 2, 36, 0, { 0, -1, -1, -1 } },
{ "MATSHITA", "CR-572", "1.0j", "matshita_572", BUS_TYPE_IDE, 0, 4, 36, 0, { 0, -1, -1, -1 } },
{ "MITSUMI", "CRMC-FX4820T", "D02A", "mitsumi_4820t", BUS_TYPE_IDE, 0, 48, 36, 0, { 4, 2, 2, 2 } },
/* TODO: Find an IDENTIFY and/or INQUIRY dump. */
{ "MITSUMI", "CRMC-FX810T4", "????", "mitsumi_810t4", BUS_TYPE_IDE, 0, 8, 36, 0, { 4, 2, 2, -1 } },
{ "NEC", "CD-ROM DRIVE:260", "1.00", "nec_260_early", BUS_TYPE_IDE, 1, 2, 36, 1, { 0, -1, -1, -1 } },
{ "NEC", "CD-ROM DRIVE:260", "1.01", "nec_260", BUS_TYPE_IDE, 1, 4, 36, 1, { 0, -1, -1, -1 } },
{ "NEC", "CD-ROM DRIVE:273", "4.20", "nec_273", BUS_TYPE_IDE, 0, 4, 36, 0, { 0, -1, -1, -1 } },
{ "NEC", "CD-ROM DRIVE:280", "1.05", "nec_280_early", BUS_TYPE_IDE, 0, 6, 36, 1, { 4, 2, 2, -1 } },
{ "NEC", "CD-ROM DRIVE:280", "3.08", "nec_280", BUS_TYPE_IDE, 0, 8, 36, 1, { 4, 2, 2, -1 } },
{ "NEC", "CDR-1300A", "1.05", "nec_1300a", BUS_TYPE_IDE, 0, 6, 36, 0, { 4, 2, 2, -1 } },
{ "NEC", "CDR-1900A", "1.00", "nec_1900a", BUS_TYPE_IDE, 0, 32, 36, 0, { 4, 2, 2, -1 } },
{ "PHILIPS", "CD-ROM PCA403CD", "U31P", "philips_403", BUS_TYPE_IDE, 0, 40, 36, 0, { 4, 2, 2, -1 } },
{ "SONY", "CD-ROM CDU76", "1.0i", "sony_76", BUS_TYPE_IDE, 0, 4, 36, 0, { 2, -1, -1, -1 } },
{ "SONY", "CD-ROM CDU311", "3.0h", "sony_311", BUS_TYPE_IDE, 0, 8, 36, 0, { 3, 2, 1, -1 } },
{ "SONY", "CD-ROM CDU5225", "NYS4", "sony_5225", BUS_TYPE_IDE, 0, 52, 36, 0, { 4, 2, 2, 4 } },
{ "TEAC", "CD-516E", "1.0G", "teac_516e", BUS_TYPE_IDE, 0, 16, 36, 0, { 3, 2, 2, -1 } },
{ "TEAC", "CD-524EA", "3.0D", "teac_524ea", BUS_TYPE_IDE, 0, 24, 36, 0, { 3, 2, 2, -1 } },
{ "TEAC", "CD-532E", "2.0A", "teac_532e", BUS_TYPE_IDE, 0, 32, 36, 0, { 3, 2, 2, -1 } },
{ "TOSHIBA", "CD-ROM XM-5302TA", "0305", "toshiba_5302ta", BUS_TYPE_IDE, 0, 4, 96, 0, { 0, -1, -1, -1 } },
{ "TOSHIBA", "CD-ROM XM-5702B", "TA70", "toshiba_5702b", BUS_TYPE_IDE, 0, 12, 96, 0, { 3, 2, 1, -1 } },
{ "TOSHIBA", "CD-ROM XM-6202B", "1512", "toshiba_6202b", BUS_TYPE_IDE, 0, 32, 96, 0, { 4, 2, 2, -1 } },
{ "TOSHIBA", "CD-ROM XM-6402B", "1008", "toshiba_6402b", BUS_TYPE_IDE, 0, 32, 96, 0, { 4, 2, 2, 2 } },
{ "TOSHIBA", "CD-ROM XM-6702B", "1007", "toshiba_6720b", BUS_TYPE_IDE, 0, 48, 96, 0, { 4, 2, 2, 2 } },
{ "TOSHIBA", "DVD-ROM SD-M1802", "1051", "toshiba_m1802", BUS_TYPE_IDE, 0, 48, 96, 0, { 4, 2, 2, 2 } },
{ "CHINON", "CD-ROM CDS-431", "H42 ", "chinon_431", BUS_TYPE_SCSI, 1, 1, 36, 1, { -1, -1, -1, -1 } },
{ "CHINON", "CD-ROM CDX-435", "M62 ", "chinon_435", BUS_TYPE_SCSI, 1, 2, 36, 1, { -1, -1, -1, -1 } },
{ "DEC", "RRD45 (C) DEC", "0436", "dec_45", BUS_TYPE_SCSI, 1, 4, 36, 0, { -1, -1, -1, -1 } },
{ "MATSHITA", "CD-ROM CR-501", "1.0b", "matshita_501", BUS_TYPE_SCSI, 1, 1, 36, 1, { -1, -1, -1, -1 } },
{ "NEC", "CD-ROM DRIVE:25", "1.0a", "nec_25", BUS_TYPE_SCSI, 1, 2, 36, 0, { -1, -1, -1, -1 } },
{ "NEC", "CD-ROM DRIVE:38", "1.00", "nec_38", BUS_TYPE_SCSI, 2, 1, 36, 0, { -1, -1, -1, -1 } },
/* The speed of the following two is guesswork based on the CDR-74. */
{ "NEC", "CD-ROM DRIVE:75", "1.03", "nec_75", BUS_TYPE_SCSI, 1, 1, 36, 1, { -1, -1, -1, -1 } },
{ "NEC", "CD-ROM DRIVE:77", "1.06", "nec_77", BUS_TYPE_SCSI, 1, 1, 36, 1, { -1, -1, -1, -1 } },
{ "NEC", "CD-ROM DRIVE:211", "1.00", "nec_211", BUS_TYPE_SCSI, 2, 3, 36, 0, { -1, -1, -1, -1 } },
/* The speed of the following two is guesswork based on the CDR-400. */
{ "NEC", "CD-ROM DRIVE:464", "1.05", "nec_464", BUS_TYPE_SCSI, 2, 3, 36, 0, { -1, -1, -1, -1 } },
/* The speed of the following two is guesswork based on the name. */
{ "ShinaKen", "CD-ROM DM-3x1S", "1.04", "shinaken_3x1s", BUS_TYPE_SCSI, 1, 3, 36, 0, { -1, -1, -1, -1 } },
{ "SONY", "CD-ROM CDU-541", "1.0i", "sony_541", BUS_TYPE_SCSI, 1, 1, 36, 1, { -1, -1, -1, -1 } },
{ "SONY", "CD-ROM CDU-561", "1.8k", "sony_561", BUS_TYPE_SCSI, 2, 2, 36, 1, { -1, -1, -1, -1 } },
{ "SONY", "CD-ROM CDU-76S", "1.00", "sony_76s", BUS_TYPE_SCSI, 2, 4, 36, 0, { -1, -1, -1, -1 } },
{ "PHILIPS", "CDD2600", "1.07", "philips_2600", BUS_TYPE_SCSI, 2, 6, 36, 0, { -1, -1, -1, -1 } },
/* NOTE: The real thing is a CD changer drive! */
{ "PIONEER", "CD-ROM DRM-604X", "2403", "pioneer_604x", BUS_TYPE_SCSI, 2, 4, 47, 0, { -1, -1, -1, -1 } },
{ "PLEXTOR", "CD-ROM PX-32TS", "1.03", "plextor_32ts", BUS_TYPE_SCSI, 2, 32, 36, 0, { -1, -1, -1, -1 } },
/* The speed of the following two is guesswork based on the R55S. */
{ "TEAC", "CD 50", "1.00", "teac_50", BUS_TYPE_SCSI, 2, 4, 36, 1, { -1, -1, -1, -1 } },
{ "TEAC", "CD-ROM R55S", "1.0R", "teac_55s", BUS_TYPE_SCSI, 2, 4, 36, 0, { -1, -1, -1, -1 } },
/* Texel is Plextor according to Plextor's own EU website. */
{ "TEXEL", "CD-ROM DM-3024", "1.00", "texel_3024", BUS_TYPE_SCSI, 2, 2, 36, 1, { -1, -1, -1, -1 } },
/*
Unusual 2.23x according to Google, I'm rounding it upwards to 3x.
Assumed caddy based on the DM-3024.
*/
{ "TEXEL", "CD-ROM DM-3028", "1.06", "texel_3028", BUS_TYPE_SCSI, 2, 3, 36, 1 }, /* Caddy. */
/*
The characteristics are a complete guesswork because I can't find
this one on Google.
Also, INQUIRY length is always 96 on these Toshiba drives.
*/
{ "TOSHIBA", "CD-ROM DRIVE:XM", "3433", "toshiba_xm", BUS_TYPE_SCSI, 2, 2, 96, 0 }, /* Tray. */
{ "TOSHIBA", "CD-ROM XM-3201B", "3232", "toshiba_3201b", BUS_TYPE_SCSI, 1, 1, 96, 1 }, /* Caddy. */
{ "TOSHIBA", "CD-ROM XM-3301TA", "0272", "toshiba_3301ta", BUS_TYPE_SCSI, 2, 2, 96, 0 }, /* Tray. */
{ "TOSHIBA", "CD-ROM XM-5701TA", "3136", "toshiba_5701a", BUS_TYPE_SCSI, 2, 12, 96, 0 }, /* Tray. */
{ "TOSHIBA", "DVD-ROM SD-M1401", "1008", "toshiba_m1401", BUS_TYPE_SCSI, 2, 40, 96, 0 }, /* Tray. */
{ "", "", "", "", BUS_TYPE_NONE, 0, -1, 0, 0 }
};
/* To shut up the GCC compilers. */
@@ -258,133 +258,177 @@ typedef struct raw_track_info_t {
/* Define the various CD-ROM drive operations (ops). */
typedef struct cdrom_ops_t {
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, 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);
int (*get_track_info)(const void *local, const uint32_t track,
const int end, track_info_t *ti);
void (*get_raw_track_info)(const void *local, int *num,
uint8_t *rti);
int (*is_track_pre)(const void *local, const uint32_t sector);
int (*read_sector)(const void *local, uint8_t *buffer,
const uint32_t sector);
uint8_t (*get_track_type)(const void *local, const uint32_t sector);
uint32_t (*get_last_block)(const void *local);
int (*read_dvd_structure)(const void *local, const uint8_t layer,
const uint8_t format, uint8_t *buffer,
uint32_t *info);
int (*is_dvd)(const void *local);
int (*has_audio)(const void *local);
int (*ext_medium_changed)(void *local);
void (*close)(void *local);
} cdrom_ops_t;
typedef struct cdrom {
uint8_t id;
uint8_t id;
union {
uint8_t res;
uint8_t res0; /* Reserved for other ID's. */
uint8_t res1;
uint8_t ide_channel;
uint8_t scsi_device_id;
uint8_t res;
uint8_t res0; /* Reserved for other ID's. */
uint8_t res1;
uint8_t ide_channel;
uint8_t scsi_device_id;
};
uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */
uint8_t bus_mode; /* Bit 0 = PIO suported;
Bit 1 = DMA supportd. */
uint8_t cd_status; /* Struct variable reserved for
media status. */
uint8_t speed;
uint8_t cur_speed;
uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */
uint8_t bus_mode; /* Bit 0 = PIO suported;
Bit 1 = DMA supportd. */
uint8_t cd_status; /* Struct variable reserved for
media status. */
uint8_t speed;
uint8_t cur_speed;
void *priv;
void * priv;
char image_path[1024];
char prev_image_path[1024];
char image_path[1024];
char prev_image_path[1024];
char *image_history[CD_IMAGE_HISTORY];
char * image_history[CD_IMAGE_HISTORY];
uint32_t sound_on;
uint32_t cdrom_capacity;
uint32_t seek_pos;
uint32_t seek_diff;
uint32_t cd_end;
uint32_t type;
uint32_t sector_size;
uint32_t sound_on;
uint32_t cdrom_capacity;
uint32_t seek_pos;
uint32_t seek_diff;
uint32_t cd_end;
uint32_t type;
uint32_t sector_size;
int cd_buflen;
int audio_op;
int audio_muted_soft;
int sony_msf;
int cd_buflen;
int audio_op;
int audio_muted_soft;
int sony_msf;
int real_speed;
int is_early;
int is_nec;
uint32_t inv_field;
const cdrom_ops_t *ops;
void *local;
void * local;
void * log;
void (*insert)(void *priv);
void (*close)(void *priv);
uint32_t (*get_volume)(void *p, int channel);
uint32_t (*get_channel)(void *p, int channel);
void (*insert)(void *priv);
void (*close)(void *priv);
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];
uint8_t subch_buffer[96];
} cdrom_t;
extern cdrom_t cdrom[CDROM_NUM];
extern char *cdrom_getname(int type);
/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong:
there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start
of the audio while audio still plays. With an absolute conversion, the counter is fine. */
#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
extern char *cdrom_get_internal_name(int type);
extern int cdrom_get_from_internal_name(char *s);
extern void cdrom_set_type(int model, int type);
extern int cdrom_get_type(int model);
static __inline int
bin2bcd(int x)
{
return (x % 10) | ((x / 10) << 4);
}
extern int cdrom_lba_to_msf_accurate(int lba);
extern double cdrom_seek_time(cdrom_t *dev);
extern void cdrom_stop(cdrom_t *dev);
extern int cdrom_is_pre(cdrom_t *dev, uint32_t lba);
extern int cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len);
extern uint8_t cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf);
extern uint8_t cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit);
extern uint8_t cdrom_audio_track_search_pioneer(cdrom_t *dev, uint32_t pos, uint8_t playbit);
extern uint8_t cdrom_audio_play_pioneer(cdrom_t *dev, uint32_t pos);
extern uint8_t cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type);
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_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);
extern int cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type,
unsigned char start_track, int msf, int max_len);
extern int cdrom_read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf, int max_len);
extern void cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf);
extern void cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode);
extern uint8_t cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len);
extern int cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf,
int cdrom_sector_type, int cdrom_sector_flags, int *len, uint8_t vendor_type);
extern uint8_t cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type);
static __inline int
bcd2bin(int x)
{
return (x >> 4) * 10 + (x & 0x0f);
}
extern void cdrom_seek(cdrom_t *dev, uint32_t pos, uint8_t vendor_type);
extern char *cdrom_get_vendor(const int type);
extern void cdrom_get_model(const int type, char *name, const int id);
extern char *cdrom_get_revision(const int type);
extern int cdrom_get_scsi_std(const int type);
extern int cdrom_is_early(const int type);
extern int cdrom_is_generic(const int type);
extern int cdrom_has_date(const int type);
extern int cdrom_is_sony(const int type);
extern int cdrom_is_caddy(const int type);
extern int cdrom_get_speed(const int type);
extern int cdrom_get_inquiry_len(const int type);
extern int cdrom_has_dma(const int type);
extern int cdrom_get_transfer_max(const int type, const int mode);
extern int cdrom_get_type_count(void);
extern void cdrom_get_identify_model(const int type, char *name, const int id);
extern void cdrom_get_name(const int type, char *name);
extern char *cdrom_get_internal_name(const int type);
extern int cdrom_get_from_internal_name(const char *s);
/* TODO: Configuration migration, remove when no longer needed. */
extern int cdrom_get_from_name(const char *s);
extern void cdrom_set_type(const int model, const int type);
extern int cdrom_get_type(const int model);
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);
extern int cdrom_lba_to_msf_accurate(const int lba);
extern double cdrom_seek_time(const cdrom_t *dev);
extern void cdrom_stop(cdrom_t *dev);
extern void cdrom_seek(cdrom_t *dev, const uint32_t pos, const uint8_t vendor_type);
extern int cdrom_is_pre(const cdrom_t *dev, const uint32_t lba);
extern int cdrom_image_open(cdrom_t *dev, const char *fn);
extern void cdrom_image_close(cdrom_t *dev);
extern int cdrom_audio_callback(cdrom_t *dev, int16_t *output, const int len);
extern uint8_t cdrom_audio_play(cdrom_t *dev, const uint32_t pos, const uint32_t len, const int ismsf);
extern uint8_t cdrom_audio_track_search(cdrom_t *dev, const uint32_t pos,
const int type, const uint8_t playbit);
extern uint8_t cdrom_audio_track_search_pioneer(cdrom_t *dev, const uint32_t pos, const uint8_t playbit);
extern uint8_t cdrom_audio_play_pioneer(cdrom_t *dev, const uint32_t pos);
extern uint8_t cdrom_audio_play_toshiba(cdrom_t *dev, const uint32_t pos, const int type);
extern uint8_t cdrom_audio_scan(cdrom_t *dev, const uint32_t pos, const int type);
extern void cdrom_audio_pause_resume(cdrom_t *dev, const uint8_t resume);
extern int cdrom_ioctl_open(cdrom_t *dev, const char *drv);
extern void cdrom_ioctl_close(cdrom_t *dev);
extern uint8_t cdrom_get_current_status(const cdrom_t *dev);
extern void cdrom_get_current_subchannel(const cdrom_t *dev, uint8_t *b, const int msf);
extern void cdrom_get_current_subchannel_sony(const cdrom_t *dev, uint8_t *b, const int msf);
extern uint8_t cdrom_get_audio_status_pioneer(const cdrom_t *dev, uint8_t *b);
extern uint8_t cdrom_get_audio_status_sony(const cdrom_t *dev, uint8_t *b, const int msf);
extern void cdrom_get_current_subcodeq(const cdrom_t *dev, uint8_t *b);
extern uint8_t cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b);
extern int cdrom_read_toc(const cdrom_t *dev, uint8_t *b, const int type,
const uint8_t start_track, const int msf, const int max_len);
extern int cdrom_read_toc_sony(const cdrom_t *dev, uint8_t *b, const uint8_t start_track,
const int msf, const int max_len);
#ifdef USE_CDROM_MITSUMI
extern void cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf);
extern void cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode);
extern uint8_t cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len);
#endif
extern uint8_t cdrom_read_disc_info_toc(cdrom_t *dev, uint8_t *b,
const uint8_t track, const int type);
extern int cdrom_readsector_raw(const cdrom_t *dev, uint8_t *buffer, const int sector, const int ismsf,
int cdrom_sector_type, const int cdrom_sector_flags,
int *len, const uint8_t vendor_type);
extern int cdrom_read_dvd_structure(const cdrom_t *dev, const uint8_t layer, const uint8_t format,
uint8_t *buffer, uint32_t *info);
extern void cdrom_read_disc_information(const cdrom_t *dev, uint8_t *buffer);
extern int cdrom_read_track_information(const cdrom_t *dev, const uint8_t *cdb, uint8_t *buffer);
extern int cdrom_ext_medium_changed(const cdrom_t *dev);
extern int cdrom_load(cdrom_t *dev, const char *fn, const int skip_insert);
extern void cdrom_update_cdb(uint8_t *cdb, int lba_pos,
int number_of_blocks);
extern int find_cdrom_for_scsi_id(uint8_t scsi_id);
extern void cdrom_close(void);
extern void cdrom_global_init(void);
extern void cdrom_global_reset(void);
extern void cdrom_hard_reset(void);
extern void scsi_cdrom_drive_reset(int c);
extern void cdrom_global_init(void);
extern void cdrom_hard_reset(void);
extern void cdrom_close(void);
extern void cdrom_insert(const uint8_t id);
extern void cdrom_exit(const uint8_t id);
extern int cdrom_is_empty(const uint8_t id);
extern void cdrom_eject(const uint8_t id);
extern void cdrom_reload(const uint8_t id);
#ifdef __cplusplus
}

View File

@@ -6,35 +6,33 @@
*
* 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: RichardG,
* Miran Grca, <mgrca8@gmail.com>
* Authors: Miran Grca, <mgrca8@gmail.com>
* RichardG, <richardg867@gmail.com>
* Cacodemon345
*
* Copyright 2016-2022 RichardG.
* Copyright 2016-2022 Miran Grca.
* Copyright 2016-2025 Miran Grca.
* Copyright 2016-2025 RichardG.
* Copyright 2024-2025 Cacodemon345.
*/
#ifndef CDROM_IMAGE_H
#define CDROM_IMAGE_H
/* this header file lists the functions provided by
various platform specific cdrom-ioctl files */
/* Track file struct. */
typedef struct track_file_t {
int (*read)(void *priv, uint8_t *buffer, uint64_t seek, size_t count);
uint64_t (*get_length)(void *priv);
void (*close)(void *priv);
#ifdef __cplusplus
extern "C" {
#endif
char fn[260];
FILE *fp;
void *priv;
void *log;
extern int image_open(uint8_t id, wchar_t *fn);
extern void image_reset(uint8_t id);
int motorola;
} track_file_t;
extern void image_close(uint8_t id);
void update_status_bar_icon_state(int tag, int state);
extern void cdrom_set_null_handler(uint8_t id);
#ifdef __cplusplus
}
#endif
extern void * image_open(cdrom_t *dev, const char *path);
#endif /*CDROM_IMAGE_H*/

View File

@@ -1,119 +0,0 @@
/*
* 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.
*
* CD-ROM image file handling module header.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* RichardG, <richardg867@gmail.com>
* Cacodemon345
*
* Copyright 2016-2025 Miran Grca.
* Copyright 2016-2025 Miran Grca.
* Copyright 2024-2025 Cacodemon345.
*/
#ifndef CDROM_IMAGE_BACKEND_H
#define CDROM_IMAGE_BACKEND_H
#define RAW_SECTOR_SIZE 2352
#define COOKED_SECTOR_SIZE 2048
#define DATA_TRACK 0x14
#define AUDIO_TRACK 0x10
#define CD_FPS 75
#define FRAMES_TO_MSF(f, M, S, F) \
{ \
uint64_t value = f; \
*(F) = (value % CD_FPS) & 0xff; \
value /= CD_FPS; \
*(S) = (value % 60) & 0xff; \
value /= 60; \
*(M) = value & 0xff; \
}
#define MSF_TO_FRAMES(M, S, F) ((M) *60 * CD_FPS + (S) *CD_FPS + (F))
typedef struct SMSF {
uint16_t min;
uint8_t sec;
uint8_t fr;
} TMSF;
/* Track file struct. */
typedef struct track_file_t {
int (*read)(void *priv, uint8_t *buffer, uint64_t seek, size_t count);
uint64_t (*get_length)(void *priv);
void (*close)(void *priv);
char fn[260];
FILE *fp;
void *priv;
int motorola;
} track_file_t;
#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. */
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. */
int32_t skip;
/* Starting and ending sector LBA - negative in order to accomodate LBA -150 to -1
to read the pregap of track 1. */
uint64_t start;
uint64_t length;
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 {
int32_t tracks_num;
track_t *tracks;
} cd_img_t;
/* Binary file functions. */
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_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 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);
extern uint64_t viso_get_length(void *priv);
extern void viso_close(void *priv);
extern track_file_t *viso_init(const char *dirname, int *error);
#endif /*CDROM_IMAGE_BACKEND_H*/

View File

@@ -0,0 +1,26 @@
/*
* 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.
*
* CD-ROM image file handling module header.
*
* Authors: RichardG, <richardg867@gmail.com>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2016-2025 RichardG.
* Copyright 2016-2025 Miran Grca.
*/
#ifndef CDROM_IMAGE_VISO_H
#define CDROM_IMAGE_VISO_H
/* Virtual ISO functions. */
extern int viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count);
extern uint64_t viso_get_length(void *priv);
extern void viso_close(void *priv);
extern track_file_t *viso_init(const uint8_t id, const char *dirname, int *error);
#endif /*CDROM_IMAGE_VISO_H*/

View File

@@ -21,11 +21,13 @@ extern int cdrom_interface_current;
extern void cdrom_interface_reset(void);
extern const char *cdrom_interface_get_internal_name(int cdinterface);
extern int cdrom_interface_get_from_internal_name(char *s);
extern int cdrom_interface_has_config(int cdinterface);
extern const device_t *cdrom_interface_get_device(int cdinterface);
extern int cdrom_interface_get_flags(int cdinterface);
extern int cdrom_interface_available(int cdinterface);
const char *cdrom_interface_get_internal_name(const int cdinterface);
extern int cdrom_interface_get_from_internal_name(const char *s);
#ifdef EMU_DEVICE_H
extern const device_t *cdrom_interface_get_device(const int cdinterface);
#endif
extern int cdrom_interface_has_config(const int cdinterface);
extern int cdrom_interface_get_flags(const int cdinterface);
extern int cdrom_interface_available(const int cdinterface);
#endif /*EMU_CDROM_INTERFACE_H*/

View File

@@ -1,32 +0,0 @@
/*
* 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.
*
* CD-ROM image file handling module header, translated to C
* from cdrom_dosbox.h.
*
* Authors: RichardG,
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2016-2022 RichardG.
* Copyright 2016-2022 Miran Grca.
*/
#ifndef CDROM_IOCTL_H
#define CDROM_IOCTL_H
/* this header file lists the functions provided by
various platform specific cdrom-ioctl files */
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /*CDROM_IOCTL_H*/

View File

@@ -22,11 +22,6 @@
#define MFM_NUM 2 /* 2 drives per controller supported */
#define ESDI_NUM 2 /* 2 drives per controller supported */
#define XTA_NUM 2 /* 2 drives per controller supported */
#define IDE_NUM 10 /* 8 drives per AT IDE + 2 for XT IDE */
#define ATAPI_NUM 8 /* 8 drives per AT IDE */
#define SCSI_NUM 16 /* theoretically the controller can have at \
* least 7 devices, with each device being \
* able to support 8 units, but hey... */
/* Controller types. */
#define HDC_NONE 0

View File

@@ -19,6 +19,9 @@
#ifndef EMU_IDE_H
#define EMU_IDE_H
#define IDE_NUM 10 /* 8 drives per AT IDE + 2 for XT IDE */
#define ATAPI_NUM 10 /* 8 drives per AT IDE + 2 for XT IDE */
#define IDE_BUS_MAX 4
#define IDE_CHAN_MAX 2
@@ -121,11 +124,11 @@ typedef struct ide_s {
double pending_delay;
#ifdef SCSI_DEVICE_H
int (*get_max)(int ide_has_dma, int type);
int (*get_timings)(int ide_has_dma, int type);
void (*identify)(struct ide_s *ide, int ide_has_dma);
void (*stop)(scsi_common_t *sc);
void (*packet_command)(scsi_common_t *sc, uint8_t *cdb);
int (*get_max)(const struct ide_s *ide, const int ide_has_dma, const int type);
int (*get_timings)(const struct ide_s *ide, const int ide_has_dma, const int type);
void (*identify)(const struct ide_s *ide, const int ide_has_dma);
void (*stop)(const scsi_common_t *sc);
void (*packet_command)(scsi_common_t *sc, const uint8_t *cdb);
void (*device_reset)(scsi_common_t *sc);
uint8_t (*phase_data_out)(scsi_common_t *sc);
void (*command_stop)(scsi_common_t *sc);
@@ -142,10 +145,8 @@ typedef struct ide_s {
#endif
} ide_t;
#ifdef EMU_HDC_H
extern ide_t *ide_drives[IDE_NUM];
#endif
#endif
/* Type:
0 = PIO,

View File

@@ -148,7 +148,7 @@ typedef struct hard_disk_t {
uint8_t ide_channel;
uint8_t scsi_id;
};
uint8_t bus;
uint8_t bus_type;
uint8_t bus_mode; /* Bit 0 = PIO suported;
Bit 1 = DMA supportd. */
uint8_t wp; /* Disk has been mounted READ-ONLY */

View File

@@ -6,24 +6,20 @@
*
* This file is part of the 86Box distribution.
*
* Main include file for the application.
*
*
* New logging system handler header.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* Connor Hyde <mario64crashed@gmail.com, nomorestarfrost@gmail.com>
* Connor Hyde, <mario64crashed@gmail.com, nomorestarfrost@gmail.com>
*
* Copyright 2021 Miran Grca.
* Copyright 2021 Fred N. van Kempen.
* Copyright 2021-25 Miran Grca.
* Copyright 2021-25 Fred N. van Kempen.
* Copyright 2025 Connor Hyde.
*/
#ifndef EMU_LOG_H
#define EMU_LOG_H
#ifndef RELEASE_BUILD
# ifdef __cplusplus
extern "C" {
# endif
@@ -35,20 +31,17 @@ extern "C" {
/* Function prototypes. */
extern void log_set_suppr_seen(void *priv, int suppr_seen);
extern void log_set_dev_name(void *priv, char *dev_name);
# ifdef HAVE_STDARG_H
#ifndef RELEASE_BUILD
extern void log_out(void *priv, const char *fmt, va_list);
extern void log_out_cyclic(void* priv, const char *fmt, va_list);
#endif /*RELEASE_BUILD*/
extern void log_fatal(void *priv, const char *fmt, ...);
# endif
extern void *log_open(char *dev_name);
extern void *log_open(const char *dev_name);
extern void *log_open_cyclic(const char *dev_name);
extern void log_close(void *priv);
# ifdef __cplusplus
}
# endif
#else
# define log_fatal(priv, fmt, ...) fatal(fmt, ...)
#endif /*RELEASE_BUILD*/
#endif /*EMU_LOG_H*/

View File

@@ -9,13 +9,13 @@
* Implementation of a generic Magneto-Optical Disk drive
* commands, for both ATAPI and SCSI usage.
*
*
*
* Authors: Natalia Portillo <claunia@claunia.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2020 Miran Grca.
* Copyright 2020-2025 Natalia Portillo.
* Copyright 2020-2025 Miran Grca.
* Copyright 2020-2025 Fred N. van Kempen
*/
#ifndef EMU_MO_H
@@ -91,88 +91,87 @@ enum {
};
typedef struct mo_drive_t {
uint8_t id;
uint8_t id;
union {
uint8_t res;
uint8_t res0; /* Reserved for other ID's. */
uint8_t res1;
uint8_t ide_channel;
uint8_t scsi_device_id;
uint8_t res;
/* Reserved for other ID's. */
uint8_t res0;
uint8_t res1;
uint8_t ide_channel;
uint8_t scsi_device_id;
};
uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */
uint8_t bus_mode; /* Bit 0 = PIO suported;
Bit 1 = DMA supportd. */
uint8_t read_only; /* Struct variable reserved for
media status. */
uint8_t pad;
uint8_t pad0;
uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */
uint8_t bus_mode; /* Bit 0 = PIO suported;
Bit 1 = DMA supportd. */
uint8_t read_only; /* Struct variable reserved for
media status. */
uint8_t pad;
uint8_t pad0;
FILE *fp;
void *priv;
FILE * fp;
void * priv;
char image_path[1024];
char prev_image_path[1024];
char image_path[1024];
char prev_image_path[1024];
char *image_history[MO_IMAGE_HISTORY];
char * image_history[MO_IMAGE_HISTORY];
uint32_t type;
uint32_t medium_size;
uint32_t base;
uint16_t sector_size;
uint32_t type;
uint32_t medium_size;
uint32_t base;
uint16_t sector_size;
} mo_drive_t;
typedef struct mo_t {
mode_sense_pages_t ms_pages_saved;
mo_drive_t *drv;
mo_drive_t * drv;
#ifdef EMU_IDE_H
ide_tf_t * tf;
ide_tf_t * tf;
#else
void * tf;
void * tf;
#endif
uint8_t *buffer;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
void * log;
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
uint8_t * buffer;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
uint16_t max_transfer_len;
uint16_t pad2;
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
int requested_blocks;
int packet_status;
int total_length;
int do_page_save;
int unit_attention;
int request_pos;
int old_len;
int pad3;
uint16_t max_transfer_len;
uint16_t pad2;
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
int requested_blocks;
int packet_status;
int total_length;
int do_page_save;
int unit_attention;
int request_pos;
int old_len;
int transition;
double callback;
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen);
double callback;
uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen);
} mo_t;
extern mo_t *mo[MO_NUM];
extern mo_drive_t mo_drives[MO_NUM];
#if 0
extern uint8_t atapi_mo_drives[8];
extern uint8_t scsi_mo_drives[16];
#endif
extern mo_drive_t mo_drives[MO_NUM];
#define mo_sense_error dev->sense[0]
#define mo_sense_key dev->sense[2]
#define mo_info *(uint32_t *) &(dev->sense[3])
#define mo_asc dev->sense[12]
#define mo_ascq dev->sense[13]
@@ -180,15 +179,16 @@ extern uint8_t scsi_mo_drives[16];
extern "C" {
#endif
extern void mo_disk_close(mo_t *dev);
extern void mo_disk_reload(mo_t *dev);
extern void mo_disk_close(const mo_t *dev);
extern void mo_disk_reload(const mo_t *dev);
extern void mo_insert(mo_t *dev);
extern void mo_global_init(void);
extern void mo_hard_reset(void);
extern void mo_reset(scsi_common_t *sc);
extern int mo_load(mo_t *dev, char *fn);
extern int mo_is_empty(const uint8_t id);
extern void mo_load(const mo_t *dev, const char *fn, const int skip_insert);
extern void mo_close(void);
#ifdef __cplusplus

View File

@@ -1,73 +0,0 @@
/*
* 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.
*
* Definitions for platform specific serial to host passthrough.
*
*
* Authors: Andreas J. Reichel <webmaster@6th-dimension.com>,
* Jasmine Iwanek <jasmine@iwanek.co.uk>
*
* Copyright 2021 Andreas J. Reichel.
* Copyright 2021-2022 Jasmine Iwanek.
*/
#ifndef PLAT_CDROM_H
#define PLAT_CDROM_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define RAW_SECTOR_SIZE 2352
#define COOKED_SECTOR_SIZE 2048
#define DATA_TRACK 0x14
#define AUDIO_TRACK 0x10
#define CD_FPS 75
#define FRAMES_TO_MSF(f, M, S, F) \
{ \
uint64_t value = f; \
*(F) = (value % CD_FPS) & 0xff; \
value /= CD_FPS; \
*(S) = (value % 60) & 0xff; \
value /= 60; \
*(M) = value & 0xff; \
}
#define MSF_TO_FRAMES(M, S, F) ((M) *60 * CD_FPS + (S) *CD_FPS + (F))
typedef struct SMSF {
uint16_t min;
uint8_t sec;
uint8_t fr;
} TMSF;
extern void plat_cdrom_get_raw_track_info(void *local, int *num, raw_track_info_t *rti);
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 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, 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);
extern int plat_cdrom_ext_medium_changed(void *local);
extern uint32_t plat_cdrom_get_track_start(void *local, uint32_t sector, uint8_t *attr, uint8_t *track);
extern int plat_cdrom_get_local_size(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,34 @@
/*
* 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.
*
* Definitions for platform specific serial to host passthrough.
*
*
* Authors: Andreas J. Reichel <webmaster@6th-dimension.com>,
* Jasmine Iwanek <jasmine@iwanek.co.uk>
*
* Copyright 2021 Andreas J. Reichel.
* Copyright 2021-2022 Jasmine Iwanek.
*/
#ifndef PLAT_CDROM_IOCTL_H
#define PLAT_CDROM_IOCTL_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern void * ioctl_open(cdrom_t *dev, const char *drv);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -29,15 +29,21 @@
#define SCSI_ID_MAX 16 /* 16 on wide buses */
#define SCSI_LUN_MAX 8 /* always 8 */
extern int scsi_card_current[SCSI_CARD_MAX];
extern int scsi_card_current[SCSI_CARD_MAX];
extern int scsi_card_available(int card);
extern void scsi_reset(void);
extern uint8_t scsi_get_bus(void);
extern int scsi_card_available(int card);
#ifdef EMU_DEVICE_H
extern const device_t *scsi_card_getdevice(int card);
#endif
extern int scsi_card_has_config(int card);
extern const char *scsi_card_get_internal_name(int card);
extern int scsi_card_get_from_internal_name(char *s);
extern void scsi_card_init(void);
extern int scsi_card_has_config(int card);
extern const char *scsi_card_get_internal_name(int card);
extern int scsi_card_get_from_internal_name(char *s);
extern void scsi_card_init(void);
extern void scsi_bus_set_speed(uint8_t bus, double speed);
extern double scsi_bus_get_speed(uint8_t bus);
#endif /*EMU_SCSI_H*/

View File

@@ -26,47 +26,56 @@ typedef struct scsi_cdrom_t {
/* Common block. */
mode_sense_pages_t ms_pages_saved;
cdrom_t * drv;
cdrom_t * drv;
#ifdef EMU_IDE_H
ide_tf_t *tf;
ide_tf_t * tf;
#else
void * tf;
void * tf;
#endif
uint8_t *buffer;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
void * log;
uint8_t id;
uint8_t cur_lun;
uint8_t early;
uint8_t pad1;
uint8_t * buffer;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
uint16_t max_transfer_len;
uint16_t pad2;
uint8_t id;
uint8_t cur_lun;
uint8_t early;
uint8_t sector_type;
int requested_blocks;
int packet_status;
int total_length;
int do_page_save;
int unit_attention;
int request_pos;
int old_len;
int media_status;
uint16_t max_transfer_len;
uint16_t sector_flags;
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
int requested_blocks;
int packet_status;
int total_length;
int do_page_save;
int unit_attention;
int request_pos;
int old_len;
int media_status;
double callback;
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen);
double callback;
int sony_vendor;
int is_sony;
int use_cdb_9;
uint8_t ven_cmd_is_data[256];
mode_sense_pages_t ms_pages_saved_sony;
mode_sense_pages_t ms_drive_status_pages_saved;
uint64_t ms_page_flags;
mode_sense_pages_t ms_pages_default;
mode_sense_pages_t ms_pages_changeable;
uint8_t (*ven_cmd)(void *sc, const uint8_t *cdb, int32_t *BufLen);
} scsi_cdrom_t;
#endif
@@ -74,10 +83,12 @@ extern scsi_cdrom_t *scsi_cdrom[CDROM_NUM];
#define scsi_cdrom_sense_error dev->sense[0]
#define scsi_cdrom_sense_key dev->sense[2]
#define scsi_cdrom_info *(uint32_t *) &(dev->sense[3])
#define scsi_cdrom_asc dev->sense[12]
#define scsi_cdrom_ascq dev->sense[13]
#define scsi_cdrom_drive cdrom_drives[id].host_drive
extern void scsi_cdrom_reset(scsi_common_t *sc);
extern void scsi_cdrom_drive_reset(const int c);
#endif /*EMU_SCSI_CDROM_H*/

View File

@@ -21,6 +21,7 @@
#define SCSI_DEVICE_H
/* Configuration. */
#define SCSI_NUM (SCSI_BUS_MAX * SCSI_ID_MAX)
#define SCSI_LUN_USE_CDB 0xff
@@ -53,8 +54,8 @@
#define GPCMD_SEEK_6 0x0b
#define GPCMD_IOMEGA_SET_PROTECTION_MODE 0x0c
#define GPCMD_IOMEGA_EJECT 0x0d /* ATAPI only? */
#define GPCMD_NO_OPERATION_TOSHIBA 0x0d /* Toshiba Vendor Unique command */
#define GPCMD_NO_OPERATION_NEC 0x0d /* NEC Vendor Unique command */
#define GPCMD_NO_OPERATION_TOSHIBA 0x0d /* Toshiba Vendor Unique command. */
#define GPCMD_NO_OPERATION_NEC 0x0d /* NEC Vendor Unique command. */
#define GPCMD_INQUIRY 0x12
#define GPCMD_VERIFY_6 0x13
#define GPCMD_MODE_SELECT_6 0x15
@@ -66,7 +67,7 @@
#define GPCMD_PREVENT_REMOVAL 0x1e
#define GPCMD_READ_FORMAT_CAPACITIES 0x23
#define GPCMD_READ_CDROM_CAPACITY 0x25
#define GPCMD_UNKNOWN_CHINON 0x26 /*Chinon Vendor Unique command*/
#define GPCMD_UNKNOWN_CHINON 0x26 /* Chinon Vendor Unique command. */
#define GPCMD_READ_10 0x28
#define GPCMD_READ_GENERATION 0x29
#define GPCMD_WRITE_10 0x2a
@@ -233,16 +234,12 @@
#define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12
#define ASCQ_AUDIO_PLAY_OPERATION_COMPLETED 0x13
/* Tell RISC OS that we have a 4x CD-ROM drive (600kb/sec data, 706kb/sec raw).
Not that it means anything */
#define CDROM_SPEED 706 /* 0x2C2 */
#define BUFFER_SIZE (256 * 1024)
#define RW_DELAY (TIMER_USEC * 500)
/* Some generally useful CD-ROM information */
#ifdef CONSERVATIVE_MAXIMUM
#define CD_MINS 90 /* max. minutes per CD */
#else
#define CD_MINS 100 /* max. minutes per CD - yes, 100-minute CD's in fact existed */
#endif
#define CD_SECS 60 /* seconds per minute */
#define CD_FRAMES 75 /* frames per second */
#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */
@@ -276,6 +273,10 @@
/* Profile list from MMC-6 revision 1 table 91 */
#define MMC_PROFILE_NONE 0x0000
#define MMC_PROFILE_REMOVABLE_DISK 0x0002
#define MMC_PROFILE_MO 0x0003
#define MMC_PROFILE_MO_WORM 0x0004
#define MMC_PROFILE_AS_MO 0x0005
#define MMC_PROFILE_CD_ROM 0x0008
#define MMC_PROFILE_CD_R 0x0009
#define MMC_PROFILE_CD_RW 0x000A
@@ -304,7 +305,6 @@
#define MMC_PROFILE_HDDVD_RW_DL 0x005A
#define MMC_PROFILE_INVALID 0xFFFF
#define EARLY_ONLY 64
#define SCSI_ONLY 32
#define ATAPI_ONLY 16
#define IMPLEMENTED 8
@@ -312,8 +312,6 @@
#define CHECK_READY 2
#define ALLOW_UA 1
#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
#define MSG_COMMAND_COMPLETE 0x00
#define BUS_DBP 0x01
@@ -371,7 +369,7 @@
#define MODE_SELECT_PHASE_PAGE 4
typedef struct mode_sense_pages_t {
uint8_t pages[0x40][0x40];
uint8_t pages[0x40][0x40];
} mode_sense_pages_t;
/* This is so we can access the common elements to all SCSI device structs
@@ -379,89 +377,105 @@ typedef struct mode_sense_pages_t {
typedef struct scsi_common_s {
mode_sense_pages_t ms_pages_saved;
void * priv;
void * priv;
#ifdef EMU_IDE_H
ide_tf_t *tf;
ide_tf_t * tf;
#else
void * tf;
void * tf;
#endif
uint8_t *temp_buffer;
uint8_t atapi_cdb[16]; /* This is atapi_cdb in ATAPI-supporting devices,
and pad in SCSI-only devices. */
uint8_t current_cdb[16];
uint8_t sense[256];
void * log;
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
uint8_t * temp_buffer;
/*
This is atapi_cdb in ATAPI-supporting devices,
and pad in SCSI-only devices.
*/
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
uint16_t max_transfer_len;
uint16_t pad2;
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
int requested_blocks;
int packet_status;
int total_length;
int do_page_save;
int unit_attention;
int request_pos;
int old_len;
int media_status;
uint16_t max_transfer_len;
uint16_t pad2;
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
int requested_blocks;
int packet_status;
int total_length;
int do_page_save;
int unit_attention;
int request_pos;
int old_len;
int media_status;
double callback;
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen);
double callback;
uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen);
} scsi_common_t;
typedef struct scsi_device_t {
int32_t buffer_length;
int32_t buffer_length;
uint8_t status;
uint8_t phase;
uint16_t type;
uint8_t status;
uint8_t phase;
scsi_common_t *sc;
uint16_t type;
void (*command)(scsi_common_t *sc, uint8_t *cdb);
void (*request_sense)(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length);
void (*reset)(scsi_common_t *sc);
uint8_t (*phase_data_out)(scsi_common_t *sc);
void (*command_stop)(scsi_common_t *sc);
scsi_common_t * sc;
void (*command)(scsi_common_t *sc, const uint8_t *cdb);
void (*request_sense)(scsi_common_t *sc, uint8_t *buffer,
uint8_t alloc_length);
void (*reset)(scsi_common_t *sc);
uint8_t (*phase_data_out)(scsi_common_t *sc);
void (*command_stop)(scsi_common_t *sc);
} scsi_device_t;
typedef struct scsi_bus_t {
int tx_mode;
int clear_req;
int wait_data;
int wait_complete;
int bus_out;
int bus_in;
int command_pos;
int command_issued;
int data_pos;
int msgout_pos;
int is_msgout;
int state;
int dma_on_pio_enabled;
uint8_t data;
uint8_t msglun;
uint8_t data_wait;
uint8_t command[16];
uint8_t msgout[4];
uint8_t target_id;
uint8_t bus_device;
uint32_t bus_phase;
double period;
double speed;
double divider;
double multi;
void *priv;
void (*timer)(void *priv, double period);
uint8_t data;
uint8_t msglun;
uint8_t data_wait;
uint8_t target_id;
uint8_t bus_device;
uint8_t pad;
uint8_t pad0;
uint8_t pad1;
uint8_t command[16];
uint8_t msgout[4];
uint8_t pad2[4];
int tx_mode;
int clear_req;
int wait_data;
int wait_complete;
int bus_out;
int bus_in;
int command_pos;
int command_issued;
int data_pos;
int msgout_pos;
int is_msgout;
int state;
int dma_on_pio_enabled;
uint32_t bus_phase;
double period;
double speed;
double divider;
double multi;
void *priv;
void (*timer)(void *priv, double period);
} scsi_bus_t;
/* These are based on the INQUIRY values. */
@@ -474,15 +488,8 @@ typedef struct scsi_bus_t {
extern scsi_device_t scsi_devices[SCSI_BUS_MAX][SCSI_ID_MAX];
#endif /* EMU_SCSI_H */
extern int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type);
extern int cdrom_LBAtoMSF_accurate(void);
extern int mode_select_init(uint8_t command, uint16_t pl_length, uint8_t do_save);
extern int mode_select_terminate(int force);
extern int mode_select_write(uint8_t val);
extern uint8_t *scsi_device_sense(scsi_device_t *dev);
extern double scsi_device_get_callback(scsi_device_t *dev);
extern uint8_t *scsi_device_sense(scsi_device_t *dev);
extern void scsi_device_request_sense(scsi_device_t *dev, uint8_t *buffer,
uint8_t alloc_length);
extern void scsi_device_reset(scsi_device_t *dev);
@@ -490,8 +497,8 @@ extern int scsi_device_present(scsi_device_t *dev);
extern int scsi_device_valid(scsi_device_t *dev);
extern int scsi_device_cdb_length(scsi_device_t *dev);
extern void scsi_device_command_phase0(scsi_device_t *dev, uint8_t *cdb);
extern void scsi_device_command_phase1(scsi_device_t *dev);
extern void scsi_device_command_stop(scsi_device_t *dev);
extern void scsi_device_command_phase1(scsi_device_t *dev);
extern void scsi_device_identify(scsi_device_t *dev, uint8_t lun);
extern void scsi_device_close_all(void);
extern void scsi_device_init(void);

View File

@@ -19,42 +19,44 @@
typedef struct scsi_disk_t {
mode_sense_pages_t ms_pages_saved;
hard_disk_t *drv;
hard_disk_t * drv;
#ifdef EMU_IDE_H
ide_tf_t * tf;
ide_tf_t * tf;
#else
void * tf;
void * tf;
#endif
uint8_t *temp_buffer;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
void * log;
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
uint8_t * temp_buffer;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
uint16_t max_transfer_len;
uint16_t pad2;
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
int requested_blocks;
int packet_status;
int total_length;
int do_page_save;
int unit_attention;
int request_pos;
int pad6;
int pad7;
uint16_t max_transfer_len;
uint16_t pad2;
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
int requested_blocks;
int packet_status;
int total_length;
int do_page_save;
int unit_attention;
int request_pos;
int pad6;
int pad7;
double callback;
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen);
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

@@ -13,7 +13,7 @@
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2018-2019 Miran Grca.
* Copyright 2018-2025 Miran Grca.
*/
#ifndef EMU_ZIP_H
@@ -39,76 +39,79 @@ enum {
};
typedef struct zip_drive_t {
uint8_t id;
uint8_t id;
union {
uint8_t res;
uint8_t res0; /* Reserved for other ID's. */
uint8_t res1;
uint8_t ide_channel;
uint8_t scsi_device_id;
uint8_t res;
/* Reserved for other ID's. */
uint8_t res0;
uint8_t res1;
uint8_t ide_channel;
uint8_t scsi_device_id;
};
uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */
uint8_t bus_mode; /* Bit 0 = PIO suported;
Bit 1 = DMA supportd. */
uint8_t read_only; /* Struct variable reserved for
media status. */
uint8_t pad;
uint8_t pad0;
uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */
uint8_t bus_mode; /* Bit 0 = PIO suported;
Bit 1 = DMA supportd. */
uint8_t read_only; /* Struct variable reserved for
media status. */
uint8_t pad;
uint8_t pad0;
FILE *fp;
void *priv;
FILE * fp;
void * priv;
char image_path[1024];
char prev_image_path[1024];
char image_path[1024];
char prev_image_path[1024];
char *image_history[ZIP_IMAGE_HISTORY];
char * image_history[ZIP_IMAGE_HISTORY];
uint32_t is_250;
uint32_t medium_size;
uint32_t base;
uint32_t is_250;
uint32_t medium_size;
uint32_t base;
} zip_drive_t;
typedef struct zip_t {
mode_sense_pages_t ms_pages_saved;
zip_drive_t *drv;
zip_drive_t * drv;
#ifdef EMU_IDE_H
ide_tf_t * tf;
ide_tf_t * tf;
#else
void * tf;
void * tf;
#endif
uint8_t *buffer;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
void * log;
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
uint8_t * buffer;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint8_t sense[256];
uint16_t max_transfer_len;
uint16_t pad2;
uint8_t id;
uint8_t cur_lun;
uint8_t pad0;
uint8_t pad1;
int requested_blocks;
int packet_status;
int total_length;
int do_page_save;
int unit_attention;
int request_pos;
int old_len;
int pad3;
uint16_t max_transfer_len;
uint16_t pad2;
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
int requested_blocks;
int packet_status;
int total_length;
int do_page_save;
int unit_attention;
int request_pos;
int old_len;
int transition;
double callback;
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen);
double callback;
uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen);
} zip_t;
extern zip_t *zip[ZIP_NUM];
@@ -118,6 +121,7 @@ extern uint8_t scsi_zip_drives[16];
#define zip_sense_error dev->sense[0]
#define zip_sense_key dev->sense[2]
#define zip_info *(uint32_t *) &(dev->sense[3])
#define zip_asc dev->sense[12]
#define zip_ascq dev->sense[13]
@@ -125,15 +129,16 @@ extern uint8_t scsi_zip_drives[16];
extern "C" {
#endif
extern void zip_disk_close(zip_t *dev);
extern void zip_disk_reload(zip_t *dev);
extern void zip_disk_close(const zip_t *dev);
extern void zip_disk_reload(const zip_t *dev);
extern void zip_insert(zip_t *dev);
extern void zip_global_init(void);
extern void zip_hard_reset(void);
extern void zip_reset(scsi_common_t *sc);
extern int zip_load(zip_t *dev, char *fn);
extern int zip_is_empty(const uint8_t id);
extern void zip_load(const zip_t *dev, const char *fn, const int skip_insert);
extern void zip_close(void);
#ifdef __cplusplus

353
src/log.c
View File

@@ -6,16 +6,14 @@
*
* This file is part of the 86Box distribution.
*
* The handler of the new logging system.
*
*
* New logging system handler.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* Connor Hyde <mario64crashed@gmail.com, nomorestarfrost@gmail.com>
* Connor Hyde, <mario64crashed@gmail.com, nomorestarfrost@gmail.com>
*
* Copyright 2021 Miran Grca.
* Copyright 2021 Fred N. van Kempen.
* Copyright 2021-25 Miran Grca.
* Copyright 2021-25 Fred N. van Kempen.
* Copyright 2025 Connor Hyde.
*/
#include <inttypes.h>
@@ -37,21 +35,44 @@
#include <86box/version.h>
#include <86box/log.h>
#ifndef RELEASE_BUILD
typedef struct log_t {
char buff[1024];
char *dev_name;
int seen;
int suppr_seen;
char cyclic_buff[LOG_SIZE_BUFFER_CYCLIC_LINES][LOG_SIZE_BUFFER]; // Cyclical log buffer. This is 32kb, might calloc?
int32_t cyclic_last_line;
int32_t log_cycles;
char buff[1024];
char dev_name[1024];
int seen;
int suppr_seen;
/* Cyclical log buffer. */
char **cyclic_buff;
int32_t cyclic_last_line;
int32_t log_cycles;
} log_t;
extern FILE *stdlog; /* file to log output to */
// Functions only used in this translation unit
/* File to log output to. */
extern FILE *stdlog;
/* Functions only used in this translation unit. */
void log_ensure_stdlog_open(void);
void
log_set_dev_name(void *priv, char *dev_name)
{
log_t *log = (log_t *) priv;
memcpy(log->dev_name, dev_name, strlen(dev_name) + 1);
}
static void
log_copy(log_t *log, char *dest, const char *src, size_t dest_size)
{
memset(dest, 0x00, dest_size * sizeof(char));
if ((log != NULL) && strcmp(log->dev_name, "")) {
strcat(dest, log->dev_name);
strcat(dest, ": ");
}
strcat(dest, src);
}
#ifndef RELEASE_BUILD
void
log_ensure_stdlog_open(void)
{
@@ -73,31 +94,12 @@ log_set_suppr_seen(void *priv, int suppr_seen)
log->suppr_seen = suppr_seen;
}
void
log_set_dev_name(void *priv, char *dev_name)
{
log_t *log = (log_t *) priv;
log->dev_name = dev_name;
}
static void
log_copy(log_t *log, char *dest, const char *src, size_t dest_size)
{
memset(dest, 0x00, dest_size * sizeof(char));
if (log && log->dev_name && strcmp(log->dev_name, "")) {
strcat(dest, log->dev_name);
strcat(dest, ": ");
}
strcat(dest, src);
}
/*
* Log something to the logfile or stdout.
*
* To avoid excessively-large logfiles because some
* module repeatedly logs, we keep track of what is
* being logged, and catch repeating entries.
Log something to the logfile or stdout.
To avoid excessively-large logfiles because some
module repeatedly logs, we keep track of what is
being logged, and catch repeating entries.
*/
void
log_out(void *priv, const char *fmt, va_list ap)
@@ -107,154 +109,164 @@ log_out(void *priv, const char *fmt, va_list ap)
char fmt2[1024];
if (log == NULL)
return;
pclog("WARNING: Logging called with a NULL log pointer\n");
else if (fmt == NULL)
pclog("WARNING: Logging called with a NULL format pointer\n");
else if (fmt[0] != '\0') {
log_ensure_stdlog_open();
if (strcmp(fmt, "") == 0)
return;
log_ensure_stdlog_open();
vsprintf(temp, fmt, ap);
if (log->suppr_seen && !strcmp(log->buff, temp))
log->seen++;
else {
if (log->suppr_seen && log->seen) {
log_copy(log, fmt2, "*** %d repeats ***\n", 1024);
fprintf(stdlog, fmt2, log->seen);
vsprintf(temp, fmt, ap);
if (log->suppr_seen && !strcmp(log->buff, temp))
log->seen++;
else {
if (log->suppr_seen && log->seen) {
log_copy(log, fmt2, "*** %d repeats ***\n", 1024);
fprintf(stdlog, fmt2, log->seen);
}
log->seen = 0;
strcpy(log->buff, temp);
log_copy(log, fmt2, temp, 1024);
fprintf(stdlog, fmt2, ap);
}
log->seen = 0;
strcpy(log->buff, temp);
log_copy(log, fmt2, temp, 1024);
fprintf(stdlog, fmt2, ap);
}
fflush(stdlog);
fflush(stdlog);
}
}
/*
Starfrost, 7-8 January 2025:
Starfrost, 7-8 January 2025:
For RIVA 128 emulation I needed a way to suppress logging if a repeated pattern of the same set of lines were found.
For RIVA 128 emulation I needed a way to suppress logging if a repeated
pattern of the same set of lines were found.
Implements a version of the Rabin-Karp algorithm https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm
Implements a version of the Rabin-Karp algorithm:
https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm .
*/
void
log_out_cyclic(void* priv, const char* fmt, va_list ap)
{
#ifndef RELEASE_BUILD
// get our new logging system instance.
log_t* log = (log_t*)priv;
/* Get our new logging system instance. */
log_t* log = (log_t*) priv;
// does the log actually exist?
if (!log)
return;
/* Does the log actually exist? */
if (log == NULL)
pclog("WARNING: Cyclical logging called with a NULL log pointer\n");
else if (log->cyclic_buff == NULL)
pclog("WARNING: Cyclical logging called with a non-cyclic log\n");
else if (fmt == NULL)
pclog("WARNING: Cyclical logging called with a NULL format pointer\n");
/* Is the string empty? */
else if (fmt[0] != '\0') {
/* Ensure stdlog is open. */
log_ensure_stdlog_open();
// is the string empty?
if (fmt[0] == '\0')
return;
// ensure stdlog is open
log_ensure_stdlog_open();
char temp[LOG_SIZE_BUFFER] = {0};
char temp[LOG_SIZE_BUFFER] = {0};
log->cyclic_last_line %= LOG_SIZE_BUFFER_CYCLIC_LINES;
log->cyclic_last_line %= LOG_SIZE_BUFFER_CYCLIC_LINES;
vsprintf(temp, fmt, ap);
vsprintf(temp, fmt, ap);
log_copy(log, log->cyclic_buff[log->cyclic_last_line], temp,
LOG_SIZE_BUFFER);
log_copy(log, log->cyclic_buff[log->cyclic_last_line], temp, LOG_SIZE_BUFFER);
uint32_t hashes[LOG_SIZE_BUFFER_CYCLIC_LINES] = {0};
uint32_t hashes[LOG_SIZE_BUFFER_CYCLIC_LINES] = {0};
/* Random numbers. */
uint32_t base = 257;
uint32_t mod = 1000000007;
// Random numbers
uint32_t base = 257;
uint32_t mod = 1000000007;
uint32_t repeat_order = 0;
bool is_cycle = false;
uint32_t repeat_order = 0;
bool is_cycle = false;
/* Compute the set of hashes for the current log buffer. */
for (int32_t log_line = 0; log_line < LOG_SIZE_BUFFER_CYCLIC_LINES;
log_line++) {
if (log->cyclic_buff[log_line][0] == '\0')
continue; /* Skip. */
// compute the set of hashes for the current log buffer
for (int32_t log_line = 0; log_line < LOG_SIZE_BUFFER_CYCLIC_LINES; log_line++)
{
if (log->cyclic_buff[log_line][0] == '\0')
continue; // skip
for (int32_t log_line_char = 0; log_line_char < LOG_SIZE_BUFFER; log_line_char++)
{
hashes[log_line] = hashes[log_line] * base + log->cyclic_buff[log_line][log_line_char] % mod;
for (int32_t log_line_char = 0; log_line_char < LOG_SIZE_BUFFER;
log_line_char++)
hashes[log_line] = hashes[log_line] * base +
log->cyclic_buff[log_line][log_line_char] % mod;
}
}
// Now see if there are real cycles...
// We implement a minimum repeat size.
for (int32_t check_size = LOG_MINIMUM_REPEAT_ORDER; check_size < LOG_SIZE_BUFFER_CYCLIC_LINES / 2; check_size++)
{
//TODO: Log what we need for cycle 1.
//TODO: Command line option that lets us turn off this behaviour.
for (int32_t log_line_to_check = 0; log_line_to_check < check_size; log_line_to_check++)
{
if (hashes[log_line_to_check] == hashes[(log_line_to_check + check_size) % LOG_SIZE_BUFFER_CYCLIC_LINES])
{
repeat_order = check_size;
break;
/*
Now see if there are real cycles.
We implement a minimum repeat size.
*/
for (int32_t check_size = LOG_MINIMUM_REPEAT_ORDER;
check_size < LOG_SIZE_BUFFER_CYCLIC_LINES / 2; check_size++) {
/*
TODO: Log what we need for cycle 1.
TODO: Command line option that lets us turn off this behaviour.
*/
for (int32_t log_line_to_check = 0; log_line_to_check < check_size;
log_line_to_check++) {
if (hashes[log_line_to_check] ==
hashes[(log_line_to_check + check_size) %
LOG_SIZE_BUFFER_CYCLIC_LINES]) {
repeat_order = check_size;
break;
}
}
is_cycle = (repeat_order != 0);
/* If there still is a cycle, break. */
if (is_cycle)
break;
}
is_cycle = (repeat_order != 0);
if (is_cycle) {
if (log->cyclic_last_line % repeat_order == 0) {
log->log_cycles++;
// if there still is a cycle..
if (is_cycle)
break;
}
if (log->log_cycles == 1) {
/*
'Replay' the last few log entries so they actually
show up.
if (is_cycle)
{
if (log->cyclic_last_line % repeat_order == 0)
{
log->log_cycles++;
TODO: Is this right?
*/
if (log->log_cycles == 1)
{
// 'Replay' the last few log entries so they actually show up
// Todo: is this right?
for (uint32_t index = log->cyclic_last_line - 1;
index > (log->cyclic_last_line - repeat_order);
index--) {
/* *Very important* to prevent out of bounds index. */
uint32_t real_index = index %
LOG_SIZE_BUFFER_CYCLIC_LINES;
log_copy(log, temp, log->cyclic_buff[real_index],
LOG_SIZE_BUFFER);
for (uint32_t index = log->cyclic_last_line - 1; index > (log->cyclic_last_line - repeat_order); index--)
{
// *very important* to prevent out of bounds index
uint32_t real_index = index % LOG_SIZE_BUFFER_CYCLIC_LINES;
log_copy(log, temp, log->cyclic_buff[real_index], LOG_SIZE_BUFFER);
fprintf(stdlog, "%s", log->cyclic_buff[real_index]);
fprintf(stdlog, "%s", log->cyclic_buff[real_index]);
}
/* Restore the original line. */
log_copy(log, temp,
log->cyclic_buff[log->cyclic_last_line],
LOG_SIZE_BUFFER);
/* Allow normal logging. */
fprintf(stdlog, "%s", temp);
}
// restore the original line
log_copy(log, temp, log->cyclic_buff[log->cyclic_last_line], LOG_SIZE_BUFFER);
fprintf(stdlog, "%s", temp); // allow normal logging
if (log->log_cycles > 1 && log->log_cycles < 100)
fprintf(stdlog, "***** Cyclical Log Repeat of Order %d "
"#%d *****\n", repeat_order, log->log_cycles);
else if (log->log_cycles == 100)
fprintf(stdlog, "Logged the same cycle 100 times... "
"Silence until something interesting happens\n");
}
if (log->log_cycles > 1 && log->log_cycles < 100)
fprintf(stdlog, "***** Cyclical Log Repeat of Order %d #%d *****\n", repeat_order, log->log_cycles);
else if (log->log_cycles == 100)
fprintf(stdlog, "Logged the same cycle 100 times...shutting up until something interesting happens\n");
} else {
log->log_cycles = 0;
fprintf(stdlog, "%s", temp);
}
}
else
{
log->log_cycles = 0;
fprintf(stdlog, "%s", temp);
}
log->cyclic_last_line++;
#endif
log->cyclic_last_line++;
}
}
#endif
void
log_fatal(void *priv, const char *fmt, ...)
@@ -267,6 +279,13 @@ log_fatal(void *priv, const char *fmt, ...)
if (log == NULL)
return;
if (log->cyclic_buff != NULL) {
for (int i = 0; i < LOG_SIZE_BUFFER_CYCLIC_LINES; i++)
if (log->cyclic_buff[i] != NULL)
free(log->cyclic_buff[i]);
free(log->cyclic_buff);
}
va_start(ap, fmt);
log_copy(log, fmt2, fmt, 1024);
vsprintf(temp, fmt2, ap);
@@ -275,21 +294,42 @@ log_fatal(void *priv, const char *fmt, ...)
exit(-1);
}
void *
log_open(char *dev_name)
static void *
log_open_common(const char *dev_name, const int cyclic)
{
log_t *log = malloc(sizeof(log_t));
log_t *log = calloc(1, sizeof(log_t));
memset(log, 0, sizeof(log_t));
log->dev_name = dev_name;
memcpy(log->dev_name, dev_name, strlen(dev_name) + 1);
log->suppr_seen = 1;
log->cyclic_last_line = 0;
log->log_cycles = 0;
if (cyclic) {
log->cyclic_buff = calloc(LOG_SIZE_BUFFER_CYCLIC_LINES,
sizeof(char *));
for (int i = 0; i < LOG_SIZE_BUFFER_CYCLIC_LINES; i++)
log->cyclic_buff[i] = calloc(LOG_SIZE_BUFFER, sizeof(char));
}
return (void *) log;
}
void *
log_open(const char *dev_name)
{
return log_open_common(dev_name, 0);
}
/*
This is so that not all logs get the 32k cyclical buffer
they may not need.
*/
void *
log_open_cyclic(const char *dev_name)
{
return log_open_common(dev_name, 1);
}
void
log_close(void *priv)
{
@@ -297,4 +337,3 @@ log_close(void *priv)
free(log);
}
#endif

View File

@@ -1311,7 +1311,7 @@ ps1_hdc_init(UNUSED(const device_t *info))
/* Load any disks for this device class. */
c = 0;
for (uint8_t i = 0; i < HDD_NUM; i++) {
if ((hdd[i].bus == HDD_BUS_XTA) && (hdd[i].xta_channel < 1)) {
if ((hdd[i].bus_type == HDD_BUS_XTA) && (hdd[i].xta_channel < 1)) {
drive = &dev->drives[hdd[i].xta_channel];
if (!hdd_image_load(i)) {

View File

@@ -17,16 +17,18 @@
* Copyright 2023 Miran Grca.
*/
#include <inttypes.h>
#ifdef ENABLE_IOCTL_LOG
#include <stdarg.h>
#endif
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/scsi_device.h>
#include <86box/cdrom.h>
#include <86box/log.h>
#include <86box/plat_unused.h>
#include <86box/plat_cdrom.h>
@@ -35,223 +37,203 @@
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)
typedef struct dummy_cdrom_ioctl_t {
typedef struct ioctl_t {
cdrom_t *dev;
void *log;
int toc_valid;
} dummy_cdrom_ioctl_t;
} ioctl_t;
#ifdef ENABLE_DUMMY_CDROM_IOCTL_LOG
int dummy_cdrom_ioctl_do_log = ENABLE_DUMMY_CDROM_IOCTL_LOG;
#ifdef ENABLE_IOCTL_LOG
int ioctl_do_log = ENABLE_IOCTL_LOG;
void
dummy_cdrom_ioctl_log(const char *fmt, ...)
ioctl_log(void *priv, const char *fmt, ...)
{
va_list ap;
if (dummy_cdrom_ioctl_do_log) {
if (ioctl_do_log) {
va_list ap;
va_start(ap, fmt);
pclog_ex(fmt, ap);
log_out(priv, fmt, ap);
va_end(ap);
}
}
#else
# define dummy_cdrom_ioctl_log(fmt, ...)
# define ioctl_log(priv, fmt, ...)
#endif
static int
plat_cdrom_open(void *local)
/* Internal functions. */
static void
ioctl_close_handle(UNUSED(const ioctl_t *ioctl))
{
return 0;
}
static int
plat_cdrom_load(void *local)
ioctl_open_handle(UNUSED(ioctl_t *ioctl))
{
return 0;
}
static void
plat_cdrom_read_toc(void *local)
ioctl_read_toc(ioctl_t *ioctl)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
if (!ioctl->toc_valid) {
ioctl->toc_valid = 1;
}
}
/* Shared functions. */
static int
ioctl_get_track_info(UNUSED(const void *local), UNUSED(const uint32_t track),
UNUSED(int end), UNUSED(track_info_t *ti))
{
return 0;
}
static void
ioctl_get_raw_track_info(const void *local, UNUSED(int *num), UNUSED(uint8_t *rti))
{
ioctl_t *ioctl = (ioctl_t *) local;
if (!ioctl->toc_valid)
ioctl->toc_valid = 1;
}
void
plat_cdrom_get_raw_track_info(UNUSED(void *local), int *num, raw_track_info_t *rti)
static void
ioctl_get_raw_track_info(UNUSED(const void *local), int *num, uint8_t *rti)
{
*num = 1;
memset(rti, 0x00, 11);
}
int
plat_cdrom_is_track_audio(void *local, uint32_t sector)
static int
ioctl_is_track_pre(const void *local, const uint32_t sector)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_read_toc(ioctl);
const int ret = 0;
dummy_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret);
return ret;
}
int
plat_cdrom_is_track_pre(void *local, uint32_t sector)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
ioctl_t *ioctl = (ioctl_t *) local;
plat_cdrom_read_toc(ioctl);
const int ret = 0;
dummy_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret);
ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret);
return ret;
}
uint32_t
plat_cdrom_get_track_start(void *local, uint32_t sector, uint8_t *attr, uint8_t *track)
static int
ioctl_read_sector(const void *local, uint8_t *buffer, uint32_t const sector)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_read_toc(ioctl);
return 0x00000000;
}
uint32_t
plat_cdrom_get_last_block(void *local)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_read_toc(ioctl);
return 0x00000000;
}
int
plat_cdrom_ext_medium_changed(UNUSED(void *local))
{
#if 0
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_read_toc(ioctl);
#endif
int ret = 0;
dummy_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret);
return ret;
}
/* 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)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_read_toc(ioctl);
if ((track < 1) || (track == 0xaa)) {
dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track);
return 0;
}
start->min = 0;
start->sec = 0;
start->fr = 2;
*track_num = 1;
*attr = 0x14;
dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i): %02i:%02i:%02i, %02i, %02X\n",
track, start->min, start->sec, start->fr, *track_num, *attr);
return 1;
}
/* TODO: See if track start is adjusted by 150 or not. */
int
plat_cdrom_get_audio_sub(UNUSED(void *local), UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index,
TMSF *rel_pos, TMSF *abs_pos)
{
*track = 1;
*attr = 0x14;
*index = 1;
rel_pos->min = 0;
rel_pos->sec = 0;
rel_pos->fr = 0;
abs_pos->min = 0;
abs_pos->sec = 0;
abs_pos->fr = 2;
dummy_cdrom_ioctl_log("plat_cdrom_get_audio_sub(): %02i, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n",
*track, *attr, *index, rel_pos->min, rel_pos->sec, rel_pos->fr, abs_pos->min, abs_pos->sec, abs_pos->fr);
return 1;
}
int
plat_cdrom_get_sector_size(UNUSED(void *local), UNUSED(uint32_t sector))
{
dummy_cdrom_ioctl_log("BytesPerSector=2048\n");
return 2048;
}
int
plat_cdrom_read_sector(void *local, uint8_t *buffer, uint32_t sector)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
ioctl_t *ioctl = (ioctl_t *) local;
plat_cdrom_open(ioctl);
/* Raw */
dummy_cdrom_ioctl_log("Raw\n");
ioctl_log("Raw\n");
plat_cdrom_close(ioctl);
dummy_cdrom_ioctl_log("ReadSector sector=%d.\n", sector);
ioctl_log("ReadSector sector=%d.\n", sector);
return 0;
}
void
plat_cdrom_eject(void *local)
static uint8_t
ioctl_get_track_type(UNUSED(const void *local), UNUSED(const uint32_t sector))
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_open(ioctl);
plat_cdrom_close(ioctl);
return 0x00;
}
void
plat_cdrom_close(UNUSED(void *local))
static uint32_t
ioctl_get_last_block(const void *local)
{
ioctl_t *ioctl = (ioctl_t *) local;
ioctl_read_toc(ioctl);
return 0x00000000;
}
int
plat_cdrom_set_drive(void *local, const char *drv)
static int
ioctl_read_dvd_structure(UNUSED(const void *local), UNUSED(const uint8_t layer), UNUSED(const uint8_t format),
UNUSED(uint8_t *buffer), UNUSED(uint32_t *info))
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_close(ioctl);
ioctl->toc_valid = 0;
plat_cdrom_load(ioctl);
return 1;
return -0x00052100;
}
int
plat_cdrom_get_local_size(void)
static int
ioctl_is_dvd(UNUSED(const void *local))
{
return sizeof(dummy_cdrom_ioctl_t);
return 0;
}
static int
ioctl_has_audio(UNUSED(const void *local))
{
return 0;
}
static int
ioctl_ext_medium_changed(UNUSED(void *local))
{
#if 0
ioctl_t *ioctl = (ioctl_t *) local;
#endif
int ret = 0;
ioctl_log("ioctl_ext_medium_changed(): %i\n", ret);
return ret;
}
static void
ioctl_close(void *local)
{
ioctl_t *ioctl = (ioctl_t *) local;
ioctl_close_handle(ioctl);
ioctl->handle = NULL;
ioctl_log(ioctl->log, "Log closed\n");
log_close(ioctl->log);
ioctl->log = NULL;
}
static const cdrom_ops_t ioctl_ops = {
ioctl_get_track_info,
ioctl_get_raw_track_info,
ioctl_is_track_pre,
ioctl_read_sector,
ioctl_get_track_type,
ioctl_get_last_block,
ioctl_read_dvd_structure,
ioctl_is_dvd,
ioctl_has_audio,
ioctl_ext_medium_changed,
ioctl_close
};
/* Public functions. */
void *
ioctl_open(cdrom_t *dev, const char *drv)
{
ioctl_t *ioctl = (ioctl_t *) calloc(1, sizeof(ioctl_t));
if (ioctl != NULL) {
char n[1024] = { 0 };
sprintf(n, "CD-ROM %i IOCtl", dev->id + 1);
ioctl->log = log_open(n);
memset(ioctl->path, 0x00, sizeof(ioctl->path));
wsprintf(ioctl->path, L"%S", &(drv[8]));
ioctl_log(ioctl->log, "Path is %S\n", ioctl->path);
ioctl->dev = dev;
ioctl->toc_valid = 0;
dev->ops = &ioctl_ops;
}
return ioctl;
}

View File

@@ -369,12 +369,12 @@ MachineStatus::iterateNIC(const std::function<void(int)> &cb)
}
static int
hdd_count(int bus)
hdd_count(const int bus_type)
{
int c = 0;
for (uint8_t i = 0; i < HDD_NUM; i++) {
if (hdd[i].bus == bus) {
if (hdd[i].bus_type == bus_type) {
c++;
}
}

View File

@@ -537,10 +537,7 @@ MediaMenu::cdromMount(int i, const QString &filename)
if ((fn.data() != NULL) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '\\'))
fn.data()[strlen(fn.data()) - 1] = '/';
#endif
if ((fn.data() != nullptr) && fn.contains("ioctl://"))
cdrom_ioctl_open(&(cdrom[i]), fn.data());
else
cdrom_image_open(&(cdrom[i]), fn.data());
cdrom_load(&(cdrom[i]), fn.data(), 1);
/* Signal media change to the emulated machine. */
if (cdrom[i].insert) {
@@ -806,14 +803,21 @@ MediaMenu::zipSelectImage(int i, bool wp)
void
MediaMenu::zipMount(int i, const QString &filename, bool wp)
{
const auto dev = static_cast<zip_t *>(zip_drives[i].priv);
const auto dev = static_cast<zip_t *>(zip_drives[i].priv);
int was_empty = zip_is_empty(i);
zip_disk_close(dev);
zip_drives[i].read_only = wp;
if (!filename.isEmpty()) {
QByteArray filenameBytes = filename.toUtf8();
zip_load(dev, filenameBytes.data());
zip_load(dev, filenameBytes.data(), 1);
/* Signal media change to the emulated machine. */
zip_insert(dev);
/* The drive was previously empty, transition directly to UNIT ATTENTION. */
if (was_empty)
zip_insert(dev);
}
mhm.addImageToHistory(i, ui::MediaType::Zip, zip_drives[i].prev_image_path, zip_drives[i].image_path);
@@ -935,14 +939,21 @@ MediaMenu::moSelectImage(int i, bool wp)
void
MediaMenu::moMount(int i, const QString &filename, bool wp)
{
const auto dev = static_cast<mo_t *>(mo_drives[i].priv);
const auto dev = static_cast<mo_t *>(mo_drives[i].priv);
int was_empty = mo_is_empty(i);
mo_disk_close(dev);
mo_drives[i].read_only = wp;
if (!filename.isEmpty()) {
QByteArray filenameBytes = filename.toUtf8();
mo_load(dev, filenameBytes.data());
mo_load(dev, filenameBytes.data(), 1);
/* Signal media change to the emulated machine. */
mo_insert(dev);
/* The drive was previously empty, transition directly to UNIT ATTENTION. */
if (was_empty)
mo_insert(dev);
}
mhm.addImageToHistory(i, ui::MediaType::Mo, mo_drives[i].prev_image_path, mo_drives[i].image_path);

View File

@@ -90,6 +90,14 @@ setCDROMSpeed(QAbstractItemModel *model, const QModelIndex &idx, uint8_t speed)
model->setData(i, speed, Qt::UserRole);
}
static QString
CDROMName(int type)
{
char temp[512];
cdrom_get_name(type, temp);
return QObject::tr((const char *) temp);
}
static void
setCDROMType(QAbstractItemModel *model, const QModelIndex &idx, int type)
{
@@ -97,7 +105,7 @@ setCDROMType(QAbstractItemModel *model, const QModelIndex &idx, int type)
if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() == CDROM_BUS_DISABLED)
model->setData(i, QCoreApplication::translate("", "None"));
else if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() != CDROM_BUS_MITSUMI)
model->setData(i, QObject::tr(cdrom_getname(type)));
model->setData(i, CDROMName(type));
model->setData(i, type, Qt::UserRole);
}
@@ -156,8 +164,12 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent)
auto idx = model->index(i, 0);
int type = cdrom_get_type(i);
setCDROMBus(model, idx, cdrom[i].bus_type, cdrom[i].res);
setCDROMSpeed(model, idx.siblingAtColumn(1), cdrom[i].speed);
setCDROMType(model, idx.siblingAtColumn(2), type);
int speed = cdrom_get_speed(type);
if (speed == -1)
setCDROMSpeed(model, idx.siblingAtColumn(1), cdrom[i].speed);
else
setCDROMSpeed(model, idx.siblingAtColumn(1), speed);
if (cdrom[i].bus_type == CDROM_BUS_ATAPI)
Harddrives::busTrackClass->device_track(1, DEV_CDROM, cdrom[i].bus_type, cdrom[i].ide_channel);
else if (cdrom[i].bus_type == CDROM_BUS_SCSI)
@@ -186,7 +198,7 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent)
if (((bus_type == CDROM_BUS_ATAPI) || (bus_type == CDROM_BUS_SCSI)) &&
((cdrom_drive_types[j].bus_type == bus_type) ||
(cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH))) {
QString name = tr(cdrom_getname(j));
QString name = CDROMName(j);
Models::AddEntry(modelType, name, j);
if ((cdrom[cdromIdx].bus_type == bus_type) && (cdrom[cdromIdx].type == j))
selectedTypeRow = eligibleRows;
@@ -246,7 +258,6 @@ SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex &current)
{
uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt();
uint8_t channel = current.siblingAtColumn(0).data(Qt::UserRole + 1).toUInt();
uint8_t speed = current.siblingAtColumn(1).data(Qt::UserRole).toUInt();
int type = current.siblingAtColumn(2).data(Qt::UserRole).toInt();
ui->comboBoxBus->setCurrentIndex(-1);
@@ -260,7 +271,14 @@ SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex &current)
if (!match.isEmpty())
ui->comboBoxChannel->setCurrentIndex(match.first().row());
int speed = cdrom_get_speed(type);
if (speed == -1) {
speed = current.siblingAtColumn(1).data(Qt::UserRole).toUInt();
ui->comboBoxSpeed->setEnabled(true);
} else
ui->comboBoxSpeed->setEnabled(false);
ui->comboBoxSpeed->setCurrentIndex(speed == 0 ? 7 : speed - 1);
ui->comboBoxCDROMType->setCurrentIndex(type);
enableCurrentlySelectedChannel();
}
@@ -351,7 +369,7 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int)
if (((bus_type == CDROM_BUS_ATAPI) || (bus_type == CDROM_BUS_SCSI)) &&
((cdrom_drive_types[j].bus_type == bus_type) ||
(cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH))) {
QString name = tr(cdrom_getname(j));
QString name = CDROMName(j);
Models::AddEntry(modelType, name, j);
if ((cdrom[cdromIdx].bus_type == bus_type) && (cdrom[cdromIdx].type == j))
selectedTypeRow = eligibleRows;
@@ -401,9 +419,22 @@ SettingsFloppyCDROM::on_comboBoxChannel_activated(int)
void
SettingsFloppyCDROM::on_comboBoxCDROMType_activated(int)
{
int type = ui->comboBoxCDROMType->currentData().toUInt();
setCDROMType(ui->tableViewCDROM->model(),
ui->tableViewCDROM->selectionModel()->currentIndex(),
ui->comboBoxCDROMType->currentData().toUInt());
type);
ui->tableViewCDROM->resizeColumnsToContents();
ui->tableViewCDROM->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
int speed = cdrom_get_speed(type);
if (speed == -1) {
speed = ui->comboBoxSpeed->currentData().toUInt();
ui->comboBoxSpeed->setEnabled(true);
} else
ui->comboBoxSpeed->setEnabled(false);
ui->comboBoxSpeed->setCurrentIndex(speed == 0 ? 7 : speed - 1);
auto idx = ui->tableViewCDROM->selectionModel()->currentIndex();
setCDROMSpeed(ui->tableViewCDROM->model(), idx.siblingAtColumn(1), speed);
}

View File

@@ -55,7 +55,7 @@ normalize_hd_list()
memset(ihdd, 0x00, HDD_NUM * sizeof(hard_disk_t));
for (uint8_t i = 0; i < HDD_NUM; i++) {
if (temp_hdd[i].bus != HDD_BUS_DISABLED) {
if (temp_hdd[i].bus_type != HDD_BUS_DISABLED) {
memcpy(&(ihdd[j]), &(temp_hdd[i]), sizeof(hard_disk_t));
j++;
}
@@ -79,14 +79,14 @@ addRow(QAbstractItemModel *model, hard_disk_t *hd)
int row = model->rowCount();
model->insertRow(row);
QString busName = Harddrives::BusChannelName(hd->bus, hd->channel);
QString busName = Harddrives::BusChannelName(hd->bus_type, hd->channel);
model->setData(model->index(row, ColumnBus), busName);
model->setData(model->index(row, ColumnBus), ProgSettings::loadIcon("/hard_disk.ico"), Qt::DecorationRole);
model->setData(model->index(row, ColumnBus), hd->bus, DataBus);
model->setData(model->index(row, ColumnBus), hd->bus, DataBusPrevious);
model->setData(model->index(row, ColumnBus), hd->bus_type, DataBus);
model->setData(model->index(row, ColumnBus), hd->bus_type, DataBusPrevious);
model->setData(model->index(row, ColumnBus), hd->channel, DataBusChannel);
model->setData(model->index(row, ColumnBus), hd->channel, DataBusChannelPrevious);
Harddrives::busTrackClass->device_track(1, DEV_HDD, hd->bus, hd->channel);
Harddrives::busTrackClass->device_track(1, DEV_HDD, hd->bus_type, hd->channel);
QString fileName = hd->fn;
if (fileName.startsWith(userPath, Qt::CaseInsensitive)) {
model->setData(model->index(row, ColumnFilename), fileName.mid(userPath.size()));
@@ -120,7 +120,7 @@ SettingsHarddisks::SettingsHarddisks(QWidget *parent)
ui->tableView->setModel(model);
for (int i = 0; i < HDD_NUM; i++) {
if (hdd[i].bus > 0) {
if (hdd[i].bus_type > 0) {
addRow(model, &hdd[i]);
}
}
@@ -153,7 +153,7 @@ SettingsHarddisks::save()
int rows = model->rowCount();
for (int i = 0; i < rows; ++i) {
auto idx = model->index(i, ColumnBus);
hdd[i].bus = idx.data(DataBus).toUInt();
hdd[i].bus_type = idx.data(DataBus).toUInt();
hdd[i].channel = idx.data(DataBusChannel).toUInt();
hdd[i].tracks = idx.siblingAtColumn(ColumnCylinders).data().toUInt();
hdd[i].hpc = idx.siblingAtColumn(ColumnHeads).data().toUInt();
@@ -313,11 +313,11 @@ addDriveFromDialog(Ui::SettingsHarddisks *ui, const HarddiskDialog &dlg)
hard_disk_t hd;
memset(&hd, 0, sizeof(hd));
hd.bus = dlg.bus();
hd.channel = dlg.channel();
hd.tracks = dlg.cylinders();
hd.hpc = dlg.heads();
hd.spt = dlg.sectors();
hd.bus_type = dlg.bus();
hd.channel = dlg.channel();
hd.tracks = dlg.cylinders();
hd.hpc = dlg.heads();
hd.spt = dlg.sectors();
strncpy(hd.fn, fn.data(), sizeof(hd.fn) - 1);
hd.speed_preset = dlg.speed();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -5913,7 +5913,7 @@ const device_t sb_16_pnp_device = {
.init = sb_16_pnp_init,
.close = sb_close,
.reset = NULL,
{ .available = sb_16_pnp_noide_available },
.available = sb_16_pnp_noide_available,
.speed_changed = sb_speed_changed,
.force_redraw = NULL,
.config = sb_16_pnp_config
@@ -6039,7 +6039,7 @@ const device_t sb_awe64_device = {
.init = sb_awe32_pnp_init,
.close = sb_awe32_close,
.reset = NULL,
{ .available = sb_awe64_noide_available },
.available = sb_awe64_noide_available,
.speed_changed = sb_speed_changed,
.force_redraw = NULL,
.config = sb_awe64_config

View File

@@ -17,16 +17,18 @@
* Copyright 2023 Miran Grca.
*/
#include <inttypes.h>
#ifdef ENABLE_IOCTL_LOG
#include <stdarg.h>
#endif
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/scsi_device.h>
#include <86box/cdrom.h>
#include <86box/log.h>
#include <86box/plat_unused.h>
#include <86box/plat_cdrom.h>
@@ -35,223 +37,203 @@
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)
typedef struct dummy_cdrom_ioctl_t {
typedef struct ioctl_t {
cdrom_t *dev;
void *log;
int toc_valid;
} dummy_cdrom_ioctl_t;
} ioctl_t;
#ifdef ENABLE_DUMMY_CDROM_IOCTL_LOG
int dummy_cdrom_ioctl_do_log = ENABLE_DUMMY_CDROM_IOCTL_LOG;
#ifdef ENABLE_IOCTL_LOG
int ioctl_do_log = ENABLE_IOCTL_LOG;
void
dummy_cdrom_ioctl_log(const char *fmt, ...)
ioctl_log(void *priv, const char *fmt, ...)
{
va_list ap;
if (dummy_cdrom_ioctl_do_log) {
if (ioctl_do_log) {
va_list ap;
va_start(ap, fmt);
pclog_ex(fmt, ap);
log_out(priv, fmt, ap);
va_end(ap);
}
}
#else
# define dummy_cdrom_ioctl_log(fmt, ...)
# define ioctl_log(priv, fmt, ...)
#endif
static int
plat_cdrom_open(void *local)
/* Internal functions. */
static void
ioctl_close_handle(UNUSED(const ioctl_t *ioctl))
{
return 0;
}
static int
plat_cdrom_load(void *local)
ioctl_open_handle(UNUSED(ioctl_t *ioctl))
{
return 0;
}
static void
plat_cdrom_read_toc(void *local)
ioctl_read_toc(ioctl_t *ioctl)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
if (!ioctl->toc_valid) {
ioctl->toc_valid = 1;
}
}
/* Shared functions. */
static int
ioctl_get_track_info(UNUSED(const void *local), UNUSED(const uint32_t track),
UNUSED(int end), UNUSED(track_info_t *ti))
{
return 0;
}
static void
ioctl_get_raw_track_info(const void *local, UNUSED(int *num), UNUSED(uint8_t *rti))
{
ioctl_t *ioctl = (ioctl_t *) local;
if (!ioctl->toc_valid)
ioctl->toc_valid = 1;
}
void
plat_cdrom_get_raw_track_info(UNUSED(void *local), int *num, raw_track_info_t *rti)
static void
ioctl_get_raw_track_info(UNUSED(const void *local), int *num, uint8_t *rti)
{
*num = 1;
memset(rti, 0x00, 11);
}
int
plat_cdrom_is_track_audio(void *local, uint32_t sector)
static int
ioctl_is_track_pre(const void *local, const uint32_t sector)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_read_toc(ioctl);
const int ret = 0;
dummy_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret);
return ret;
}
int
plat_cdrom_is_track_pre(void *local, uint32_t sector)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
ioctl_t *ioctl = (ioctl_t *) local;
plat_cdrom_read_toc(ioctl);
const int ret = 0;
dummy_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret);
ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret);
return ret;
}
uint32_t
plat_cdrom_get_track_start(void *local, uint32_t sector, uint8_t *attr, uint8_t *track)
static int
ioctl_read_sector(const void *local, uint8_t *buffer, uint32_t const sector)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_read_toc(ioctl);
return 0x00000000;
}
uint32_t
plat_cdrom_get_last_block(void *local)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_read_toc(ioctl);
return 0x00000000;
}
int
plat_cdrom_ext_medium_changed(UNUSED(void *local))
{
#if 0
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_read_toc(ioctl);
#endif
int ret = 0;
dummy_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret);
return ret;
}
/* 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)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_read_toc(ioctl);
if ((track < 1) || (track == 0xaa)) {
dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track);
return 0;
}
start->min = 0;
start->sec = 0;
start->fr = 2;
*track_num = 1;
*attr = 0x14;
dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i): %02i:%02i:%02i, %02i, %02X\n",
track, start->min, start->sec, start->fr, *track_num, *attr);
return 1;
}
/* TODO: See if track start is adjusted by 150 or not. */
int
plat_cdrom_get_audio_sub(UNUSED(void *local), UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index,
TMSF *rel_pos, TMSF *abs_pos)
{
*track = 1;
*attr = 0x14;
*index = 1;
rel_pos->min = 0;
rel_pos->sec = 0;
rel_pos->fr = 0;
abs_pos->min = 0;
abs_pos->sec = 0;
abs_pos->fr = 2;
dummy_cdrom_ioctl_log("plat_cdrom_get_audio_sub(): %02i, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n",
*track, *attr, *index, rel_pos->min, rel_pos->sec, rel_pos->fr, abs_pos->min, abs_pos->sec, abs_pos->fr);
return 1;
}
int
plat_cdrom_get_sector_size(UNUSED(void *local), UNUSED(uint32_t sector))
{
dummy_cdrom_ioctl_log("BytesPerSector=2048\n");
return 2048;
}
int
plat_cdrom_read_sector(void *local, uint8_t *buffer, uint32_t sector)
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
ioctl_t *ioctl = (ioctl_t *) local;
plat_cdrom_open(ioctl);
/* Raw */
dummy_cdrom_ioctl_log("Raw\n");
ioctl_log("Raw\n");
plat_cdrom_close(ioctl);
dummy_cdrom_ioctl_log("ReadSector sector=%d.\n", sector);
ioctl_log("ReadSector sector=%d.\n", sector);
return 0;
}
void
plat_cdrom_eject(void *local)
static uint8_t
ioctl_get_track_type(UNUSED(const void *local), UNUSED(const uint32_t sector))
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_open(ioctl);
plat_cdrom_close(ioctl);
return 0x00;
}
void
plat_cdrom_close(UNUSED(void *local))
static uint32_t
ioctl_get_last_block(const void *local)
{
ioctl_t *ioctl = (ioctl_t *) local;
ioctl_read_toc(ioctl);
return 0x00000000;
}
int
plat_cdrom_set_drive(void *local, const char *drv)
static int
ioctl_read_dvd_structure(UNUSED(const void *local), UNUSED(const uint8_t layer), UNUSED(const uint8_t format),
UNUSED(uint8_t *buffer), UNUSED(uint32_t *info))
{
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_close(ioctl);
ioctl->toc_valid = 0;
plat_cdrom_load(ioctl);
return 1;
return -0x00052100;
}
int
plat_cdrom_get_local_size(void)
static int
ioctl_is_dvd(UNUSED(const void *local))
{
return sizeof(dummy_cdrom_ioctl_t);
return 0;
}
static int
ioctl_has_audio(UNUSED(const void *local))
{
return 0;
}
static int
ioctl_ext_medium_changed(UNUSED(void *local))
{
#if 0
ioctl_t *ioctl = (ioctl_t *) local;
#endif
int ret = 0;
ioctl_log("ioctl_ext_medium_changed(): %i\n", ret);
return ret;
}
static void
ioctl_close(void *local)
{
ioctl_t *ioctl = (ioctl_t *) local;
ioctl_close_handle(ioctl);
ioctl->handle = NULL;
ioctl_log(ioctl->log, "Log closed\n");
log_close(ioctl->log);
ioctl->log = NULL;
}
static const cdrom_ops_t ioctl_ops = {
ioctl_get_track_info,
ioctl_get_raw_track_info,
ioctl_is_track_pre,
ioctl_read_sector,
ioctl_get_track_type,
ioctl_get_last_block,
ioctl_read_dvd_structure,
ioctl_is_dvd,
ioctl_has_audio,
ioctl_ext_medium_changed,
ioctl_close
};
/* Public functions. */
void *
ioctl_open(cdrom_t *dev, const char *drv)
{
ioctl_t *ioctl = (ioctl_t *) calloc(1, sizeof(ioctl_t));
if (ioctl != NULL) {
char n[1024] = { 0 };
sprintf(n, "CD-ROM %i IOCtl", dev->id + 1);
ioctl->log = log_open(n);
memset(ioctl->path, 0x00, sizeof(ioctl->path));
wsprintf(ioctl->path, L"%S", &(drv[8]));
ioctl_log(ioctl->log, "Path is %S\n", ioctl->path);
ioctl->dev = dev;
ioctl->toc_valid = 0;
dev->ops = &ioctl_ops;
}
return ioctl;
}