mirror of
https://github.com/86Box/86Box.git
synced 2026-02-24 10:28:19 -07:00
Merge branch 'master' of https://github.com/86Box/86Box
This commit is contained in:
@@ -23,8 +23,6 @@ endif()
|
||||
add_executable(86Box
|
||||
86box.c
|
||||
config.c
|
||||
log.c
|
||||
random.c
|
||||
timer.c
|
||||
io.c
|
||||
acpi.c
|
||||
@@ -41,15 +39,11 @@ add_executable(86Box
|
||||
pci.c
|
||||
mca.c
|
||||
usb.c
|
||||
fifo.c
|
||||
fifo8.c
|
||||
device.c
|
||||
nvr.c
|
||||
nvr_at.c
|
||||
nvr_ps2.c
|
||||
machine_status.c
|
||||
ini.c
|
||||
cJSON.c
|
||||
)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
@@ -106,7 +100,7 @@ if(INSTRUMENT)
|
||||
endif()
|
||||
|
||||
target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom zip mo hdd
|
||||
net print scsi sio snd vid voodoo plat ui)
|
||||
net print scsi sio snd utils vid voodoo plat ui)
|
||||
|
||||
if(HAIKU)
|
||||
target_link_libraries(86Box be)
|
||||
@@ -256,7 +250,9 @@ add_subdirectory(printer)
|
||||
add_subdirectory(sio)
|
||||
add_subdirectory(scsi)
|
||||
add_subdirectory(sound)
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(video)
|
||||
|
||||
if (APPLE)
|
||||
add_subdirectory(mac)
|
||||
endif()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -409,7 +409,7 @@ image_get_track_and_index(const cd_image_t *img, const uint32_t sector,
|
||||
|
||||
for (int i = 0; i < img->tracks_num; i++) {
|
||||
track_t *ct = &(img->tracks[i]);
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if ((ct->point >= 1) && (ct->point <= 99)) for (int j = 0; j < 3; j++) {
|
||||
track_index_t *ci = &(ct->idx[j]);
|
||||
if ((ci->type >= INDEX_ZERO) && (ci->length != 0ULL) &&
|
||||
((sector + 150) >= ci->start) && ((sector + 150) <= (ci->start + ci->length - 1))) {
|
||||
|
||||
@@ -1028,9 +1028,8 @@ ide_atapi_command_bus(ide_t *ide)
|
||||
static void
|
||||
ide_atapi_callback(ide_t *ide)
|
||||
{
|
||||
int out;
|
||||
int ret = 0;
|
||||
ide_bm_t *bm = ide_boards[ide->board]->bm;
|
||||
static int ret = 0;
|
||||
ide_bm_t *bm = ide_boards[ide->board]->bm;
|
||||
#ifdef ENABLE_IDE_LOG
|
||||
char *phases[7] = { "Idle", "Command", "Data in", "Data out", "Data in DMA", "Data out DMA",
|
||||
"Complete" };
|
||||
@@ -1056,14 +1055,17 @@ ide_atapi_callback(ide_t *ide)
|
||||
|
||||
switch (ide->sc->packet_status) {
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case PHASE_IDLE:
|
||||
ret = 0;
|
||||
ide->tf->pos = 0;
|
||||
ide->tf->phase = 1;
|
||||
ide->tf->atastat = READY_STAT | DRQ_STAT | (ide->tf->atastat & ERR_STAT);
|
||||
break;
|
||||
case PHASE_COMMAND:
|
||||
ret = 1;
|
||||
ide->tf->atastat = BUSY_STAT | (ide->tf->atastat & ERR_STAT);
|
||||
if (ide->packet_command) {
|
||||
ide->packet_command(ide->sc, ide->sc->atapi_cdb);
|
||||
@@ -1073,6 +1075,7 @@ ide_atapi_callback(ide_t *ide)
|
||||
break;
|
||||
case PHASE_COMPLETE:
|
||||
case PHASE_ERROR:
|
||||
ret = 0;
|
||||
ide->tf->atastat = READY_STAT;
|
||||
if (ide->sc->packet_status == PHASE_ERROR)
|
||||
ide->tf->atastat |= ERR_STAT;
|
||||
@@ -1082,19 +1085,34 @@ ide_atapi_callback(ide_t *ide)
|
||||
break;
|
||||
case PHASE_DATA_IN:
|
||||
case PHASE_DATA_OUT:
|
||||
ret = 0;
|
||||
ide->tf->atastat = READY_STAT | DRQ_STAT | (ide->tf->atastat & ERR_STAT);
|
||||
ide->tf->phase = !(ide->sc->packet_status & 0x01) << 1;
|
||||
ide_irq_raise(ide);
|
||||
break;
|
||||
case PHASE_DATA_IN_DMA:
|
||||
case PHASE_DATA_OUT_DMA:
|
||||
out = (ide->sc->packet_status & 0x01);
|
||||
|
||||
if (!IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 &&
|
||||
(bm != NULL) && bm->dma) {
|
||||
ret = bm->dma(ide->sc->temp_buffer, ide->sc->packet_len, out, bm->priv);
|
||||
}
|
||||
/* Else, DMA command without a bus master, ret = 0 (default). */
|
||||
if (ide->sc->block_len == 0) {
|
||||
ret = bm->dma(ide->sc->temp_buffer, ide->sc->packet_len, 0, bm->priv);
|
||||
|
||||
/* Underrun. */
|
||||
if (ret == 1)
|
||||
ret = 3;
|
||||
} else {
|
||||
ret = bm->dma(ide->sc->temp_buffer + ide->sc->buffer_pos -
|
||||
ide->sc->block_len, ide->sc->block_len,
|
||||
0, bm->priv);
|
||||
|
||||
if (ret == 1) {
|
||||
if (ide->sc->sector_len == 0)
|
||||
ret = 3;
|
||||
else if (ide->read != NULL)
|
||||
ide->read(ide->sc);
|
||||
}
|
||||
}
|
||||
} else
|
||||
ret = 0;
|
||||
|
||||
switch (ret) {
|
||||
default:
|
||||
@@ -1103,18 +1121,73 @@ ide_atapi_callback(ide_t *ide)
|
||||
if (ide->bus_master_error)
|
||||
ide->bus_master_error(ide->sc);
|
||||
break;
|
||||
case 1:
|
||||
if (out && ide->phase_data_out)
|
||||
(void) ide->phase_data_out(ide->sc);
|
||||
else if (!out && ide->command_stop)
|
||||
ide->command_stop(ide->sc);
|
||||
case 2:
|
||||
ide_atapi_command_bus(ide);
|
||||
break;
|
||||
case 3:
|
||||
/* Reached EOT - terminate the command as there's nothing
|
||||
more to transfer. */
|
||||
ide->sc->packet_status = PHASE_COMPLETE;
|
||||
ide->sc->callback = 0.0;
|
||||
|
||||
if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0))
|
||||
if (ide->command_stop != NULL)
|
||||
ide->command_stop(ide->sc);
|
||||
fallthrough;
|
||||
case 1:
|
||||
if ((ide->sc->packet_status == PHASE_COMPLETE) &&
|
||||
(ide->sc->callback == 0.0))
|
||||
ide_atapi_callback(ide);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PHASE_DATA_OUT_DMA:
|
||||
if (!IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 &&
|
||||
(bm != NULL) && bm->dma) {
|
||||
if (ide->sc->block_len == 0) {
|
||||
ret = bm->dma(ide->sc->temp_buffer, ide->sc->packet_len, 1, bm->priv);
|
||||
|
||||
/* Underrun. */
|
||||
if (ret == 1)
|
||||
ret = 3;
|
||||
} else {
|
||||
ret = bm->dma(ide->sc->temp_buffer + ide->sc->buffer_pos,
|
||||
ide->sc->block_len, 1, bm->priv);
|
||||
|
||||
if (ret & 1) {
|
||||
if (ide->write != NULL)
|
||||
ide->write(ide->sc);
|
||||
|
||||
if ((ret == 1) && (ide->sc->sector_len == 0))
|
||||
ret = 3;
|
||||
}
|
||||
}
|
||||
} else
|
||||
ret = 0;
|
||||
|
||||
switch (ret) {
|
||||
default:
|
||||
break;
|
||||
case 0:
|
||||
if (ide->bus_master_error)
|
||||
ide->bus_master_error(ide->sc);
|
||||
break;
|
||||
case 2:
|
||||
ide_atapi_command_bus(ide);
|
||||
break;
|
||||
case 3:
|
||||
/* Reached EOT - terminate the command as there's nothing
|
||||
more to transfer. */
|
||||
ide->sc->packet_status = PHASE_COMPLETE;
|
||||
ide->sc->callback = 0.0;
|
||||
|
||||
if (ide->phase_data_out != NULL)
|
||||
(void) ide->phase_data_out(ide->sc);
|
||||
fallthrough;
|
||||
case 1:
|
||||
if ((ide->sc->packet_status == PHASE_COMPLETE) &&
|
||||
(ide->sc->callback == 0.0))
|
||||
ide_atapi_callback(ide);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1128,28 +1201,36 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
|
||||
|
||||
ide_irq_lower(ide);
|
||||
|
||||
ide->tf->atastat = BSY_STAT;
|
||||
ide->tf->atastat = BSY_STAT;
|
||||
|
||||
if (ide->tf->pos >= dev->packet_len) {
|
||||
ide_log("%i bytes %s, command done\n", ide->tf->pos, out ? "written" : "read");
|
||||
|
||||
ide->tf->pos = dev->request_pos = 0;
|
||||
if (out && ide->phase_data_out)
|
||||
ide->phase_data_out(dev);
|
||||
else if (!out && ide->command_stop)
|
||||
ide->command_stop(dev);
|
||||
|
||||
if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0))
|
||||
ide_atapi_callback(ide);
|
||||
if (dev->block_len == 0) {
|
||||
if (out && (ide->phase_data_out != NULL))
|
||||
ide->phase_data_out(dev);
|
||||
else if (!out && (ide->command_stop != NULL))
|
||||
ide->command_stop(dev);
|
||||
|
||||
if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0))
|
||||
ide_atapi_callback(ide);
|
||||
}
|
||||
} else {
|
||||
ide_log("%i bytes %s, %i bytes are still left\n", ide->tf->pos,
|
||||
out ? "written" : "read", dev->packet_len - ide->tf->pos);
|
||||
|
||||
/* If less than (packet length) bytes are remaining, update packet length
|
||||
accordingly. */
|
||||
/*
|
||||
If less than (packet length) bytes are remaining, update packet length
|
||||
accordingly.
|
||||
*/
|
||||
if ((dev->packet_len - ide->tf->pos) < (dev->max_transfer_len)) {
|
||||
dev->max_transfer_len = dev->packet_len - ide->tf->pos;
|
||||
/* Also update the request length so the host knows how many bytes to transfer. */
|
||||
/*
|
||||
Also update the request length so the host knows how many bytes to
|
||||
transfer.
|
||||
*/
|
||||
ide->tf->request_length = dev->max_transfer_len;
|
||||
}
|
||||
ide_log("CD-ROM %i: Packet length %i, request length %i\n", dev->id, dev->packet_len,
|
||||
@@ -1157,12 +1238,40 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
|
||||
|
||||
dev->packet_status = PHASE_DATA_IN | out;
|
||||
|
||||
ide->tf->atastat = BSY_STAT;
|
||||
ide->tf->phase = 1;
|
||||
ide_atapi_callback(ide);
|
||||
ide_set_callback(ide, 0.0);
|
||||
if (dev->block_len == 0) {
|
||||
ide_atapi_callback(ide);
|
||||
ide_set_callback(ide, 0.0);
|
||||
}
|
||||
|
||||
dev->request_pos = 0;
|
||||
dev->request_pos = 0;
|
||||
}
|
||||
|
||||
if (dev->block_len != 0) {
|
||||
if (out) {
|
||||
if (ide->write != NULL)
|
||||
ide->write(dev);
|
||||
|
||||
if (dev->sector_len == 0) {
|
||||
ide->sc->packet_status = PHASE_COMPLETE;
|
||||
ide->sc->callback = 0.0;
|
||||
|
||||
if (ide->phase_data_out != NULL)
|
||||
(void) ide->phase_data_out(dev);
|
||||
|
||||
ide_atapi_callback(ide);
|
||||
}
|
||||
} else {
|
||||
if (dev->sector_len == 0) {
|
||||
if (ide->command_stop != NULL)
|
||||
ide->command_stop(dev);
|
||||
|
||||
ide->sc->packet_status = PHASE_COMPLETE;
|
||||
ide->sc->callback = 0.0;
|
||||
|
||||
ide_atapi_callback(ide);
|
||||
} else if (ide->read != NULL)
|
||||
ide->read(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1179,16 +1288,19 @@ ide_atapi_packet_read(ide_t *ide)
|
||||
|
||||
bufferw = (uint16_t *) dev->temp_buffer;
|
||||
|
||||
/* Make sure we return a 0 and don't attempt to read from the buffer if
|
||||
/*
|
||||
Make sure we return a 0 and don't attempt to read from the buffer if
|
||||
we're transferring bytes beyond it, which can happen when issuing media
|
||||
access commands with an allocated length below minimum request length
|
||||
(which is 1 sector = 2048 bytes). */
|
||||
(which is 1 sector = 2048 bytes).
|
||||
*/
|
||||
ret = (ide->tf->pos < dev->packet_len) ? bufferw[ide->tf->pos >> 1] : 0;
|
||||
ide->tf->pos += 2;
|
||||
|
||||
dev->request_pos += 2;
|
||||
|
||||
if ((dev->request_pos >= dev->max_transfer_len) || (ide->tf->pos >= dev->packet_len)) {
|
||||
if ((dev->request_pos >= dev->max_transfer_len) ||
|
||||
(ide->tf->pos >= dev->packet_len)) {
|
||||
/* Time for a DRQ. */
|
||||
ide_atapi_pio_request(ide, 0);
|
||||
}
|
||||
@@ -1221,7 +1333,8 @@ ide_atapi_packet_write(ide_t *ide, const uint16_t val)
|
||||
dev->request_pos += 2;
|
||||
|
||||
if (dev->packet_status == PHASE_DATA_OUT) {
|
||||
if ((dev->request_pos >= dev->max_transfer_len) || (ide->tf->pos >= dev->packet_len)) {
|
||||
if ((dev->request_pos >= dev->max_transfer_len) ||
|
||||
(ide->tf->pos >= dev->packet_len)) {
|
||||
/* Time for a DRQ. */
|
||||
ide_atapi_pio_request(ide, 1);
|
||||
}
|
||||
@@ -1287,7 +1400,7 @@ ide_writew(uint16_t addr, uint16_t val, void *priv)
|
||||
ide = ide_drives[ch];
|
||||
|
||||
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
|
||||
ide_log("ide_writew(%04X, %04X, %08X)\n", addr, val, priv);
|
||||
ide_log("[%04X:%08X] ide_writew(%04X, %04X, %08X)\n", CS, cpu_state.pc, addr, val, priv);
|
||||
#endif
|
||||
|
||||
addr &= 0x7;
|
||||
@@ -1321,7 +1434,7 @@ ide_writel(uint16_t addr, uint32_t val, void *priv)
|
||||
ide = ide_drives[ch];
|
||||
|
||||
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
|
||||
ide_log("ide_writel(%04X, %08X, %08X)\n", addr, val, priv);
|
||||
ide_log("[%04X:%08X] ide_writel(%04X, %08X, %08X)\n", CS, cpu_state.pc, addr, val, priv);
|
||||
#endif
|
||||
|
||||
addr &= 0x7;
|
||||
@@ -1371,9 +1484,9 @@ ide_write_devctl(UNUSED(uint16_t addr), uint8_t val, void *priv)
|
||||
ide = ide_drives[ch];
|
||||
ide_other = ide_drives[ch ^ 1];
|
||||
|
||||
ide_log("ide_write_devctl(%04X, %02X, %08X)\n", addr, val, priv);
|
||||
ide_log("[%04X:%08X] ide_write_devctl(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv);
|
||||
|
||||
if ((ide->type == IDE_NONE) && (ide_other->type == IDE_NONE))
|
||||
if ((addr & 0x0001) || ((ide->type == IDE_NONE) && (ide_other->type == IDE_NONE)))
|
||||
return;
|
||||
|
||||
dev->diag = 0;
|
||||
@@ -1481,7 +1594,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
||||
ide = ide_drives[ch];
|
||||
ide_other = ide_drives[ch ^ 1];
|
||||
|
||||
ide_log("ide_writeb(%04X, %02X, %08X)\n", addr, val, priv);
|
||||
ide_log("[%04X:%08X] ide_writeb(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv);
|
||||
|
||||
addr &= 0x7;
|
||||
|
||||
@@ -1831,7 +1944,7 @@ ide_read_data(ide_t *ide)
|
||||
const uint16_t *idebufferw = ide->buffer;
|
||||
uint16_t ret = 0x0000;
|
||||
|
||||
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
|
||||
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 3)
|
||||
ide_log("ide_read_data(): ch = %i, board = %i, type = %i\n", ide->channel,
|
||||
ide->board, ide->type);
|
||||
#endif
|
||||
@@ -2010,7 +2123,7 @@ ide_readb(uint16_t addr, void *priv)
|
||||
break;
|
||||
}
|
||||
|
||||
ide_log("ide_readb(%04X, %08X) = %02X\n", addr, priv, ret);
|
||||
ide_log("[%04X:%08X] ide_readb(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2022,12 +2135,14 @@ ide_read_alt_status(UNUSED(const uint16_t addr), void *priv)
|
||||
|
||||
const int ch = dev->cur_dev;
|
||||
ide_t * ide = ide_drives[ch];
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
/* Per the Seagate ATA-3 specification:
|
||||
Reading the alternate status does *NOT* clear the IRQ. */
|
||||
const uint8_t ret = ide_status(ide, ide_drives[ch ^ 1], ch);
|
||||
if (!(addr & 0x0001))
|
||||
ret = ide_status(ide, ide_drives[ch ^ 1], ch);
|
||||
|
||||
ide_log("ide_read_alt_status(%04X, %08X) = %02X\n", addr, priv, ret);
|
||||
ide_log("[%04X:%08X] ide_read_alt_status(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2053,7 +2168,7 @@ ide_readw(uint16_t addr, void *priv)
|
||||
}
|
||||
|
||||
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
|
||||
ide_log("ide_readw(%04X, %08X) = %04X\n", addr, priv, ret);
|
||||
ide_log("[%04X:%08X] ide_readw(%04X, %08X) = %04X\n", CS, cpu_state.pc, addr, priv, ret);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
@@ -2084,7 +2199,7 @@ ide_readl(uint16_t addr, void *priv)
|
||||
}
|
||||
|
||||
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
|
||||
ide_log("ide_readl(%04X, %08X) = %04X\n", addr, priv, ret);
|
||||
ide_log("[%04X:%08X] ide_readl(%04X, %08X) = %04X\n", CS, cpu_state.pc, addr, priv, ret);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
@@ -2270,7 +2385,7 @@ ide_callback(void *priv)
|
||||
ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
|
||||
ide_set_callback(ide, 6.0 * IDE_TIME);
|
||||
return;
|
||||
} else if (ret == 1) {
|
||||
} else if (ret & 1) {
|
||||
/* DMA successful */
|
||||
ide_log("IDE %i: DMA read successful\n", ide->channel);
|
||||
|
||||
@@ -2379,7 +2494,7 @@ ide_callback(void *priv)
|
||||
ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
|
||||
ide_set_callback(ide, 6.0 * IDE_TIME);
|
||||
return;
|
||||
} else if (ret == 1) {
|
||||
} else if (ret & 1) {
|
||||
/* DMA successful */
|
||||
ret = hdd_image_write(ide->hdd_num, ide_get_sector(ide),
|
||||
ide->sector_pos, ide->sector_buffer);
|
||||
@@ -2637,7 +2752,7 @@ ide_handlers(uint8_t board, int set)
|
||||
}
|
||||
|
||||
if (ide_boards[board]->base[1]) {
|
||||
io_handler(set, ide_boards[board]->base[1], 1,
|
||||
io_handler(set, ide_boards[board]->base[1], 2,
|
||||
ide_read_alt_status, NULL, NULL,
|
||||
ide_write_devctl, NULL, NULL,
|
||||
ide_boards[board]);
|
||||
|
||||
@@ -375,7 +375,7 @@ sff_bus_master_dma(uint8_t *data, int transfer_length, int out, void *priv)
|
||||
} else if (dev->eot) {
|
||||
sff_log("Regular EOT\n");
|
||||
dev->status &= ~3;
|
||||
return 1; /* We have regularly reached EOT - clear status and break. */
|
||||
return 3; /* We have regularly reached EOT - clear status and break. */
|
||||
} else {
|
||||
/* We have more to transfer and there are blocks left, get next block. */
|
||||
sff_bus_master_next_addr(dev);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/crc.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/random.h>
|
||||
@@ -223,6 +224,7 @@ typedef struct d86f_t {
|
||||
uint8_t *filebuf;
|
||||
uint8_t *outbuf;
|
||||
sector_t *last_side_sector[2];
|
||||
uint16_t crc_table[256];
|
||||
} d86f_t;
|
||||
|
||||
static const uint8_t encoded_fm[64] = {
|
||||
@@ -247,7 +249,6 @@ static const uint8_t encoded_mfm[64] = {
|
||||
};
|
||||
|
||||
static d86f_t *d86f[FDD_NUM];
|
||||
static uint16_t CRCTable[256];
|
||||
static fdc_t *d86f_fdc;
|
||||
uint64_t poly = 0x42F0E1EBA9EA3693LL; /* ECMA normal */
|
||||
|
||||
@@ -276,28 +277,6 @@ d86f_log(const char *fmt, ...)
|
||||
# define d86f_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
setup_crc(uint16_t poly)
|
||||
{
|
||||
int c = 256;
|
||||
int bc;
|
||||
uint16_t temp;
|
||||
|
||||
while (c--) {
|
||||
temp = c << 8;
|
||||
bc = 8;
|
||||
|
||||
while (bc--) {
|
||||
if (temp & 0x8000)
|
||||
temp = (temp << 1) ^ poly;
|
||||
else
|
||||
temp <<= 1;
|
||||
|
||||
CRCTable[c] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
d86f_destroy_linked_lists(int drive, int side)
|
||||
{
|
||||
@@ -1237,16 +1216,10 @@ decodefm(UNUSED(int drive), uint16_t dat)
|
||||
return temp;
|
||||
}
|
||||
|
||||
void
|
||||
fdd_calccrc(uint8_t byte, crc_t *crc_var)
|
||||
{
|
||||
crc_var->word = (crc_var->word << 8) ^ CRCTable[(crc_var->word >> 8) ^ byte];
|
||||
}
|
||||
|
||||
static void
|
||||
d86f_calccrc(d86f_t *dev, uint8_t byte)
|
||||
{
|
||||
fdd_calccrc(byte, &(dev->calc_crc));
|
||||
crc16_calc(dev->crc_table, byte, &(dev->calc_crc));
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1274,7 +1247,9 @@ d86f_word_is_aligned(int drive, int side, uint32_t base_pos)
|
||||
|
||||
/* State 1: Find sector ID */
|
||||
void
|
||||
d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_am, uint16_t other_am, uint16_t wrong_am, uint16_t ignore_other_am)
|
||||
d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_am,
|
||||
uint16_t other_am, uint16_t wrong_am,
|
||||
uint16_t ignore_other_am)
|
||||
{
|
||||
d86f_t *dev = d86f[drive];
|
||||
|
||||
@@ -1282,7 +1257,8 @@ d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_am, ui
|
||||
|
||||
if (dev->last_word[side] == req_am) {
|
||||
dev->calc_crc.word = 0xFFFF;
|
||||
fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc));
|
||||
crc16_calc(dev->crc_table, decodefm(drive, dev->last_word[side]),
|
||||
&(dev->calc_crc));
|
||||
find->sync_marks = find->bits_obtained =
|
||||
find->bytes_obtained = 0;
|
||||
find->sync_pos = 0xFFFFFFFF;
|
||||
@@ -1302,7 +1278,8 @@ d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_am, ui
|
||||
|
||||
if ((ignore_other_am & 2) && (dev->last_word[side] == other_am)) {
|
||||
dev->calc_crc.word = 0xFFFF;
|
||||
fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc));
|
||||
crc16_calc(dev->crc_table, decodefm(drive, dev->last_word[side]),
|
||||
&(dev->calc_crc));
|
||||
find->sync_marks = find->bits_obtained = find->bytes_obtained = 0;
|
||||
find->sync_pos = 0xFFFFFFFF;
|
||||
if (ignore_other_am & 1) {
|
||||
@@ -1378,7 +1355,8 @@ d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_am, u
|
||||
if ((dev->last_word[side] == req_am) && (find->sync_marks >= 3)) {
|
||||
if (d86f_word_is_aligned(drive, side, find->sync_pos)) {
|
||||
dev->calc_crc.word = 0xCDB4;
|
||||
fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc));
|
||||
crc16_calc(dev->crc_table, decodefm(drive, dev->last_word[side]),
|
||||
&(dev->calc_crc));
|
||||
find->sync_marks = find->bits_obtained = find->bytes_obtained = 0;
|
||||
find->sync_pos = 0xFFFFFFFF;
|
||||
dev->preceding_bit[side] = dev->last_word[side] & 1;
|
||||
@@ -1390,7 +1368,8 @@ d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_am, u
|
||||
if ((ignore_other_am & 2) && (dev->last_word[side] == other_am) && (find->sync_marks >= 3)) {
|
||||
if (d86f_word_is_aligned(drive, side, find->sync_pos)) {
|
||||
dev->calc_crc.word = 0xCDB4;
|
||||
fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc));
|
||||
crc16_calc(dev->crc_table, decodefm(drive, dev->last_word[side]),
|
||||
&(dev->calc_crc));
|
||||
find->sync_marks = find->bits_obtained = find->bytes_obtained = 0;
|
||||
find->sync_pos = 0xFFFFFFFF;
|
||||
if (ignore_other_am & 1) {
|
||||
@@ -1464,8 +1443,11 @@ d86f_read_sector_id(int drive, int side, int match)
|
||||
if (dev->id_find.bytes_obtained < 4) {
|
||||
dev->last_sector.byte_array[dev->id_find.bytes_obtained] =
|
||||
decodefm(drive, dev->last_word[side]);
|
||||
fdd_calccrc(dev->last_sector.byte_array[dev->id_find.bytes_obtained], &(dev->calc_crc));
|
||||
} else if ((dev->id_find.bytes_obtained >= 4) && (dev->id_find.bytes_obtained < 6)) {
|
||||
crc16_calc(dev->crc_table,
|
||||
dev->last_sector.byte_array[dev->id_find.bytes_obtained],
|
||||
&(dev->calc_crc));
|
||||
} else if ((dev->id_find.bytes_obtained >= 4) &&
|
||||
(dev->id_find.bytes_obtained < 6)) {
|
||||
dev->track_crc.bytes[(dev->id_find.bytes_obtained & 1) ^ 1] =
|
||||
decodefm(drive, dev->last_word[side]);
|
||||
}
|
||||
@@ -1643,7 +1625,7 @@ d86f_read_sector_data(int drive, int side)
|
||||
}
|
||||
}
|
||||
}
|
||||
fdd_calccrc(data, &(dev->calc_crc));
|
||||
crc16_calc(dev->crc_table, data, &(dev->calc_crc));
|
||||
} else if (dev->data_find.bytes_obtained < crc_pos)
|
||||
dev->track_crc.bytes[(dev->data_find.bytes_obtained - sector_len) ^ 1] =
|
||||
decodefm(drive, dev->last_word[side]);
|
||||
@@ -1730,11 +1712,12 @@ d86f_write_sector_data(int drive, int side, int mfm, uint16_t am)
|
||||
|
||||
if (dev->data_find.bytes_obtained < sector_len) {
|
||||
/* This is a data byte, so CRC it. */
|
||||
if (!dev->data_find.bytes_obtained) {
|
||||
fdd_calccrc(decodefm(drive, am), &(dev->calc_crc));
|
||||
} else {
|
||||
fdd_calccrc(dev->current_byte[side], &(dev->calc_crc));
|
||||
}
|
||||
if (!dev->data_find.bytes_obtained)
|
||||
crc16_calc(dev->crc_table, decodefm(drive, am),
|
||||
&(dev->calc_crc));
|
||||
else
|
||||
crc16_calc(dev->crc_table, dev->current_byte[side],
|
||||
&(dev->calc_crc));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -3861,8 +3844,6 @@ d86f_load(int drive, char *fn)
|
||||
void
|
||||
d86f_init(void)
|
||||
{
|
||||
setup_crc(0x1021);
|
||||
|
||||
for (uint8_t i = 0; i < FDD_NUM; i++)
|
||||
d86f[i] = NULL;
|
||||
}
|
||||
@@ -3926,6 +3907,8 @@ d86f_setup(int drive)
|
||||
dev->last_side_sector[0] = NULL;
|
||||
dev->last_side_sector[1] = NULL;
|
||||
|
||||
crc16_setup(dev->crc_table, 0x1021);
|
||||
|
||||
/* Set the drive as active. */
|
||||
d86f[drive] = dev;
|
||||
}
|
||||
|
||||
@@ -28,8 +28,9 @@
|
||||
#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
|
||||
#define CD_STATUS_HOLD 8
|
||||
#define CD_STATUS_HAS_AUDIO 0xc
|
||||
#define CD_STATUS_MASK 0xf
|
||||
|
||||
/* Medium changed flag. */
|
||||
#define CD_STATUS_TRANSITION 0x40
|
||||
@@ -50,8 +51,6 @@
|
||||
|
||||
#define CD_IMAGE_HISTORY 10
|
||||
|
||||
#define BUF_SIZE 32768
|
||||
|
||||
#define CDROM_IMAGE 200
|
||||
|
||||
/* This is so that if/when this is changed to something else,
|
||||
@@ -63,6 +62,8 @@
|
||||
#define RAW_SECTOR_SIZE 2352
|
||||
#define COOKED_SECTOR_SIZE 2048
|
||||
|
||||
#define CD_BUF_SIZE (16 * RAW_SECTOR_SIZE)
|
||||
|
||||
#define DATA_TRACK 0x14
|
||||
#define AUDIO_TRACK 0x10
|
||||
|
||||
@@ -105,9 +106,9 @@ enum {
|
||||
#define CDV EMU_VERSION_EX
|
||||
|
||||
static const struct cdrom_drive_types_s {
|
||||
const char vendor[9];
|
||||
const char model[17];
|
||||
const char revision[5];
|
||||
const char * vendor;
|
||||
const char * model;
|
||||
const char * revision;
|
||||
const char * internal_name;
|
||||
const int bus_type;
|
||||
/* SCSI standard for SCSI (or both) devices, early for IDE. */
|
||||
@@ -298,9 +299,7 @@ typedef struct cdrom {
|
||||
void * priv;
|
||||
|
||||
char image_path[1024];
|
||||
char prev_image_path[1024];
|
||||
|
||||
char * image_history[CD_IMAGE_HISTORY];
|
||||
char prev_image_path[1280];
|
||||
|
||||
uint32_t sound_on;
|
||||
uint32_t cdrom_capacity;
|
||||
@@ -310,18 +309,21 @@ typedef struct cdrom {
|
||||
uint32_t type;
|
||||
uint32_t sector_size;
|
||||
|
||||
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;
|
||||
int32_t cached_sector;
|
||||
int32_t cd_buflen;
|
||||
int32_t sony_msf;
|
||||
int32_t real_speed;
|
||||
int32_t is_early;
|
||||
int32_t is_nec;
|
||||
int32_t is_bcd;
|
||||
|
||||
int32_t cdrom_sector_size;
|
||||
|
||||
const cdrom_ops_t *ops;
|
||||
|
||||
char * image_history[CD_IMAGE_HISTORY];
|
||||
|
||||
void * local;
|
||||
void * log;
|
||||
|
||||
@@ -330,24 +332,29 @@ typedef struct cdrom {
|
||||
uint32_t (*get_volume)(void *p, int channel);
|
||||
uint32_t (*get_channel)(void *p, int channel);
|
||||
|
||||
int16_t cd_buffer[BUF_SIZE];
|
||||
int16_t cd_buffer[CD_BUF_SIZE];
|
||||
|
||||
uint8_t subch_buffer[96];
|
||||
|
||||
int cdrom_sector_size;
|
||||
/* Needs some extra breathing space in case of overflows. */
|
||||
uint8_t raw_buffer[2][4096];
|
||||
uint8_t extra_buffer[296];
|
||||
|
||||
int32_t is_chinon;
|
||||
int32_t is_pioneer;
|
||||
int32_t is_plextor;
|
||||
int32_t is_sony;
|
||||
int32_t is_toshiba;
|
||||
|
||||
int32_t c2_first;
|
||||
int32_t cur_buf;
|
||||
|
||||
/* Only used on Windows hosts for disc change notifications. */
|
||||
uint8_t host_letter;
|
||||
|
||||
/* Needs some extra breathing space in case of overflows. */
|
||||
uint8_t raw_buffer[4096];
|
||||
uint8_t extra_buffer[296];
|
||||
} cdrom_t;
|
||||
|
||||
extern cdrom_t cdrom[CDROM_NUM];
|
||||
|
||||
/* 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 __inline int
|
||||
@@ -368,8 +375,6 @@ 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);
|
||||
@@ -386,6 +391,7 @@ extern void cdrom_set_type(const int model, const int type);
|
||||
extern int cdrom_get_type(const int model);
|
||||
|
||||
extern int cdrom_lba_to_msf_accurate(const int lba);
|
||||
extern void cdrom_interleave_subch(uint8_t *d, const uint8_t *s);
|
||||
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);
|
||||
@@ -398,7 +404,7 @@ extern uint8_t cdrom_audio_track_search(cdrom_t *dev, const uint32_t pos
|
||||
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 uint8_t cdrom_audio_scan(cdrom_t *dev, const uint32_t pos);
|
||||
extern void cdrom_audio_pause_resume(cdrom_t *dev, const uint8_t resume);
|
||||
|
||||
extern uint8_t cdrom_get_current_status(const cdrom_t *dev);
|
||||
@@ -426,6 +432,7 @@ extern int cdrom_read_dvd_structure(const cdrom_t *dev, const uint8_
|
||||
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(cdrom_t *dev, const uint8_t *cdb, uint8_t *buffer);
|
||||
extern uint8_t cdrom_get_current_mode(cdrom_t *dev);
|
||||
extern void cdrom_set_empty(cdrom_t *dev);
|
||||
extern void cdrom_update_status(cdrom_t *dev);
|
||||
extern int cdrom_load(cdrom_t *dev, const char *fn, const int skip_insert);
|
||||
|
||||
34
src/include/86box/crc.h
Normal file
34
src/include/86box/crc.h
Normal 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 the CRC code.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2025 Miran Grca.
|
||||
*/
|
||||
#ifndef EMU_CRC_H
|
||||
#define EMU_CRC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
uint16_t word;
|
||||
uint8_t bytes[2];
|
||||
} crc_t;
|
||||
|
||||
extern void crc16_setup(uint16_t *crc_table, uint16_t poly);
|
||||
extern void crc16_calc(uint16_t *crc_table, uint8_t byte, crc_t *crc_var);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*EMU_CRC_H*/
|
||||
@@ -8,15 +8,13 @@
|
||||
*
|
||||
* Definitions for the floppy drive emulation.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2018 Fred N. van Kempen.
|
||||
* Copyright 2008-2025 Sarah Walker.
|
||||
* Copyright 2016-2025 Miran Grca.
|
||||
* Copyright 2018-2025 Fred N. van Kempen.
|
||||
*/
|
||||
#ifndef EMU_FDD_H
|
||||
#define EMU_FDD_H
|
||||
@@ -129,13 +127,6 @@ extern int drive_empty[FDD_NUM];
|
||||
#define SECTOR_FIRST -2
|
||||
#define SECTOR_NEXT -1
|
||||
|
||||
typedef union {
|
||||
uint16_t word;
|
||||
uint8_t bytes[2];
|
||||
} crc_t;
|
||||
|
||||
void fdd_calccrc(uint8_t byte, crc_t *crc_var);
|
||||
|
||||
typedef struct d86f_handler_t {
|
||||
uint16_t (*disk_flags)(int drive);
|
||||
uint16_t (*side_flags)(int drive);
|
||||
|
||||
@@ -133,6 +133,8 @@ typedef struct ide_s {
|
||||
uint8_t (*phase_data_out)(scsi_common_t *sc);
|
||||
void (*command_stop)(scsi_common_t *sc);
|
||||
void (*bus_master_error)(scsi_common_t *sc);
|
||||
void (*read)(scsi_common_t *sc);
|
||||
void (*write)(scsi_common_t *sc);
|
||||
#else
|
||||
void * get_max;
|
||||
void * get_timings;
|
||||
|
||||
@@ -138,55 +138,63 @@ typedef struct hdd_zone_t {
|
||||
|
||||
/* Define the virtual Hard Disk. */
|
||||
typedef struct hard_disk_t {
|
||||
uint8_t id;
|
||||
uint8_t id;
|
||||
|
||||
union {
|
||||
uint8_t channel; /* Needed for Settings to reduce the number of if's */
|
||||
/* Needed for Settings to reduce the number of if's */
|
||||
uint8_t channel;
|
||||
|
||||
uint8_t mfm_channel; /* Should rename and/or unionize */
|
||||
uint8_t esdi_channel;
|
||||
uint8_t xta_channel;
|
||||
uint8_t ide_channel;
|
||||
uint8_t scsi_id;
|
||||
uint8_t mfm_channel;
|
||||
uint8_t esdi_channel;
|
||||
uint8_t xta_channel;
|
||||
uint8_t ide_channel;
|
||||
uint8_t scsi_id;
|
||||
};
|
||||
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 */
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
|
||||
void *priv;
|
||||
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 */
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
|
||||
char fn[1024]; /* Name of current image file */
|
||||
char vhd_parent[1041]; /* Differential VHD parent file */
|
||||
void * priv;
|
||||
|
||||
uint32_t seek_pos;
|
||||
uint32_t seek_len;
|
||||
uint32_t base;
|
||||
uint32_t spt;
|
||||
uint32_t hpc; /* Physical geometry parameters */
|
||||
uint32_t tracks;
|
||||
const char *model;
|
||||
char fn[1024]; /* Name of current image file */
|
||||
/* Differential VHD parent file */
|
||||
char vhd_parent[1280];
|
||||
|
||||
hdd_zone_t zones[HDD_MAX_ZONES];
|
||||
uint32_t num_zones;
|
||||
hdd_cache_t cache;
|
||||
uint32_t phy_cyl;
|
||||
uint32_t phy_heads;
|
||||
uint32_t rpm;
|
||||
uint8_t max_multiple_block;
|
||||
uint32_t seek_pos;
|
||||
uint32_t seek_len;
|
||||
uint32_t base;
|
||||
uint32_t spt; /* Physical geometry parameters */
|
||||
uint32_t hpc;
|
||||
uint32_t tracks;
|
||||
uint32_t speed_preset;
|
||||
|
||||
uint32_t cur_cylinder;
|
||||
uint32_t cur_track;
|
||||
uint32_t cur_addr;
|
||||
uint32_t num_zones;
|
||||
uint32_t phy_cyl;
|
||||
uint32_t phy_heads;
|
||||
uint32_t rpm;
|
||||
uint32_t cur_cylinder;
|
||||
uint32_t cur_track;
|
||||
uint32_t cur_addr;
|
||||
uint32_t vhd_blocksize;
|
||||
|
||||
uint32_t speed_preset;
|
||||
uint32_t vhd_blocksize;
|
||||
uint8_t max_multiple_block;
|
||||
uint8_t pad1[3];
|
||||
|
||||
double avg_rotation_lat_usec;
|
||||
double full_stroke_usec;
|
||||
double head_switch_usec;
|
||||
double cyl_switch_usec;
|
||||
const char * model;
|
||||
|
||||
hdd_zone_t zones[HDD_MAX_ZONES];
|
||||
|
||||
hdd_cache_t cache;
|
||||
|
||||
double avg_rotation_lat_usec;
|
||||
double full_stroke_usec;
|
||||
double head_switch_usec;
|
||||
double cyl_switch_usec;
|
||||
} hard_disk_t;
|
||||
|
||||
extern hard_disk_t hdd[HDD_NUM];
|
||||
|
||||
@@ -51,10 +51,10 @@ static const mo_type_t mo_types[KNOWN_MO_TYPES] = {
|
||||
};
|
||||
|
||||
typedef struct mo_drive_type_t {
|
||||
const char vendor[9];
|
||||
const char model[16];
|
||||
const char revision[5];
|
||||
int8_t supported_media[KNOWN_MO_TYPES];
|
||||
const char *vendor;
|
||||
const char *model;
|
||||
const char *revision;
|
||||
int8_t supported_media[KNOWN_MO_TYPES];
|
||||
} mo_drive_type_t;
|
||||
|
||||
#define KNOWN_MO_DRIVE_TYPES 22
|
||||
@@ -161,6 +161,7 @@ typedef struct mo_t {
|
||||
uint32_t sector_pos;
|
||||
uint32_t sector_len;
|
||||
uint32_t packet_len;
|
||||
uint32_t block_len;
|
||||
|
||||
double callback;
|
||||
|
||||
|
||||
@@ -54,18 +54,24 @@ typedef struct scsi_cdrom_t {
|
||||
int do_page_save;
|
||||
int unit_attention;
|
||||
int request_pos;
|
||||
int old_len;
|
||||
int media_status;
|
||||
int wait;
|
||||
int buffer_pos;
|
||||
|
||||
uint32_t sector_pos;
|
||||
uint32_t sector_len;
|
||||
uint32_t packet_len;
|
||||
uint32_t block_len;
|
||||
|
||||
double callback;
|
||||
|
||||
int is_sony;
|
||||
int use_cdb_9;
|
||||
uint8_t (*ven_cmd)(void *sc, const uint8_t *cdb, int32_t *BufLen);
|
||||
|
||||
int use_cdb_9;
|
||||
int was_cached;
|
||||
int toc_cached;
|
||||
int media_access;
|
||||
|
||||
uint8_t vendor_type;
|
||||
uint8_t ven_cmd_is_data[256];
|
||||
|
||||
mode_sense_pages_t ms_drive_status_pages_saved;
|
||||
@@ -74,8 +80,6 @@ typedef struct scsi_cdrom_t {
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -110,39 +110,40 @@
|
||||
#define GPCMD_MECHANISM_STATUS 0xbd
|
||||
#define GPCMD_READ_CD 0xbe
|
||||
#define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to 86Box. */
|
||||
#define GPCMD_EJECT_CHINON 0xc0 /* Chinon Vendor Unique command */
|
||||
#define GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA 0xc0 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_SET_ADDRESS_FORMAT_SONY 0xc0 /* Sony Vendor Unique command */
|
||||
#define GPCMD_EJECT_CHINON 0xc0 /* Chinon Vendor Unique command */
|
||||
#define GPCMD_MAGAZINE_EJECT_PIONEER 0xc0 /* Pioneer Vendor Unique command */
|
||||
#define GPCMD_SET_ADDRESS_FORMAT_SONY 0xc0 /* Sony Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_TOSHIBA 0xc1 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_READ_TOC_SONY 0xc1 /* Sony Vendor Unique command */
|
||||
#define GPCMD_READ_TOC_PIONEER 0xc1 /* Pioneer Vendor Unique command */
|
||||
#define GPCMD_READ_TOC_SONY 0xc1 /* Sony Vendor Unique command */
|
||||
#define GPCMD_PAUSE_RESUME_ALT 0xc2
|
||||
#define GPCMD_READ_SUBCHANNEL_MATSUSHITA 0xc2 /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_READ_SUBCODEQ_PIONEER 0xc2 /* Pioneer Vendor Unique command */
|
||||
#define GPCMD_READ_SUBCHANNEL_SONY 0xc2 /* Sony Vendor Unique command */
|
||||
#define GPCMD_STILL_TOSHIBA 0xc2 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_READ_SUBCODEQ_PIONEER 0xc2 /* Pioneer Vendor Unique command */
|
||||
#define GPCMD_READ_TOC_MATSUSHITA 0xc3 /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_READ_HEADER_SONY 0xc3 /* Sony Vendor Unique command */
|
||||
#define GPCMD_SET_STOP_TIME_TOSHIBA 0xc3 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_READ_HEADER_MATSUSHITA 0xc4 /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_PLAYBACK_STATUS_SONY 0xc4 /* Sony Vendor Unique command */
|
||||
#define GPCMD_CADDY_EJECT_TOSHIBA 0xc4 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_PLAYBACK_STATUS_SONY 0xc4 /* Sony Vendor Unique command */
|
||||
#define GPCMD_READ_HEADER_MATSUSHITA 0xc4 /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_PAUSE_SONY 0xc5 /* Sony Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_MATSUSHITA 0xc5 /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_UNKNOWN_SCSI2_NEC 0xc5 /* NEC Vendor Unique Command */
|
||||
#define GPCMD_STOP_CHINON 0xc6 /* Chinon Vendor Unique command */
|
||||
#define GPCMD_PLAY_TRACK_SONY 0xc6 /* Sony Vendor Unique command */
|
||||
#define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA 0xc6 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_STOP_CHINON 0xc6 /* Chinon Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_MSF_MATSUSHITA 0xc7 /* Matsushita Vendor Unique command*/
|
||||
#define GPCMD_PLAY_MSF_SONY 0xc7 /* Sony Vendor Unique command*/
|
||||
#define GPCMD_READ_DISC_INFORMATION_TOSHIBA 0xc7 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA 0xc8 /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_SONY 0xc8 /* Sony Vendor Unique command */
|
||||
#define GPCMD_AUDIO_TRACK_SEARCH_PIONEER 0xc8 /* Pioneer Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_SONY 0xc8 /* Sony Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA 0xc8 /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_READ_CDROM_MODE_TOSHIBA 0xc8 /* Toshiba Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_PIONEER 0xc9 /* Pioneer Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA 0xc9 /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_PLAYBACK_CONTROL_SONY 0xc9 /* Sony Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_PIONEER 0xc9 /* Pioneer Vendor Unique command */
|
||||
#define GPCMD_PAUSE_PIONEER 0xca /* Pioneer Vendor Unique command */
|
||||
#define GPCMD_PAUSE_RESUME_MATSUSHITA 0xcb /* Matsushita Vendor Unique command */
|
||||
#define GPCMD_STOP_PIONEER 0xcb /* Pioneer Vendor Unique command */
|
||||
@@ -151,8 +152,8 @@
|
||||
#define GPCMD_READ_CD_MSF_OLD 0xd5 /* Should be equivalent to 0xb9 */
|
||||
#define GPCMD_AUDIO_TRACK_SEARCH_NEC 0xd8 /* NEC Vendor Unique command */
|
||||
#define GPCMD_PLAY_AUDIO_NEC 0xd9 /* NEC Vendor Unique command */
|
||||
#define GPCMD_STILL_NEC 0xda /* NEC Vendor Unique command */
|
||||
#define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */
|
||||
#define GPCMD_STILL_NEC 0xda /* NEC Vendor Unique command */
|
||||
#define GPCMD_SET_STOP_TIME_NEC 0xdb /* NEC Vendor Unique command */
|
||||
#define GPCMD_CADDY_EJECT_NEC 0xdc /* NEC Vendor Unique command */
|
||||
#define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC 0xdd /* NEC Vendor Unique command */
|
||||
@@ -409,12 +410,13 @@ typedef struct scsi_common_s {
|
||||
int do_page_save;
|
||||
int unit_attention;
|
||||
int request_pos;
|
||||
int old_len;
|
||||
int media_status;
|
||||
int wait;
|
||||
int buffer_pos;
|
||||
|
||||
uint32_t sector_pos;
|
||||
uint32_t sector_len;
|
||||
uint32_t packet_len;
|
||||
uint32_t block_len;
|
||||
|
||||
double callback;
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ typedef struct scsi_disk_t {
|
||||
uint32_t sector_pos;
|
||||
uint32_t sector_len;
|
||||
uint32_t packet_len;
|
||||
uint32_t block_len;
|
||||
|
||||
double callback;
|
||||
|
||||
|
||||
@@ -108,6 +108,7 @@ typedef struct zip_t {
|
||||
uint32_t sector_pos;
|
||||
uint32_t sector_len;
|
||||
uint32_t packet_len;
|
||||
uint32_t block_len;
|
||||
|
||||
double callback;
|
||||
|
||||
|
||||
@@ -43,9 +43,6 @@ typedef struct ioctl_t {
|
||||
void *log;
|
||||
int is_dvd;
|
||||
int has_audio;
|
||||
int32_t tracks_num;
|
||||
uint8_t cur_toc[65536];
|
||||
CDROM_READ_TOC_EX cur_read_toc_ex;
|
||||
int blocks_num;
|
||||
uint8_t cur_rti[65536];
|
||||
HANDLE handle;
|
||||
@@ -91,37 +88,50 @@ ioctl_open_handle(ioctl_t *ioctl)
|
||||
ioctl_log(ioctl->log, "handle=%p, error=%x\n",
|
||||
ioctl->handle, (unsigned int) GetLastError());
|
||||
|
||||
if (ioctl->handle != INVALID_HANDLE_VALUE) {
|
||||
CDROM_SET_SPEED set_speed = { 0 };
|
||||
|
||||
set_speed.RequestType = CdromSetSpeed;
|
||||
set_speed.ReadSpeed = 0xffff;
|
||||
set_speed.WriteSpeed = 0xffff;
|
||||
set_speed.RotationControl = CdromDefaultRotation;
|
||||
|
||||
(void) DeviceIoControl(ioctl->handle, IOCTL_CDROM_SET_SPEED,
|
||||
&set_speed, sizeof(set_speed),
|
||||
NULL, 0,
|
||||
0, NULL);
|
||||
}
|
||||
|
||||
return (ioctl->handle != INVALID_HANDLE_VALUE);
|
||||
}
|
||||
|
||||
static int
|
||||
ioctl_read_normal_toc(ioctl_t *ioctl, uint8_t *toc_buf)
|
||||
ioctl_read_normal_toc(ioctl_t *ioctl, uint8_t *toc_buf, int32_t *tracks_num)
|
||||
{
|
||||
long size = 0;
|
||||
PCDROM_TOC_FULL_TOC_DATA cur_full_toc = NULL;
|
||||
long size = 0;
|
||||
PCDROM_TOC_FULL_TOC_DATA cur_full_toc = NULL;
|
||||
CDROM_READ_TOC_EX cur_read_toc_ex = { 0 };
|
||||
|
||||
ioctl->tracks_num = 0;
|
||||
*tracks_num = 0;
|
||||
memset(toc_buf, 0x00, 65536);
|
||||
|
||||
cur_full_toc = (PCDROM_TOC_FULL_TOC_DATA) calloc(1, 65536);
|
||||
|
||||
ioctl->cur_read_toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_TOC;
|
||||
ioctl_log(ioctl->log, "cur_read_toc_ex.Format = %i\n", ioctl->cur_read_toc_ex.Format);
|
||||
ioctl->cur_read_toc_ex.Msf = 1;
|
||||
ioctl->cur_read_toc_ex.SessionTrack = 1;
|
||||
cur_read_toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_TOC;
|
||||
ioctl_log(ioctl->log, "cur_read_toc_ex.Format = %i\n", cur_read_toc_ex.Format);
|
||||
cur_read_toc_ex.Msf = 1;
|
||||
cur_read_toc_ex.SessionTrack = 1;
|
||||
|
||||
ioctl_open_handle(ioctl);
|
||||
const int temp = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX,
|
||||
&ioctl->cur_read_toc_ex, 65535,
|
||||
cur_full_toc, 65535,
|
||||
&cur_read_toc_ex, sizeof(CDROM_READ_TOC_EX),
|
||||
cur_full_toc, 65535,
|
||||
(LPDWORD) &size, NULL);
|
||||
ioctl_close_handle(ioctl);
|
||||
ioctl_log(ioctl->log, "temp = %i\n", temp);
|
||||
|
||||
if (temp != 0) {
|
||||
const int length = ((cur_full_toc->Length[0] << 8) | cur_full_toc->Length[1]) + 2;
|
||||
memcpy(toc_buf, cur_full_toc, length);
|
||||
ioctl->tracks_num = (length - 4) / 8;
|
||||
*tracks_num = (length - 4) / 8;
|
||||
}
|
||||
|
||||
free(cur_full_toc);
|
||||
@@ -130,9 +140,9 @@ ioctl_read_normal_toc(ioctl_t *ioctl, uint8_t *toc_buf)
|
||||
PCDROM_TOC toc = (PCDROM_TOC) toc_buf;
|
||||
|
||||
ioctl_log(ioctl->log, "%i tracks: %02X %02X %02X %02X\n",
|
||||
ioctl->tracks_num, toc_buf[0], toc_buf[1], toc_buf[2], toc_buf[3]);
|
||||
*tracks_num, toc_buf[0], toc_buf[1], toc_buf[2], toc_buf[3]);
|
||||
|
||||
for (int i = 0; i < ioctl->tracks_num; i++) {
|
||||
for (int i = 0; i < *tracks_num; i++) {
|
||||
const uint8_t *t = (const uint8_t *) &toc->TrackData[i];
|
||||
ioctl_log(ioctl->log, "Track %03i: %02X %02X %02X %02X %02X %02X %02X %02X\n",
|
||||
i, t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7]);
|
||||
@@ -145,10 +155,12 @@ ioctl_read_normal_toc(ioctl_t *ioctl, uint8_t *toc_buf)
|
||||
static void
|
||||
ioctl_read_raw_toc(ioctl_t *ioctl)
|
||||
{
|
||||
PCDROM_TOC_FULL_TOC_DATA cur_full_toc = NULL;
|
||||
long size = 0;
|
||||
raw_track_info_t *rti = (raw_track_info_t *) ioctl->cur_rti;
|
||||
uint8_t *buffer = (uint8_t *) calloc (1, 2052);
|
||||
PCDROM_TOC_FULL_TOC_DATA cur_full_toc = NULL;
|
||||
long size = 0;
|
||||
raw_track_info_t *rti = (raw_track_info_t *) ioctl->cur_rti;
|
||||
uint8_t *buffer = (uint8_t *) calloc (1, 2052);
|
||||
int status = 0;
|
||||
CDROM_READ_TOC_EX cur_read_toc_ex = { 0 };
|
||||
|
||||
ioctl->is_dvd = (ioctl_read_dvd_structure(ioctl, 0, 0, buffer, NULL) > 0);
|
||||
free(buffer);
|
||||
@@ -159,65 +171,75 @@ ioctl_read_raw_toc(ioctl_t *ioctl)
|
||||
|
||||
cur_full_toc = (PCDROM_TOC_FULL_TOC_DATA) calloc(1, 65536);
|
||||
|
||||
ioctl->cur_read_toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC;
|
||||
ioctl_log(ioctl->log, "cur_read_toc_ex.Format = %i\n", ioctl->cur_read_toc_ex.Format);
|
||||
ioctl->cur_read_toc_ex.Msf = 1;
|
||||
ioctl->cur_read_toc_ex.SessionTrack = 1;
|
||||
cur_read_toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC;
|
||||
ioctl_log(ioctl->log, "cur_read_toc_ex.Format = %i\n", cur_read_toc_ex.Format);
|
||||
cur_read_toc_ex.Msf = 1;
|
||||
cur_read_toc_ex.SessionTrack = 1;
|
||||
|
||||
ioctl_open_handle(ioctl);
|
||||
const int status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX,
|
||||
&ioctl->cur_read_toc_ex, 65535,
|
||||
cur_full_toc, 65535,
|
||||
(LPDWORD) &size, NULL);
|
||||
ioctl_close_handle(ioctl);
|
||||
ioctl_log(ioctl->log, "status = %i\n", status);
|
||||
if (!ioctl->is_dvd) {
|
||||
status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX,
|
||||
&cur_read_toc_ex, sizeof(CDROM_READ_TOC_EX),
|
||||
cur_full_toc, 65535,
|
||||
(LPDWORD) &size, NULL);
|
||||
ioctl_log(ioctl->log, "status = %i\n", status);
|
||||
}
|
||||
|
||||
if ((status == 0) && (ioctl->tracks_num >= 1)) {
|
||||
if (status == 0) {
|
||||
/*
|
||||
This is needed because in some circumstances (eg. a DVD .MDS
|
||||
mounted in Daemon Tools), reading the raw TOC fails but
|
||||
reading the cooked TOC does not, so we have to construct the
|
||||
raw TOC from the cooked TOC.
|
||||
*/
|
||||
const CDROM_TOC *toc = (const CDROM_TOC *) ioctl->cur_toc;
|
||||
const TRACK_DATA *ct = &(toc->TrackData[ioctl->tracks_num - 1]);
|
||||
uint8_t cur_toc[65536] = { 0 };
|
||||
int32_t tracks_num = 0;
|
||||
|
||||
rti[0].adr_ctl = ((ct->Adr & 0xf) << 4) | (ct->Control & 0xf);
|
||||
rti[0].point = 0xa0;
|
||||
rti[0].pm = toc->FirstTrack;
|
||||
const CDROM_TOC * toc = (const CDROM_TOC *) cur_toc;
|
||||
|
||||
rti[1].adr_ctl = rti[0].adr_ctl;
|
||||
rti[1].point = 0xa1;
|
||||
rti[1].pm = toc->LastTrack;
|
||||
status = ioctl_read_normal_toc(ioctl, cur_toc, &tracks_num);
|
||||
|
||||
rti[2].adr_ctl = rti[0].adr_ctl;
|
||||
rti[2].point = 0xa2;
|
||||
rti[2].pm = ct->Address[1];
|
||||
rti[2].ps = ct->Address[2];
|
||||
rti[2].pf = ct->Address[3];
|
||||
const TRACK_DATA *ct = &(toc->TrackData[tracks_num - 1]);
|
||||
|
||||
ioctl->blocks_num = 3;
|
||||
if ((status > 0) && (tracks_num >= 1)) {
|
||||
rti[0].adr_ctl = ((ct->Adr & 0xf) << 4) | (ct->Control & 0xf);
|
||||
rti[0].point = 0xa0;
|
||||
rti[0].pm = toc->FirstTrack;
|
||||
|
||||
for (int i = 0; i < (ioctl->tracks_num - 1); i++) {
|
||||
raw_track_info_t *crt = &(rti[ioctl->blocks_num]);
|
||||
rti[1].adr_ctl = rti[0].adr_ctl;
|
||||
rti[1].point = 0xa1;
|
||||
rti[1].pm = toc->LastTrack;
|
||||
|
||||
ct = &(toc->TrackData[i]);
|
||||
rti[2].adr_ctl = rti[0].adr_ctl;
|
||||
rti[2].point = 0xa2;
|
||||
rti[2].pm = ct->Address[1];
|
||||
rti[2].ps = ct->Address[2];
|
||||
rti[2].pf = ct->Address[3];
|
||||
|
||||
crt->adr_ctl = ((ct->Adr & 0xf) << 4) | (ct->Control & 0xf);
|
||||
crt->point = ct->TrackNumber;
|
||||
crt->pm = ct->Address[1];
|
||||
crt->ps = ct->Address[2];
|
||||
crt->pf = ct->Address[3];
|
||||
ioctl->blocks_num = 3;
|
||||
|
||||
ioctl->blocks_num++;
|
||||
}
|
||||
for (int i = 0; i < (tracks_num - 1); i++) {
|
||||
raw_track_info_t *crt = &(rti[ioctl->blocks_num]);
|
||||
|
||||
ct = &(toc->TrackData[i]);
|
||||
|
||||
crt->adr_ctl = ((ct->Adr & 0xf) << 4) | (ct->Control & 0xf);
|
||||
crt->point = ct->TrackNumber;
|
||||
crt->pm = ct->Address[1];
|
||||
crt->ps = ct->Address[2];
|
||||
crt->pf = ct->Address[3];
|
||||
|
||||
ioctl->blocks_num++;
|
||||
}
|
||||
} else if (status > 0)
|
||||
/* Announce that we've had a failure. */
|
||||
status = 0;
|
||||
} else if (status != 0) {
|
||||
ioctl->blocks_num = (((cur_full_toc->Length[0] << 8) |
|
||||
cur_full_toc->Length[1]) - 2) / 11;
|
||||
memcpy(ioctl->cur_rti, cur_full_toc->Descriptors, ioctl->blocks_num * 11);
|
||||
}
|
||||
|
||||
if (ioctl->blocks_num) for (int i = 0; i < ioctl->tracks_num; i++) {
|
||||
if (ioctl->blocks_num) for (int i = 0; i < ioctl->blocks_num; i++) {
|
||||
const raw_track_info_t *crt = &(rti[i]);
|
||||
|
||||
if ((crt->point >= 1) && (crt->point <= 99) && !(crt->adr_ctl & 0x04)) {
|
||||
@@ -244,13 +266,6 @@ ioctl_read_raw_toc(ioctl_t *ioctl)
|
||||
free(cur_full_toc);
|
||||
}
|
||||
|
||||
static void
|
||||
ioctl_read_toc(ioctl_t *ioctl)
|
||||
{
|
||||
(void) ioctl_read_normal_toc(ioctl, ioctl->cur_toc);
|
||||
ioctl_read_raw_toc(ioctl);
|
||||
}
|
||||
|
||||
static int
|
||||
ioctl_get_track(const ioctl_t *ioctl, const uint32_t sector) {
|
||||
raw_track_info_t *rti = (raw_track_info_t *) ioctl->cur_rti;
|
||||
@@ -296,23 +311,28 @@ static int
|
||||
ioctl_get_track_info(const void *local, const uint32_t track,
|
||||
int end, track_info_t *ti)
|
||||
{
|
||||
const ioctl_t * ioctl = (const ioctl_t *) local;
|
||||
const CDROM_TOC *toc = (const CDROM_TOC *) ioctl->cur_toc;
|
||||
int ret = 1;
|
||||
const ioctl_t * ioctl = (const ioctl_t *) local;
|
||||
const raw_track_info_t *rti = (const raw_track_info_t *) ioctl->cur_rti;
|
||||
int ret = 1;
|
||||
int trk = -1;
|
||||
|
||||
if ((track < 1) || (track == 0xaa) || (track > (toc->LastTrack + 1))) {
|
||||
if ((track >= 1) && (track < 99))
|
||||
for (int i = 0; i < ioctl->blocks_num; i++)
|
||||
if (rti[i].point == track) {
|
||||
trk = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((track == 0xaa) || (trk == -1)) {
|
||||
ioctl_log(ioctl->log, "ioctl_get_track_info(%02i)\n", track);
|
||||
ret = 0;
|
||||
} else {
|
||||
const TRACK_DATA * td = &toc->TrackData[track - 1];
|
||||
ti->m = rti[trk].pm;
|
||||
ti->s = rti[trk].ps;
|
||||
ti->f = rti[trk].pf;
|
||||
|
||||
ti->m = td->Address[1];
|
||||
ti->s = td->Address[2];
|
||||
ti->f = td->Address[3];
|
||||
|
||||
ti->number = td->TrackNumber;
|
||||
ti->attr = td->Control;
|
||||
ti->attr |= ((td->Adr << 4) & 0xf0);
|
||||
ti->number = rti[trk].point;
|
||||
ti->attr = rti[trk].adr_ctl;
|
||||
|
||||
ioctl_log(ioctl->log, "ioctl_get_track_info(%02i): %02i:%02i:%02i, %02i, %02X\n",
|
||||
track, ti->m, ti->s, ti->f, ti->number, ti->attr);
|
||||
@@ -370,8 +390,6 @@ ioctl_read_sector(const void *local, uint8_t *buffer, uint32_t const sector)
|
||||
int ret;
|
||||
SCSI_PASS_THROUGH_DIRECT_BUF req;
|
||||
|
||||
ioctl_open_handle((ioctl_t *) ioctl);
|
||||
|
||||
if (ioctl->is_dvd) {
|
||||
int track;
|
||||
|
||||
@@ -503,8 +521,6 @@ ioctl_read_sector(const void *local, uint8_t *buffer, uint32_t const sector)
|
||||
for (int j = 7; j >= 0; j--)
|
||||
buffer[2352 + (i * 8) + j] = ((buffer[sc_offs + i] >> (7 - j)) & 0x01) << 6;
|
||||
|
||||
ioctl_close_handle((ioctl_t *) ioctl);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -540,18 +556,15 @@ ioctl_get_track_type(const void *local, const uint32_t sector)
|
||||
static uint32_t
|
||||
ioctl_get_last_block(const void *local)
|
||||
{
|
||||
const ioctl_t *ioctl = (const ioctl_t *) local;
|
||||
const CDROM_TOC *toc = (const CDROM_TOC *) ioctl->cur_toc;
|
||||
const ioctl_t * ioctl = (const ioctl_t *) local;
|
||||
raw_track_info_t *rti = (raw_track_info_t *) ioctl->cur_rti;
|
||||
uint32_t lb = 0;
|
||||
|
||||
for (int c = 0; c <= toc->LastTrack; c++) {
|
||||
const TRACK_DATA *td = &toc->TrackData[c];
|
||||
const uint32_t address = MSFtoLBA(td->Address[1], td->Address[2],
|
||||
td->Address[3]) - 150;
|
||||
|
||||
if (address > lb)
|
||||
lb = address;
|
||||
}
|
||||
for (int i = (ioctl->blocks_num - 1); i >= 0; i--)
|
||||
if (rti[i].point == 0xa2) {
|
||||
lb = MSFtoLBA(rti[i].pm, rti[i].ps, rti[i].pf) - 151;
|
||||
break;
|
||||
}
|
||||
|
||||
ioctl_log(ioctl->log, "LBCapacity=%d\n", lb);
|
||||
|
||||
@@ -573,8 +586,6 @@ ioctl_read_dvd_structure(const void *local, const uint8_t layer, const uint8_t f
|
||||
const int len = 2052;
|
||||
SCSI_PASS_THROUGH_DIRECT_BUF req;
|
||||
|
||||
ioctl_open_handle((ioctl_t *) ioctl);
|
||||
|
||||
memset(&req, 0x00, sizeof(SCSI_PASS_THROUGH_DIRECT_BUF));
|
||||
req.spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
|
||||
req.spt.PathId = 0;
|
||||
@@ -636,8 +647,6 @@ ioctl_read_dvd_structure(const void *local, const uint8_t layer, const uint8_t f
|
||||
} else
|
||||
ret = ret ? (req.spt.DataTransferLength >= len) : 0;
|
||||
|
||||
ioctl_close_handle((ioctl_t *) ioctl);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -670,8 +679,6 @@ ioctl_is_empty(const void *local)
|
||||
unsigned long int unused = 0;
|
||||
SCSI_PASS_THROUGH_DIRECT_BUF req;
|
||||
|
||||
ioctl_open_handle((ioctl_t *) ioctl);
|
||||
|
||||
memset(&req, 0x00, sizeof(SCSI_PASS_THROUGH_DIRECT_BUF));
|
||||
req.spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
|
||||
req.spt.PathId = 0;
|
||||
@@ -731,8 +738,6 @@ ioctl_is_empty(const void *local)
|
||||
} else
|
||||
ret = 0;
|
||||
|
||||
ioctl_close_handle((ioctl_t *) ioctl);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -760,14 +765,13 @@ ioctl_load(const void *local)
|
||||
{
|
||||
const ioctl_t *ioctl = (const ioctl_t *) local;
|
||||
|
||||
if (ioctl_open_handle((ioctl_t *) ioctl)) {
|
||||
long size;
|
||||
DeviceIoControl(ioctl->handle, IOCTL_STORAGE_LOAD_MEDIA,
|
||||
NULL, 0, NULL, 0,
|
||||
(LPDWORD) &size, NULL);
|
||||
ioctl_close_handle((ioctl_t *) ioctl);
|
||||
if ((ioctl->handle != NULL) || ioctl_open_handle((ioctl_t *) ioctl)) {
|
||||
long size = 0;
|
||||
(void) DeviceIoControl(ioctl->handle, IOCTL_STORAGE_LOAD_MEDIA,
|
||||
NULL, 0, NULL, 0,
|
||||
(LPDWORD) &size, NULL);
|
||||
|
||||
ioctl_read_toc((ioctl_t *) ioctl);
|
||||
ioctl_read_raw_toc((ioctl_t *) ioctl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -274,83 +274,89 @@ sound_cd_thread(UNUSED(void *param))
|
||||
temp_buffer[0] = temp_buffer[1] = 0;
|
||||
|
||||
for (uint8_t i = 0; i < CDROM_NUM; i++) {
|
||||
if ((cdrom[i].bus_type == CDROM_BUS_DISABLED) || (cdrom[i].cd_status == CD_STATUS_EMPTY))
|
||||
/* Just in case the thread is in a loop when it gets terminated. */
|
||||
if (!cdaudioon)
|
||||
break;
|
||||
|
||||
if ((cdrom[i].bus_type == CDROM_BUS_DISABLED) ||
|
||||
(cdrom[i].cd_status != CD_STATUS_PLAYING))
|
||||
continue;
|
||||
const uint32_t lba = cdrom[i].seek_pos;
|
||||
const int r = cdrom_audio_callback(&(cdrom[i]), cd_buffer[i], CD_BUFLEN * 2);
|
||||
if (!cdrom[i].sound_on || !r)
|
||||
continue;
|
||||
const int pre = cdrom_is_pre(&(cdrom[i]), lba);
|
||||
const int ret = cdrom_audio_callback(&(cdrom[i]), cd_buffer[i],
|
||||
CD_BUFLEN * 2);
|
||||
|
||||
|
||||
if (cdrom[i].get_volume) {
|
||||
audio_vol_l = cd_audio_volume_lut[cdrom[i].get_volume(cdrom[i].priv, 0)];
|
||||
audio_vol_r = cd_audio_volume_lut[cdrom[i].get_volume(cdrom[i].priv, 1)];
|
||||
} else {
|
||||
audio_vol_l = cd_audio_volume_lut[255];
|
||||
audio_vol_r = cd_audio_volume_lut[255];
|
||||
}
|
||||
|
||||
if (cdrom[i].get_channel) {
|
||||
channel_select[0] = (int) cdrom[i].get_channel(cdrom[i].priv, 0);
|
||||
channel_select[1] = (int) cdrom[i].get_channel(cdrom[i].priv, 1);
|
||||
} else {
|
||||
channel_select[0] = 1;
|
||||
channel_select[1] = 2;
|
||||
}
|
||||
|
||||
for (int c = 0; c < CD_BUFLEN * 2; c += 2) {
|
||||
/*Apply ATAPI channel select*/
|
||||
cd_buffer_temp[0] = cd_buffer_temp[1] = 0.0;
|
||||
|
||||
if ((audio_vol_l != 0.0) && (channel_select[0] != 0)) {
|
||||
if (channel_select[0] & 1)
|
||||
cd_buffer_temp[0] += ((double) cd_buffer[i][c]); /* Channel 0 => Port 0 */
|
||||
if (channel_select[0] & 2)
|
||||
cd_buffer_temp[0] += ((double) cd_buffer[i][c + 1]); /* Channel 1 => Port 0 */
|
||||
|
||||
cd_buffer_temp[0] *= audio_vol_l; /* Multiply Port 0 by Port 0 volume */
|
||||
|
||||
if (pre)
|
||||
cd_buffer_temp[0] = deemph_iir(0, cd_buffer_temp[0]); /* De-emphasize if necessary */
|
||||
}
|
||||
|
||||
if ((audio_vol_r != 0.0) && (channel_select[1] != 0)) {
|
||||
if (channel_select[1] & 1)
|
||||
cd_buffer_temp[1] += ((double) cd_buffer[i][c]); /* Channel 0 => Port 1 */
|
||||
if (channel_select[1] & 2)
|
||||
cd_buffer_temp[1] += ((double) cd_buffer[i][c + 1]); /* Channel 1 => Port 1 */
|
||||
|
||||
cd_buffer_temp[1] *= audio_vol_r; /* Multiply Port 1 by Port 1 volume */
|
||||
|
||||
if (pre)
|
||||
cd_buffer_temp[1] = deemph_iir(1, cd_buffer_temp[1]); /* De-emphasize if necessary */
|
||||
}
|
||||
|
||||
/* Apply sound card CD volume and filters */
|
||||
if (filter_cd_audio != NULL) {
|
||||
filter_cd_audio(0, &(cd_buffer_temp[0]), filter_cd_audio_p);
|
||||
filter_cd_audio(1, &(cd_buffer_temp[1]), filter_cd_audio_p);
|
||||
}
|
||||
|
||||
if (sound_is_float) {
|
||||
cd_out_buffer[c] += (float) (cd_buffer_temp[0] / 32768.0);
|
||||
cd_out_buffer[c + 1] += (float) (cd_buffer_temp[1] / 32768.0);
|
||||
if (ret) {
|
||||
if (cdrom[i].get_volume) {
|
||||
audio_vol_l = cd_audio_volume_lut[cdrom[i].get_volume(cdrom[i].priv, 0)];
|
||||
audio_vol_r = cd_audio_volume_lut[cdrom[i].get_volume(cdrom[i].priv, 1)];
|
||||
} else {
|
||||
temp_buffer[0] += (int) trunc(cd_buffer_temp[0]);
|
||||
temp_buffer[1] += (int) trunc(cd_buffer_temp[1]);
|
||||
audio_vol_l = cd_audio_volume_lut[255];
|
||||
audio_vol_r = cd_audio_volume_lut[255];
|
||||
}
|
||||
|
||||
if (temp_buffer[0] > 32767)
|
||||
temp_buffer[0] = 32767;
|
||||
if (temp_buffer[0] < -32768)
|
||||
temp_buffer[0] = -32768;
|
||||
if (temp_buffer[1] > 32767)
|
||||
temp_buffer[1] = 32767;
|
||||
if (temp_buffer[1] < -32768)
|
||||
temp_buffer[1] = -32768;
|
||||
if (cdrom[i].get_channel) {
|
||||
channel_select[0] = (int) cdrom[i].get_channel(cdrom[i].priv, 0);
|
||||
channel_select[1] = (int) cdrom[i].get_channel(cdrom[i].priv, 1);
|
||||
} else {
|
||||
channel_select[0] = 1;
|
||||
channel_select[1] = 2;
|
||||
}
|
||||
|
||||
cd_out_buffer_int16[c] = (int16_t) temp_buffer[0];
|
||||
cd_out_buffer_int16[c + 1] = (int16_t) temp_buffer[1];
|
||||
// uint16_t *cddab = (uint16_t *) cdrom[i].raw_buffer;
|
||||
for (int c = 0; c < CD_BUFLEN * 2; c += 2) {
|
||||
/* Apply ATAPI channel select */
|
||||
cd_buffer_temp[0] = cd_buffer_temp[1] = 0.0;
|
||||
|
||||
if ((audio_vol_l != 0.0) && (channel_select[0] != 0)) {
|
||||
if (channel_select[0] & 1)
|
||||
/* Channel 0 => Port 0 */
|
||||
cd_buffer_temp[0] += ((double) cd_buffer[i][c]);
|
||||
if (channel_select[0] & 2)
|
||||
/* Channel 1 => Port 0 */
|
||||
cd_buffer_temp[0] += ((double) cd_buffer[i][c + 1]);
|
||||
|
||||
/* Multiply Port 0 by Port 0 volume */
|
||||
cd_buffer_temp[0] *= audio_vol_l;
|
||||
}
|
||||
|
||||
if ((audio_vol_r != 0.0) && (channel_select[1] != 0)) {
|
||||
if (channel_select[1] & 1)
|
||||
/* Channel 0 => Port 1 */
|
||||
cd_buffer_temp[1] += ((double) cd_buffer[i][c]);
|
||||
if (channel_select[1] & 2)
|
||||
/* Channel 1 => Port 1 */
|
||||
cd_buffer_temp[1] += ((double) cd_buffer[i][c + 1]);
|
||||
|
||||
/* Multiply Port 1 by Port 1 volume */
|
||||
cd_buffer_temp[1] *= audio_vol_r;
|
||||
}
|
||||
|
||||
/* Apply sound card CD volume and filters */
|
||||
if (filter_cd_audio != NULL) {
|
||||
filter_cd_audio(0, &(cd_buffer_temp[0]),
|
||||
filter_cd_audio_p);
|
||||
filter_cd_audio(1, &(cd_buffer_temp[1]),
|
||||
filter_cd_audio_p);
|
||||
}
|
||||
|
||||
if (sound_is_float) {
|
||||
cd_out_buffer[c] += (float) (cd_buffer_temp[0] / 32768.0);
|
||||
cd_out_buffer[c + 1] += (float) (cd_buffer_temp[1] / 32768.0);
|
||||
} else {
|
||||
temp_buffer[0] = (int) trunc(cd_buffer_temp[0]);
|
||||
temp_buffer[1] = (int) trunc(cd_buffer_temp[1]);
|
||||
|
||||
if (temp_buffer[0] > 32767)
|
||||
temp_buffer[0] = 32767;
|
||||
if (temp_buffer[0] < -32768)
|
||||
temp_buffer[0] = -32768;
|
||||
if (temp_buffer[1] > 32767)
|
||||
temp_buffer[1] = 32767;
|
||||
if (temp_buffer[1] < -32768)
|
||||
temp_buffer[1] = -32768;
|
||||
|
||||
cd_out_buffer_int16[c] += (int16_t) temp_buffer[0];
|
||||
cd_out_buffer_int16[c + 1] += (int16_t) temp_buffer[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
26
src/utils/CMakeLists.txt
Normal file
26
src/utils/CMakeLists.txt
Normal 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.
|
||||
#
|
||||
# CMake build script.
|
||||
#
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
# Jasmine Iwanek, <jriwanek@gmail.com>
|
||||
#
|
||||
# Copyright 2020-2021 David Hrdlička.
|
||||
# Copyright 2024 Jasmine Iwanek.
|
||||
#
|
||||
|
||||
add_library(utils OBJECT
|
||||
cJSON.c
|
||||
crc.c
|
||||
fifo.c
|
||||
fifo8.c
|
||||
ini.c
|
||||
log.c
|
||||
random.c
|
||||
)
|
||||
77
src/utils/crc.c
Normal file
77
src/utils/crc.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* CRC implementation.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2025 Miran Grca.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/random.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/ui.h>
|
||||
#include <86box/crc.h>
|
||||
|
||||
#ifdef ENABLE_CRC_LOG
|
||||
int d86f_do_log = ENABLE_CRC_LOG;
|
||||
|
||||
static void
|
||||
crc_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (crc_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define crc_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
void
|
||||
crc16_setup(uint16_t *crc_table, uint16_t poly)
|
||||
{
|
||||
int c = 256;
|
||||
int bc;
|
||||
uint16_t temp;
|
||||
|
||||
while (c--) {
|
||||
temp = c << 8;
|
||||
bc = 8;
|
||||
|
||||
while (bc--) {
|
||||
if (temp & 0x8000)
|
||||
temp = (temp << 1) ^ poly;
|
||||
else
|
||||
temp <<= 1;
|
||||
|
||||
crc_table[c] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
crc16_calc(uint16_t *crc_table, uint8_t byte, crc_t *crc_var)
|
||||
{
|
||||
crc_var->word = (crc_var->word << 8) ^
|
||||
crc_table[(crc_var->word >> 8) ^ byte];
|
||||
}
|
||||
Reference in New Issue
Block a user