Implement timer for reads from CD-ROM

This commit is contained in:
Cacodemon345
2025-07-27 02:17:55 +06:00
parent bc1b5f63bc
commit 7392f81536

View File

@@ -34,8 +34,10 @@
#include <86box/cdrom_interface.h> #include <86box/cdrom_interface.h>
#include <86box/cdrom_mke.h> #include <86box/cdrom_mke.h>
#include <86box/plat.h> #include <86box/plat.h>
#include <86box/ui.h>
#include <86box/sound.h> #include <86box/sound.h>
#include <86box/fifo8.h> #include <86box/fifo8.h>
#include <86box/timer.h>
/* /*
https://elixir.bootlin.com/linux/2.0.29/source/include/linux/sbpcd.h https://elixir.bootlin.com/linux/2.0.29/source/include/linux/sbpcd.h
@@ -110,7 +112,11 @@ typedef struct mke_t {
uint32_t unit_attention; uint32_t unit_attention;
uint8_t cdbuffer[624240]; uint8_t cdbuffer[624240 * 2];
uint32_t data_to_push;
pc_timer_t timer;
} mke_t; } mke_t;
mke_t mke; mke_t mke;
@@ -255,6 +261,7 @@ static void
mke_reset(void) mke_reset(void)
{ {
cdrom_stop(mke.cdrom_dev); cdrom_stop(mke.cdrom_dev);
timer_disable(&mke.timer);
mke.sector_type = 0x08 | (1 << 4); mke.sector_type = 0x08 | (1 << 4);
mke.sector_flags = 0x10; mke.sector_flags = 0x10;
memset(mke.mode_select, 0, 5); memset(mke.mode_select, 0, 5);
@@ -266,6 +273,24 @@ mke_reset(void)
mke.cdrom_dev->sector_size = 2048; mke.cdrom_dev->sector_size = 2048;
} }
void
mke_command_callback(void* priv)
{
switch (mke.command_buffer[0]) {
case CMD1_SEEK: {
fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke));
break;
}
case CMD1_READ: {
fifo8_push_all(&mke.data_fifo, mke.cdbuffer, mke.data_to_push);
fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke));
mke.data_to_push = 0;
ui_sb_update_icon(SB_CDROM | mke.cdrom_dev->id, 0);
break;
}
}
}
void void
mke_command(uint8_t value) mke_command(uint8_t value)
{ {
@@ -283,6 +308,8 @@ mke_command(uint8_t value)
mke_log("CMD_ABORT\n"); mke_log("CMD_ABORT\n");
// fifo8_reset(&mke.info_fifo); // fifo8_reset(&mke.info_fifo);
fifo8_reset(&mke.info_fifo); fifo8_reset(&mke.info_fifo);
fifo8_reset(&mke.data_fifo);
timer_disable(&mke.timer);
mke.command_buffer[0] = 0; mke.command_buffer[0] = 0;
mke.command_buffer_pending = 7; mke.command_buffer_pending = 7;
// fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); // fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke));
@@ -322,11 +349,13 @@ mke_command(uint8_t value)
int error = 0; int error = 0;
uint64_t lba = MSFtoLBA(mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3]) - 150; uint64_t lba = MSFtoLBA(mke.command_buffer[1], mke.command_buffer[2], mke.command_buffer[3]) - 150;
CHECK_READY(); CHECK_READY();
mke.data_to_push = 0;
while (count) { while (count) {
if ((res = cdrom_readsector_raw(mke.cdrom_dev, buf, lba, 0, mke.sector_type, mke.sector_flags, &len, 0)) > 0) { if ((res = cdrom_readsector_raw(mke.cdrom_dev, buf, lba, 0, mke.sector_type, mke.sector_flags, &len, 0)) > 0) {
fifo8_push_all(&mke.data_fifo, buf, mke.cdrom_dev->sector_size); //fifo8_push_all(&mke.data_fifo, buf, mke.cdrom_dev->sector_size);
lba++; lba++;
buf += mke.cdrom_dev->sector_size; buf += mke.cdrom_dev->sector_size;
mke.data_to_push += mke.cdrom_dev->sector_size;
} else { } else {
fifo8_push(&mke.errors_fifo, res == 0 ? 0x10 : 0x05); fifo8_push(&mke.errors_fifo, res == 0 ? 0x10 : 0x05);
break; break;
@@ -335,8 +364,11 @@ mke_command(uint8_t value)
} }
if (count != 0) { if (count != 0) {
fifo8_reset(&mke.data_fifo); fifo8_reset(&mke.data_fifo);
mke.data_to_push = 0;
} else { } else {
fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke)); //fifo8_push(&mke.info_fifo, mke_cdrom_status(mke.cdrom_dev, &mke));
ui_sb_update_icon(SB_CDROM | mke.cdrom_dev->id, 1);
timer_on_auto(&mke.timer, (1000000.0 / (176400.0 * 2.)) * mke.data_to_push);
} }
break; break;
} }
@@ -634,6 +666,7 @@ mke_close(void *priv)
fifo8_destroy(&mke.info_fifo); fifo8_destroy(&mke.info_fifo);
fifo8_destroy(&mke.data_fifo); fifo8_destroy(&mke.data_fifo);
fifo8_destroy(&mke.errors_fifo); fifo8_destroy(&mke.errors_fifo);
timer_disable(&mke.timer);
} }
static void static void
@@ -647,6 +680,11 @@ mke_cdrom_insert(void *priv)
if (dev->cdrom_dev->ops == NULL) { if (dev->cdrom_dev->ops == NULL) {
// dev->unit_attention = 0; // dev->unit_attention = 0;
dev->cdrom_dev->cd_status = CD_STATUS_EMPTY; dev->cdrom_dev->cd_status = CD_STATUS_EMPTY;
if (timer_is_enabled(&dev->timer)) {
timer_disable(&dev->timer);
mke.data_to_push = 0;
fifo8_push(&dev->errors_fifo, 0x15);
}
fifo8_push(&dev->errors_fifo, 0x11); fifo8_push(&dev->errors_fifo, 0x11);
} else { } else {
// dev->unit_attention = 1; // dev->unit_attention = 1;
@@ -685,7 +723,7 @@ mke_init(const device_t *info)
return NULL; return NULL;
fifo8_create(&mke.info_fifo, 128); fifo8_create(&mke.info_fifo, 128);
fifo8_create(&mke.data_fifo, 624240); fifo8_create(&mke.data_fifo, 624240 * 2);
fifo8_create(&mke.errors_fifo, 8); fifo8_create(&mke.errors_fifo, 8);
fifo8_reset(&mke.info_fifo); fifo8_reset(&mke.info_fifo);
fifo8_reset(&mke.data_fifo); fifo8_reset(&mke.data_fifo);
@@ -707,6 +745,7 @@ mke_init(const device_t *info)
dev->get_channel = mke_get_channel; dev->get_channel = mke_get_channel;
dev->cached_sector = -1; dev->cached_sector = -1;
timer_add(&mke.timer, mke_command_callback, &mke, 0);
uint16_t base = device_get_config_hex16("base"); uint16_t base = device_get_config_hex16("base");
io_sethandler(base, 16, mke_read, NULL, NULL, mke_write, NULL, NULL, &mke); io_sethandler(base, 16, mke_read, NULL, NULL, mke_write, NULL, NULL, &mke);
return &mke; return &mke;